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


Reply via email to