Hello!
Attached patch fixes a couple of thinkos in new ia64 vector permutation code.
2012-01-02 Uros Bizjak <[email protected]>
PR target/51681
* config/ia64/ia64.c (expand_vec_perm_shrp): Use correct operands
for shrp pattern. Correctly handle and fixup shift variable.
2012-01-02 Uros Bizjak <[email protected]>
* config/ia64/ia64.c (expand_vec_perm_broadcast): Use correct
operands for extzv pattern.
Patch was bootstrapped and regression tested on
ia64-unknown-linux-gnu, and fixes following testsuite failures:
FAIL: gcc.dg/torture/vshuf-v2si.c -O2 (internal compiler error)
FAIL: gcc.dg/torture/vshuf-v2si.c -O2 (test for excess errors)
WARNING: gcc.dg/torture/vshuf-v2si.c -O2 compilation failed to
produce executable
FAIL: gcc.dg/torture/vshuf-v8qi.c -O2 execution test
OK for mainline?
Uros.
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c (revision 182780)
+++ config/ia64/ia64.c (working copy)
@@ -11085,7 +11085,7 @@ static bool
expand_vec_perm_shrp (struct expand_vec_perm_d *d)
{
unsigned i, nelt = d->nelt, shift, mask;
- rtx tmp, op0, op1;;
+ rtx tmp, hi, lo;
/* ??? Don't force V2SFmode into the integer registers. */
if (d->vmode == V2SFmode)
@@ -11101,6 +11101,11 @@ expand_vec_perm_shrp (struct expand_vec_perm_d *d)
if (d->testing_p)
return true;
+ hi = shift < nelt ? d->op1 : d->op0;
+ lo = shift < nelt ? d->op0 : d->op1;
+
+ shift %= nelt;
+
shift *= GET_MODE_UNIT_SIZE (d->vmode) * BITS_PER_UNIT;
/* We've eliminated the shift 0 case via expand_vec_perm_identity. */
@@ -11113,11 +11118,9 @@ expand_vec_perm_shrp (struct expand_vec_perm_d *d)
shift = 64 - shift;
tmp = gen_reg_rtx (DImode);
- op0 = (shift < nelt ? d->op0 : d->op1);
- op1 = (shift < nelt ? d->op1 : d->op0);
- op0 = gen_lowpart (DImode, op0);
- op1 = gen_lowpart (DImode, op1);
- emit_insn (gen_shrp (tmp, op0, op1, GEN_INT (shift)));
+ hi = gen_lowpart (DImode, hi);
+ lo = gen_lowpart (DImode, lo);
+ emit_insn (gen_shrp (tmp, hi, lo, GEN_INT (shift)));
emit_move_insn (d->target, gen_lowpart (d->vmode, tmp));
return true;
@@ -11207,7 +11210,7 @@ expand_vec_perm_broadcast (struct expand_vec_perm_
elt *= BITS_PER_UNIT;
temp = gen_reg_rtx (DImode);
emit_insn (gen_extzv (temp, gen_lowpart (DImode, d->op0),
- GEN_INT (elt), GEN_INT (8)));
+ GEN_INT (8), GEN_INT (elt)));
emit_insn (gen_mux1_brcst_qi (d->target, gen_lowpart (QImode, temp)));
break;