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 #4)


Hi,

This is the final part. Currently the condition used to switch between short 
and long branches is:

(if_then_else (and (ge (minus (match_dup 0) (pc))
				  (const_int -128))
			      (lt (minus (match_dup 0) (pc))
				  (const_int 124)))

This is wrong because the range (-128 to 127) must be mesured after the PC 
has been incremented by the instruction length, which is 2 for the short 
branch versions of all variable length instructions. Now the branch 
shortening pass does the calculation before incrementing the current 
address, so the range must be shifted by 2, that is -126 to 129.

However it is safer to assume that the calculation could be performed after 
incrementing the current address too; so taking the intersection of both 
ranges provides a good enough solution, that is -126 to 127 or

(if_then_else (and (ge (minus (match_dup 0) (pc))
				  (const_int -126))
			      (lt (minus (match_dup 0) (pc))
				  (const_int 128)))

(The stormy16 port uses this approach too).

Bootstrapped/regtested (c,c++,f77,objc for all 3 active branches) on 
k6-redhat-linux-gnu. Also bootstrapped on the 3.2 branch with -g -Os.
Ok for mainline and 3.3? Ok for 3.2?

-- 
Eric Botcazou


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

        PR optimization/9888
        * config/i386/i386.md (jcc_1): Fix range.
	(jcc_2): Likewise.
	(jump): LIkewise.
	(doloop_end_internal): Likewise.


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

	* gcc.dg/i386-loop-2.c: New test.
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.404.2.8
diff -u -r1.404.2.8 i386.md
--- config/i386/i386.md	22 Feb 2003 10:04:12 -0000	1.404.2.8
+++ config/i386/i386.md	9 Mar 2003 23:10:23 -0000
@@ -12840,9 +12828,9 @@
    (set_attr "modrm" "0")
    (set (attr "length")
 	   (if_then_else (and (ge (minus (match_dup 0) (pc))
-				  (const_int -128))
+				  (const_int -126))
 			      (lt (minus (match_dup 0) (pc))
-				  (const_int 124)))
+				  (const_int 128)))
 	     (const_int 2)
 	     (const_int 6)))])
 
@@ -12858,9 +12846,9 @@
    (set_attr "modrm" "0")
    (set (attr "length")
 	   (if_then_else (and (ge (minus (match_dup 0) (pc))
-				  (const_int -128))
+				  (const_int -126))
 			      (lt (minus (match_dup 0) (pc))
-				  (const_int 124)))
+				  (const_int 128)))
 	     (const_int 2)
 	     (const_int 6)))])
 
@@ -13125,9 +13113,9 @@
   [(set_attr "type" "ibr")
    (set (attr "length")
 	   (if_then_else (and (ge (minus (match_dup 0) (pc))
-				  (const_int -128))
+				  (const_int -126))
 			      (lt (minus (match_dup 0) (pc))
-				  (const_int 124)))
+				  (const_int 128)))
 	     (const_int 2)
 	     (const_int 5)))
    (set_attr "modrm" "0")])
@@ -13251,9 +13239,9 @@
    (set (attr "length")
 	(if_then_else (and (eq_attr "alternative" "0")
 			   (and (ge (minus (match_dup 0) (pc))
-			            (const_int -128))
+			            (const_int -126))
 			        (lt (minus (match_dup 0) (pc))
-			            (const_int 124))))
+			            (const_int 128))))
 		      (const_int 2)
 		      (const_int 16)))
    ;; We don't know the type before shorten branches.  Optimistically expect
/* PR optimization/9888 */
/* Originator: Jim Bray <jb at as220 dot org> */
/* { dg-do run { target i?86-*-* } } */
/* { dg-options "-mcpu=k6 -Os" } */

enum reload_type
{
  RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN,
  RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_INPADDR_ADDRESS,
  RELOAD_FOR_OUTPUT_ADDRESS, RELOAD_FOR_OUTADDR_ADDRESS,
  RELOAD_FOR_OPERAND_ADDRESS, RELOAD_FOR_OPADDR_ADDR,
  RELOAD_OTHER, RELOAD_FOR_OTHER_ADDRESS
};

#define FOO_SIZE 3

/* My results, varying with FOO_SIZE:
   30: asm error "value of ..fff77 too large:
   3 to 29: ....ff7d...
   1 to 2: no error.  */

struct reload
{
   int foo[FOO_SIZE];
   int opnum; 
   enum reload_type when_needed;
   unsigned int optional:1; 
   unsigned int secondary_p:1;
};

#define N_RELOADS  2

struct reload rld[N_RELOADS];
int n_reloads = N_RELOADS;

int main(void)
{
  int i;

  enum reload_type operand_type[1];

  enum reload_type address_type[1];

  int operand_reloadnum[1];
  int goal_alternative_matches[1];

  for (i = 0; i < n_reloads; i++)
    {
      if (rld[i].secondary_p
          && rld[i].when_needed == operand_type[rld[i].opnum])
        rld[i].when_needed = address_type[rld[i].opnum];

      if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
           || rld[i].when_needed == RELOAD_FOR_OUTPUT_ADDRESS
           || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
           || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
          && (operand_reloadnum[rld[i].opnum] < 0
              || rld[operand_reloadnum[rld[i].opnum]].optional))
        {

          if (rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS
              || rld[i].when_needed == RELOAD_FOR_OUTADDR_ADDRESS)
            rld[i].when_needed = RELOAD_FOR_OPADDR_ADDR;
          else
            rld[i].when_needed = RELOAD_FOR_OPERAND_ADDRESS;
        }

      if ((rld[i].when_needed == RELOAD_FOR_INPUT_ADDRESS
           || rld[i].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
          && operand_reloadnum[rld[i].opnum] >= 0
          && (rld[operand_reloadnum[rld[i].opnum]].when_needed
              == RELOAD_OTHER))
        rld[i].when_needed = RELOAD_FOR_OTHER_ADDRESS;

      if (goal_alternative_matches[rld[i].opnum] >= 0)
        rld[i].opnum = goal_alternative_matches[rld[i].opnum];
    }

  return 0;
}

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