diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-09-30 22:15:20 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-09-30 22:15:20 +0200 |
commit | f66d089128669ca6f4bbd8f661fb064012bdd595 (patch) | |
tree | 05e6bf576979c3dbd647a166f68af3be286880e3 /gcc/fold-const.c | |
parent | 05357ac367d24f312969ad738d701a682a4a4d97 (diff) | |
download | gcc-f66d089128669ca6f4bbd8f661fb064012bdd595.zip gcc-f66d089128669ca6f4bbd8f661fb064012bdd595.tar.gz gcc-f66d089128669ca6f4bbd8f661fb064012bdd595.tar.bz2 |
re PR middle-end/58564 (possible wrong code bug at -O0)
PR middle-end/58564
* fold-const.c (fold_ternary_loc): For A < 0 : <sign bit of A> : 0
optimization, punt if sign_bit_p looked through any zero extension.
* gcc.c-torture/execute/pr58564.c: New test.
From-SVN: r203042
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 72a43e0..f68fd8b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14196,14 +14196,29 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, && integer_zerop (op2) && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1))) { + /* sign_bit_p looks through both zero and sign extensions, + but for this optimization only sign extensions are + usable. */ + tree tem2 = TREE_OPERAND (arg0, 0); + while (tem != tem2) + { + if (TREE_CODE (tem2) != NOP_EXPR + || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (tem2, 0)))) + { + tem = NULL_TREE; + break; + } + tem2 = TREE_OPERAND (tem2, 0); + } /* sign_bit_p only checks ARG1 bits within A's precision. If <sign bit of A> has wider type than A, bits outside of A's precision in <sign bit of A> need to be checked. If they are all 0, this optimization needs to be done in unsigned A's type, if they are all 1 in signed A's type, otherwise this can't be done. */ - if (TYPE_PRECISION (TREE_TYPE (tem)) - < TYPE_PRECISION (TREE_TYPE (arg1)) + if (tem + && TYPE_PRECISION (TREE_TYPE (tem)) + < TYPE_PRECISION (TREE_TYPE (arg1)) && TYPE_PRECISION (TREE_TYPE (tem)) < TYPE_PRECISION (type)) { |