Hi Segher,
On 12/8/2022 上午 1:40, Segher Boessenkool wrote:
> Yes, but combine will use splitters as well.
Combine pass invokes combine_split_insns for 3-insn combine. If we want
to do the split for 2-insn combine (like the test case in PR), we have to
add a special case?
>
> You can use nonzero_bits in the split condition (the second condition in
> a define_split, or the sole condition in a define_split) just fine, as
> long as the replacement RTL does not rely on the nonzero_bits itself.
> You cannot use it in the insn condition (the first condition in a
> define_insn_and_split, or the one condition in a define_insn) because
> that RTL will survive past combine, and then nonzero_bits can have bits
> cleared that were set before (that were determined to be always zero
> during combine, but that knowledge is gone later).
I tried to add a define_insn_and split pattern in rs6000.md, just like the
following code. The nonzero_bits is used in insn condition (for combine)
and no condition for the split. I can't set nonzero_bits in split condition
as it never matches and cause ICE then.
I am not sure if it is safe. If such an insn doesn't stem from the combine,
there is no guarantee that the nonzero_bits condition matches.
(define_insn_and_split "*test"
[(set (match_operand:GPR 0 "gpc_reg_operand")
(plus_ior_xor:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
(match_operand:SI 2 "const_int_operand"))
(match_operand:GPR 3 "gpc_reg_operand")))]
"nonzero_bits (operands[3], <MODE>mode)
< HOST_WIDE_INT_1U << INTVAL (operands[2])"
"#"
""
[(set (match_dup 0)
(ior:GPR (and:GPR (match_dup 3)
(match_dup 4))
(ashift:GPR (match_dup 1)
(match_dup 2))))]
{
operands[4] = GEN_INT ((HOST_WIDE_INT_1U << INTVAL (operands[2])) - 1);
})
Thanks
Gui Haochen