aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2017-12-08 00:56:34 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-12-08 00:56:34 +0100
commit7f5aed1e5d7b8f02ed81178f65d84cbd27ec88cd (patch)
tree19a103430578ba4a53e3f95d98e6a0aa9aa7770d /gcc
parent9b6c97373a0ca04b5888a1c4ca6519c94388da50 (diff)
downloadgcc-7f5aed1e5d7b8f02ed81178f65d84cbd27ec88cd.zip
gcc-7f5aed1e5d7b8f02ed81178f65d84cbd27ec88cd.tar.gz
gcc-7f5aed1e5d7b8f02ed81178f65d84cbd27ec88cd.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c25
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr81906.c37
4 files changed, 66 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7cf9889..58081c1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-12-08 Joseph Myers <joseph@codesourcery.com>
+ Alexander Monakov <amonakov@ispras.ru>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR target/81906
+ * config/i386/i386.c (ix86_expand_rint): Handle flag_rounding_math.
+
2017-12-07 Richard Sandiford <richard.sandiford@linaro.org>
* config/aarch64/aarch64.c (aarch64_print_address_internal): Return
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5d77f28..e323102 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 d4cb0d2..d12ca43 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2017-12-08 Jakub Jelinek <jakub@redhat.com>
+ 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 0000000..6c71bec
--- /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 <fenv.h>
+
+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;
+}