Since the revision, I see: $ gcc /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/pr68835-2.c -fno-tree-forwprop -fno-tree-ccp -O1 -fno-tree-dominator-opts -fno-tree-fre during RTL pass: expand /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/pr68835-2.c: In function ‘foo’: /home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/pr68835-2.c:12:11: internal compiler error: in as_a, at machmode.h:361 12 | return w.a; | ~^~ 0x647496 scalar_int_mode as_a<scalar_int_mode>(machine_mode) /home/marxin/Programming/gcc/gcc/machmode.h:361 0x64c7e6 reduce_to_bit_field_precision /home/marxin/Programming/gcc/gcc/expr.c:4521 0xa3e713 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier) /home/marxin/Programming/gcc/gcc/expr.c:9971 0xa465c1 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/marxin/Programming/gcc/gcc/expr.c:10165 0xa4192c expand_expr_real(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/marxin/Programming/gcc/gcc/expr.c:8469 0xa4192c expand_expr /home/marxin/Programming/gcc/gcc/expr.h:282 0xa4192c expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier) /home/marxin/Programming/gcc/gcc/expr.c:8737 0xa465c1 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool) /home/marxin/Programming/gcc/gcc/expr.c:10165 0x925ee3 expand_expr /home/marxin/Programming/gcc/gcc/expr.h:282 0x925ee3 expand_return /home/marxin/Programming/gcc/gcc/cfgexpand.c:3611 0x925ee3 expand_gimple_stmt_1 /home/marxin/Programming/gcc/gcc/cfgexpand.c:3720 0x925ee3 expand_gimple_stmt /home/marxin/Programming/gcc/gcc/cfgexpand.c:3847 0x92b20a expand_gimple_basic_block /home/marxin/Programming/gcc/gcc/cfgexpand.c:5888 0x92ccb6 execute /home/marxin/Programming/gcc/gcc/cfgexpand.c:6572 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. and historically it disappeared in r6-201-geff973a26bfec703.
We're expanding <ssa_name 0x7ffff6bc1e10 type <integer_type 0x7ffff6cf03f0 sizes-gimplified public unsigned TI size <integer_cst 0x7ffff6bb7d20 constant 128> unit-size <integer_cst 0x7ffff6bb7d38 constant 16> align:128 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6cf03f0 precision:65 min <integer_cst 0x7ffff6d0d018 0> max <integer_cst 0x7ffff6cf6100 0x1ffffffffffffffff>> visited def_stmt _5 = (<unnamed-unsigned:65>) _4; version:5> and #2 0x0000000000d9a5bf in reduce_to_bit_field_precision (exp=0x7ffff6d1d180, target=0x0, type=<integer_type 0x7ffff6cf03f0>) at /space/rguenther/src/gcc/gcc/expr.c:11553 (gdb) p debug_rtx (exp) (const_wide_int 0x1fffffffffffffffe) $1 = void (gdb) p debug_tree (type) <integer_type 0x7ffff6cf03f0 sizes-gimplified public unsigned TI size <integer_cst 0x7ffff6bb7d20 type <integer_type 0x7ffff6bd00a8 bitsizetype> constant 128> unit-size <integer_cst 0x7ffff6bb7d38 type <integer_type 0x7ffff6bd0000 sizetype> constant 16> align:128 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff6cf03f0 precision:65 min <integer_cst 0x7ffff6d0d018 0> max <integer_cst 0x7ffff6cf6100 0x1ffffffffffffffff>> $2 = void here a CONST_WIDE_INT does not have a mode. Note somehow the earlier /* For constant values, reduce using build_int_cst_type. */ poly_int64 const_exp; if (poly_int_rtx_p (exp, &const_exp)) { tree t = build_int_cst_type (type, const_exp); return expand_expr (t, target, VOIDmode, EXPAND_NORMAL); } does not trigger. Ah, poly_int64 ... but diff --git a/gcc/expr.c b/gcc/expr.c index ca6b1c1291e..7367e332a05 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -11541,11 +11541,10 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type) HOST_WIDE_INT prec = TYPE_PRECISION (type); if (target && GET_MODE (target) != GET_MODE (exp)) target = 0; - /* For constant values, reduce using build_int_cst_type. */ - poly_int64 const_exp; - if (poly_int_rtx_p (exp, &const_exp)) + /* For constant values, reduce using build_poly_int_cst. */ + if (poly_int_rtx_p (exp)) { - tree t = build_int_cst_type (type, const_exp); + tree t = build_poly_int_cst (type, wi::to_poly_wide (exp)); return expand_expr (t, target, VOIDmode, EXPAND_NORMAL); } else if (TYPE_UNSIGNED (type)) does not compile and insists on a mode - but the implementation for poly_int64 does not need a mode. And we shouldn't need one (and the whole point of this path is we don't have one). Richard? Can you please take this?
OK. It looks like the mode is readily available in each call to REDUCE_BIT_FIELD, so I think we should just pass that down. It would also avoid: if (target && GET_MODE (target) != GET_MODE (exp)) target = 0; creating unnecessary temporaries for constant integers.
Looks really similar to PR95528.
(In reply to Richard Biener from comment #3) > Looks really similar to PR95528. Sorry - wrong bug.
The master branch has been updated by Richard Sandiford <rsandifo@gcc.gnu.org>: https://gcc.gnu.org/g:760df6d296b8fc59796f42dca5eb14012fbfa28b commit r11-1914-g760df6d296b8fc59796f42dca5eb14012fbfa28b Author: Richard Sandiford <richard.sandiford@arm.com> Date: Wed Jul 8 15:01:14 2020 +0100 expr: Fix REDUCE_BIT_FIELD for constants [PR95694] This is yet another PR caused by constant integer rtxes not storing a mode. We were calling REDUCE_BIT_FIELD on a constant integer that didn't fit in poly_int64, and then tripped the as_a<scalar_int_mode> assert on VOIDmode. AFAICT REDUCE_BIT_FIELD is always passed rtxes that have TYPE_MODE (rather than some other mode) and it just fills in the redundant sign bits of that TYPE_MODE value. So it should be safe to get the mode from the type instead of the rtx. The patch does that and asserts that the modes agree, where information is available. That on its own is enough to fix the bug, but we might as well extend the folding case to all constant integers, not just those that fit poly_int64. gcc/ PR middle-end/95694 * expr.c (expand_expr_real_2): Get the mode from the type rather than the rtx, and assert that it is consistent with the mode of the rtx (where known). Optimize all constant integers, not just those that can be represented in poly_int64. gcc/testsuite/ PR middle-end/95694 * gcc.dg/pr95694.c: New test.
Just realised that this breaks bootstrap on arm-linux-gnueabihf. I'd originally moved the zeroing of incorrect targets to expand_expr_real_2, but then forgot why and undid it in the name of going for the minimal fix. The reason is/was code like: else if (target == 0) op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0))); else { convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0))); op0 = target; } where we could convert to the mode of the supplied target instead of “mode”. Testing a fix.
The releases/gcc-10 branch has been updated by Richard Sandiford <rsandifo@gcc.gnu.org>: https://gcc.gnu.org/g:00bcb8380bf755c60d5ad605a21818f6d3ed9912 commit r10-9114-g00bcb8380bf755c60d5ad605a21818f6d3ed9912 Author: Richard Sandiford <richard.sandiford@arm.com> Date: Thu Dec 3 10:23:25 2020 +0000 expr: Fix REDUCE_BIT_FIELD for constants [PR95694, PR96151] This is yet another PR caused by constant integer rtxes not storing a mode. We were calling REDUCE_BIT_FIELD on a constant integer that didn't fit in poly_int64, and then tripped the as_a<scalar_int_mode> assert on VOIDmode. AFAICT REDUCE_BIT_FIELD is always passed rtxes that have TYPE_MODE (rather than some other mode) and it just fills in the redundant sign bits of that TYPE_MODE value. So it should be safe to get the mode from the type instead of the rtx. The patch does that and asserts that the modes agree, where information is available. That on its own is enough to fix the bug, but we might as well extend the folding case to all constant integers, not just those that fit poly_int64. gcc/ PR middle-end/95694 * expr.c (expand_expr_real_2): Get the mode from the type rather than the rtx, and assert that it is consistent with the mode of the rtx (where known). Optimize all constant integers, not just those that can be represented in poly_int64. gcc/testsuite/ PR middle-end/95694 * gcc.dg/pr95694.c: New test. (cherry picked from commit 760df6d296b8fc59796f42dca5eb14012fbfa28b)
The releases/gcc-9 branch has been updated by Richard Sandiford <rsandifo@gcc.gnu.org>: https://gcc.gnu.org/g:90ce58cf411f06292dc8f96aba61f3e3d07f22e8 commit r9-9461-g90ce58cf411f06292dc8f96aba61f3e3d07f22e8 Author: Richard Sandiford <richard.sandiford@arm.com> Date: Sun Apr 25 14:51:13 2021 +0100 expr: Fix REDUCE_BIT_FIELD for constants [PR95694, PR96151] This is yet another PR caused by constant integer rtxes not storing a mode. We were calling REDUCE_BIT_FIELD on a constant integer that didn't fit in poly_int64, and then tripped the as_a<scalar_int_mode> assert on VOIDmode. AFAICT REDUCE_BIT_FIELD is always passed rtxes that have TYPE_MODE (rather than some other mode) and it just fills in the redundant sign bits of that TYPE_MODE value. So it should be safe to get the mode from the type instead of the rtx. The patch does that and asserts that the modes agree, where information is available. That on its own is enough to fix the bug, but we might as well extend the folding case to all constant integers, not just those that fit poly_int64. gcc/ PR middle-end/95694 * expr.c (expand_expr_real_2): Get the mode from the type rather than the rtx, and assert that it is consistent with the mode of the rtx (where known). Optimize all constant integers, not just those that can be represented in poly_int64. gcc/testsuite/ PR middle-end/95694 * gcc.dg/pr95694.c: New test. (cherry picked from commit 760df6d296b8fc59796f42dca5eb14012fbfa28b)
Fixed.