https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118362
Bug ID: 118362 Summary: [15 Regression] ICE in require, at machmode.h:313 since r15-2002 Product: gcc Version: 15.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: --- int a, b, c[18]; void foo (void) { for (int i = 0; i < 8; i++) if (b) { c[i * 2 + 1] = a; c[i * 2 + 2] = 200; } else { c[i * 2 + 1] = 1000000; c[i * 2 + 2] = 200; } } ICEs on s390x-linux with -O2 -march=z14 starting with r15-2002-g61715e9340ab8941d40d62158fe437e9dbe3e068: /usr/src/gcc-test/objz3/gcc/cc1.r15-6702 -quiet -nostdinc -march=z14 -O2 ccPWXpC5.i during RTL pass: combine ccPWXpC5.i: In function ‘foo’: ccPWXpC5.i:17:1: internal compiler error: in require, at machmode.h:323 17 | } | ^ 0x2b96cd7 internal_error(char const*, ...) ../../gcc/diagnostic-global-context.cc:517 0x2b666db fancy_abort(char const*, int, char const*) ../../gcc/diagnostic.cc:1722 0xf4d545 opt_mode<machine_mode>::require() const ../../gcc/machmode.h:323 0x1c1d389 s390_constant_via_vgbm_p(rtx_def*, unsigned int*) ../../gcc/config/s390/s390.cc:2831 0x1c06ba2 satisfies_constraint_jyy ../../gcc/config/s390/constraints.md:449 0x1c21810 s390_legitimate_constant_p ../../gcc/config/s390/s390.cc:4448 0x15ff76f general_operand(rtx_def*, machine_mode) ../../gcc/recog.cc:1529 0x27a8782 combine_simplify_rtx ../../gcc/combine.cc:5822 0x27a7edf subst ../../gcc/combine.cc:5630 0x27a7c12 subst ../../gcc/combine.cc:5557 0x27a7c12 subst ../../gcc/combine.cc:5557 0x27a0b25 try_combine ../../gcc/combine.cc:3379 0x279b0eb combine_instructions ../../gcc/combine.cc:1357 0x27c3446 rest_of_handle_combine ../../gcc/combine.cc:15158 0x27c3502 execute ../../gcc/combine.cc:15202 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. This is on 2830 /* Handle floats by bitcasting them to ints. */ 2831 op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (), 2832 op); where op is: (const_vector:V8SI [ (const_int 1000000 [0xf4240]) repeated x4 (const_int 200 [0xc8]) repeated x4 ]) The comment suggests we shouldn't reach it, but the previous if just handles cases with GET_MODE_INNER (GET_MODE (op)) being T[IF]mode. Maybe just s390_constant_via_vgbm_p doesn't expect any 32-byte vectors? Though, combine just tries to combine and simplify random stuff and attempts to match, so the predicates better should return false instead of ICEing. The ICE is when trying to simplify (vec_concat:V8SI (if_then_else:V4SI (eq (not:V4SI (reg:V4SI 84 [ mask_patt_30.7_35 ])) (const_vector:V4SI [ (const_int 0 [0]) repeated x4 ])) (mem/u/c:V4SI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S16 A64]) (reg:V4SI 85 [ _36 ])) (const_vector:V4SI [ (const_int 200 [0xc8]) repeated x4 ])) true_rtx from that becomes (const_vector:V8SI [ (const_int 1000000 [0xf4240]) repeated x4 (const_int 200 [0xc8]) repeated x4 ]) and false_rtx from that becomes (vec_concat:V8SI (reg:V4SI 85 [ _36 ]) (const_vector:V4SI [ (const_int 200 [0xc8]) repeated x4 ])) and combine_simplify_rtx tests if both are general_operand. --- gcc/config/s390/s390.cc.jj 2025-01-02 11:23:55.822968123 +0100 +++ gcc/config/s390/s390.cc 2025-01-08 19:30:33.763998865 +0100 @@ -2820,16 +2820,18 @@ s390_constant_via_vgbm_p (rtx op, unsign if (GET_CODE (op) == CONST_VECTOR) { + machine_mode relmode; if (GET_MODE_INNER (GET_MODE (op)) == TImode || GET_MODE_INNER (GET_MODE (op)) == TFmode) /* For the sake of simplicity, bitcast 16-byte one-element vector into two-element vector so we don't have to special case them in the following. */ op = gen_lowpart (V2DImode, op); - else + else if (related_int_vector_mode (GET_MODE (op)).exists (&relmode)) /* Handle floats by bitcasting them to ints. */ - op = gen_lowpart (related_int_vector_mode (GET_MODE (op)).require (), - op); + op = gen_lowpart (relmode, op); + else + return false; } else if ((CONST_WIDE_INT_P (op) && CONST_WIDE_INT_NUNITS (op) == 2) || (CONST_DOUBLE_P (op) && GET_MODE (op) == TFmode)) fixes the ICE, but dunno whether that is the best fix.