On Wed, May 2, 2018 at 9:42 AM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > operands[2] is an input operand in these define_insn_and_split patterns, > so when the masking needs to be still performed, we shouldn't modify that > input register; all the patterns are guarded with can_create_pseudo_p, > so we can create new pseudos there. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2018-05-02 Jakub Jelinek <ja...@redhat.com> > > PR target/85582 > * config/i386/i386.md (*ashl<dwi>3_doubleword_mask, > *ashl<dwi>3_doubleword_mask_1, *<shift_insn><dwi>3_doubleword_mask, > *<shift_insn><dwi>3_doubleword_mask_1): If and[sq]i3 is needed, don't > clobber operands[2], instead use a new pseudo. Formatting fixes. > > * gcc.c-torture/execute/pr85582-1.c: New test. > * gcc.c-torture/execute/pr85582-2.c: New test.
O. Thanks, Uros. > --- gcc/config/i386/i386.md.jj 2018-05-01 12:18:15.566832552 +0200 > +++ gcc/config/i386/i386.md 2018-05-01 13:09:36.635164943 +0200 > @@ -10366,7 +10366,7 @@ (define_insn_and_split "*ashl<dwi>3_doub > (match_operand:SI 2 "register_operand" "c") > (match_operand:SI 3 "const_int_operand")) 0))) > (clobber (reg:CC FLAGS_REG))] > - "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 > + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT) - 1 > && can_create_pseudo_p ()" > "#" > "&& 1" > @@ -10385,8 +10385,12 @@ (define_insn_and_split "*ashl<dwi>3_doub > > operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); > > - if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) > - emit_insn (gen_andsi3 (operands[2], operands[2], operands[3])); > + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT) - 1) > + { > + rtx tem = gen_reg_rtx (SImode); > + emit_insn (gen_andsi3 (tem, operands[2], operands[3])); > + operands[2] = tem; > + } > > operands[2] = gen_lowpart (QImode, operands[2]); > > @@ -10402,7 +10406,7 @@ (define_insn_and_split "*ashl<dwi>3_doub > (match_operand:QI 2 "register_operand" "c") > (match_operand:QI 3 "const_int_operand")))) > (clobber (reg:CC FLAGS_REG))] > - "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 > + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT) - 1 > && can_create_pseudo_p ()" > "#" > "&& 1" > @@ -10421,8 +10425,12 @@ (define_insn_and_split "*ashl<dwi>3_doub > > operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); > > - if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) > - emit_insn (gen_andqi3 (operands[2], operands[2], operands[3])); > + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT) - 1) > + { > + rtx tem = gen_reg_rtx (QImode); > + emit_insn (gen_andqi3 (tem, operands[2], operands[3])); > + operands[2] = tem; > + } > > if (!rtx_equal_p (operands[6], operands[7])) > emit_move_insn (operands[6], operands[7]); > @@ -11118,7 +11126,7 @@ (define_insn_and_split "*<shift_insn><dw > (match_operand:SI 2 "register_operand" "c") > (match_operand:SI 3 "const_int_operand")) 0))) > (clobber (reg:CC FLAGS_REG))] > - "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 > + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT) - 1 > && can_create_pseudo_p ()" > "#" > "&& 1" > @@ -11138,7 +11146,11 @@ (define_insn_and_split "*<shift_insn><dw > operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); > > if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) > - emit_insn (gen_andsi3 (operands[2], operands[2], operands[3])); > + { > + rtx tem = gen_reg_rtx (SImode); > + emit_insn (gen_andsi3 (tem, operands[2], operands[3])); > + operands[2] = tem; > + } > > operands[2] = gen_lowpart (QImode, operands[2]); > > @@ -11154,7 +11166,7 @@ (define_insn_and_split "*<shift_insn><dw > (match_operand:QI 2 "register_operand" "c") > (match_operand:QI 3 "const_int_operand")))) > (clobber (reg:CC FLAGS_REG))] > - "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT)-1 > + "INTVAL (operands[3]) <= (<MODE_SIZE> * BITS_PER_UNIT) - 1 > && can_create_pseudo_p ()" > "#" > "&& 1" > @@ -11173,8 +11185,12 @@ (define_insn_and_split "*<shift_insn><dw > > operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); > > - if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT)-1) > - emit_insn (gen_andqi3 (operands[2], operands[2], operands[3])); > + if (INTVAL (operands[3]) < (<MODE_SIZE> * BITS_PER_UNIT) - 1) > + { > + rtx tem = gen_reg_rtx (QImode); > + emit_insn (gen_andqi3 (tem, operands[2], operands[3])); > + operands[2] = tem; > + } > > if (!rtx_equal_p (operands[4], operands[5])) > emit_move_insn (operands[4], operands[5]); > --- gcc/testsuite/gcc.c-torture/execute/pr85582-1.c.jj 2018-05-01 > 13:28:07.547933727 +0200 > +++ gcc/testsuite/gcc.c-torture/execute/pr85582-1.c 2018-05-01 > 13:26:32.270868649 +0200 > @@ -0,0 +1,21 @@ > +/* PR target/85582 */ > + > +int a, b, d = 2, e; > +long long c = 1; > + > +int > +main () > +{ > + int g = 6; > +L1: > + e = d; > + if (a) > + goto L1; > + g--; > + int i = c >> ~(~e | ~g); > +L2: > + c = (b % c) * i; > + if (!e) > + goto L2; > + return 0; > +} > --- gcc/testsuite/gcc.c-torture/execute/pr85582-2.c.jj 2018-05-01 > 13:28:10.332935636 +0200 > +++ gcc/testsuite/gcc.c-torture/execute/pr85582-2.c 2018-05-01 > 13:28:00.615929000 +0200 > @@ -0,0 +1,51 @@ > +/* PR target/85582 */ > + > +#ifdef __SIZEOF_INT128__ > +typedef __int128 S; > +typedef unsigned __int128 U; > +#else > +typedef long long S; > +typedef unsigned long long U; > +#endif > + > +__attribute__((noipa)) S > +f1 (S x, int y) > +{ > + x = x << (y & 5); > + x += y; > + return x; > +} > + > +__attribute__((noipa)) S > +f2 (S x, int y) > +{ > + x = x >> (y & 5); > + x += y; > + return x; > +} > + > +__attribute__((noipa)) U > +f3 (U x, int y) > +{ > + x = x >> (y & 5); > + x += y; > + return x; > +} > + > +int > +main () > +{ > + S a = (S) 1 << (sizeof (S) * __CHAR_BIT__ - 7); > + S b = f1 (a, 12); > + if (b != ((S) 1 << (sizeof (S) * __CHAR_BIT__ - 3)) + 12) > + __builtin_abort (); > + S c = (U) 1 << (sizeof (S) * __CHAR_BIT__ - 1); > + S d = f2 (c, 12); > + if ((U) d != ((U) 0x1f << (sizeof (S) * __CHAR_BIT__ - 5)) + 12) > + __builtin_abort (); > + U e = (U) 1 << (sizeof (U) * __CHAR_BIT__ - 1); > + U f = f3 (c, 12); > + if (f != ((U) 1 << (sizeof (U) * __CHAR_BIT__ - 5)) + 12) > + __builtin_abort (); > + return 0; > +} > > Jakub