https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126667

            Bug ID: 126667
           Summary: [15/16/17 Regression] s390x ICE since r15-6791
           Product: gcc
           Version: 16.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

Created attachment 65248
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65248&action=edit
botan.ii

The attached testcase ICEs with -O3 -march=z14 -std=gnu++20 I believe starting
with
r15-6791-g8a2d5bc28089b2660310b964ef75fb05eb387f88
The bug is fairly obvious.
The newly added usubc<mode>5 pattern uses general_operand predicate for
operands[4],
because it e.g. wants to compare it against const0_rtx.
But then it uses
+      emit_insn (gen_xor<mode>3 (tmp, operands[4], const1_rtx));               
where xor<mode>3 requires the second operand to be nonimmediate_operand.

I'd sugggest
--- gcc/config/s390/s390.md.jj  2026-07-10 08:56:56.478169249 +0200
+++ gcc/config/s390/s390.md     2026-08-05 20:20:40.725323301 +0200
@@ -6745,7 +6745,9 @@
   else
     {
       rtx tmp = gen_reg_rtx (<MODE>mode);
-      emit_insn (gen_xor<mode>3 (tmp, operands[4], const1_rtx));
+      emit_insn (gen_xor<mode>3 (tmp, CONSTANT_P (operands[4])
+                                     ? force_reg (<MODE>mode, operands[4])
+                                     : operands[4], const1_rtx));
       rtx slb_cond = s390_emit_compare (<MODE>mode, LEU, tmp, const0_rtx);
       emit_insn (gen_sub<mode>3_slb_borrow1_cc (operands[0], operands[2],
operands[3], slb_cond));
     }
as a fix (verified it fixes the ICE) and let combine/cse clean it up later if
needed.  Of course, if operands[4] is a CONST_INT, the most common immediate
operand here, one could do the xor at compile time and even figure out if the
compare is false or true, but how to propagate that to the following insn.

Reply via email to