This is the mail archive of the gcc@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]

trouble emilinating redundant compares


In the port I'm working on I have used the newer CC tracking technique (i.e. not cc0). I have followed the directions at the top of compare-elim.c and have the following pattern for addhi3

(define_insn "addhi3"
[
(set (match_operand:WORD 0 "register_operand" "=r,r,r")
(plus:WORD (match_operand:WORD 1 "register_operand" "0,0,0")
(match_operand:WORD 2 "rhs_operand" "m,r,i")))
(set (reg:CC CC_REGNUM)
(compare:CC
(plus:WORD
(match_dup 1)
(match_dup 2))
(const_int 0)))
]
""
"@
add\t\t%0,[%2]
add\t\t%0,%2
add\t\t%0,#%2"
[(set_attr "length" "4,2,2")]
)


the following code snippet

int x, y;
char ch1 = 1, ch2 = -2;
...
    if( --x )
    {
        ch1 =  ch2;
    }

produces the following rtl

(insn 5 2 6 2 (set (reg:HI 0 r0 [orig:17 x ] [17])
(mem/c/i:HI (symbol_ref:HI ("x") <var_decl 0xb76fe0c0 x>) [0 x+0 S2 A16])) t.c:6 60 {*movhihi}
(expr_list:REG_EQUIV (mem/c/i:HI (symbol_ref:HI ("x") <var_decl 0xb76fe0c0 x>) [0 x+0 S2 A16])
(nil)))
+(insn 6 5 7 2 (parallel [
+ (set (reg:HI 0 r0 [orig:15 x.1 ] [15])
+ (plus:HI (reg:HI 0 r0 [orig:17 x ] [17])
+ (const_int -1 [0xffffffff])))
+ (set (reg:CC 6 flags)
+ (compare:CC (plus:HI (reg:HI 0 r0 [orig:17 x ] [17])
+ (const_int -1 [0xffffffff]))
+ (const_int 0 [0])))
+ ]) t.c:6 20 {addhi3}
+ (nil))
(insn 7 6 8 2 (set (mem/c/i:HI (symbol_ref:HI ("x") <var_decl 0xb76fe0c0 x>) [0 x+0 S2 A16])
(reg:HI 0 r0 [orig:15 x.1 ] [15])) t.c:6 61 {*storehihi}
(nil))
?(insn 8 7 9 2 (set (reg:CC 6 flags)
? (compare:CC (reg:HI 0 r0 [orig:15 x.1 ] [15])
? (const_int 0 [0]))) t.c:6 53 {comparehi3}
? (nil))
(jump_insn 9 8 10 2 (set (pc)
(if_then_else (eq (reg:CC 6 flags)
(const_int 0 [0]))
(label_ref:HI 15)
(pc))) t.c:6 73 {cbranchcc4}
(expr_list:REG_BR_PROB (const_int 3900 [0xf3c])
(nil))
-> 15)
(insn 18 11 12 3 (set (reg:QI 0 r0)
(mem/v/c/i:QI (symbol_ref:HI ("ch2") [flags 0x2] <var_decl 0xb76fe240 ch2>) [0 ch2+0 S1 A8])) t.c:8 62 {*movqiqi}
(nil))
(insn 12 18 15 3 (set (mem/v/c/i:QI (symbol_ref:HI ("ch1") [flags 0x2] <var_decl 0xb76fe1e0 ch1>) [0 ch1+0 S1 A8])
(reg:QI 0 r0)) t.c:8 62 {*movqiqi}
(nil))


I've marked the (plus-1) operation with + in the left border and the subsequent compare the duplicates the CC_REG setting with ? in the left border.

As you can see, the redundant compare hasn't been eliminated and there are no clobbers that should require a re-compare.

I've used gdb to trace through compare-elim.c and discovered that the problem is

conforming_compare (rtx insn)

calling

set = single_set (insn);

on the parallel [plus:compare] operation and not finding the compare:CC sub-operation because the plus::HI operation doesn't include a DEAD_REG note (and I can't see that it should).

I'm clearly missing something... can anyone provide a hint ?

Paul S



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