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.

Reply via email to