diff mbox

[v2] Fix PR78588 - rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too large for 64-bit type

Message ID 20161129160005.GE441@x4
State New
Headers show

Commit Message

Markus Trippelsdorf Nov. 29, 2016, 4 p.m. UTC
Here is v2 of the fix.

Building gcc with -fsanitize=undefined shows:
 rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too large for 64-bit type 'long unsigned int'

This happens because if_then_else_cond() in combine.c calls
num_sign_bit_copies() in rtlanal.c with mode==BLKmode.

5205   bitwidth = GET_MODE_PRECISION (mode);
5206   if (bitwidth > HOST_BITS_PER_WIDE_INT)
5207     return 1;
5208
5209   nonzero = nonzero_bits (x, mode);
5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;

This causes (bitwidth - 1) to wrap around.

Fix by also guarding against BLKmode.

Tested on pcc64le.
OK for trunk?

Thanks.

	PR rtl-optimization/78588 
	* combine.c (if_then_else_cond): Also guard against BLKmode.


--
Markus

Comments

Segher Boessenkool Nov. 29, 2016, 9:25 p.m. UTC | #1
On Tue, Nov 29, 2016 at 05:00:05PM +0100, Markus Trippelsdorf wrote:
> Building gcc with -fsanitize=undefined shows:
>  rtlanal.c:5210:38: runtime error: shift exponent 4294967295 is too large for 64-bit type 'long unsigned int'
> 
> This happens because if_then_else_cond() in combine.c calls
> num_sign_bit_copies() in rtlanal.c with mode==BLKmode.
> 
> 5205   bitwidth = GET_MODE_PRECISION (mode);
> 5206   if (bitwidth > HOST_BITS_PER_WIDE_INT)
> 5207     return 1;
> 5208
> 5209   nonzero = nonzero_bits (x, mode);
> 5210   return nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))
> 5211          ? 1 : bitwidth - floor_log2 (nonzero) - 1;
> 
> This causes (bitwidth - 1) to wrap around.

Could you also add a gcc_assert here?

> 	PR rtl-optimization/78588 
> 	* combine.c (if_then_else_cond): Also guard against BLKmode.

Approved, please apply.  Thanks,


Segher
diff mbox

Patch

diff --git a/gcc/combine.c b/gcc/combine.c
index 22fb7a976538..a32a0ecc72fb 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -9176,7 +9176,7 @@  if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
   /* If X is known to be either 0 or -1, those are the true and
      false values when testing X.  */
   else if (x == constm1_rtx || x == const0_rtx
-	   || (mode != VOIDmode
+	   || (mode != VOIDmode && mode != BLKmode
 	       && num_sign_bit_copies (x, mode) == GET_MODE_PRECISION (mode)))
     {
       *ptrue = constm1_rtx, *pfalse = const0_rtx;