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]

[arm] 64-bit host bug in arm_canonicalize_comparison


The code in arm_canonicalize_comparison incorrectly uses the width of 
HOST_WIDE_INT to determine if a signed value will wrap. This breaks on 64-bit 
hosts.
The attached patch changes this code to use the mode of the argument when 
determining if the increment would overflow.

Tested on arm-none-eabi.
Applied to mainline and csl-arm-branch.

Paul

2005-07-30  Paul Brook  <paul@codesourcery.com>

	* config/arm/arm-protos.h (arm_canonicalize_comparison): Update
	prototype.
	* config/arm/arm.c (arm_canonicalize_comparison): Use correct limit
	value for mode.
	* config/arm/arm.h (CANONICALIZE_COMPARISON): Pass mode argument.
Index: gcc/config/arm/arm-protos.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.88
diff -u -p -r1.88 arm-protos.h
--- gcc/config/arm/arm-protos.h	28 Jun 2005 19:51:26 -0000	1.88
+++ gcc/config/arm/arm-protos.h	29 Jul 2005 15:46:34 -0000
@@ -52,7 +52,8 @@ extern int arm_hard_regno_mode_ok (unsig
 extern int const_ok_for_arm (HOST_WIDE_INT);
 extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
 			       HOST_WIDE_INT, rtx, rtx, int);
-extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
+extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
+					     rtx *);
 extern int legitimate_pic_operand_p (rtx);
 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
 extern int arm_legitimate_address_p  (enum machine_mode, rtx, RTX_CODE, int);
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.468
diff -u -p -r1.468 arm.c
--- gcc/config/arm/arm.c	7 Jul 2005 22:14:07 -0000	1.468
+++ gcc/config/arm/arm.c	29 Jul 2005 15:46:34 -0000
@@ -2328,9 +2328,12 @@ arm_gen_constant (enum rtx_code code, en
    immediate value easier to load.  */
 
 enum rtx_code
-arm_canonicalize_comparison (enum rtx_code code, rtx * op1)
+arm_canonicalize_comparison (enum rtx_code code, enum machine_mode mode,
+			     rtx * op1)
 {
   unsigned HOST_WIDE_INT i = INTVAL (*op1);
+  unsigned HOST_WIDE_INT maxval;
+  maxval = (((unsigned HOST_WIDE_INT) 1) << (GET_MODE_BITSIZE(mode) - 1)) - 1;
 
   switch (code)
     {
@@ -2340,7 +2343,7 @@ arm_canonicalize_comparison (enum rtx_co
 
     case GT:
     case LE:
-      if (i != ((((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1)) - 1)
+      if (i != maxval
 	  && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
 	{
 	  *op1 = GEN_INT (i + 1);
@@ -2350,7 +2353,7 @@ arm_canonicalize_comparison (enum rtx_co
 
     case GE:
     case LT:
-      if (i != (((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1))
+      if (i != ~maxval
 	  && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
 	{
 	  *op1 = GEN_INT (i - 1);
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /var/cvsroot/gcc-cvs/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.285
diff -u -p -r1.285 arm.h
--- gcc/config/arm/arm.h	28 Jun 2005 19:51:29 -0000	1.285
+++ gcc/config/arm/arm.h	29 Jul 2005 15:48:31 -0000
@@ -2243,7 +2243,8 @@ extern int making_const_table;
 	        || (const_ok_for_arm (- INTVAL (OP1)))))		\
         {								\
           rtx const_op = OP1;						\
-          CODE = arm_canonicalize_comparison ((CODE), &const_op);	\
+          CODE = arm_canonicalize_comparison ((CODE), GET_MODE (OP0),	\
+					      &const_op);		\
           OP1 = const_op;						\
         }								\
     }									\

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