On Mon, Oct 19, 2020 at 12:44 PM Jakub Jelinek <[email protected]> wrote:
>
> On Mon, Oct 19, 2020 at 12:36:24PM +0200, Aldy Hernandez via Gcc-patches
> wrote:
> > The test is trying to shift by 129, but the underlying type is 128 bits.
> > This causes low_bits to wrap around to -1 and things go bad really
> > quick.
> >
> > Attached is my proposed solution.
> >
> > Andrew, do you have a preference on how to fix this?
>
> Shifts are undefined already when the shift count is equal to the precision.
> And arbitrarily choosing one of the values as the shift count seems risky to
> me (and even when used, the most natural would be truncating the excess bits
> rather than saturating), can't it just punt (return VARYING) for the UB
> shifts?
Good point. It looks cleaner too.
How about this?
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 30d2a4d3987..0ab5e62be7f 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1579,6 +1579,9 @@ operator_lshift::op1_range (irange &r,
wide_int shift = wi::to_wide (shift_amount);
if (wi::lt_p (shift, 0, SIGNED))
return false;
+ if (wi::gt_p (shift, wi::uhwi (TYPE_PRECISION (type),
+ TYPE_PRECISION (op2.type ()))))
+ return false;
if (shift == 0)
{
r = lhs;