aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-04-08 18:18:08 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-04-08 18:18:08 -0400
commite92d30482ecfa8b870e09648544af9ad54e60ccd (patch)
tree1a8b7d3e467624056daa3e30865e7e8bd6380057
parent69887ad921a264512d90b5087087476d2deead17 (diff)
downloadgcc-e92d30482ecfa8b870e09648544af9ad54e60ccd.zip
gcc-e92d30482ecfa8b870e09648544af9ad54e60ccd.tar.gz
gcc-e92d30482ecfa8b870e09648544af9ad54e60ccd.tar.bz2
(fold, case GT_EXPR): Simplify X < (1 << Y) into X >> Y == 0.
From-SVN: r6999
-rw-r--r--gcc/fold-const.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index e681278..4cfd2a9 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4517,6 +4517,30 @@ fold (expr)
return build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
arg0, integer_zero_node);
+ /* If X is unsigned, convert X < (1 << Y) into X >> Y == 0
+ and similarly for <= into !=. */
+ if ((code == LT_EXPR || code == GE_EXPR)
+ && TREE_UNSIGNED (TREE_TYPE (arg0))
+ && TREE_CODE (arg1) == LSHIFT_EXPR
+ && integer_onep (TREE_OPERAND (arg1, 0)))
+ return build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
+ build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
+ TREE_OPERAND (arg1, 1)),
+ convert (TREE_TYPE (arg0), integer_zero_node));
+
+ else if ((code == LT_EXPR || code == GE_EXPR)
+ && TREE_UNSIGNED (TREE_TYPE (arg0))
+ && (TREE_CODE (arg1) == NOP_EXPR
+ || TREE_CODE (arg1) == CONVERT_EXPR)
+ && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
+ && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
+ return
+ build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
+ convert (TREE_TYPE (arg0),
+ build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
+ TREE_OPERAND (TREE_OPERAND (arg1, 0), 1))),
+ convert (TREE_TYPE (arg0), integer_zero_node));
+
/* Simplify comparison of something with itself. (For IEEE
floating-point, we can only do some of these simplifications.) */
if (operand_equal_p (arg0, arg1, 0))