GCC-SH: bug in force_to_mode()
Toshi Morita
tm2@best.com
Sun Feb 25 13:21:00 GMT 2001
version: GCC CVS 2/23/2001 & gcc-2.95.2
host: i386-linux
target: sh-elf
I've found a bug in force_to_mode() in combine.c.
The bug occurs when simplify_logical() is called for SImode, with reg:SI 57
known to contain 0:
(gdb)
simplify_logical (x=0x8289138, last=0) at combine.c:4912
4912 if (last
(gdb)
4907 x = simplify_and_const_int (x, mode, op0, INTVAL (op1));
(gdb) call debug_rtx(x)
(and:SI (plus:SI (reg/v:SI 57)
(const_int 23 [0x17]))
(const_int 60 [0x3c]))
(gdb) next
4912 if (last
(gdb) call debug_rtx(x)
(const_int 23 [0x17])
(gdb)
simplify_logical() winds up calling a few things, and eventually winds up
in force_to_mode():
(gdb) bt
#0 force_to_mode (x=0x82890c8, mode=SImode, mask=4294967295, reg=0x0,
just_select=0) at combine.c:6493
#1 0x81525d3 in simplify_and_const_int (x=0x8289138, mode=SImode,
varop=0x82890c8, constop=60) at combine.c:7322
#2 0x814e945 in simplify_logical (x=0x8289138, last=0) at combine.c:4907
The bug occurs because of this code in force_to_mode():
/* When we have an arithmetic operation, or a shift whose count we
do not know, we need to assume that all bit the up to the highest-order
bit in MASK will be needed. This is how we form such a mask. */
if (op_mode)
fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
? GET_MODE_MASK (op_mode)
: ((HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1)) - 1);
else
fuller_mask = ~ (HOST_WIDE_INT) 0;
...
case MINUS:
case MULT:
/* For PLUS, MINUS and MULT, we need any bits less significant than the
most significant bit in MASK since carries from those bits will
affect the bits we are interested in. */
mask = fuller_mask;
goto binop;
This code appears to be needed because ((A + B) & C) != (A & C) + (B & C)
because the low-order bits may affect the result. This is fine, but
the original mask is never applied because the mask = fuller_mask; is
executed and the original mask has been overwritten!
How should this be fixed? Should simplify_and_const_int not be calling
force_to_mode?
Toshi
More information about the Gcc-bugs
mailing list