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]

[PATCH] Fix PR optimization/9888 (part #1)


Hi,

GCC emits out of range 'loop' instructions on the 3.2 branch for the K6 
family of processors. This is no breaking news since the insn length 
counting machinery has been severely broken for x86 on that branch since the 
following patch:

Tue Jun  6 16:57:30 CEST 2000  Jan Hubicka  <jh at suse dot cz>

 * genattrtab.c (write_attr_value): Do not abort for CONST_INT operands.
 * i386.c (ix86_attr_length_default): Kill.
 (ix86_attr_length_immediate_default, ix86_attr_length_address_default):
 New.
 * i386-protos.h (ix86_attr_length_default): Kill
 (ix86_attr_length_immediate_default, ix86_attr_length_address_default):
 Add prototype
 * i386.md (attribute type): Add "test".
 (attribute length_prefix): Kill.
 (attribute length_opcode): Kill.
 (attribute i387, mode, length_immediate, length_address, prefix_data16,
 prefix_rep, prefix_0f, modrm): New.
 (attribute length): Compute using the new attributes.
 (attribute pent_prefix): New.
 (attribute pent_pair): Compute using pent_prefix.
 (all insn patterns): Set mode,modrm and immediate_length attributes where
 needed.
 (cmpsi patterns): Compute sizes propertly for test instruction.
 (movsi, movhi patterns): Compute sizes propertly for eax shortcuts.
 (movstricthi_xor, movstrictqi_xor): New patterns.
 (andsi/andhi): Use splitters to generate xor instructions.
 (xorqi_ext_1): New pattern.
 (movstricthi->movstricthi_xor peep2): New


I think the complete fix will take at least three patches (the next 2 patches 
will apply to mainline and 3.3 branch too) but I'd like to start by 
backporting one of my patches (present on mainline and 3.3 branch) that 
fixes the most obvious mistakes of the patch above, see:
http://gcc.gnu.org/ml/gcc-patches/2002-06/msg02173.html

Bootstrapped/regtested on k6-redhat-linux-gnu (c,c++,objc,f77). Ok for the 
3.2 branch?

As mentioned in the message from 2002, the patch fixes two testsuite failures

FAIL: gcc.c-torture/execute/dbra-1.c execution,  -O3 -fomit-frame-pointer
FAIL: gcc.c-torture/execute/dbra-1.c execution,  -O3 -g

on k6-redhat-linux-gnu but, since GCC is not bootstrapped very often nowadays 
on K6, I'd like the test to be run on all x86 processors so I made a gcc.dg 
test modeled on it. Ok everywhere?

-- 
Eric Botcazou


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

	PR optimization/9888
	Backport patch from mainline:

	2002-07-03  Eric Botcazou  <ebotcazou at multimania dot com>
	    Jeff Law  <law at redhat dot com>

	* i386.md (length_immediate attribute): Fix typo.
	(length_address attribute): Likewise.
	(modrm attribute): Set it to 0 for immediate call instructions.
	(jcc_1 pattern): Set modrm attribute to 0.
	(jcc_2 pattern ): Likewise.
	(jump pattern): Likewise.
	(doloop_end_internal pattern): Explicitly set length.
	(leave pattern): Fix typo.
	(leave_rex64 pattern): Likewise.


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

	*gcc.dg/i386-loop-1.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.2
diff -u -r1.339.2.13.2.2 i386.md
--- config/i386/i386.md	24 Oct 2002 17:11:54 -0000	1.339.2.13.2.2
+++ config/i386/i386.md	15 Feb 2003 15:43:52 -0000
@@ -131,7 +131,7 @@
 
 ;; The (bounding maximum) length of an instruction immediate.
 (define_attr "length_immediate" ""
-  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
+  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,sse,mmx")
 	   (const_int 0)
 	 (eq_attr "i387" "1")
 	   (const_int 0)
@@ -162,7 +162,7 @@
   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
 	   (const_int 0)
 	 (and (eq_attr "type" "call")
-	      (match_operand 1 "constant_call_address_operand" ""))
+	      (match_operand 0 "constant_call_address_operand" ""))
 	     (const_int 0)
 	 (and (eq_attr "type" "callv")
 	      (match_operand 1 "constant_call_address_operand" ""))
@@ -205,6 +205,12 @@
 	      (and (match_operand 0 "register_operand" "")
 	           (match_operand 1 "immediate_operand" "")))
 	   (const_int 0)
