Well, I run combine pass in debug mode and found my mistakes. I'd like to share what I have found :)
There were 2 mistake. First my HARD_REGNO_MODE_OK returned 0 for regno=CCI_REG and mode=CCmode which lead to an early failure in combine.c. So I added this to my macro : if (GET_MODE_CLASS (mode) == MODE_CC) return (regno == CCI_REG) Secondly, I figured out that combination was different for the 2 following code : c = a + b; if (c) {...} /* use c further in code */ and if (a + b) {...} /* the addition result is a DEAD_REG */ In the first case the combiner create and try to match a parallel rtx similar to my "add_and_compare". This case was in fact working. In the second case the combiner see the DEAD_REG and try to match a single set rtx of this form : (define_insn "comparesi_plus" [(set (reg:CC CCI_REG) (compare:CC (match_operand:SI 0 "register_operand" "r") (neg:SI (match_operand:SI 1 "register_operand" "r"))))] ;; the 'trick' is in the neg !! "" "cmp_plus %1,%0" ) As I had no such insn the combination was failing, when I added one (with a clobbered result because I have no cmp_plus instruction), everything run ok. I watched in arm backend and I found a similar insn... So the solution was in front of me but I did not see it :) Selim -----Message d'origine----- De : gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] De la part de BELBACHIR Selim Envoyé : jeudi 15 décembre 2011 16:12 À : gcc@gcc.gnu.org Objet : add and compare combination Hi, I'd like to know if there a way to express 'add' and 'compare' insn so that the combiner transform it in and 'add_and_compare' insn. I watch arm backend and it seems possible when I look at 'addsi3', 'cbranchsi4' and '*addsi3_compare0'. In my backend I have written the following insn/expand : (define_expand "addsi3" [(set (match_operand:SI 0 "register_operand" "") (plus:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "off1post_general_op" "")))] "" "" ) (define_insn "add_and_compare" [(set (reg:CC CCI_REG) (compare:CC (plus:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "register_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 1) (match_dup 2)))] "" "add %1,%2,%0" ) (define_insn "add" [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "register_operand" "r")))] "" "addk %1,%2,%0" ) (define_expand "cbranchsi4" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" "")]) (label_ref (match_operand 3 "" "")) (pc)))] { emit_insn(gen_comparesi (operands[1], operands[2])); operands[1] = gen_rtx_REG (CCmode, CCI_REG); operands[2] = const0_rtx; } ) (define_insn "comparesi" [(set (reg:CC CCI_REG) (compare:CC (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "register_operand" "r")))] "" "cmp %1,%0" ) (define_insn "jmpifsi" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(reg:CC CCI_REG) (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] "" "jmp.if %c0 %1" ) When I compile : c = a + b; if (c) {...} No combination occurs between "add" and "comparesi" insn. I was expecting to see my "add_and_compare" pattern. The resulting assembler is addk cmp jmp.if instead of add jmp.if Do someone see why combination fails ? (gcc 4.5.2) Thanks, Selim