Fix PR rtl-optimization/56178

Eric Botcazou ebotcazou@adacore.com
Wed Feb 6 18:15:00 GMT 2013


This is the miscompilation of the Ada front-end (ureal.adb) on x86-64/Linux 
with profiled bootstrap and another instance of the infamous webizer bug, 
whereby a REG_EQUAL note for a dead pseudo-register ends up creating an insn 
that wrongly zeroes another pseudo-register.

The origin is fwprop1: from

(insn 399 205 400 13 (set (reg:DI 282 [ ln ])
        (subreg:DI (reg:TI 189) 0)) /home/eric/svn/gcc/gcc/ada/urealp.adb:622 
87 {*movdi_internal_rex64}
     (nil))

(insn 400 399 208 13 (set (reg:DI 283 [ ln+8 ])
        (subreg:DI (reg:TI 189) 8)) /home/eric/svn/gcc/gcc/ada/urealp.adb:622 
87 {*movdi_internal_rex64}
     (expr_list:REG_DEAD (reg:TI 189)

the pass tries to forward-propagate (subreg:DI (reg:TI 189) 0)) into a bunch 
of insns, which almost always fails and thus generates the much dreaded 
REG_EQUAL notes:

In insn 208, replacing
 (subreg:SI (reg:DI 282 [ ln ]) 0)
 with (subreg:SI (reg:TI 189) 0)
Changes to insn 208 not profitable
 Setting REG_EQUAL note

In insn 210, replacing
 (lshiftrt:DI (reg:DI 282 [ ln ])
        (const_int 32 [0x20]))
 with (lshiftrt:DI (subreg:DI (reg:TI 189) 0)
        (const_int 32 [0x20]))
Changes to insn 210 not profitable
 Setting REG_EQUAL note

In insn 252, replacing
 (lshiftrt:DI (reg:DI 283 [ ln+8 ])
        (const_int 32 [0x20]))
 with (lshiftrt:DI (subreg:DI (reg:TI 189) 8)
        (const_int 32 [0x20]))
Changes to insn 252 not profitable
 Setting REG_EQUAL note

In insn 257, replacing
 (subreg:SI (reg:DI 282 [ ln ]) 0)
 with (subreg:SI (reg:TI 189) 0)
Changes to insn 257 not profitable
 Setting REG_EQUAL note

I think there is no point in creating a REG_EQUAL note when you're trying to 
propagate a pseudo (or a subreg of a pseudo here).  As a matter of fact, 
that's what CSE explicitly does not:

      /* If this is a single SET, we are setting a register, and we have an
	 equivalent constant, we want to add a REG_NOTE.   We don't want
	 to write a REG_EQUAL note for a constant pseudo since verifying that
	 that pseudo hasn't been eliminated is a pain.  Such a note also
	 won't help anything.

	 Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
	 which can be created for a reference to a compile time computable
	 entry in a jump table.  */

      if (n_sets == 1 && src_const && REG_P (dest)
	  && !REG_P (src_const)

so we should not do it in fwprop either.  Patch attached (which adds the 
SUBREG case to cse.c as well); it introduces no changes at -O2 for the 
testcases in gcc.c-torture/compile.  Tested on x86-64/Linux.

Thoughts?


2013-02-06  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/56178
	* cse.c (cse_insn): Do not create a REG_EQUAL note if the source is a
	SUBREG of a register.  Tidy up related block of code.
	* fwprop.c (orward_propagate_and_simplify): Do not create a REG_EQUAL
	note if the source is a register or a SUBREG of a register.


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pr56178.diff
Type: text/x-patch
Size: 3483 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20130206/94408941/attachment.bin>


More information about the Gcc-patches mailing list