+	 (and (eq_attr "type" "call")
+	      (match_operand 0 "constant_call_address_operand" ""))
+	     (const_int 0)
+	 (and (eq_attr "type" "callv")
+	      (match_operand 1 "constant_call_address_operand" ""))
+	     (const_int 0)
 	 ]
 	 (const_int 1)))
 
@@ -12961,6 +12967,7 @@
   ""
   "%+j%C1\t%l0"
   [(set_attr "type" "ibr")
+   (set_attr "modrm" "0")
    (set (attr "prefix_0f")
 	   (if_then_else (and (ge (minus (match_dup 0) (pc))
 				  (const_int -128))
@@ -12978,6 +12985,7 @@
   ""
   "%+j%c1\t%l0"
   [(set_attr "type" "ibr")
+   (set_attr "modrm" "0")
    (set (attr "prefix_0f")
 	   (if_then_else (and (ge (minus (match_dup 0) (pc))
 				  (const_int -128))
@@ -13244,7 +13252,8 @@
 	(label_ref (match_operand 0 "" "")))]
   ""
   "jmp\t%l0"
-  [(set_attr "type" "ibr")])
+  [(set_attr "type" "ibr")
+   (set_attr "modrm" "0")])
 
 (define_expand "indirect_jump"
   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
@@ -13357,6 +13366,14 @@
     return "dec{l}\t%1\;%+jne\t%l0";
 }
   [(set_attr "ppro_uops" "many")
+   (set (attr "length")
+	(if_then_else (and (eq_attr "alternative" "0")
+			   (and (ge (minus (match_dup 0) (pc))
+			            (const_int -128))
+			        (lt (minus (match_dup 0) (pc))
+			            (const_int 124))))
+		      (const_int 2)
+		      (const_int 16)))
    (set (attr "type")
 	(if_then_else (and (eq_attr "alternative" "0")
 			   (and (ge (minus (match_dup 0) (pc))
@@ -13879,7 +13896,6 @@
   [(set_attr "length_immediate" "0")
    (set_attr "length" "1")
    (set_attr "modrm" "0")
-   (set_attr "modrm" "0")
    (set_attr "athlon_decode" "vector")
    (set_attr "ppro_uops" "few")])
 
@@ -13891,7 +13907,6 @@
   "leave"
   [(set_attr "length_immediate" "0")
    (set_attr "length" "1")
-   (set_attr "modrm" "0")
    (set_attr "modrm" "0")
    (set_attr "athlon_decode" "vector")
    (set_attr "ppro_uops" "few")])
/* PR optimization/9888 */
/* { dg-do run { target i?86-*-* } } */
/* { dg-options "-mcpu=k6 -O3" } */

/* Verify that GCC doesn't emit out of range 'loop' instructions.  */

extern void abort (void);
extern void exit (int);

   
f1 (a)
     long a;
{
  int i;
  for (i = 0; i < 10; i++)
    {
      if (--a == -1)
	return i;
    }
  return -1;
}

f2 (a)
     long a;
{
  int i;
  for (i = 0; i < 10; i++)
    {
      if (--a != -1)
	return i;
    }
  return -1;
}

f3 (a)
     long a;
{
  int i;
  for (i = 0; i < 10; i++)
    {
      if (--a == 0)
	return i;
    }
  return -1;
}

f4 (a)
     long a;
{
  int i;
  for (i = 0; i < 10; i++)
    {
      if (--a != 0)
	return i;
    }
  return -1;
}

f5 (a)
     long a;
{
  int i;
  for (i = 0; i < 10; i++)
    {
      if (++a == 0)
	return i;
    }
  return -1;
}

f6 (a)
     long a;
{
  int i;
  for (i = 0; i < 10; i++)
    {
      if (++a != 0)
	return i;
    }
  return -1;
}


int main()
{
  if (f1 (5L) != 5)
    abort ();
  if (f2 (1L) != 0)
    abort ();
  if (f2 (0L) != 1)
    abort ();
  if (f3 (5L) != 4)
    abort ();
  if (f4 (1L) != 1)
    abort ();
  if (f4 (0L) != 0)
    abort ();
  if (f5 (-5L) != 4)
    abort ();
  if (f6 (-1L) != 1)
    abort ();
  if (f6 (0L) != 0)
    abort ();
  exit (0);
}

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