This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR optimization/8746 (x86)


> Ok, I'll prepare both patches tomorrow.

I've actually prepared a patch for each active branch, but those for the 3.3 
branch and mainline are identical.

The only difference in the patch for the 3.2 branch is that we don't have 
TARGET_FAST_PREFIX. Jan suggested to assume it to be true; however, this 
would end up disabling entirely the HI-->SI promoters, which are currently 
unconditionally enabled (even with optimize_size) on the 3.2 branch.

So I went the conservative way and assumed it to be false on the 3.2 branch, 
so the HI-->SI promoters are only disabled when optimize_size is true.

Ok everywhere after bootstrapping/regtesting (c,c++,objc,f77) on 
i586-redhat-linux-gnu on every active branch?

-- 
Eric Botcazou


2003-03-24  Eric Botcazou  <ebotcazou at libertysurf dot fr>

        PR optimization/8746
        * i386.md (and promoting splitters): Disable HImode to SImode
	promoting when the sign bit matters and is not preserved. Disable
	promoting when optimize_size is true.

2003-03-24  Eric Botcazou  <ebotcazou at libertysurf dot fr>

        PR optimization/8746
        * 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 optimize_size is true.


2003-03-24  Eric Botcazou  <ebotcazou at libertysurf dot fr>

        * gcc.dg/i386-signbit-2.c: New test.
        * gcc.dg/i386-signbit-3.c: New test.
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.339.2.13.2.9
diff -u -r1.339.2.13.2.9 i386.md
--- config/i386/i386.md	19 Mar 2003 19:54:24 -0000	1.339.2.13.2.9
+++ config/i386/i386.md	24 Mar 2003 08:25:28 -0000
@@ -16864,6 +16864,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" "")
@@ -16872,12 +16876,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)
+   /* 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
-       || (GET_MODE (operands[0]) == QImode 
-	   /* Ensure that the operand will remain sign extended immediate.  */
-	   && INTVAL (operands[2]) >= 0
-	   && (TARGET_PROMOTE_QImode || optimize_size)))"
+       || (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)))
@@ -16890,17 +16893,19 @@
    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)
+   && ! optimize_size"
   [(set (reg:CCNO 17)
 	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
 		      (const_int 0)))]
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.404.2.12
diff -u -r1.404.2.12 i386.md
--- config/i386/i386.md	16 Mar 2003 22:24:59 -0000	1.404.2.12
+++ config/i386/i386.md	24 Mar 2003 08:31:36 -0000
@@ -16845,6 +16845,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" "")
@@ -16853,12 +16857,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)))
@@ -16871,17 +16874,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)))]
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.451
diff -u -r1.451 i386.md
--- config/i386/i386.md	18 Mar 2003 19:02:52 -0000	1.451
+++ config/i386/i386.md	24 Mar 2003 08:44:45 -0000
@@ -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)))]
/* PR optimization/8746 */
/* { dg-do run } */
/* { dg-options "-O" { target i?86-*-* } } */

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;
}
/* PR optimization/8746 */
/* { dg-do run } */
/* { dg-options "-O" { target i?86-*-* } } */

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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]