Hello! Attached patch fixes a couple of thinkos in new ia64 vector permutation code.
2012-01-02 Uros Bizjak <ubiz...@gmail.com> 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 <ubiz...@gmail.com> * 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;