[PATCH] s390: Fix ICE in usubc5 [PR126667]
Jakub Jelinek <[email protected]> Thu, 6 Aug 2026 22:14:10 +0200
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <anTrEiEYq-eb5OZv@tucnak> |
Hi! 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). Bootstrapped/regtested on s390x-linux, ok for trunk, 16.2.1 (after 16.2 is released) and 15.4? 2026-08-06 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. --- gcc/config/s390/s390.md.jj 2026-08-06 10:24:00.121415450 +0200 +++ gcc/config/s390/s390.md 2026-08-06 13:36:37.344210259 +0200 @@ -6745,7 +6745,9 @@ (define_expand "usubc<mode>5" 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)); } --- gcc/testsuite/gcc.dg/pr126667.c.jj 2026-08-06 13:37:24.743970575 +0200 +++ gcc/testsuite/gcc.dg/pr126667.c 2026-08-06 13:37:18.352048196 +0200 @@ -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); +} --- gcc/testsuite/gcc.target/s390/pr126667.c.jj 2026-08-06 13:37:50.592656684 +0200 +++ gcc/testsuite/gcc.target/s390/pr126667.c 2026-08-06 13:38:11.096407697 +0200 @@ -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); +} Jakub