re PR target/85582 (wrong code at -O1 and above on x86_64-linux-gnu in 32-bit mode)
authorJakub Jelinek <jakub@redhat.com>
Wed, 2 May 2018 07:52:08 +0000 (09:52 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 2 May 2018 07:52:08 +0000 (09:52 +0200)
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.

From-SVN: r259825

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr85582-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/pr85582-2.c [new file with mode: 0644]

index 53fa68d9cbb171da28f5d53e2b31bad83db2b176..2792c886b67b9b6c208a1fb5eb3bdb8f678e519e 100644 (file)
@@ -1,3 +1,11 @@
+2018-05-02  Jakub Jelinek  <jakub@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.
+
 2018-05-02  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR tree-optimization/85586
index d85d3467a2fb802a45159c41c8d8fbef216bef89..5913424cfc18791ac9644bad1414b41d892d689c 100644 (file)
              (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"
 
   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]);
 
            (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"
 
   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]);
              (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"
   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]);
 
            (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"
 
   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]);
index 9c93c81a3efa0e0f0fcb784fe0811cc9add903c6..bdbdd17fd463bb9930a63ae6e9ec182ec5565e3a 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-02  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <richard.sandiford@linaro.org>
 
        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 (file)
index 0000000..2a5c5b1
--- /dev/null
@@ -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 (file)
index 0000000..7fd5b55
--- /dev/null
@@ -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;
+}