This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA:] combine.c: Fold comparison in original mode. Fix for execute/960608-1.c and execute/20001009-1.c
- To: gcc-patches at gcc dot gnu dot org
- Subject: [RFA:] combine.c: Fold comparison in original mode. Fix for execute/960608-1.c and execute/20001009-1.c
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- Date: Thu, 23 Nov 2000 15:51:14 +0100
I think I have the right fix for execute/960608-1.c and
execute/20001009-1.c which are giving failures on both
i686-pc-linux-gnu and cris-axis-none (or cris-axis-elf if you're
confused by "none") and it seems also a few other targets.
For CRIS and 960608-1.c, I get this coming in to try_combine:
(insn 28 27 32 (set (reg:QI 34)
(const_int -50 [0xffffffce])) 41 {movqi} (nil)
(nil))
(insn/i 36 32 37 (set (cc0)
(compare (reg:QI 34)
(const_int 206 [0xce]))) 11 {cmpqi} (insn_list 28 (nil))
(expr_list:REG_DEAD (reg:QI 34)
(nil)))
(insn/i 37 36 43 (set (reg:SI 39)
(ne:SI (cc0)
(const_int 0 [0x0]))) 180 {sne} (nil)
(nil))
This gets combined to:
(set (reg:SI 39)
(ne:SI (const_int -50 [0xffffffce])
(const_int 206 [0xce])))
and folded as:
(insn/i 37 36 43 (set (reg:SI 39)
(const_int 1 [0x1])) 32 {movsi} (nil)
(nil))
This happens when (const_int -50) is substituted into (reg:QI
34) because the comparison-folding is not done in QImode, but
instead in VOIDmode, i.e. "infinite precision", where -50 !=
206. In QImode, the values are equal. The mode of the
substituted operand is provided in op0_mode for what seems like
exactly the purpose of folding in the right mode.
I don't know if the incoming value 206 above should in fact have
been sign-extended, but I can't find an explicit assertion that
such an assumption can be done about bits outside the used type,
so I believe nothing should be assumed, and the incoming values
are ok.
Bootstrapped on i686-pc-linux-gnu with no new regressions, and
fixing the two failures (or seven, depending on how you count)
in execute/960608-1.c and execute/20001009-1.c.
Ok to commit?
* combine.c (combine_simplify_rtx) <expression folding>: Do any
simplification in op0_mode for a comparison of two constants.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.164
diff -c -p -c -p -5 -r1.164 combine.c
*** combine.c 2000/11/07 22:49:51 1.164
--- combine.c 2000/11/22 22:10:18
*************** combine_simplify_rtx (x, op0_mode, last,
*** 3636,3645 ****
--- 3636,3654 ----
case '<':
{
enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
if (cmp_mode == VOIDmode)
cmp_mode = GET_MODE (XEXP (x, 1));
+
+ /* Both operands can now be constants. This happens when
+ substituting a constant into a register, when the other
+ operand is a constant. We must then use the original mode
+ for operand 0 when simplifying the comparison, as the
+ constants cannot be assumed to both be zero- or sign-extended
+ outside that mode. */
+ if (cmp_mode == VOIDmode)
+ cmp_mode = op0_mode;
temp = simplify_relational_operation (code, cmp_mode,
XEXP (x, 0), XEXP (x, 1));
}
#ifdef FLOAT_STORE_FLAG_VALUE
if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
brgds, H-P