Hi! The following testcase ICEs in cross to riscv64-linux. The problem is that we have a DImode integral constant (that doesn't fit into SImode), which is pushed into a constant pool and later access just the first half of it using a MEM. When plus_constant is called on such a MEM, if the constant has mode, we verify the mode, but if it doesn't, we don't and ICE later on when we think the CONST_INT is a valid SImode constant.
Fixed thusly, tested with cross to riscv64-linux and bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-03-03 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/94002 * explow.c (plus_constant): Punt if cst has VOIDmode and get_pool_mode is different from mode. * gcc.dg/pr94002.c: New test. --- gcc/explow.c.jj 2020-01-12 11:54:36.564411130 +0100 +++ gcc/explow.c 2020-03-02 22:09:19.544380020 +0100 @@ -128,6 +128,9 @@ plus_constant (machine_mode mode, rtx x, cst = gen_lowpart (mode, cst); gcc_assert (cst); } + else if (GET_MODE (cst) == VOIDmode + && get_pool_mode (XEXP (x, 0)) != mode) + break; if (GET_MODE (cst) == VOIDmode || GET_MODE (cst) == mode) { tem = plus_constant (mode, cst, c); --- gcc/testsuite/gcc.dg/pr94002.c.jj 2020-03-02 22:05:58.508338170 +0100 +++ gcc/testsuite/gcc.dg/pr94002.c 2020-03-02 22:05:32.864715503 +0100 @@ -0,0 +1,13 @@ +/* PR rtl-optimization/94002 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-tree-dce -fno-tree-reassoc" } */ +/* { dg-additional-options "-fPIC" { target fpic } } */ + +unsigned a, b; + +void +foo (void) +{ + __builtin_sub_overflow (b, 44852956282LL, &a); + a += ~b; +} Jakub