From d2fc77254d4bc5cb5e784cc7823607cc85bc77af Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 25 Mar 2003 11:18:47 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 8 +++++++ gcc/config/i386/i386.md | 28 ++++++++++++++--------- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gcc.dg/i386-signbit-1.c | 28 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/i386-signbit-2.c | 28 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/i386-signbit-3.c | 32 +++++++++++++++++++++++++++ 6 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/i386-signbit-1.c create mode 100644 gcc/testsuite/gcc.dg/i386-signbit-2.c create mode 100644 gcc/testsuite/gcc.dg/i386-signbit-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c6d4ee16504..2d7117119844 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-03-25 Eric Botcazou + + 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 * 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 ae3957da1e37..78663dc37b20 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 53a729be4318..cf70618d46f8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2003-03-25 Eric Botcazou + + * 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 * 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 index 000000000000..8b8866e92aa2 --- /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 000000000000..5687d857a077 --- /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 000000000000..ae97f2156032 --- /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; +} -- 2.47.2