diff mbox series

explow: Fix ICE caused by plus_constant [PR94002]

Message ID 20200303073819.GX2156@tucnak
State New
Headers show
Series explow: Fix ICE caused by plus_constant [PR94002] | expand

Commit Message

Jakub Jelinek March 3, 2020, 7:38 a.m. UTC
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  <jakub@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.


	Jakub

Comments

Richard Biener March 3, 2020, 9:20 a.m. UTC | #1
On Tue, 3 Mar 2020, Jakub Jelinek wrote:

> 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?

Looks OK, but I guess we could do better by appropriately sub-regging
the constant (which might not always be possible of course).

Thanks,
Richard.

> 2020-03-03  Jakub Jelinek  <jakub@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
> 
>
diff mbox series

Patch

--- 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;
+}