diff options
-rw-r--r-- | gcc/simplify-rtx.cc | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/ieee/pr119002.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr117186.c | 2 |
3 files changed, 34 insertions, 3 deletions
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index c478bd0..fe007bc 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -2655,6 +2655,9 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, enum rtx_code code0 = GET_CODE (op0); enum rtx_code code1 = GET_CODE (op1); + machine_mode cmp_mode = GET_MODE (XEXP (op0, 0)); + if (cmp_mode == VOIDmode) + cmp_mode = GET_MODE (XEXP (op0, 1)); /* Assume at first that the comparisons are on integers, and that the operands are therefore ordered. */ @@ -2672,8 +2675,10 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, } else { - /* See whether the operands might be unordered. */ - if (HONOR_NANS (GET_MODE (XEXP (op0, 0)))) + /* See whether the operands might be unordered. Assume that all + results are possible for CC modes, and punt later if we don't get an + always-true or always-false answer. */ + if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode)) all = 15; mask0 = comparison_to_mask (code0) & all; mask1 = comparison_to_mask (code1) & all; @@ -2702,6 +2707,9 @@ simplify_context::simplify_logical_relational_operation (rtx_code code, code = mask_to_unsigned_comparison (mask); else { + if (GET_MODE_CLASS (cmp_mode) == MODE_CC) + return 0; + code = mask_to_comparison (mask); /* LTGT and NE are arithmetically equivalent for ordered operands, with NE being the canonical choice. */ diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr119002.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr119002.c new file mode 100644 index 0000000..af1a705 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr119002.c @@ -0,0 +1,23 @@ +/* PR rtl-optimization/119002 */ + +__attribute__((noipa)) unsigned int +foo (void *x, float y, float z) +{ + unsigned int a, b; + float c, d, e; + c = y; + d = z; + a = c < d; + d = y; + e = z; + b = d >= e; + a |= b; + return a; +} + +int +main () +{ + if (foo ((void *) 0, 0.f, __builtin_nanf (""))) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr117186.c b/gcc/testsuite/gcc.target/aarch64/pr117186.c index afe3c25..3090f2c 100644 --- a/gcc/testsuite/gcc.target/aarch64/pr117186.c +++ b/gcc/testsuite/gcc.target/aarch64/pr117186.c @@ -1,4 +1,4 @@ -/* { dg-options "-O" } */ +/* { dg-options "-O2" } */ /* { dg-final { check-function-bodies "**" "" "" } } */ /* |