diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-05-15 12:01:11 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-05-15 12:01:11 +0200 |
commit | ceed6e6732830adb0c0ba5b7eab21d22977a5abf (patch) | |
tree | 31b84afe27a71436ba3b93702a5cb9d603f125fc /gcc/fold-const.c | |
parent | a2555c65a0f29b846038229b2f55adbb1c550ac3 (diff) | |
download | gcc-ceed6e6732830adb0c0ba5b7eab21d22977a5abf.zip gcc-ceed6e6732830adb0c0ba5b7eab21d22977a5abf.tar.gz gcc-ceed6e6732830adb0c0ba5b7eab21d22977a5abf.tar.bz2 |
re PR middle-end/61158 (negative shift at fold-const.c:12095)
PR tree-optimization/61158
* fold-const.c (fold_binary_loc): If X is zero-extended and
shiftc >= prec, make sure zerobits is all ones instead of
invoking undefined behavior.
* gcc.dg/pr61158.c: New test.
From-SVN: r210467
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5e064df..8f659db 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11972,11 +11972,17 @@ fold_binary_loc (location_t loc, /* See if we can shorten the right shift. */ if (shiftc < prec) shift_type = inner_type; + /* Otherwise X >> C1 is all zeros, so we'll optimize + it into (X, 0) later on by making sure zerobits + is all ones. */ } } zerobits = ~(unsigned HOST_WIDE_INT) 0; - zerobits >>= HOST_BITS_PER_WIDE_INT - shiftc; - zerobits <<= prec - shiftc; + if (shiftc < prec) + { + zerobits >>= HOST_BITS_PER_WIDE_INT - shiftc; + zerobits <<= prec - shiftc; + } /* For arithmetic shift if sign bit could be set, zerobits can contain actually sign bits, so no transformation is possible, unless MASK masks them all away. In that @@ -11994,7 +12000,7 @@ fold_binary_loc (location_t loc, /* ((X << 16) & 0xff00) is (X, 0). */ if ((mask & zerobits) == mask) return omit_one_operand_loc (loc, type, - build_int_cst (type, 0), arg0); + build_int_cst (type, 0), arg0); newmask = mask | zerobits; if (newmask != mask && (newmask & (newmask + 1)) == 0) |