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, rtl-optimization]: Fix post-reload compare elimination pre-pass


Hello!

I am trying to enable post-reload compare elimination pass on x86, and
I discovered a problem in the way redundant compares are eliminated.
The problem lies in the assumption that:

  (1) All comparison patterns are represented as

       [(set (reg:CC) (compare:CC (reg) (immediate)))]

which is not true for x86 or any target which exposes FLAGS_REG early
and defines SELECT_CC_MODE.

Following testcase:

--cut here--
int test (int a, int b)
{
 int lt = a + b < 0;
 int eq = a + b == 0;
 if (lt)
   return 1;
 return eq;
}
--cut here--

compiles to the following dump before entering post-reload compare
elimination pass:

(insn 8 4 9 2 (parallel [
           (set (reg:SI 4 si [orig:60 D.1710 ] [60])
               (plus:SI (reg/v:SI 5 di [orig:63 a ] [63])
                   (reg/v:SI 4 si [orig:64 b ] [64])))
           (clobber (reg:CC 17 flags))
       ]) cmp.c:3 253 {*addsi_1}
    (nil))

(insn 9 8 10 2 (set (reg:CCZ 17 flags)
       (compare:CCZ (reg:SI 4 si [orig:60 D.1710 ] [60])
           (const_int 0 [0]))) cmp.c:4 2 {*cmpsi_ccno_1}
    (nil))

(note 10 9 33 2 NOTE_INSN_DELETED)

(insn 33 10 34 2 (set (reg:QI 1 dx [65])
       (eq:QI (reg:CCZ 17 flags)
           (const_int 0 [0]))) cmp.c:4 595 {*setcc_qi}
    (nil))

(insn 34 33 30 2 (set (reg:SI 1 dx [65])
       (zero_extend:SI (reg:QI 1 dx [65]))) cmp.c:4 123
{*zero_extendqisi2_movzbl}
    (nil))

(insn 30 34 29 2 (set (reg/v:SI 0 ax [orig:59 eq ] [59])
       (const_int 1 [0x1])) cmp.c:6 64 {*movsi_internal}
    (expr_list:REG_EQUAL (const_int 1 [0x1])
       (nil)))

(insn 29 30 31 2 (set (reg:CCGOC 17 flags)
       (compare:CCGOC (reg:SI 4 si [orig:60 D.1710 ] [60])
           (const_int 0 [0]))) cmp.c:6 2 {*cmpsi_ccno_1}
    (nil))

(insn 31 29 25 2 (set (reg/v:SI 0 ax [orig:59 eq ] [59])
       (if_then_else:SI (ge (reg:CCGOC 17 flags)
               (const_int 0 [0]))
           (reg:SI 1 dx [65])
           (reg/v:SI 0 ax [orig:59 eq ] [59]))) cmp.c:6 903 {*movsicc_noc}
    (nil))

The redundant-compare elimination pre-pass blindly eliminates (insn
29) from the sequence. The elimination is done without updating the
compare mode in (insn 9)! The correct approach would be to also update
the compare mode of (insn 9) to the mode of
targetm.cc_modes_compatible target hook, which in the case abowe would
be (CCZmode, CCGOCmode) -> CCGOCmode.

Attached patch fixes this problem by checking for mode compatibility
of redundant compare with previous compare before elimination, and
sets the mode of previous compare to mode, compatible with both
compares.

2012-02-10  Uros Bizjak  <ubizjak@gmail.com>

	* compare-elim.c (find_comparisons_in_bb): Eliminate only compares
	having mode compatible with the mode of previous compare.  Substitute
	compare mode of previous compare with the mode, compatible
	with eliminated and previous compare.

Patch was bootstrapped and regression tested with additional x86
specific patch that enables post-reload compare eliminations on
x86_64-pc-linux-gnu {,-m32}. The complete patch is attached to this
message.

Is RTL optimisation part of the patch OK for mainline SVN and 4.6 ?

Uros.

Attachment: cc.diff.txt
Description: Text document


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