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/13318


Hi,

This is an integer overflow in the loop optimizer on x86, which causes the 
compiler to abort with SIGFPE.

We have a giv with INT_MIN as the multiplier:

Giv 67: insn 29 src reg 59 benefit 4 lifetime 1 replaceable ncav
 mult (-2147483648)
 add  (0)
Giv 69: insn 33 src reg 59 benefit 4 lifetime 1 replaceable ncav
 mult (-1)
 add  (reg 60)

When trying to express giv 67 from giv 69, loop.c has the following check:

  INTVAL (g2->mult_val) % INTVAL (g1->mult_val) != 0

This is emitted as a signed division on x86 (idivl), which raises SIGFPE 
since the result would be -INT_MIN.

The proposed fix is to add the ad-hoc guard to the check.  I inspected the 
assembly output and it looks correct for the reduced testcase.

Compiled on i586-redhat-linux-gnu. Ok for mainline?


2003-12-06  Eric Botcazou  <ebotcazou@libertysurf.fr>

        PR optimization/13318
        * loop.c (express_from): Protect integer division from overflow.


2003-12-06  Wolfgang Bangerth <bangerth@dealii.org>

	* gcc.dg/overflow-1.c: New test.


-- 
Eric Botcazou
Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.433.2.9
diff -u -p -r1.433.2.9 loop.c
--- loop.c	14 Oct 2003 08:10:28 -0000	1.433.2.9
+++ loop.c	5 Dec 2003 19:52:41 -0000
@@ -7300,6 +7300,9 @@ express_from (g1, g2)
       && GET_CODE (g2->mult_val) == CONST_INT)
     {
       if (g1->mult_val == const0_rtx
+	  || (g1->mult_val == constm1_rtx
+	      && INTVAL (g2->mult_val)
+		 == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
 	  || INTVAL (g2->mult_val) % INTVAL (g1->mult_val) != 0)
 	return NULL_RTX;
       mult = GEN_INT (INTVAL (g2->mult_val) / INTVAL (g1->mult_val));
/* PR optimization/13318 */
/* Origin: <bremner@unb.ca> */
/* Reduced testcase: Wolfgang Bangerth <bangerth@dealii.org> */

/* Verify that the big multiplier doesn't cause an integer
   overflow in the loop optimizer.  */

/* { dg-do compile } */
/* { dg-options "-O2" } */

struct S {
  int key;
  int rnext,rprev;
};
 
void foo(struct S* H)
{
  int i, k;
  for (i=0; i<2; i++){
    struct S* cell=H+k;
    cell->key=i*(0xffffffffUL/2);
    cell->rnext=k+(1-i);
    cell->rprev=k+(1-i);
  }
}

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