From: Roger Sayle Date: Sat, 11 Sep 2004 03:21:22 +0000 (+0000) Subject: re PR middle-end/17024 (ICE in fold_cond_expr_with_comparison, at fold-const.c:4324) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3ae472c234e4d4fb0898b3e82b36c8ac72822824;p=gcc.git 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 --- 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 + + 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 * 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 + + PR middle-end/17024 + * gcc.dg/pr17024-1.c: New test case. + 2004-09-10 Eric Christopher * 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; +} +