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]

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))


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