https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127474
Bug ID: 127474
Summary: ICE in expand_mult, at expmed.cc:3636
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: ice-on-valid-code
Severity: normal
Priority: P3
Component: middle-end
Assignee: stefansf at gcc dot gnu.org
Reporter: stefansf at gcc dot gnu.org
Target Milestone: ---
Target: s390x-*-*
typedef __int128 v1ti __attribute__ ((vector_size (16)));
v1ti foo (v1ti x)
{
return x * (v1ti){(__int128)123456789 << 64 | (__int128)123456789};
}
gcc t.c -O2 -march=z17 -S
during RTL pass: expand
t.c: In function 'foo':
t.c:5:12: internal compiler error: in as_a, at machmode.h:391
5 | return x * (v1ti){(__int128)123456789 << 64 | (__int128)123456789};
| ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0x4899099 internal_error(char const*, ...)
/devel/src/gcc/diagnostic-global-context.cc:787
0x48ac595 fancy_abort(char const*, int, char const*)
/devel/src/gcc/diagnostics/context.cc:1813
0x1b2c0e7 scalar_mode as_a<scalar_mode>(machine_mode)
/devel/src/gcc/machmode.h:391
0x1f7fe57 wi::int_traits<std::pair<rtx_def*, machine_mode>
>::get_precision(std::pair<rtx_def*, machine_mode> const&)
/devel/src/gcc/rtl.h:2326
0x1fa4639 unsigned int wi::get_precision<std::pair<rtx_def*, machine_mode>
>(std::pair<rtx_def*, machine_mode> const&)
/devel/src/gcc/wide-int.h:2168
0x1f95373 wide_int_ref_storage<false,
true>::wide_int_ref_storage<std::pair<rtx_def*, machine_mode>
>(std::pair<rtx_def*, machine_mode> const&)
/devel/src/gcc/wide-int.h:1089
0x1f85a89 generic_wide_int<wide_int_ref_storage<false, true>
>::generic_wide_int<std::pair<rtx_def*, machine_mode> >(std::pair<rtx_def*,
machine_mode> const&)
/devel/src/gcc/wide-int.h:847
0x200b725 expand_mult(machine_mode, rtx_def*, rtx_def*, rtx_def*, int, bool)
/devel/src/gcc/expmed.cc:3636
0x204f607 expand_expr_real_2(separate_ops const*, rtx_def*, machine_mode,
expand_modifier)
/devel/src/gcc/expr.cc:10630
0x205379f expand_expr_real_gassign(gassign*, rtx_def*, machine_mode,
expand_modifier, rtx_def**, bool)
/devel/src/gcc/expr.cc:11451
0x2054f7f expand_expr_real_1(tree_node*, rtx_def*, machine_mode,
expand_modifier, rtx_def**, bool)
/devel/src/gcc/expr.cc:11684
0x204952d expand_expr_real(tree_node*, rtx_def*, machine_mode, expand_modifier,
rtx_def**, bool)
/devel/src/gcc/expr.cc:9655
0x1d935ad expand_expr(tree_node*, rtx_def*, machine_mode, expand_modifier)
/devel/src/gcc/expr.h:323
0x1dd70f7 expand_return
/devel/src/gcc/cfgexpand.cc:4212
0x1dd7693 expand_gimple_stmt_1
/devel/src/gcc/cfgexpand.cc:4321
0x1dd7d65 expand_gimple_stmt
/devel/src/gcc/cfgexpand.cc:4430
0x1de2c67 expand_gimple_basic_block
/devel/src/gcc/cfgexpand.cc:6547
0x1de5b7b execute
/devel/src/gcc/cfgexpand.cc:7298
/devel/build/gcc/cc1 -quiet -iprefix
/devel/build/gcc/../lib/gcc/s390x-ibm-linux-gnu/17.0.0/ -isystem
/devel/build/gcc/include -isystem /devel/build/gcc/include-fixed t.c -quiet
-dumpbase t.c -dumpbase-ext .c -march=z17 -O2 -o t.s
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.
In expand_mult() we look through vectors for scalars
scalar_op1 = unwrap_const_vec_duplicate (op1);
but forget to also look through the passed mode in
#if TARGET_SUPPORTS_WIDE_INT
else if (CONST_WIDE_INT_P (scalar_op1))
#else
else if (CONST_DOUBLE_AS_INT_P (scalar_op1))
#endif
{
int shift = wi::exact_log2 (rtx_mode_t (scalar_op1, mode));
Starting with z17, expand_mult is also called for mode V1TI. Currently
bootstrapping+regtesting the following fix in order to also look through vector
modes:
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index c6494484251..b82c0bb10db 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -3633,7 +3633,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,