diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-10-09 15:48:24 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-10-09 15:48:24 +0000 |
commit | d2e74f6fd5b8dfff688b382b2fcb076f4f87a724 (patch) | |
tree | 170040c8e28a24edb9414cf344d53a3ab20d0b53 /gcc | |
parent | 0d2e6ffef6be51ec2e1fd9f593c26e1e53b23825 (diff) | |
download | gcc-d2e74f6fd5b8dfff688b382b2fcb076f4f87a724.zip gcc-d2e74f6fd5b8dfff688b382b2fcb076f4f87a724.tar.gz gcc-d2e74f6fd5b8dfff688b382b2fcb076f4f87a724.tar.bz2 |
re PR middle-end/17894 (div/compare folding incorrect)
PR middle-end/17894
* fold-const.c (fold_div_compare): When optimizing X/C1 op C2, the
relational comparison operator op needs to be swapped/reversed when
C1 is negative. i.e. X/-10 < 1 becomes X >= -9, not X < -9.
* gcc.c-torture/execute/divcmp-4.c: New test case.
From-SVN: r88818
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/divcmp-4.c | 202 |
4 files changed, 217 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f9daf8..5d968b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-10-09 Roger Sayle <roger@eyesopen.com> + + PR middle-end/17894 + * fold-const.c (fold_div_compare): When optimizing X/C1 op C2, the + relational comparison operator op needs to be swapped/reversed when + C1 is negative. i.e. X/-10 < 1 becomes X >= -9, not X < -9. + 2004-10-08 Andrew Pinski <pinskia@physics.uc.edu> PR tree-opt/17902 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 7de102f..41feda3 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -5720,6 +5720,9 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) } else { + /* A negative divisor reverses the relational operators. */ + code = swap_tree_comparison (code); + tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0); switch (tree_int_cst_sgn (arg1)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0ac5e9b..28d0a11 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-10-09 Roger Sayle <roger@eyesopen.com> + + PR middle-end/17894 + * gcc.c-torture/execute/divcmp-4.c: New test case. + 2004-10-08 Andrew Pinski <pinskia@physics.uc.edu> PR tree-opt/17902 diff --git a/gcc/testsuite/gcc.c-torture/execute/divcmp-4.c b/gcc/testsuite/gcc.c-torture/execute/divcmp-4.c new file mode 100644 index 0000000..ebc09a1 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/divcmp-4.c @@ -0,0 +1,202 @@ +/* PR middle-end/17894 */ + +extern void abort(void); + +int test1(int x) +{ + return x/-10 == 2; +} + +int test2(int x) +{ + return x/-10 == 0; +} + +int test3(int x) +{ + return x/-10 != 2; +} + +int test4(int x) +{ + return x/-10 != 0; +} + +int test5(int x) +{ + return x/-10 < 2; +} + +int test6(int x) +{ + return x/-10 < 0; +} + +int test7(int x) +{ + return x/-10 <= 2; +} + +int test8(int x) +{ + return x/-10 <= 0; +} + +int test9(int x) +{ + return x/-10 > 2; +} + +int test10(int x) +{ + return x/-10 > 0; +} + +int test11(int x) +{ + return x/-10 >= 2; +} + +int test12(int x) +{ + return x/-10 >= 0; +} + + +int main() +{ + if (test1(-30) != 0) + abort (); + if (test1(-29) != 1) + abort (); + if (test1(-20) != 1) + abort (); + if (test1(-19) != 0) + abort (); + + if (test2(0) != 1) + abort (); + if (test2(9) != 1) + abort (); + if (test2(10) != 0) + abort (); + if (test2(-1) != 1) + abort (); + if (test2(-9) != 1) + abort (); + if (test2(-10) != 0) + abort (); + + if (test3(-30) != 1) + abort (); + if (test3(-29) != 0) + abort (); + if (test3(-20) != 0) + abort (); + if (test3(-19) != 1) + abort (); + + if (test4(0) != 0) + abort (); + if (test4(9) != 0) + abort (); + if (test4(10) != 1) + abort (); + if (test4(-1) != 0) + abort (); + if (test4(-9) != 0) + abort (); + if (test4(-10) != 1) + abort (); + + if (test5(-30) != 0) + abort (); + if (test5(-29) != 0) + abort (); + if (test5(-20) != 0) + abort (); + if (test5(-19) != 1) + abort (); + + if (test6(0) != 0) + abort (); + if (test6(9) != 0) + abort (); + if (test6(10) != 1) + abort (); + if (test6(-1) != 0) + abort (); + if (test6(-9) != 0) + abort (); + if (test6(-10) != 0) + abort (); + + if (test7(-30) != 0) + abort (); + if (test7(-29) != 1) + abort (); + if (test7(-20) != 1) + abort (); + if (test7(-19) != 1) + abort (); + + if (test8(0) != 1) + abort (); + if (test8(9) != 1) + abort (); + if (test8(10) != 1) + abort (); + if (test8(-1) != 1) + abort (); + if (test8(-9) != 1) + abort (); + if (test8(-10) != 0) + abort (); + + if (test9(-30) != 1) + abort (); + if (test9(-29) != 0) + abort (); + if (test9(-20) != 0) + abort (); + if (test9(-19) != 0) + abort (); + + if (test10(0) != 0) + abort (); + if (test10(9) != 0) + abort (); + if (test10(10) != 0) + abort (); + if (test10(-1) != 0) + abort (); + if (test10(-9) != 0) + abort (); + if (test10(-10) != 1) + abort (); + + if (test11(-30) != 1) + abort (); + if (test11(-29) != 1) + abort (); + if (test11(-20) != 1) + abort (); + if (test11(-19) != 0) + abort (); + + if (test12(0) != 1) + abort (); + if (test12(9) != 1) + abort (); + if (test12(10) != 0) + abort (); + if (test12(-1) != 1) + abort (); + if (test12(-9) != 1) + abort (); + if (test12(-10) != 1) + abort (); + + return 0; +} + |