From 6b074ef6a052a19061eba1d2305c74277429d9bd Mon Sep 17 00:00:00 2001 From: Robert Kennedy Date: Wed, 10 Jan 2007 21:07:38 +0000 Subject: [PATCH] fold-const.c (fold_comparison): Fold comparisons like (x * 1000 < 0) to (x < 0). ./: * fold-const.c (fold_comparison): Fold comparisons like (x * 1000 < 0) to (x < 0). testsuite/: * gcc.dg/fold-compare-2.c: New test case for fold_comparison. From-SVN: r120649 --- gcc/ChangeLog | 5 +++++ gcc/fold-const.c | 25 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/fold-compare-2.c | 18 ++++++++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/fold-compare-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a528142aefc..7b37633c0e3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-01-10 Robert Kennedy + + * fold-const.c (fold_comparison): Fold comparisons like (x * + 1000 < 0) to (x < 0). + 2007-01-10 Ian Lance Taylor * tree-pretty-print.c (dump_generic_node): Print parentheses when diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3a3c1f9ce92b..9f116b5c1d4b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8189,6 +8189,31 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1) variable2); } + /* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the + signed arithmetic case. That form is created by the compiler + often enough for folding it to be of value. One example is in + computing loop trip counts after Operator Strength Reduction. */ + if (!(flag_wrapv || flag_trapv) + && !TYPE_UNSIGNED (TREE_TYPE (arg0)) + && TREE_CODE (arg0) == MULT_EXPR + && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST + && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))) + && integer_zerop (arg1)) + { + tree const1 = TREE_OPERAND (arg0, 1); + tree const2 = arg1; /* zero */ + tree variable1 = TREE_OPERAND (arg0, 0); + enum tree_code cmp_code = code; + + gcc_assert (!integer_zerop (const1)); + + /* If const1 is negative we swap the sense of the comparison. */ + if (tree_int_cst_sgn (const1) < 0) + cmp_code = swap_tree_comparison (cmp_code); + + return fold_build2 (cmp_code, type, variable1, const2); + } + tem = maybe_canonicalize_comparison (code, type, arg0, arg1); if (tem) return tem; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71488e554a2b..04dd13a8389f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-01-10 Robert Kennedy + + * gcc.dg/fold-compare-2.c: New test case for fold_comparison. + 2007-01-09 Brooks Moses * gfortran.dg/chkbits.f90: Added IBCLR tests; test calls diff --git a/gcc/testsuite/gcc.dg/fold-compare-2.c b/gcc/testsuite/gcc.dg/fold-compare-2.c new file mode 100644 index 000000000000..79bade7b9e17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-compare-2.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp" } */ + +extern void abort (void); + +int a; + +int +main(void) +{ + if (a * 1000 < 0) + abort (); + if (a * -43 > 0) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "Removing basic block" 1 "vrp1" } } */ -- 2.43.5