This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: add and compare combination
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-owner@gcc.gnu.org [mailto:gcc-owner@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