From ceed6e6732830adb0c0ba5b7eab21d22977a5abf Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 15 May 2014 12:01:11 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 +++++++++++---- gcc/fold-const.c | 12 +++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr61158.c | 12 ++++++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr61158.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index beac3a7..3b4e9c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,12 +1,19 @@ +2014-05-15 Jakub Jelinek + + 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. + 2014-05-15 Zhenqiang Chen * regcprop.h: New file. * regcprop.c (skip_debug_insn_p): New decl. (replace_oldest_value_reg): Check skip_debug_insn_p. - (copyprop_hardreg_forward_bb_without_debug_insn.): New function. - * shrink-wrap.c: include regcprop.h - (prepare_shrink_wrap): - Call copyprop_hardreg_forward_bb_without_debug_insn. + (copyprop_hardreg_forward_bb_without_debug_insn): New function. + * shrink-wrap.c: Include regcprop.h. + (prepare_shrink_wrap): Call + copyprop_hardreg_forward_bb_without_debug_insn. 2014-05-15 Zhenqiang Chen 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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0146e0c..ae25792 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-05-15 Jakub Jelinek + + PR tree-optimization/61158 + * gcc.dg/pr61158.c: New test. + 2014-05-15 Andreas Schwab * obj-c++.dg/exceptions-3.mm: Remove check for message no longer diff --git a/gcc/testsuite/gcc.dg/pr61158.c b/gcc/testsuite/gcc.dg/pr61158.c new file mode 100644 index 0000000..d0ba7f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr61158.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/61158 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +unsigned long long +foo (unsigned int x) +{ + return ((unsigned long long) x & 0x00ff000000000000ULL) >> 40; +} + +/* { dg-final { scan-tree-dump "return 0;" "original" { target { ilp32 || lp64 } } } } */ +/* { dg-final { cleanup-tree-dump "original" } } */ -- 2.7.4