From 014dcf477d1504e3259a901fc9ebc4f091cf07f6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 2 May 2018 09:52:08 +0200 Subject: [PATCH] re PR target/85582 (wrong code at -O1 and above on x86_64-linux-gnu in 32-bit mode) PR target/85582 * config/i386/i386.md (*ashl3_doubleword_mask, *ashl3_doubleword_mask_1, *3_doubleword_mask, *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. From-SVN: r259825 --- gcc/ChangeLog | 8 ++++ gcc/config/i386/i386.md | 38 ++++++++++++------ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.c-torture/execute/pr85582-1.c | 21 ++++++++++ gcc/testsuite/gcc.c-torture/execute/pr85582-2.c | 51 +++++++++++++++++++++++++ 5 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr85582-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr85582-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53fa68d..2792c88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-05-02 Jakub Jelinek + + PR target/85582 + * config/i386/i386.md (*ashl3_doubleword_mask, + *ashl3_doubleword_mask_1, *3_doubleword_mask, + *3_doubleword_mask_1): If and[sq]i3 is needed, don't + clobber operands[2], instead use a new pseudo. Formatting fixes. + 2018-05-02 Richard Sandiford PR tree-optimization/85586 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index d85d346..5913424 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -10366,7 +10366,7 @@ (match_operand:SI 2 "register_operand" "c") (match_operand:SI 3 "const_int_operand")) 0))) (clobber (reg:CC FLAGS_REG))] - "INTVAL (operands[3]) <= ( * BITS_PER_UNIT)-1 + "INTVAL (operands[3]) <= ( * BITS_PER_UNIT) - 1 && can_create_pseudo_p ()" "#" "&& 1" @@ -10385,8 +10385,12 @@ operands[8] = GEN_INT ( * BITS_PER_UNIT); - if (INTVAL (operands[3]) < ( * BITS_PER_UNIT)-1) - emit_insn (gen_andsi3 (operands[2], operands[2], operands[3])); + if (INTVAL (operands[3]) < ( * 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 @@ (match_operand:QI 2 "register_operand" "c") (match_operand:QI 3 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] - "INTVAL (operands[3]) <= ( * BITS_PER_UNIT)-1 + "INTVAL (operands[3]) <= ( * BITS_PER_UNIT) - 1 && can_create_pseudo_p ()" "#" "&& 1" @@ -10421,8 +10425,12 @@ operands[8] = GEN_INT ( * BITS_PER_UNIT); - if (INTVAL (operands[3]) < ( * BITS_PER_UNIT)-1) - emit_insn (gen_andqi3 (operands[2], operands[2], operands[3])); + if (INTVAL (operands[3]) < ( * 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 @@ (match_operand:SI 2 "register_operand" "c") (match_operand:SI 3 "const_int_operand")) 0))) (clobber (reg:CC FLAGS_REG))] - "INTVAL (operands[3]) <= ( * BITS_PER_UNIT)-1 + "INTVAL (operands[3]) <= ( * BITS_PER_UNIT) - 1 && can_create_pseudo_p ()" "#" "&& 1" @@ -11138,7 +11146,11 @@ operands[8] = GEN_INT ( * BITS_PER_UNIT); if (INTVAL (operands[3]) < ( * 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 @@ (match_operand:QI 2 "register_operand" "c") (match_operand:QI 3 "const_int_operand")))) (clobber (reg:CC FLAGS_REG))] - "INTVAL (operands[3]) <= ( * BITS_PER_UNIT)-1 + "INTVAL (operands[3]) <= ( * BITS_PER_UNIT) - 1 && can_create_pseudo_p ()" "#" "&& 1" @@ -11173,8 +11185,12 @@ operands[8] = GEN_INT ( * BITS_PER_UNIT); - if (INTVAL (operands[3]) < ( * BITS_PER_UNIT)-1) - emit_insn (gen_andqi3 (operands[2], operands[2], operands[3])); + if (INTVAL (operands[3]) < ( * 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]); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c93c81..bdbdd17 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-05-02 Jakub Jelinek + + PR target/85582 + * gcc.c-torture/execute/pr85582-1.c: New test. + * gcc.c-torture/execute/pr85582-2.c: New test. + 2018-05-02 Richard Sandiford PR tree-optimization/85586 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr85582-1.c b/gcc/testsuite/gcc.c-torture/execute/pr85582-1.c new file mode 100644 index 0000000..2a5c5b1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr85582-1.c @@ -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; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr85582-2.c b/gcc/testsuite/gcc.c-torture/execute/pr85582-2.c new file mode 100644 index 0000000..7fd5b55 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr85582-2.c @@ -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; +} -- 2.7.4