backport: re PR target/81906 (Calls to rint() wrongly optimized away starting in g++ 6)

Backported from mainline
	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.

	* gcc.target/i386/pr81906.c: New test.

From-SVN: r255725
This commit is contained in:
Jakub Jelinek 2017-12-15 23:11:33 +01:00 committed by Jakub Jelinek
parent 1c8f2b0a85
commit af3b2e0538
4 changed files with 68 additions and 6 deletions

View File

@ -1,6 +1,13 @@
2017-12-15 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
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-02 Jakub Jelinek <jakub@redhat.com>
PR c++/81212

View File

@ -45299,8 +45299,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)
{
@ -45308,11 +45307,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);
@ -45325,8 +45330,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);

View File

@ -1,6 +1,11 @@
2017-12-15 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2017-12-08 Jakub Jelinek <jakub@redhat.com>
PR target/81906
* gcc.target/i386/pr81906.c: New test.
2017-12-06 Jakub Jelinek <jakub@redhat.com>
PR c++/80259

View File

@ -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;
}