]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/8746 (gcc miscompiles Linux kernel ppa driver on x86)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Tue, 25 Mar 2003 10:18:47 +0000 (11:18 +0100)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 25 Mar 2003 10:18:47 +0000 (10:18 +0000)
PR optimization/8746
* config/i386/i386.md (and promoting splitters): Disable HImode to
SImode promoting when the sign bit matters and is not preserved, or
when TARGET_FAST_PREFIX is true. Disable promoting when optimizing
for size.

From-SVN: r64840

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/i386-signbit-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/i386-signbit-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/i386-signbit-3.c [new file with mode: 0644]

index 7c6d4ee16504524adda9acdf38bf6e6a6c5227d1..2d71171198445d5dc7f3ceba7da04490fd5ffab1 100644 (file)
@@ -1,3 +1,11 @@
+2003-03-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR optimization/8746
+       * config/i386/i386.md (and promoting splitters): Disable HImode to
+       SImode promoting when the sign bit matters and is not preserved, or
+       when TARGET_FAST_PREFIX is true. Disable promoting when optimizing
+       for size.
+
 2003-03-24  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/h8300/h8300.md (a peephole2): Extend to support loads
index ae3957da1e37ba8851e6b76d3f8d313792834269..78663dc37b20979645deae4c013124e932122c3b 100644 (file)
      operands[2] = gen_lowpart (SImode, operands[2]);
    PUT_MODE (operands[3], SImode);")
 
+; Promote the QImode tests, as i386 has encoding of the AND
+; instruction with 32-bit sign-extended immediate and thus the
+; instruction size is unchanged, except in the %eax case for
+; which it is increased by one byte, hence the ! optimize_size.
 (define_split
   [(set (reg 17)
        (compare (and (match_operand 1 "aligned_operand" "")
    (set (match_operand 0 "register_operand" "")
        (and (match_dup 1) (match_dup 2)))]
   "! TARGET_PARTIAL_REG_STALL && reload_completed
-   && ix86_match_ccmode (insn, CCNOmode)
-   && (GET_MODE (operands[0]) == HImode
-       || (GET_MODE (operands[0]) == QImode 
-          /* Ensure that the operand will remain sign extended immediate.  */
-          && INTVAL (operands[2]) >= 0
-          && (TARGET_PROMOTE_QImode || optimize_size)))"
+   /* Ensure that the operand will remain sign-extended immediate.  */
+   && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
+   && ! optimize_size
+   && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
+       || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
   [(parallel [(set (reg:CCNO 17)
                   (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
                                 (const_int 0)))
    operands[0] = gen_lowpart (SImode, operands[0]);
    operands[1] = gen_lowpart (SImode, operands[1]);")
 
-; Don't promote the QImode tests, as i386 don't have encoding of
-; the test instruction with 32bit sign extended immediate and thus
-; the code grows.
+; Don't promote the QImode tests, as i386 doesn't have encoding of
+; the TEST instruction with 32-bit sign-extended immediate and thus
+; the instruction size would at least double, which is not what we
+; want even with ! optimize_size.
 (define_split
   [(set (reg 17)
        (compare (and (match_operand:HI 0 "aligned_operand" "")
                      (match_operand:HI 1 "const_int_operand" ""))
                 (const_int 0)))]
   "! TARGET_PARTIAL_REG_STALL && reload_completed
-   && ix86_match_ccmode (insn, CCNOmode)
-   && GET_MODE (operands[0]) == HImode"
+   /* Ensure that the operand will remain sign-extended immediate.  */
+   && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
+   && ! TARGET_FAST_PREFIX
+   && ! optimize_size"
   [(set (reg:CCNO 17)
        (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
                      (const_int 0)))]
index 53a729be431846a9b3f8c63a62adffe3bb9e4ea6..cf70618d46f86e2f4aa227dee9859b3f61b51ab9 100644 (file)
@@ -1,3 +1,9 @@
+2003-03-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       * gcc.dg/i386-signbit-1.c: New test.
+       * gcc.dg/i386-signbit-2.c: New test.
+       * gcc.dg/i386-signbit-3.c: New test.
+
 2003-03-25  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * gcc.dg/ultrasp5.c: Fix options.
diff --git a/gcc/testsuite/gcc.dg/i386-signbit-1.c b/gcc/testsuite/gcc.dg/i386-signbit-1.c
new file mode 100644 (file)
index 0000000..8b8866e
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR optimization/8746 */
+/* { dg-do run { target i?86-*-* } } */
+/* { dg-options "-O1 -mtune=i586" } */
+
+extern void abort (void);
+
+unsigned char r0;
+
+int foo(int x)
+{
+  unsigned char r = x&0xf0;
+
+  if (!(r&0x80))
+  {
+    r0 = r;
+    return 0;
+  }
+  else
+    return 1;
+}
+
+int main(void)
+{
+  if (foo(0x80) != 1)
+    abort();
+
+   return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/i386-signbit-2.c b/gcc/testsuite/gcc.dg/i386-signbit-2.c
new file mode 100644 (file)
index 0000000..5687d85
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR optimization/8746 */
+/* { dg-do run { target i?86-*-* } } */
+/* { dg-options "-O1 -mtune=i586" } */
+
+extern void abort (void);
+
+unsigned short r0;
+
+int foo(int x)
+{
+  unsigned short r = x&0xf000;
+
+  if (!(r&0x8000))
+  {
+    r0 = r;
+    return 0;
+  }
+  else
+    return 1;
+}
+
+int main(void)
+{
+  if (foo(0x8000) != 1)
+    abort();
+
+   return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/i386-signbit-3.c b/gcc/testsuite/gcc.dg/i386-signbit-3.c
new file mode 100644 (file)
index 0000000..ae97f21
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR optimization/8746 */
+/* { dg-do run { target i?86-*-* } } */
+/* { dg-options "-O1 -mtune=i586" } */
+
+extern void abort (void);
+
+volatile int j;
+
+void f0() { j=0; }
+void f1() { j=1; }
+
+int foo(int x)
+{
+  if ((short int)(x&0x8000) > (short int)0)
+  {
+    f0();
+    return 0;
+  }
+  else
+  {
+    f1();
+    return 1;
+  }
+}
+
+int main(void)
+{
+  if (foo(0x8000) != 1)
+    abort();
+
+   return 0;
+}