aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2006-03-09 14:54:11 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2006-03-09 14:54:11 +0000
commitd56ee62bfe7847ec4a100f3773827c2e3697879a (patch)
treee916d0c1fbf47882c6b59b371a0f0040a79db41e /gcc
parentad5dd90de05dba5f4db6bc4d1e355dab4e4a4696 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/fold-const.c26
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/divcmp-5.c31
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;
+}
+