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.