From: Aldy Hernandez Date: Wed, 5 Oct 2022 11:24:49 +0000 (+0200) Subject: range-op: Keep nonzero mask up to date with truncating casts. X-Git-Tag: basepoints/gcc-14~4117 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df4c584c567263fdcd57d8376f24f29477a892b2;p=thirdparty%2Fgcc.git range-op: Keep nonzero mask up to date with truncating casts. gcc/ChangeLog: * range-op.cc (operator_cast::fold_range): Handle truncating casts for nonzero masks. --- diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 6fa27a8904e8..df0735cb42a8 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -2516,13 +2516,17 @@ operator_cast::fold_range (irange &r, tree type ATTRIBUTE_UNUSED, return true; } - // Pass nonzero mask through the cast. - if (!truncating_cast_p (inner, outer)) - { - wide_int nz = inner.get_nonzero_bits (); - nz = wide_int::from (nz, TYPE_PRECISION (type), TYPE_SIGN (inner.type ())); - r.set_nonzero_bits (nz); - } + // Update the nonzero mask. Truncating casts are problematic unless + // the conversion fits in the resulting outer type. + wide_int nz = inner.get_nonzero_bits (); + if (truncating_cast_p (inner, outer) + && wi::rshift (nz, wi::uhwi (TYPE_PRECISION (outer.type ()), + TYPE_PRECISION (inner.type ())), + TYPE_SIGN (inner.type ())) != 0) + return true; + nz = wide_int::from (nz, TYPE_PRECISION (type), TYPE_SIGN (inner.type ())); + r.set_nonzero_bits (nz); + return true; }