This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
patch for v850 ICE in combine
- From: Jim Wilson <wilson at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 20 Sep 2002 17:43:25 -0400
- Subject: patch for v850 ICE in combine
If this testcase is compiled for a v850 target with -O, gcc fails with an ICE.
char x,c;
void func()
{
if (c) x=c;
}
In combine, we have
(parallel [
(set (cc0)
(sign_extend:SI (mem/f:QI (symbol_ref:SI ("c")) [0 c+0 S1 A8])))
(set (reg:QI 42)
(mem/f:QI (symbol_ref:SI ("c")) [0 c+0 S1 A8]))
])
We try to split this into two instructions optimizing away one MEM like so
(set (cc0) (sign_extend:SI ...))
(set (reg:QI 42) (subreg:QI (cc0)))
This dies in simplify_gen_subreg called from gen_lowpart_for_combine,
because VOIDmode subregs aren't valid.
In older gcc versions, this worked OK because gen_lowpart_for_combine just
created a SUBREG without any checks, and then this invalid RTL went
unrecognized and was discarded.
I considered fixing gen_lowpart_for_combine to handle this case, however,
I think the assumption that the invalid RTL will not be recognized is unsafe.
If we have a CCmode register instead of cc0, then it is possible that the
result might be recognized, even though this is not a valid transformation.
Thus I think it is better to fix the splitting code to verify that the
transformation is valid first. We can do this by checking the mode of the
SET_DEST of the first instruction, and making sure that it matches the mode of
its SET_SRC. If the modes are the same, then this is a move, and the
transformation is safe. If the modes are different, then this is a test,
and the transformation is not safe.
This patch was regression tested using an uberbaum tree configured for
v850-elf by running make check in the gcc directory.
I have checked in this patch.
2002-09-20 Jim Wilson <wilson@redhat.com>
* combine.c (try_combine): When split an instruction pair, where the
first has a sign_extend src, verify that the src and dest modes match.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.315
diff -p -r1.315 combine.c
*** combine.c 19 Sep 2002 23:39:34 -0000 1.315
--- combine.c 20 Sep 2002 21:36:08 -0000
*************** try_combine (i3, i2, i1, new_direct_jump
*** 2316,2321 ****
--- 2316,2325 ----
copy. This saves at least one insn, more if register allocation can
eliminate the copy.
+ We cannot do this if the destination of the first assignment is a
+ condition code register or cc0. We eliminate this case by making sure
+ the SET_DEST and SET_SRC have the same mode.
+
We cannot do this if the destination of the second assignment is
a register that we have already assumed is zero-extended. Similarly
for a SUBREG of such a register. */
*************** try_combine (i3, i2, i1, new_direct_jump
*** 2325,2330 ****
--- 2329,2336 ----
&& XVECLEN (newpat, 0) == 2
&& GET_CODE (XVECEXP (newpat, 0, 0)) == SET
&& GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
+ && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))
+ == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0))))
&& GET_CODE (XVECEXP (newpat, 0, 1)) == SET
&& rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))