]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/59101 (integer wrong code bug)
authorJakub Jelinek <jakub@redhat.com>
Wed, 7 May 2014 16:07:21 +0000 (18:07 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 7 May 2014 16:07:21 +0000 (18:07 +0200)
Backported from mainline
2013-11-14  Jakub Jelinek  <jakub@redhat.com>
    Uros Bizjak  <ubizjak@gmail.com>

PR target/59101
* config/i386/i386.md (*anddi_2): Only allow CCZmode if
operands[2] satisfies_constraint_Z that might have bit 31 set.

* gcc.c-torture/execute/pr59101.c: New test.

From-SVN: r210176

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

index 940ed0fb7c06af39ff2bcb5b186bf8a22619831f..710550042a11f1f6630364f1d5747d8074e0102f 100644 (file)
@@ -1,6 +1,13 @@
 2014-05-07  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2013-11-14  Jakub Jelinek  <jakub@redhat.com>
+                   Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/59101
+       * config/i386/i386.md (*anddi_2): Only allow CCZmode if
+       operands[2] satisfies_constraint_Z that might have bit 31 set.
+
        2013-09-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/58564
index 9b8a96e428d660d5e6f959262b71ffb46906ac35..f09717d15a0cdab4e41c69c0bef938339dd9392f 100644 (file)
         (const_int 0)))
    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
        (and:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
+  "TARGET_64BIT
+   && ix86_match_ccmode
+       (insn,
+        /* If we are going to emit andl instead of andq, and the operands[2]
+           constant might have the SImode sign bit set, make sure the sign
+           flag isn't tested, because the instruction will set the sign flag
+           based on bit 31 rather than bit 63.  If it isn't CONST_INT,
+           conservatively assume it might have bit 31 set.  */
+        (satisfies_constraint_Z (operands[2])
+         && (!CONST_INT_P (operands[2])
+             || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
+        ? CCZmode : CCNOmode)
    && ix86_binary_operator_ok (AND, DImode, operands)"
   "@
    and{l}\t{%k2, %k0|%k0, %k2}
index b28b8ad0dce999403c300f5c7c5afe7ab1d05bda..bc5ef8fe3f3df0ba26ef800420e4e7748069aaa5 100644 (file)
@@ -1,6 +1,11 @@
 2014-05-07  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2013-11-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/59101
+       * gcc.c-torture/execute/pr59101.c: New test.
+
        2013-09-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/58564
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr59101.c b/gcc/testsuite/gcc.c-torture/execute/pr59101.c
new file mode 100644 (file)
index 0000000..ed6a7e8
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/59101 */
+
+__attribute__((noinline, noclone)) int
+foo (int a)
+{
+  return (~a & 4102790424LL) > 0 | 6;
+}
+
+int
+main ()
+{
+  if (foo (0) != 7)
+    __builtin_abort ();
+  return 0;
+}