On 2/13/23 10:32, Richard Sandiford via Gcc-patches wrote:
Andrew Pinski via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
On Fri, Feb 10, 2023 at 2:47 PM Philipp Tomsich
<philipp.toms...@vrull.eu> wrote:
Some architectures, as it the case on RISC-V with the proposed
ZiCondOps and the vendor-defined XVentanaCondOps, define a
conditional-zero instruction that is equivalent to:
- the positive form: rd = (rc != 0) ? rs : 0
- the negated form: rd = (rc == 0) ? rs : 0
While noce_try_store_flag_mask will somewhat work for this case, it
will generate a number of atomic RTX that will misdirect the cost
calculation and may be too long (i.e., 4 RTX and more) to successfully
merge at combine-time.
Can you expand on this? Especially when there are patterns that use
(if_then_else) already.
Instead, we add two new transforms that attempt to build up what we
define as the canonical form of a conditional-zero expression:
(set (match_operand 0 "register_operand" "=r")
(and (neg (eq_or_ne (match_operand 1 "register_operand" "r")
(const_int 0)))
(match_operand 2 "register_operand" "r")))
Again why are you not using:
(set (reg) (if_then_else (eq_ne (reg) (const_int 0)) (reg) (const_int 0)))
Form instead of the really bad "canonical" form of the above?
I don't think one form is inherently better than the other if we think
about just this one case. But I agree that the if_then_else form is
currently the canonical form for the operation, and extends more
naturally to the general case. AArch64 already matches specifically
for it (with xzr providing the zero value).
The more I think about it, the more I prefer the if-then-else form. My
biggest hesitation with getting behind one form or the other is a lack
of knowledge about which is likely better interpreted by simplify-rtx
and friends -- though it may not matter much in practice.
Jeff