summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2004-09-11 03:21:22 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2004-09-11 03:21:22 +0000
commit3ae472c234e4d4fb0898b3e82b36c8ac72822824 (patch)
treed8c850b7dd662237f8d13d195a77666abb0e2beb /gcc
parentdc9d0b14b764ae39d8421cb83c0a3d34f16e12fc (diff)
downloadgcc-3ae472c234e4d4fb0898b3e82b36c8ac72822824.tar.gz
re PR middle-end/17024 (ICE in fold_cond_expr_with_comparison, at fold-const.c:4324)
PR middle-end/17024 * fold-const.c (fold_cond_expr_with_comparison): Handle unordered floating point comparison operators. Change aborts to gcc_asserts. * gcc.dg/pr17024-1.c: New test case. From-SVN: r87339
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c46
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr17024-1.c15
4 files changed, 59 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f5d0a00e487..ab280adb647 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-10 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/17024
+ * fold-const.c (fold_cond_expr_with_comparison): Handle unordered
+ floating point comparison operators. Change aborts to gcc_asserts.
+
2004-09-10 Geoffrey Keating <geoffk@apple.com>
* final.c (output_asm_insn): Correct problem with -fverbose-asm.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 10cdb69b487..d0720e9f023 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4162,10 +4162,17 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
switch (comp_code)
{
case EQ_EXPR:
+ case UNEQ_EXPR:
tem = fold_convert (arg1_type, arg1);
return pedantic_non_lvalue (fold_convert (type, negate_expr (tem)));
case NE_EXPR:
+ case LTGT_EXPR:
return pedantic_non_lvalue (fold_convert (type, arg1));
+ case UNGE_EXPR:
+ case UNGT_EXPR:
+ if (flag_trapping_math)
+ break;
+ /* Fall through. */
case GE_EXPR:
case GT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
@@ -4173,6 +4180,10 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
(TREE_TYPE (arg1)), arg1);
tem = fold (build1 (ABS_EXPR, TREE_TYPE (arg1), arg1));
return pedantic_non_lvalue (fold_convert (type, tem));
+ case UNLE_EXPR:
+ case UNLT_EXPR:
+ if (flag_trapping_math)
+ break;
case LE_EXPR:
case LT_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
@@ -4181,7 +4192,8 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
tem = fold (build1 (ABS_EXPR, TREE_TYPE (arg1), arg1));
return negate_expr (fold_convert (type, tem));
default:
- gcc_unreachable ();
+ gcc_assert (TREE_CODE_CLASS (comp_code) == '<');
+ break;
}
/* A != 0 ? A : 0 is simply A, unless A is -0. Likewise
@@ -4245,6 +4257,8 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
return pedantic_non_lvalue (fold_convert (type, arg1));
case LE_EXPR:
case LT_EXPR:
+ case UNLE_EXPR:
+ case UNLT_EXPR:
/* In C++ a ?: expression can be an lvalue, so put the
operand which will be used if they are equal first
so that we can convert this back to the
@@ -4253,31 +4267,37 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
{
comp_op0 = fold_convert (comp_type, comp_op0);
comp_op1 = fold_convert (comp_type, comp_op1);
- tem = fold (build2 (MIN_EXPR, comp_type,
- (comp_code == LE_EXPR
- ? comp_op0 : comp_op1),
- (comp_code == LE_EXPR
- ? comp_op1 : comp_op0)));
+ tem = (comp_code == LE_EXPR || comp_code == UNLE_EXPR)
+ ? fold (build2 (MIN_EXPR, comp_type, comp_op0, comp_op1))
+ : fold (build2 (MIN_EXPR, comp_type, comp_op1, comp_op0));
return pedantic_non_lvalue (fold_convert (type, tem));
}
break;
case GE_EXPR:
case GT_EXPR:
+ case UNGE_EXPR:
+ case UNGT_EXPR:
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
{
comp_op0 = fold_convert (comp_type, comp_op0);
comp_op1 = fold_convert (comp_type, comp_op1);
- tem = fold (build2 (MAX_EXPR, comp_type,
- (comp_code == GE_EXPR
- ? comp_op0 : comp_op1),
- (comp_code == GE_EXPR
- ? comp_op1 : comp_op0)));
- tem = fold (build2 (MAX_EXPR, comp_type, comp_op0, comp_op1));
+ tem = (comp_code == GE_EXPR || comp_code == UNGE_EXPR)
+ ? fold (build2 (MAX_EXPR, comp_type, comp_op0, comp_op1))
+ : fold (build2 (MAX_EXPR, comp_type, comp_op1, comp_op0));
return pedantic_non_lvalue (fold_convert (type, tem));
}
break;
+ case UNEQ_EXPR:
+ if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
+ return pedantic_non_lvalue (fold_convert (type, arg2));
+ break;
+ case LTGT_EXPR:
+ if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
+ return pedantic_non_lvalue (fold_convert (type, arg1));
+ break;
default:
- gcc_unreachable ();
+ gcc_assert (TREE_CODE_CLASS (comp_code) == '<');
+ break;
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3d052a9aae6..d899403219e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-09-10 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/17024
+ * gcc.dg/pr17024-1.c: New test case.
+
2004-09-10 Eric Christopher <echristo@redhat.com>
* gcc.dg/20040910-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr17024-1.c b/gcc/testsuite/gcc.dg/pr17024-1.c
new file mode 100644
index 00000000000..d8bdf012b9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr17024-1.c
@@ -0,0 +1,15 @@
+/* PR middle-end/17024 */
+/* { dg-do compile } */
+/* { dg-options "-funsafe-math-optimizations" } */
+
+#define MAX2(a,b) (((a)>(b)) ? (a) : (b))
+
+void C(double);
+
+void i(int k)
+{
+ double c[1];
+ C(MAX2(0.,c[k]));
+ return;
+}
+