diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-03-09 14:54:11 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-03-09 14:54:11 +0000 |
commit | d56ee62bfe7847ec4a100f3773827c2e3697879a (patch) | |
tree | e916d0c1fbf47882c6b59b371a0f0040a79db41e /gcc | |
parent | ad5dd90de05dba5f4db6bc4d1e355dab4e4a4696 (diff) | |
download | gcc-d56ee62bfe7847ec4a100f3773827c2e3697879a.zip gcc-d56ee62bfe7847ec4a100f3773827c2e3697879a.tar.gz gcc-d56ee62bfe7847ec4a100f3773827c2e3697879a.tar.bz2 |
re PR middle-end/26561 (ACATS failures c34004a, c46033a and cxg2024 at -O0)
2006-03-09 Roger Sayle <roger@eyesopen.com>
Eric Botcazou <ebotcazou@libertysurf.fr>
PR middle-end/26561
* fold-const.c (fold_div_compare): When optimizing X/C1 op C2 as
X op C3, consider whether C3 overflows towards +Inf or -Inf.
* gcc.c-torture/execute/divcmp-5.c: New test case.
Co-Authored-By: Eric Botcazou <ebotcazou@libertysurf.fr>
From-SVN: r111862
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/divcmp-5.c | 31 |
4 files changed, 64 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 047033c..5539174 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-03-09 Roger Sayle <roger@eyesopen.com> + + PR middle-end/26561 + * fold-const.c (fold_div_compare): When optimizing X/C1 op C2 as + X op C3, consider whether C3 overflows towards +Inf or -Inf. + 2006-03-08 DJ Delorie <dj@redhat.com> * config/m32c/addsub.md (addqi3): Disparage a0/a1. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 2e89969..be0c461 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6014,6 +6014,7 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) tree arg01 = TREE_OPERAND (arg0, 1); unsigned HOST_WIDE_INT lpart; HOST_WIDE_INT hpart; + bool neg_overflow; int overflow; /* We have to do this the hard way to detect unsigned overflow. @@ -6024,6 +6025,7 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) TREE_INT_CST_HIGH (arg1), &lpart, &hpart); prod = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart); prod = force_fit_type (prod, -1, overflow, false); + neg_overflow = false; if (TYPE_UNSIGNED (TREE_TYPE (arg0))) { @@ -6046,6 +6048,7 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) switch (tree_int_cst_sgn (arg1)) { case -1: + neg_overflow = true; lo = int_const_binop (MINUS_EXPR, prod, tmp, 0); hi = prod; break; @@ -6083,7 +6086,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) break; case 1: - lo = int_const_binop (PLUS_EXPR, prod, tmp, 0); + neg_overflow = true; + lo = int_const_binop (PLUS_EXPR, prod, tmp, 0); hi = prod; break; @@ -6114,22 +6118,34 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1) case LT_EXPR: if (TREE_OVERFLOW (lo)) - return omit_one_operand (type, integer_one_node, arg00); + { + tmp = neg_overflow ? integer_zero_node : integer_one_node; + return omit_one_operand (type, tmp, arg00); + } return fold_build2 (LT_EXPR, type, arg00, lo); case LE_EXPR: if (TREE_OVERFLOW (hi)) - return omit_one_operand (type, integer_one_node, arg00); + { + tmp = neg_overflow ? integer_zero_node : integer_one_node; + return omit_one_operand (type, tmp, arg00); + } return fold_build2 (LE_EXPR, type, arg00, hi); case GT_EXPR: if (TREE_OVERFLOW (hi)) - return omit_one_operand (type, integer_zero_node, arg00); + { + tmp = neg_overflow ? integer_one_node : integer_zero_node; + return omit_one_operand (type, tmp, arg00); + } return fold_build2 (GT_EXPR, type, arg00, hi); case GE_EXPR: if (TREE_OVERFLOW (lo)) - return omit_one_operand (type, integer_zero_node, arg00); + { + tmp = neg_overflow ? integer_one_node : integer_zero_node; + return omit_one_operand (type, tmp, arg00); + } return fold_build2 (GE_EXPR, type, arg00, lo); default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3dff55cb..b082e56 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2006-03-09 Roger Sayle <roger@eyesopen.com> + Eric Botcazou <ebotcazou@libertysurf.fr> + + PR middle-end/26561 + * gcc.c-torture/execute/divcmp-5.c: New test case. + 2006-03-09 Paul Thomas <pault@gcc.gnu.org> * PR fortran/26257 diff --git a/gcc/testsuite/gcc.c-torture/execute/divcmp-5.c b/gcc/testsuite/gcc.c-torture/execute/divcmp-5.c new file mode 100644 index 0000000..f6d1af3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/divcmp-5.c @@ -0,0 +1,31 @@ +/* PR middle-end/26561 */ + +extern void abort(void); + +int always_one_1 (int a) +{ + if (a/100 >= -999999999) + return 1; + else + return 0; +} + +int always_one_2 (int a) +{ + if (a/100 < -999999999) + return 0; + else + return 1; +} + +int main(void) +{ + if (always_one_1 (0) != 1) + abort (); + + if (always_one_2 (0) != 1) + abort (); + + return 0; +} + |