diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2022-10-05 13:24:49 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2022-10-05 15:49:01 +0200 |
commit | df4c584c567263fdcd57d8376f24f29477a892b2 (patch) | |
tree | 7ae0cfcb44cf163c03ba924278f65f3bfb745a35 /gcc | |
parent | b8473c9a2b8f27b6882b54d012e466e244445733 (diff) | |
download | gcc-df4c584c567263fdcd57d8376f24f29477a892b2.zip gcc-df4c584c567263fdcd57d8376f24f29477a892b2.tar.gz gcc-df4c584c567263fdcd57d8376f24f29477a892b2.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/range-op.cc | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 6fa27a8..df0735c 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; } |