https://gcc.gnu.org/g:c681c4f2aa8fc44c4e3822cc34b32fc93d1c607d
commit r16-9759-gc681c4f2aa8fc44c4e3822cc34b32fc93d1c607d Author: Jakub Jelinek <[email protected]> Date: Tue Sep 15 12:02:18 2026 +0200 i386: Fix up split_double_mode [PR127352] The following testcase ICEs, because we try to split during split2 pass (insn 313 311 314 36 (parallel [ (set (reg:TI 36 r8 [orig:118 b_lsm.27 ] [118]) (and:TI (subreg:TI (reg:SI 36 r8 [orig:107 f ] [107]) 0) (const_int 15 [0xf]))) (clobber (reg:CC 17 flags)) ]) 734 {*andti3_doubleword} (nil)) where the paradoxical subreg is quite reasonable, const_int 15 doesn't have any non-zero bits in the high half, so what exact value we get in the other operand in the high 64 bits is irrelevant. But split_double_mode in that case just calls gen_reg_rtx (half_mode), which ICEs. The high bits of a paradoxical SUBREG can be anything, so this patch after RA chooses one particular value for that, 0 (as the cheapest one and something that likely matches the predicates/constraints of insns using it). 2026-09-15 Jakub Jelinek <[email protected]> PR target/127352 * config/i386/i386-expand.cc (split_double_mode): For high halves of paradoxical subregs after RA use CONST0_RTX (half_mode) instead of ICE. * gcc.target/i386/pr127352.c: New test. Reviewed-by: Uros Bizjak <[email protected]> (cherry picked from commit 920fbabbc3b30c2677b2445c55b29c8547abf01c) Diff: --- gcc/config/i386/i386-expand.cc | 9 ++++-- gcc/testsuite/gcc.target/i386/pr127352.c | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 3c2b2dc6e7ec..f4968af6c72d 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -161,8 +161,13 @@ split_double_mode (machine_mode mode, rtx operands[], GET_MODE (op) == VOIDmode ? mode : GET_MODE (op), byte); /* simplify_gen_subreg will return NULL RTX for the - high half of the paradoxical subreg. */ - hi_half[num] = tmp ? tmp : gen_reg_rtx (half_mode); + high half of the paradoxical subreg. */ + if (tmp) + hi_half[num] = tmp; + else if (can_create_pseudo_p ()) + hi_half[num] = gen_reg_rtx (half_mode); + else + hi_half[num] = CONST0_RTX (half_mode); } } } diff --git a/gcc/testsuite/gcc.target/i386/pr127352.c b/gcc/testsuite/gcc.target/i386/pr127352.c new file mode 100644 index 000000000000..8f7b3a3c2522 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr127352.c @@ -0,0 +1,53 @@ +/* PR target/127352 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O3" } */ + +_BitInt(65) a, b, c; +__int128 d; +_BitInt(7) e; + +long +foo (long x) +{ + return x; +} + +_BitInt(13) +bar (unsigned x, _BitInt(3) y) +{ + return y == 0 ? : x; +} + +_BitInt(65) +baz (_BitInt(65) x, _BitInt(5) y) +{ + return y == 0 ? x : y; +} + +_BitInt(5) +qux () +{ + _BitInt(47) f; + unsigned g = d & 15; + for (unsigned i = 0; i < g; i++) + { + switch (a) + { + case 0: + b = 0; + case 8: + e = 0; + break; + case 10: + long h = g; + f = ~foo (~h); + e = f; + } + if (0 >= b) + continue; + for (unsigned j = 0; j < 1; j++) + b = (_BitInt(7)) (0 >= d ? bar (e, a) : 0); + e = c ? baz (b, i) : 0; + } + return b; +}
