https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116240
Jeffrey A. Law <law at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
CC| |law at gcc dot gnu.org
Status|UNCONFIRMED |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |law at gcc dot gnu.org
Last reconfirmed| |2024-08-06
--- Comment #1 from Jeffrey A. Law <law at gcc dot gnu.org> ---
It's a clear bug in the cost handling:
+ else if (TARGET_ZICOND
+ && outer_code == SET
+ && ((GET_CODE (XEXP (x, 1)) == REG
+ && XEXP (x, 2) == CONST0_RTX (GET_MODE (XEXP (x, 1))))
+ || (GET_CODE (XEXP (x, 2)) == REG
+ && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 2))))
+ || (GET_CODE (XEXP (x, 1)) == REG
+ && rtx_equal_p (XEXP (x, 1), XEXP (XEXP (x, 0), 0)))
+ || (GET_CODE (XEXP (x, 1)) == REG
+ && rtx_equal_p (XEXP (x, 2), XEXP (XEXP (x, 0), 0)))))
+ {
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
Where X has the form:
(if_then_else:DI (reg:DI 148)
(reg:DI 147 [ b ])
(reg/v:DI 134 [ e ]))
I think the code was likely assuming that we'd have a conditional as the first
argument and thus it could use XEXP (XEXP (x, 0), 0) to get the the first
argument of the comparison.
But the costing code has to be prepared to deal with cases that don't actually
match code that would be valid according to the MD file. So that's not a safe
assumption. I suspect we just need a COMPARISON_P check in the right place.