On Tue, Feb 7, 2012 at 5:37 PM, Uros Bizjak <ubiz...@gmail.com> wrote:
>> Attached patch declares CCZmode compatible with CCGOC, CCGO and CCNO modes. > > Actually, CCZ mode is not compatible with CCNO mode, since the later > only declares that overflow flag is not set. CCGOC and CCGO declare > garbage in overflow (and carry in case of CCGOC) flag, so implicitly > declare that CCZ flag is valid. Following this reasoning, CCZ mode > should be compatible with CCGOC and CCGO modes. > > 2012-02-07 Uros Bizjak <ubiz...@gmail.com> > > * config/i386/i386.c (ix86_cc_modes_compatible): Declare CCZmode > compatible with CCGOCmode and CCGCmode. > > Attached patch was bootstrapped and regression tested on x86_64-pc-linux-gnu. ... where it uncovers another problem how RTL optimizer handles compatible compares! With attached patch, the example from pr28685 --cut here-- int test(int a, int b) { int lt = a < b; int eq = a == b; if (lt) return 1; return eq; } --cut here-- triggers compare elimination in CSE2 pass. We enter CSE2 pass with: (insn 8 5 9 2 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:SI 62 [ a ]) (reg/v:SI 63 [ b ]))) pr28685.c:7 6 {*cmpsi_1} (nil)) (jump_insn 9 8 10 2 (set (pc) (if_then_else (lt (reg:CCGC 17 flags) (const_int 0 [0])) (label_ref:DI 15) (pc))) pr28685.c:7 599 {*jcc_1} (expr_list:REG_DEAD (reg:CCGC 17 flags) (expr_list:REG_BR_PROB (const_int 3900 [0xf3c]) (nil))) -> 15) [...] (note 10 9 11 3 [bb 3] NOTE_INSN_BASIC_BLOCK) (insn 11 10 12 3 (set (reg:CCZ 17 flags) (compare:CCZ (reg/v:SI 62 [ a ]) (reg/v:SI 63 [ b ]))) pr28685.c:6 6 {*cmpsi_1} (expr_list:REG_DEAD (reg/v:SI 63 [ b ]) (expr_list:REG_DEAD (reg/v:SI 62 [ a ]) (nil)))) (insn 12 11 13 3 (set (reg:QI 65) (eq:QI (reg:CCZ 17 flags) (const_int 0 [0]))) pr28685.c:6 595 {*setcc_qi} (expr_list:REG_DEAD (reg:CCZ 17 flags) (nil))) After CSE2 pass, we have: (insn 8 5 9 2 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:SI 62 [ a ]) (reg/v:SI 63 [ b ]))) pr28685.c:7 6 {*cmpsi_1} (nil)) (jump_insn 9 8 10 2 (set (pc) (if_then_else (lt (reg:CCGC 17 flags) (const_int 0 [0])) (label_ref:DI 15) (pc))) pr28685.c:7 599 {*jcc_1} (expr_list:REG_DEAD (reg:CCGC 17 flags) (expr_list:REG_BR_PROB (const_int 3900 [0xf3c]) (nil))) -> 15) [...] (note 10 9 12 3 [bb 3] NOTE_INSN_BASIC_BLOCK) (insn 12 10 13 3 (set (reg:QI 65) (eq:QI (reg:CCGC 17 flags) (const_int 0 [0]))) pr28685.c:6 595 {*setcc_qi} (expr_list:REG_DEAD (reg:CCGC 17 flags) (nil))) CSE2 pass eliminated (insn 11), which is OK since CCZ is compatible with CCGC, so (CCGC, CCZ)->CCGC. However, the pass also changed the mode of flags register in (insn 12). I don't think this is correct, the user should not be changed at all. Uros.