[PATCH 4.8 v2, i386]: Make CCZ mode compatible with CCGOC and CCGO modes
Uros Bizjak
ubizjak@gmail.com
Sat Feb 11 08:42:00 GMT 2012
On Tue, Feb 7, 2012 at 5:37 PM, Uros Bizjak <ubizjak@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 <ubizjak@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.
More information about the Gcc-patches
mailing list