https://gcc.gnu.org/g:8d0676db179aa31207bc4dd29e1c310823988f4b

commit r17-3140-g8d0676db179aa31207bc4dd29e1c310823988f4b
Author: Jakub Jelinek <[email protected]>
Date:   Fri Aug 7 17:33:53 2026 +0200

    s390: Fix ICE in usubc5 [PR126667]
    
    The following testcase ICEs on s390x-linux I believe since r15-6791
    when usubc<mode>5 named pattern has been introduced.
    It intentionally uses general_operand predicate for operands[4],
    so that it can test it against const0_rtx and handle that differently,
    but otherwise it uses xor<mode>3 insn with operands[4] as first input,
    which has nonimmediate_operand.  So we emit (xor:DI (const1_rtx) 
(const1_rtx))
    and then fail to recognize it.
    
    The following patch just forces it into a register in that case, cse or
    combine can then simplify it.  The other option would be
    to check for CONSTANT_P, force into REG unless it is CONST_INT and if it
    is CONST_INT, perform the xor at compile time, but then the compare
    too and unsure what to pass to the subsequent insn.
    
    The testcase is simplified from a larger botan real-world testcase (though
    there isn't usubc with a constant 1 carry in visible in the source).
    
    2026-08-07  Jakub Jelinek  <[email protected]>
    
            PR target/126667
            * config/s390/s390.md (usubc<mode>5): If operands[4] is
            an immediate operand other than const0_rtx, force it into reg
            before using it in xor<mode>3 insn.
    
            * gcc.dg/pr126667.c: New test.
            * gcc.target/s390/pr126667.c: New test.
    
    Reviewed-by: Andreas Krebbel <[email protected]>

Diff:
---
 gcc/config/s390/s390.md                  | 4 +++-
 gcc/testsuite/gcc.dg/pr126667.c          | 9 +++++++++
 gcc/testsuite/gcc.target/s390/pr126667.c | 9 +++++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 587077b84fa6..aa9b011278db 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -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));
     }
diff --git a/gcc/testsuite/gcc.dg/pr126667.c b/gcc/testsuite/gcc.dg/pr126667.c
new file mode 100644
index 000000000000..f9e4a2120add
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126667.c
@@ -0,0 +1,9 @@
+/* PR target/126667 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long
+foo (unsigned long x, unsigned long y, unsigned long *p)
+{
+  return __builtin_subcl (x, y, 1UL, p);
+}
diff --git a/gcc/testsuite/gcc.target/s390/pr126667.c 
b/gcc/testsuite/gcc.target/s390/pr126667.c
new file mode 100644
index 000000000000..0e6cd1467a2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr126667.c
@@ -0,0 +1,9 @@
+/* PR target/126667 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=z14" } */
+
+unsigned long
+foo (unsigned long x, unsigned long y, unsigned long *p)
+{
+  return __builtin_subcl (x, y, 1UL, p);
+}

Reply via email to