https://gcc.gnu.org/g:dc220cf27aa3e6e0b90e17ea9b5e36abb3f92dc8
commit r15-11624-gdc220cf27aa3e6e0b90e17ea9b5e36abb3f92dc8 Author: Stefan Schulze Frielinghaus <[email protected]> Date: Sun Sep 20 09:19:50 2026 +0200 expand_mult: Look through vector mode When expand_mult handles a constant vector multiplier where the scalar operand is a CONST_WIDE_INT, then also look through the vector mode while determining the shift amount since here we need the scalar mode. Note, when we call later on into expand_shift we need the vector mode, i.e., only for the shift amount we need the scalar mode. PR middle-end/127474 gcc/ChangeLog: * expmed.cc (expand_mult): Look through vector mode. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr127474.c: New test. (cherry picked from commit 5dc4ab23e0d01a1fd20c1365bdb2de039d831ff9) Diff: --- gcc/expmed.cc | 4 +++- gcc/testsuite/gcc.dg/torture/pr127474.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gcc/expmed.cc b/gcc/expmed.cc index 900ccf3f28ad..d6f14c7995d4 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -3548,7 +3548,9 @@ expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target, else if (CONST_DOUBLE_AS_INT_P (scalar_op1)) #endif { - int shift = wi::exact_log2 (rtx_mode_t (scalar_op1, mode)); + machine_mode scalar_mode = VECTOR_MODE_P (mode) + ? GET_MODE_INNER (mode) : mode; + int shift = wi::exact_log2 (rtx_mode_t (scalar_op1, scalar_mode)); /* Perfect power of 2 (other than 1, which is handled above). */ if (shift > 0) return expand_shift (LSHIFT_EXPR, mode, op0, diff --git a/gcc/testsuite/gcc.dg/torture/pr127474.c b/gcc/testsuite/gcc.dg/torture/pr127474.c new file mode 100644 index 000000000000..b0f63fda042b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr127474.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target int128 } */ +/* { dg-additional-options "-march=z17" { target s390x-*-* } } */ + +/* Previously we ICE'd in expand_mult when dealing with a CONST_WIDE_INT. */ + +typedef __int128 v1ti __attribute__ ((vector_size (16))); + +v1ti foo (v1ti x) +{ + return x * (v1ti){(__int128)123456789 << 64 | (__int128)123456789}; +}
