diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2003-03-25 11:18:47 +0100 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2003-03-25 10:18:47 +0000 |
commit | d2fc77254d4bc5cb5e784cc7823607cc85bc77af (patch) | |
tree | 97171a6cb94b5038efefa41b68e3e68b36a5edf5 | |
parent | 9904e2320fd33d0d02d2582a6cb78cbb9f01bff4 (diff) | |
download | gcc-d2fc77254d4bc5cb5e784cc7823607cc85bc77af.zip gcc-d2fc77254d4bc5cb5e784cc7823607cc85bc77af.tar.gz gcc-d2fc77254d4bc5cb5e784cc7823607cc85bc77af.tar.bz2 |
re PR rtl-optimization/8746 (gcc miscompiles Linux kernel ppa driver on x86)
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 28 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-signbit-1.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-signbit-2.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/i386-signbit-3.c | 32 |
6 files changed, 119 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c6d4ee..2d71171 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ae3957d..78663dc 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17628,6 +17628,10 @@ 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" "") @@ -17636,12 +17640,11 @@ (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))) @@ -17654,17 +17657,20 @@ 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)))] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 53a729b..cf70618 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 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. 2003-03-24 Eric Botcazou <ebotcazou@libertysurf.fr> diff --git a/gcc/testsuite/gcc.dg/i386-signbit-1.c b/gcc/testsuite/gcc.dg/i386-signbit-1.c new file mode 100644 index 0000000..8b8866e --- /dev/null +++ b/gcc/testsuite/gcc.dg/i386-signbit-1.c @@ -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 index 0000000..5687d85 --- /dev/null +++ b/gcc/testsuite/gcc.dg/i386-signbit-2.c @@ -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 index 0000000..ae97f21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/i386-signbit-3.c @@ -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; +} |