From 7f5aed1e5d7b8f02ed81178f65d84cbd27ec88cd Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 8 Dec 2017 00:56:34 +0100 Subject: [PATCH] re PR target/81906 (Calls to rint() wrongly optimized away starting in g++ 6) PR target/81906 * config/i386/i386.c (ix86_expand_rint): Handle flag_rounding_math. * gcc.target/i386/pr81906.c: New test. From-SVN: r255486 --- gcc/ChangeLog | 7 +++++ gcc/config/i386/i386.c | 25 +++++++++++++---- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/gcc.target/i386/pr81906.c | 37 +++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr81906.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7cf988956b7..58081c1e46e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-12-08 Joseph Myers + Alexander Monakov + Jakub Jelinek + + PR target/81906 + * config/i386/i386.c (ix86_expand_rint): Handle flag_rounding_math. + 2017-12-07 Richard Sandiford * config/aarch64/aarch64.c (aarch64_print_address_internal): Return diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5d77f28dfa3..e323102cef5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -44255,8 +44255,7 @@ ix86_expand_lfloorceil (rtx op0, rtx op1, bool do_floor) emit_move_insn (op0, ireg); } -/* Expand rint (IEEE round to nearest) rounding OPERAND1 and storing the - result in OPERAND0. */ +/* Expand rint rounding OPERAND1 and storing the result in OPERAND0. */ void ix86_expand_rint (rtx operand0, rtx operand1) { @@ -44264,11 +44263,17 @@ ix86_expand_rint (rtx operand0, rtx operand1) xa = fabs (operand1); if (!isless (xa, 2**52)) return operand1; - xa = xa + 2**52 - 2**52; + two52 = 2**52; + if (flag_rounding_math) + { + two52 = copysign (two52, operand1); + xa = operand1; + } + xa = xa + two52 - two52; return copysign (xa, operand1); */ machine_mode mode = GET_MODE (operand0); - rtx res, xa, TWO52, mask; + rtx res, xa, TWO52, two52, mask; rtx_code_label *label; res = gen_reg_rtx (mode); @@ -44281,8 +44286,16 @@ ix86_expand_rint (rtx operand0, rtx operand1) TWO52 = ix86_gen_TWO52 (mode); label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false); - xa = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT); - xa = expand_simple_binop (mode, MINUS, xa, TWO52, xa, 0, OPTAB_DIRECT); + two52 = TWO52; + if (flag_rounding_math) + { + two52 = gen_reg_rtx (mode); + ix86_sse_copysign_to_positive (two52, TWO52, res, mask); + xa = res; + } + + xa = expand_simple_binop (mode, PLUS, xa, two52, NULL_RTX, 0, OPTAB_DIRECT); + xa = expand_simple_binop (mode, MINUS, xa, two52, xa, 0, OPTAB_DIRECT); ix86_sse_copysign_to_positive (res, xa, res, mask); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4cb0d20fdd..d12ca43c7a1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-12-08 Jakub Jelinek + PR target/81906 + * gcc.target/i386/pr81906.c: New test. + PR tree-optimization/83075 * gcc.dg/tree-ssa/strncpy-2.c: Use size_t instead of unsigned, add separate function with noipa attribute to also verify behavior when diff --git a/gcc/testsuite/gcc.target/i386/pr81906.c b/gcc/testsuite/gcc.target/i386/pr81906.c new file mode 100644 index 00000000000..6c71bec41c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81906.c @@ -0,0 +1,37 @@ +/* PR target/81906 */ +/* { dg-do run { target *-*-linux* *-*-gnu* } } +/* { dg-options "-O2 -frounding-math" } */ + +#include + +int +main () +{ + #define N 12 + double a[N] = { 2.0, 2.25, 2.5, 2.75, 3.5, -2.0, -2.25, -2.5, -2.75, -3.5, 0x2.0p53, -0x2.0p53 }; + double b[N], c[N], d[N], e[N]; + double be[N] = { 2.0, 2.0, 2.0, 3.0, 4.0, -2.0, -2.0, -2.0, -3.0, -4.0, 0x2.0p53, -0x2.0p53 }; + double ce[N] = { 2.0, 2.0, 2.0, 2.0, 3.0, -2.0, -3.0, -3.0, -3.0, -4.0, 0x2.0p53, -0x2.0p53 }; + double de[N] = { 2.0, 3.0, 3.0, 3.0, 4.0, -2.0, -2.0, -2.0, -2.0, -3.0, 0x2.0p53, -0x2.0p53 }; + double ee[N] = { 2.0, 2.0, 2.0, 2.0, 3.0, -2.0, -2.0, -2.0, -2.0, -3.0, 0x2.0p53, -0x2.0p53 }; + asm volatile ("" : : "g" (a), "g" (be), "g" (ce), "g" (de), "g" (ee) : "memory"); + + int i; + fesetround (FE_TONEAREST); + for (i = 0; i < N; ++i) + b[i] = __builtin_rint (a[i]); + fesetround (FE_DOWNWARD); + for (i = 0; i < N; ++i) + c[i] = __builtin_rint (a[i]); + fesetround (FE_UPWARD); + for (i = 0; i < N; ++i) + d[i] = __builtin_rint (a[i]); + fesetround (FE_TOWARDZERO); + for (i = 0; i < N; ++i) + e[i] = __builtin_rint (a[i]); + fesetround (FE_TONEAREST); + for (i = 0; i < N; ++i) + if (b[i] != be[i] || c[i] != ce[i] || d[i] != de[i] || e[i] != ee[i]) + __builtin_abort (); + return 0; +} -- 2.30.2