diff mbox series

Fix postreload constant merging (PR target/84899)

Message ID 20180316201722.GI8577@tucnak
State New
Headers show
Series Fix postreload constant merging (PR target/84899) | expand

Commit Message

Jakub Jelinek March 16, 2018, 8:17 p.m. UTC
Hi!

The following testcase ICEs on powerpc-linux, because we merge
SImode constants 0x7fffffff and 1 into 0x80000000, which is not valid SImode
CONST_INT - -0x80000000 is.  Fixed by calling trunc_int_for_mode, and to
avoid UB in the compiler do the addition in unsigned type.

Bootstrapped/regtested on x86_64-linux and i686-linux and tested on the
testcase with powerpc64-linux cross with -m32, ok for trunk?

2018-03-16  Jakub Jelinek  <jakub@redhat.com>

	PR target/84899
	* postreload.c (reload_combine_recognize_pattern): Perform
	INTVAL addition in unsigned HOST_WIDE_INT type to avoid UB and
	truncate_int_for_mode the result for the destination's mode.

	* gcc.dg/pr84899.c: New test.


	Jakub

Comments

Jeff Law March 16, 2018, 8:57 p.m. UTC | #1
On 03/16/2018 02:17 PM, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase ICEs on powerpc-linux, because we merge
> SImode constants 0x7fffffff and 1 into 0x80000000, which is not valid SImode
> CONST_INT - -0x80000000 is.  Fixed by calling trunc_int_for_mode, and to
> avoid UB in the compiler do the addition in unsigned type.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux and tested on the
> testcase with powerpc64-linux cross with -m32, ok for trunk?
> 
> 2018-03-16  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR target/84899
> 	* postreload.c (reload_combine_recognize_pattern): Perform
> 	INTVAL addition in unsigned HOST_WIDE_INT type to avoid UB and
> 	truncate_int_for_mode the result for the destination's mode.
> 
> 	* gcc.dg/pr84899.c: New test.
OK.
jeff
diff mbox series

Patch

--- gcc/postreload.c.jj	2018-01-03 10:19:55.572534024 +0100
+++ gcc/postreload.c	2018-03-16 18:19:17.819417570 +0100
@@ -1157,11 +1157,13 @@  reload_combine_recognize_pattern (rtx_in
 	     value in PREV, the constant loading instruction.  */
 	  validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
 	  if (reg_state[regno].offset != const0_rtx)
-	    validate_change (prev,
-			     &SET_SRC (prev_set),
-			     GEN_INT (INTVAL (SET_SRC (prev_set))
-				      + INTVAL (reg_state[regno].offset)),
-			     1);
+	    {
+	      HOST_WIDE_INT c
+		= trunc_int_for_mode (UINTVAL (SET_SRC (prev_set))
+				      + UINTVAL (reg_state[regno].offset),
+				      GET_MODE (index_reg));
+	      validate_change (prev, &SET_SRC (prev_set), GEN_INT (c), 1);
+	    }
 
 	  /* Now for every use of REG that we have recorded, replace REG
 	     with REG_SUM.  */
--- gcc/testsuite/gcc.dg/pr84899.c.jj	2018-03-16 18:22:39.243512333 +0100
+++ gcc/testsuite/gcc.dg/pr84899.c	2018-03-16 18:22:22.353504390 +0100
@@ -0,0 +1,12 @@ 
+/* PR target/84899 */
+/* { dg-do compile } */
+/* { dg-options "-O -funroll-all-loops -fno-move-loop-invariants" } */
+
+void
+foo (int x)
+{
+  int a = 1 / x, b = 0;
+
+  while ((a + b + 1) < x)
+    b = __INT_MAX__;
+}