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] PR opt/12280: Avoid RTL sharing in noce_emit_cmove


The following patch resolves PR optimization/12280 which is an ICE on
valid targeted for gcc 3.4.  It turns out that the underlying problem
is caused by RTL sharing between instructions during combine.  The
source of the sharing is noce_emit_cmove in GCC's if-conversion code.

In ifcvt.c, get_condition and noce_get_condition returns the RTL of
the comparison controling a conditional jump, possibly making use of
a preceding condition code setting instruction.  If conversion then
replaces the jump with a conditional move, but leaves the condition
code setting instruction to be eliminated by DCE.  Unfortunately, its
possible to end up sharing the RTL of the comparison's operands in
both the original condition code setter and the new cmove instruction.

In the example attached to the PR, the condition code setter survives
"life analysis" (but with a REG_UNUSED annotation), and combine falls
foul of the sharing producing an unrecognizable instruction which leads
to the ICE in later passes.


The patch below fixes this problem by calling copy_rtx on the operands
of the comparison, prior to creating the conditional move instruction.
I'm also investigating an additional fix to recognize this instruction
as dead during "life", but that would only be a work-around and is
slightly more risky.


The following patch has been tested on i686-pc-linux-gnu with a complete
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.

Ok for mainline?


2003-11-08  Roger Sayle  <roger@eyesopen.com>

	PR optimization/12280
	* ifcvt.c (noce_emit_cmove): Copy the comparison operands to avoid
	sharing RTL between the new cmove and the old condition code setter.


Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 ifcvt.c
*** ifcvt.c	2 Nov 2003 13:56:40 -0000	1.129
--- ifcvt.c	8 Nov 2003 18:55:48 -0000
*************** static rtx
*** 1069,1074 ****
--- 1069,1078 ----
  noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
  		 rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
  {
+   /* Copy comparison operands to avoid sharing RTL.  */
+   cmp_a = copy_rtx (cmp_a);
+   cmp_b = copy_rtx (cmp_b);
+
    /* If earliest == jump, try to build the cmove insn directly.
       This is helpful when combine has created some complex condition
       (like for alpha's cmovlbs) that we can't hope to regenerate


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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