Add option for whether ceil etc. can raise "inexact", adjust x86 conditions

Jan Hubicka hubicka@ucw.cz
Fri May 27 06:14:00 GMT 2016


> > +ffp-int-builtin-inexact
> > +Common Report Var(flag_fp_int_builtin_inexact) Optimization
> > +Allow built-in functions ceil, floor, round, trunc to raise \"inexact\" exceptions.

When adding new codegen option which affects the correctness, it is also
necessary to update can_inline_edge_p and inline_call.

(In general it would be great if we had fewer such flags and more stuff
explicitly represented in IL. I am not sure how hard that would be here and
if it is worth the effort.)

Honza
> > +
> >  ; Nonzero means don't put addresses of constant functions in registers.
> >  ; Used for compiling the Unix kernel, where strange substitutions are
> >  ; done on the assembly output.
> > Index: gcc/config/i386/i386.md
> > ===================================================================
> > --- gcc/config/i386/i386.md     (revision 236740)
> > +++ gcc/config/i386/i386.md     (working copy)
> > @@ -15512,25 +15512,31 @@
> >    [(set (match_operand:XF 0 "register_operand" "=f")
> >         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
> >                    UNSPEC_FRNDINT))]
> > -  "TARGET_USE_FANCY_MATH_387
> > -   && flag_unsafe_math_optimizations"
> > +  "TARGET_USE_FANCY_MATH_387"
> >    "frndint"
> >    [(set_attr "type" "fpspc")
> >     (set_attr "znver1_decode" "vector")
> >     (set_attr "mode" "XF")])
> >
> > +(define_insn "rint<mode>2_frndint"
> > +  [(set (match_operand:MODEF 0 "register_operand" "=f")
> > +       (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
> > +                     UNSPEC_FRNDINT))]
> > +  "TARGET_USE_FANCY_MATH_387"
> > +  "frndint"
> > +  [(set_attr "type" "fpspc")
> > +   (set_attr "znver1_decode" "vector")
> > +   (set_attr "mode" "<MODE>")])
> > +
> >  (define_expand "rint<mode>2"
> >    [(use (match_operand:MODEF 0 "register_operand"))
> >     (use (match_operand:MODEF 1 "register_operand"))]
> >    "(TARGET_USE_FANCY_MATH_387
> >      && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> > -       || TARGET_MIX_SSE_I387)
> > -    && flag_unsafe_math_optimizations)
> > -   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
> > -       && !flag_trapping_math)"
> > +       || TARGET_MIX_SSE_I387))
> > +   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
> >  {
> > -  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
> > -      && !flag_trapping_math)
> > +  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> >      {
> >        if (TARGET_ROUND)
> >         emit_insn (gen_sse4_1_round<mode>2
> > @@ -15539,15 +15545,7 @@
> >         ix86_expand_rint (operands[0], operands[1]);
> >      }
> >    else
> > -    {
> > -      rtx op0 = gen_reg_rtx (XFmode);
> > -      rtx op1 = gen_reg_rtx (XFmode);
> > -
> > -      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
> > -      emit_insn (gen_rintxf2 (op0, op1));
> > -
> > -      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
> > -    }
> > +    emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
> >    DONE;
> >  })
> >
> > @@ -15770,13 +15768,13 @@
> >          (UNSPEC_FIST_CEIL "CEIL")])
> >
> >  ;; Rounding mode control word calculation could clobber FLAGS_REG.
> > -(define_insn_and_split "frndintxf2_<rounding>"
> > -  [(set (match_operand:XF 0 "register_operand")
> > -       (unspec:XF [(match_operand:XF 1 "register_operand")]
> > +(define_insn_and_split "frndint<mode>2_<rounding>"
> > +  [(set (match_operand:X87MODEF 0 "register_operand")
> > +       (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
> >                    FRNDINT_ROUNDING))
> >     (clobber (reg:CC FLAGS_REG))]
> >    "TARGET_USE_FANCY_MATH_387
> > -   && flag_unsafe_math_optimizations
> > +   && (flag_fp_int_builtin_inexact || !flag_trapping_math)
> >     && can_create_pseudo_p ()"
> >    "#"
> >    "&& 1"
> > @@ -15787,26 +15785,26 @@
> >    operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
> >    operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
> >
> > -  emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
> > -                                            operands[2], operands[3]));
> > +  emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
> > +                                                operands[2], operands[3]));
> >    DONE;
> >  }
> >    [(set_attr "type" "frndint")
> >     (set_attr "i387_cw" "<rounding>")
> > -   (set_attr "mode" "XF")])
> > +   (set_attr "mode" "<MODE>")])
> >
> > -(define_insn "frndintxf2_<rounding>_i387"
> > -  [(set (match_operand:XF 0 "register_operand" "=f")
> > -       (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
> > -                  FRNDINT_ROUNDING))
> > +(define_insn "frndint<mode>2_<rounding>_i387"
> > +  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
> > +       (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
> > +                        FRNDINT_ROUNDING))
> >     (use (match_operand:HI 2 "memory_operand" "m"))
> >     (use (match_operand:HI 3 "memory_operand" "m"))]
> >    "TARGET_USE_FANCY_MATH_387
> > -   && flag_unsafe_math_optimizations"
> > +   && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
> >    "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
> >    [(set_attr "type" "frndint")
> >     (set_attr "i387_cw" "<rounding>")
> > -   (set_attr "mode" "XF")])
> > +   (set_attr "mode" "<MODE>")])
> >
> >  (define_expand "<rounding_insn>xf2"
> >    [(parallel [(set (match_operand:XF 0 "register_operand")
> > @@ -15814,7 +15812,7 @@
> >                               FRNDINT_ROUNDING))
> >               (clobber (reg:CC FLAGS_REG))])]
> >    "TARGET_USE_FANCY_MATH_387
> > -   && flag_unsafe_math_optimizations")
> > +   && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
> >
> >  (define_expand "<rounding_insn><mode>2"
> >    [(parallel [(set (match_operand:MODEF 0 "register_operand")
> > @@ -15824,16 +15822,17 @@
> >    "(TARGET_USE_FANCY_MATH_387
> >      && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
> >         || TARGET_MIX_SSE_I387)
> > -    && flag_unsafe_math_optimizations)
> > +    && (flag_fp_int_builtin_inexact || !flag_trapping_math))
> >     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
> > -       && !flag_trapping_math)"
> > +       && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
> >  {
> >    if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
> > -      && !flag_trapping_math)
> > +      && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
> >      {
> >        if (TARGET_ROUND)
> >         emit_insn (gen_sse4_1_round<mode>2
> > -                  (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
> > +                  (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
> > +                                                      | ROUND_NO_EXC)));
> >        else if (TARGET_64BIT || (<MODE>mode != DFmode))
> >         {
> >           if (ROUND_<ROUNDING> == ROUND_FLOOR)
> > @@ -15858,16 +15857,7 @@
> >         }
> >      }
> >    else
> > -    {
> > -      rtx op0, op1;
> > -
> > -      op0 = gen_reg_rtx (XFmode);
> > -      op1 = gen_reg_rtx (XFmode);
> > -      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
> > -      emit_insn (gen_frndintxf2_<rounding> (op0, op1));
> > -
> > -      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
> > -    }
> > +    emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
> >    DONE;
> >  })
> >
> > Index: gcc/doc/invoke.texi
> > ===================================================================
> > --- gcc/doc/invoke.texi (revision 236740)
> > +++ gcc/doc/invoke.texi (working copy)
> > @@ -370,9 +370,9 @@ Objective-C and Objective-C++ Dialects}.
> >  -flto-partition=@var{alg} -fmerge-all-constants @gol
> >  -fmerge-constants -fmodulo-sched -fmodulo-sched-allow-regmoves @gol
> >  -fmove-loop-invariants -fno-branch-count-reg @gol
> > --fno-defer-pop -fno-function-cse -fno-guess-branch-probability @gol
> > --fno-inline -fno-math-errno -fno-peephole -fno-peephole2 @gol
> > --fno-sched-interblock -fno-sched-spec -fno-signed-zeros @gol
> > +-fno-defer-pop -fno-fp-int-builtin-inexact -fno-function-cse @gol
> > +-fno-guess-branch-probability -fno-inline -fno-math-errno -fno-peephole @gol
> > +-fno-peephole2 -fno-sched-interblock -fno-sched-spec -fno-signed-zeros @gol
> >  -fno-toplevel-reorder -fno-trapping-math -fno-zero-initialized-in-bss @gol
> >  -fomit-frame-pointer -foptimize-sibling-calls @gol
> >  -fpartial-inlining -fpeel-loops -fpredictive-commoning @gol
> > @@ -8531,6 +8531,24 @@ The default is @option{-fno-signaling-nans}.
> >  This option is experimental and does not currently guarantee to
> >  disable all GCC optimizations that affect signaling NaN behavior.
> >
> > +@item -fno-fp-int-builtin-inexact
> > +@opindex fno-fp-int-builtin-inexact
> > +Do not allow the built-in functions @code{ceil}, @code{floor},
> > +@code{round} and @code{trunc}, and their @code{float} and @code{long
> > +double} variants, to generate code that raises the ``inexact''
> > +floating-point exception for noninteger arguments.  ISO C99 and C11
> > +allow these functions to raise the ``inexact'' exception, but ISO/IEC
> > +TS 18661-1:2014, the C bindings to IEEE 754-2008, does not allow these
> > +functions to do so.
> > +
> > +The default is @option{-ffp-int-builtin-inexact}, allowing the
> > +exception to be raised.  This option does nothing unless
> > +@option{-ftrapping-math} is in effect.
> > +
> > +Even if @option{-fno-fp-int-builtin-inexact} is used, if the functions
> > +generate a call to a library function then the ``inexact'' exception
> > +may be raised if the library implementation does not follow TS 18661.
> > +
> >  @item -fsingle-precision-constant
> >  @opindex fsingle-precision-constant
> >  Treat floating-point constants as single precision instead of
> > Index: gcc/testsuite/gcc.dg/torture/builtin-fp-int-inexact.c
> > ===================================================================
> > --- gcc/testsuite/gcc.dg/torture/builtin-fp-int-inexact.c       (nonexistent)
> > +++ gcc/testsuite/gcc.dg/torture/builtin-fp-int-inexact.c       (working copy)
> > @@ -0,0 +1,72 @@
> > +/* Test -fno-fp-int-builtin-inexact.  */
> > +/* { dg-do run } */
> > +/* { dg-options "-fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target fenv_exceptions } */
> > +
> > +#include <fenv.h>
> > +
> > +/* Define functions locally to ensure that if the calls are not
> > +   expanded inline, failures do not occur because of libm raising
> > +   "inexact".  */
> > +
> > +#define LOCAL_FN(NAME, TYPE)                   \
> > +  __attribute__ ((noinline, noclone)) TYPE     \
> > +  NAME (TYPE x)                                        \
> > +  {                                            \
> > +    return x;                                  \
> > +  }
> > +
> > +#define LOCAL_FNS(NAME)                                \
> > +  LOCAL_FN (NAME, double)                      \
> > +  LOCAL_FN (NAME ## f, float)                  \
> > +  LOCAL_FN (NAME ## l, long double)
> > +
> > +LOCAL_FNS (ceil)
> > +LOCAL_FNS (floor)
> > +LOCAL_FNS (round)
> > +LOCAL_FNS (trunc)
> > +
> > +extern void abort (void);
> > +extern void exit (int);
> > +
> > +#define TEST(FN, TYPE)                         \
> > +  do                                           \
> > +    {                                          \
> > +      volatile TYPE a = 1.5, b;                        \
> > +      b = FN (a);                              \
> > +      if (fetestexcept (FE_INEXACT))           \
> > +       abort ();                               \
> > +    }                                          \
> > +  while (0)
> > +
> > +#define FN_TESTS(FN)                                   \
> > +  do                                                   \
> > +    {                                                  \
> > +      TEST (__builtin_ ## FN, double);                 \
> > +      TEST (__builtin_ ## FN ## f, float);             \
> > +      TEST (__builtin_ ## FN ## l, long double);       \
> > +    }                                                  \
> > +  while (0)
> > +
> > +static void
> > +main_test (void)
> > +{
> > +  FN_TESTS (ceil);
> > +  FN_TESTS (floor);
> > +  FN_TESTS (round);
> > +  FN_TESTS (trunc);
> > +}
> > +
> > +/* This file may be included by architecture-specific tests.  */
> > +
> > +#ifndef ARCH_MAIN
> > +
> > +int
> > +main (void)
> > +{
> > +  main_test ();
> > +  exit (0);
> > +}
> > +
> > +#endif
> > Index: gcc/testsuite/gcc.target/i386/387-builtin-fp-int-inexact.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/387-builtin-fp-int-inexact.c  (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/387-builtin-fp-int-inexact.c  (working copy)
> > @@ -0,0 +1,7 @@
> > +/* Test -fno-fp-int-builtin-inexact for 387.  */
> > +/* { dg-do run } */
> > +/* { dg-options "-O2 -mfancy-math-387 -mfpmath=387 -fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target fenv_exceptions } */
> > +
> > +#include "../../gcc.dg/torture/builtin-fp-int-inexact.c"
> > Index: gcc/testsuite/gcc.target/i386/387-rint-inline-1.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/387-rint-inline-1.c   (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/387-rint-inline-1.c   (working copy)
> > @@ -0,0 +1,36 @@
> > +/* Test rint and related functions expanded inline for 387.  All
> > +   should be expanded when spurious "inexact" allowed.  */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mfancy-math-387 -mfpmath=387 -ffp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +
> > +#define TEST(FN, TYPE)                         \
> > +  do                                           \
> > +    {                                          \
> > +      volatile TYPE a = 1.5, b;                        \
> > +      b = FN (a);                              \
> > +    }                                          \
> > +  while (0)
> > +
> > +#define FN_TESTS(FN)                                   \
> > +  do                                                   \
> > +    {                                                  \
> > +      TEST (__builtin_ ## FN, double);                 \
> > +      TEST (__builtin_ ## FN ## f, float);             \
> > +      TEST (__builtin_ ## FN ## l, long double);       \
> > +    }                                                  \
> > +  while (0)
> > +
> > +void
> > +test (void)
> > +{
> > +  FN_TESTS (rint);
> > +  FN_TESTS (ceil);
> > +  FN_TESTS (floor);
> > +  FN_TESTS (trunc);
> > +}
> > +
> > +/* { dg-final { scan-assembler-not "\[ \t\]rint" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]ceil" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]floor" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]trunc" } } */
> > Index: gcc/testsuite/gcc.target/i386/387-rint-inline-2.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/387-rint-inline-2.c   (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/387-rint-inline-2.c   (working copy)
> > @@ -0,0 +1,30 @@
> > +/* Test rint and related functions expanded inline for 387.  rint
> > +   should be expanded even when spurious "inexact" not allowed.  */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mfancy-math-387 -mfpmath=387 -fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +
> > +#define TEST(FN, TYPE)                         \
> > +  do                                           \
> > +    {                                          \
> > +      volatile TYPE a = 1.5, b;                        \
> > +      b = FN (a);                              \
> > +    }                                          \
> > +  while (0)
> > +
> > +#define FN_TESTS(FN)                                   \
> > +  do                                                   \
> > +    {                                                  \
> > +      TEST (__builtin_ ## FN, double);                 \
> > +      TEST (__builtin_ ## FN ## f, float);             \
> > +      TEST (__builtin_ ## FN ## l, long double);       \
> > +    }                                                  \
> > +  while (0)
> > +
> > +void
> > +test (void)
> > +{
> > +  FN_TESTS (rint);
> > +}
> > +
> > +/* { dg-final { scan-assembler-not "\[ \t\]rint" } } */
> > Index: gcc/testsuite/gcc.target/i386/sse2-builtin-fp-int-inexact.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/sse2-builtin-fp-int-inexact.c (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/sse2-builtin-fp-int-inexact.c (working copy)
> > @@ -0,0 +1,12 @@
> > +/* Test -fno-fp-int-builtin-inexact for SSE 2.  */
> > +/* { dg-do run } */
> > +/* { dg-options "-O2 -msse2 -mfpmath=sse -fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target fenv_exceptions } */
> > +/* { dg-require-effective-target sse2 } */
> > +
> > +#include "sse2-check.h"
> > +
> > +#define main_test sse2_test
> > +#define ARCH_MAIN
> > +#include "../../gcc.dg/torture/builtin-fp-int-inexact.c"
> > Index: gcc/testsuite/gcc.target/i386/sse2-rint-inline-1.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/sse2-rint-inline-1.c  (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/sse2-rint-inline-1.c  (working copy)
> > @@ -0,0 +1,36 @@
> > +/* Test rint and related functions expanded inline for SSE2.  All
> > +   should be expanded when spurious "inexact" allowed.  */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -msse2 -mfpmath=sse -ffp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target sse2 } */
> > +
> > +#define TEST(FN, TYPE)                         \
> > +  do                                           \
> > +    {                                          \
> > +      volatile TYPE a = 1.5, b;                        \
> > +      b = FN (a);                              \
> > +    }                                          \
> > +  while (0)
> > +
> > +#define FN_TESTS(FN)                                   \
> > +  do                                                   \
> > +    {                                                  \
> > +      TEST (__builtin_ ## FN, double);                 \
> > +      TEST (__builtin_ ## FN ## f, float);             \
> > +    }                                                  \
> > +  while (0)
> > +
> > +void
> > +test (void)
> > +{
> > +  FN_TESTS (rint);
> > +  FN_TESTS (ceil);
> > +  FN_TESTS (floor);
> > +  FN_TESTS (trunc);
> > +}
> > +
> > +/* { dg-final { scan-assembler-not "\[ \t\]rint" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]ceil" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]floor" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]trunc" } } */
> > Index: gcc/testsuite/gcc.target/i386/sse2-rint-inline-2.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/sse2-rint-inline-2.c  (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/sse2-rint-inline-2.c  (working copy)
> > @@ -0,0 +1,30 @@
> > +/* Test rint and related functions expanded inline for SSE2.  rint
> > +   should be expanded even when spurious "inexact" not allowed.  */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -msse2 -mfpmath=sse -fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target sse2 } */
> > +
> > +#define TEST(FN, TYPE)                         \
> > +  do                                           \
> > +    {                                          \
> > +      volatile TYPE a = 1.5, b;                        \
> > +      b = FN (a);                              \
> > +    }                                          \
> > +  while (0)
> > +
> > +#define FN_TESTS(FN)                                   \
> > +  do                                                   \
> > +    {                                                  \
> > +      TEST (__builtin_ ## FN, double);                 \
> > +      TEST (__builtin_ ## FN ## f, float);             \
> > +    }                                                  \
> > +  while (0)
> > +
> > +void
> > +test (void)
> > +{
> > +  FN_TESTS (rint);
> > +}
> > +
> > +/* { dg-final { scan-assembler-not "\[ \t\]rint" } } */
> > Index: gcc/testsuite/gcc.target/i386/sse4_1-builtin-fp-int-inexact.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/sse4_1-builtin-fp-int-inexact.c       (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/sse4_1-builtin-fp-int-inexact.c       (working copy)
> > @@ -0,0 +1,12 @@
> > +/* Test -fno-fp-int-builtin-inexact for SSE 4.1.  */
> > +/* { dg-do run } */
> > +/* { dg-options "-O2 -msse4.1 -mfpmath=sse -fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target fenv_exceptions } */
> > +/* { dg-require-effective-target sse4 } */
> > +
> > +#include "sse4_1-check.h"
> > +
> > +#define main_test sse4_1_test
> > +#define ARCH_MAIN
> > +#include "../../gcc.dg/torture/builtin-fp-int-inexact.c"
> > Index: gcc/testsuite/gcc.target/i386/sse4_1-rint-inline.c
> > ===================================================================
> > --- gcc/testsuite/gcc.target/i386/sse4_1-rint-inline.c  (nonexistent)
> > +++ gcc/testsuite/gcc.target/i386/sse4_1-rint-inline.c  (working copy)
> > @@ -0,0 +1,36 @@
> > +/* Test rint and related functions expanded inline for SSE4.1, even
> > +   when spurious "inexact" not allowed.  */
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -msse4.1 -mfpmath=sse -fno-fp-int-builtin-inexact" } */
> > +/* { dg-add-options c99_runtime } */
> > +/* { dg-require-effective-target sse4 } */
> > +
> > +#define TEST(FN, TYPE)                         \
> > +  do                                           \
> > +    {                                          \
> > +      volatile TYPE a = 1.5, b;                        \
> > +      b = FN (a);                              \
> > +    }                                          \
> > +  while (0)
> > +
> > +#define FN_TESTS(FN)                                   \
> > +  do                                                   \
> > +    {                                                  \
> > +      TEST (__builtin_ ## FN, double);                 \
> > +      TEST (__builtin_ ## FN ## f, float);             \
> > +    }                                                  \
> > +  while (0)
> > +
> > +void
> > +test (void)
> > +{
> > +  FN_TESTS (rint);
> > +  FN_TESTS (ceil);
> > +  FN_TESTS (floor);
> > +  FN_TESTS (trunc);
> > +}
> > +
> > +/* { dg-final { scan-assembler-not "\[ \t\]rint" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]ceil" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]floor" } } */
> > +/* { dg-final { scan-assembler-not "\[ \t\]trunc" } } */
> >
> > --
> > Joseph S. Myers
> > joseph@codesourcery.com



More information about the Gcc-patches mailing list