This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
get_condition causes overlow for sign extended constants
- To: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- Subject: get_condition causes overlow for sign extended constants
- From: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Date: Wed, 19 Feb 1997 16:59:35 +0000 (GMT)
In varasm.c:immed_double_const, around line 2052, there is this code:
/* If this would be an entire word for the target, but is not for
the host, then sign-extend on the host so that the number will look
the same way on the host that it would on the target.
For example, when building a 64 bit alpha hosted 32 bit sparc
targeted compiler, then we want the 32 bit unsigned value -1 to be
represented as a 64 bit value -1, and not as 0x00000000ffffffff.
The later confuses the sparc backend. */
if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
&& (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
i0 |= ((HOST_WIDE_INT) (-1) << width);
Thus, it is possible that there are CONST_INTs that have set bits beyond
GET_MODE_MASK. This not only happens for 64->32 bit cross-compiles, but
also for 32->16 bit cross compiles, like for execute/921207-1.c when
cross-compiling from a 32 bit host to d10v.
For 921207-1.c , this is:
(insn 11 8 12 (set (reg:CC_REV 35 f0)
(gtu:CC_REV (reg/v:HI 42)
(const_int -1))) -1 (nil)
However, loop.c:get_condition , there is code that breaks on such CONST_INTS:
HOST_WIDE_INT const_val = INTVAL (op1);
unsigned HOST_WIDE_INT uconst_val = const_val;
unsigned HOST_WIDE_INT max_val
= (unsigned HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (op0));
switch (code)
...
case GE:
if (const_val
!= (((HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
code = GT, op1 = GEN_INT (const_val - 1);
break;
case LEU:
if (uconst_val != max_val)
code = LTU, op1 = GEN_INT (uconst_val + 1);
break;
I propose to fix get_condition to handle this correctly:
Mon Feb 17 22:09:38 1997 J"orn Rennecke <amylaar@cygnus.co.uk>
* loop.c (get_condition): handle sign-extended constants.
Index: loop.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/loop.c,v
retrieving revision 1.97
diff -p -r1.97 loop.c
*** loop.c 1997/02/12 01:38:06 1.97
--- loop.c 1997/02/17 22:12:00
*************** get_condition (jump, earliest)
*** 6980,6994 ****
code = LT, op1 = GEN_INT (const_val + 1);
break;
case GE:
! if (const_val
!= (((HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
code = GT, op1 = GEN_INT (const_val - 1);
break;
case LEU:
! if (uconst_val != max_val)
code = LTU, op1 = GEN_INT (uconst_val + 1);
break;
--- 6980,6996 ----
code = LT, op1 = GEN_INT (const_val + 1);
break;
+ /* When cross-compiling, const_val might be sign-extended from
+ BITS_PER_WORD to HOST_BITS_PER_WIDE_INT */
case GE:
! if ((const_val & max_val)
!= (((HOST_WIDE_INT) 1
<< (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
code = GT, op1 = GEN_INT (const_val - 1);
break;
case LEU:
! if (uconst_val < max_val)
code = LTU, op1 = GEN_INT (uconst_val + 1);
break;