On 2016.11.29 at 15:25 -0600, Segher Boessenkool wrote:
> 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,
Because it can only happen when mode==BLKmode, this is what I checked
in:
diff --git a/gcc/combine.c b/gcc/combine.c
index 22fb7a9..a32a0ec 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;
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 4e4eb2e..60550ad 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4840,6 +4840,8 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode,
const_rtx known_x,
if (mode == VOIDmode)
mode = GET_MODE (x);
+ gcc_checking_assert (mode != BLKmode);
+
if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x))
|| VECTOR_MODE_P (GET_MODE (x)) || VECTOR_MODE_P (mode))
return 1;
--
Markus