This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
i386 non-matching patterns
- To: gcc at gcc dot gnu dot org
- Subject: i386 non-matching patterns
- From: Torbjorn Granlund <tege at swox dot com>
- Date: 17 Nov 2000 03:39:51 +0100
- Cc: user42 at zip dot com dot au
I am looking into why certain i386 patterns never seem to match:
(define_insn "*addsi3_carry"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
(plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
(match_operand:SI 1 "nonimmediate_operand" "%0,0"))
(match_operand:SI 2 "general_operand" "ri,rm")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (PLUS, SImode, operands)"
"adc{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")
(set_attr "ppro_uops" "few")])
(define_insn "*addsi3_carry0"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
(plus:SI (ltu:SI (reg:CC 17) (const_int 0))
(match_operand:SI 1 "general_operand" "%0,0")))
(clobber (reg:CC 17))]
""
"*
{
operands[2] = const0_rtx;
return \"adc{l}\\t{%2, %0|%0, %2}\";
}"
[(set_attr "type" "alu")
(set_attr "pent_pair" "pu")
(set_attr "mode" "SI")
(set_attr "ppro_uops" "few")])
The first pattern here is in the current snapshots, the 2nd was added
by me as an experiments (it might need an ix86_binary_operator_ok
test, but that is beside the point).
None of these patterns seem to match, at least not for anything that I
have been able to come up with. I debugged combine to see why they
are rejected.
try_combine will first delete the clobber from an incoming addsi_1.
With my experimental pattern, these two patterns,
(insn 36 9 38 (parallel[
(set (reg:SI 46)
(plus:SI (reg/v:SI 42)
(const_int 1 [0x1])))
(clobber (reg:CC 17 flags))
] ) 118 {*addsi_1} (insn_list 4 (nil))
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))
(insn 39 38 24 (set (reg/v:SI 42)
(if_then_else:SI (ltu (reg:CC 17 flags)
(const_int 0 [0x0]))
(reg:SI 46)
(reg/v:SI 42))) 362 {*movsicc_noc} (insn_list 36 (insn_list 38 (nil)))
(expr_list:REG_DEAD (reg:CC 17 flags)
(expr_list:REG_DEAD (reg:SI 46)
(nil))))
get combined into this pattern,
(set (reg/v:SI 42)
(plus:SI (ltu:SI (reg:CC 17 flags)
(const_int 0 [0x0]))
(reg/v:SI 42)))
without the clobber.
In try_combine, we then come here:
/* Note which hard regs this insn has as inputs. */
mark_used_regs_combine (newpat);
/* Is the result of combination a valid instruction? */
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
In mark_used_regs_combine, the register 17 (`flags') will be marked.
Then, when we are trying to match our new pattern, recog sets
num_clobbers_to_add to 1. A PARALLEL is then formed, one that is
exactly what we want:
(parallel[
(set (reg/v:SI 42)
(plus:SI (ltu:SI (reg:CC 17 flags)
(const_int 0 [0x0]))
(reg/v:SI 42)))
(clobber (reg:CC 17 flags))
] )
But then strange things happen that makes this pattern be rejected.
A few lines further down we have this:
for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
i < XVECLEN (newpat, 0); i++)
{
if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG
=> && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
return -1;
notes = gen_rtx_EXPR_LIST (REG_UNUSED,
here the naughty compiler rejects the pattern because register 17 is
marked in newpat_used_regs.
The requirement that clobbered hard regs may not be explicitly
mentioned in the combined pattern seems very strange. Can somebody
please explain why this is needed?
--
Torbjörn