re PR middle-end/17024 (ICE in fold_cond_expr_with_comparison, at fold-const.c:4324)
authorRoger Sayle <roger@eyesopen.com>
Sat, 11 Sep 2004 03:21:22 +0000 (03:21 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sat, 11 Sep 2004 03:21:22 +0000 (03:21 +0000)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr17024-1.c [new file with mode: 0644]

index f5d0a00..ab280ad 100644 (file)
@@ -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.
index 10cdb69..d0720e9 100644 (file)
@@ -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;
        }
     }
 
index 3d052a9..d899403 100644 (file)
@@ -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 (file)
index 0000000..d8bdf01
--- /dev/null
@@ -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;
+}
+