summaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-30 20:15:20 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-30 20:15:20 +0000
commitc60fcb502eb64f4d8888d13f236d4c6da5d79e2a (patch)
tree05e6bf576979c3dbd647a166f68af3be286880e3 /gcc/fold-const.c
parent353f9f1628a39a4188175704565f242f2cc1c260 (diff)
downloadgcc-c60fcb502eb64f4d8888d13f236d4c6da5d79e2a.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@203042 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 72a43e04a44..f68fd8b15d5 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))
{