diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59b11c3d8d6..d52fa3d1ffe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2016-06-03 Joseph Myers + + PR target/71276 + PR target/71277 + * common.opt (ffp-int-builtin-inexact): New option. + * doc/invoke.texi (-fno-fp-int-builtin-inexact): Document. + * doc/md.texi (floor@var{m}2, btrunc@var{m}2, round@var{m}2) + (ceil@var{m}2): Document dependence on this option. + * ipa-inline-transform.c (inline_call): Handle + flag_fp_int_builtin_inexact. + * ipa-inline.c (can_inline_edge_p): Likewise. + * config/i386/i386.md (rintxf2): Do not test + flag_unsafe_math_optimizations. + (rint2_frndint): New define_insn. + (rint2): Do not test flag_unsafe_math_optimizations for 387 + or !flag_trapping_math for SSE. Just use gen_rint2_frndint + for 387 instead of extending and truncating. + (frndintxf2_): Test flag_fp_int_builtin_inexact || + !flag_trapping_math instead of flag_unsafe_math_optimizations. + Change to frndint2_. + (frndintxf2__i387): Likewise. Change to + frndint2__i387. + (xf2): Likewise. + (2): Test flag_fp_int_builtin_inexact || + !flag_trapping_math instead of flag_unsafe_math_optimizations for + x87. Test TARGET_ROUND || !flag_trapping_math || + flag_fp_int_builtin_inexact instead of !flag_trapping_math for + SSE. Use ROUND_NO_EXC in constant operand of + gen_sse4_1_round2. Just use gen_frndint2_ + for 387 instead of extending and truncating. + 2016-06-03 H.J. Lu Julia Koval diff --git a/gcc/common.opt b/gcc/common.opt index fccd4b5f9a5..2bb576c51c4 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1330,6 +1330,10 @@ Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_OFF) EnumValue Enum(fp_contract_mode) String(fast) Value(FP_CONTRACT_FAST) +ffp-int-builtin-inexact +Common Report Var(flag_fp_int_builtin_inexact) Init(1) Optimization +Allow built-in functions ceil, floor, round, trunc to raise \"inexact\" exceptions. + ; 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. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index e4ae4f214bd..a32c4e204ce 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15526,25 +15526,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 "rint2_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" "")]) + (define_expand "rint2" [(use (match_operand:MODEF 0 "register_operand")) (use (match_operand:MODEF 1 "register_operand"))] "(TARGET_USE_FANCY_MATH_387 && (!(SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387) - && flag_unsafe_math_optimizations) - || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH - && !flag_trapping_math)" + || TARGET_MIX_SSE_I387)) + || (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)" { - if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH - && !flag_trapping_math) + if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH) { if (TARGET_ROUND) emit_insn (gen_sse4_1_round2 @@ -15553,15 +15559,7 @@ ix86_expand_rint (operands[0], operands[1]); } else - { - rtx op0 = gen_reg_rtx (XFmode); - rtx op1 = gen_reg_rtx (XFmode); - - emit_insn (gen_extendxf2 (op1, operands[1])); - emit_insn (gen_rintxf2 (op0, op1)); - - emit_insn (gen_truncxf2_i387_noop (operands[0], op0)); - } + emit_insn (gen_rint2_frndint (operands[0], operands[1])); DONE; }) @@ -15784,13 +15782,13 @@ (UNSPEC_FIST_CEIL "CEIL")]) ;; Rounding mode control word calculation could clobber FLAGS_REG. -(define_insn_and_split "frndintxf2_" - [(set (match_operand:XF 0 "register_operand") - (unspec:XF [(match_operand:XF 1 "register_operand")] +(define_insn_and_split "frndint2_" + [(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" @@ -15801,26 +15799,26 @@ operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); operands[3] = assign_386_stack_local (HImode, SLOT_CW_); - emit_insn (gen_frndintxf2__i387 (operands[0], operands[1], - operands[2], operands[3])); + emit_insn (gen_frndint2__i387 (operands[0], operands[1], + operands[2], operands[3])); DONE; } [(set_attr "type" "frndint") (set_attr "i387_cw" "") - (set_attr "mode" "XF")]) + (set_attr "mode" "")]) -(define_insn "frndintxf2__i387" - [(set (match_operand:XF 0 "register_operand" "=f") - (unspec:XF [(match_operand:XF 1 "register_operand" "0")] - FRNDINT_ROUNDING)) +(define_insn "frndint2__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" "") - (set_attr "mode" "XF")]) + (set_attr "mode" "")]) (define_expand "xf2" [(parallel [(set (match_operand:XF 0 "register_operand") @@ -15828,7 +15826,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 "2" [(parallel [(set (match_operand:MODEF 0 "register_operand") @@ -15838,16 +15836,17 @@ "(TARGET_USE_FANCY_MATH_387 && (!(SSE_FLOAT_MODE_P (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) && TARGET_SSE_MATH - && !flag_trapping_math)" + && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))" { if (SSE_FLOAT_MODE_P (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_round2 - (operands[0], operands[1], GEN_INT (ROUND_))); + (operands[0], operands[1], GEN_INT (ROUND_ + | ROUND_NO_EXC))); else if (TARGET_64BIT || (mode != DFmode)) { if (ROUND_ == ROUND_FLOOR) @@ -15872,16 +15871,7 @@ } } else - { - rtx op0, op1; - - op0 = gen_reg_rtx (XFmode); - op1 = gen_reg_rtx (XFmode); - emit_insn (gen_extendxf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_ (op0, op1)); - - emit_insn (gen_truncxf2_i387_noop (operands[0], op0)); - } + emit_insn (gen_frndint2_ (operands[0], operands[1])); DONE; }) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ce162a08835..89bd983d741 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 @@ -8532,6 +8532,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 diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index e7b51c10593..12fc7128343 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5554,7 +5554,9 @@ This pattern is not allowed to @code{FAIL}. @item @samp{floor@var{m}2} Store the largest integral value not greater than operand 1 in operand 0. Both operands have mode @var{m}, which is a scalar or vector -floating-point mode. +floating-point mode. If @option{-ffp-int-builtin-inexact} is in +effect, the ``inexact'' exception may be raised for noninteger +operands; otherwise, it may not. This pattern is not allowed to @code{FAIL}. @@ -5562,7 +5564,9 @@ This pattern is not allowed to @code{FAIL}. @item @samp{btrunc@var{m}2} Round operand 1 to an integer, towards zero, and store the result in operand 0. Both operands have mode @var{m}, which is a scalar or -vector floating-point mode. +vector floating-point mode. If @option{-ffp-int-builtin-inexact} is +in effect, the ``inexact'' exception may be raised for noninteger +operands; otherwise, it may not. This pattern is not allowed to @code{FAIL}. @@ -5570,7 +5574,10 @@ This pattern is not allowed to @code{FAIL}. @item @samp{round@var{m}2} Round operand 1 to the nearest integer, rounding away from zero in the event of a tie, and store the result in operand 0. Both operands have -mode @var{m}, which is a scalar or vector floating-point mode. +mode @var{m}, which is a scalar or vector floating-point mode. If +@option{-ffp-int-builtin-inexact} is in effect, the ``inexact'' +exception may be raised for noninteger operands; otherwise, it may +not. This pattern is not allowed to @code{FAIL}. @@ -5578,7 +5585,9 @@ This pattern is not allowed to @code{FAIL}. @item @samp{ceil@var{m}2} Store the smallest integral value not less than operand 1 in operand 0. Both operands have mode @var{m}, which is a scalar or vector -floating-point mode. +floating-point mode. If @option{-ffp-int-builtin-inexact} is in +effect, the ``inexact'' exception may be raised for noninteger +operands; otherwise, it may not. This pattern is not allowed to @code{FAIL}. diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 90a0d7ebbb7..f6b7d41d47e 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -369,6 +369,8 @@ inline_call (struct cgraph_edge *e, bool update_original, != opt_for_fn (to->decl, flag_associative_math) || opt_for_fn (callee->decl, flag_reciprocal_math) != opt_for_fn (to->decl, flag_reciprocal_math) + || opt_for_fn (callee->decl, flag_fp_int_builtin_inexact) + != opt_for_fn (to->decl, flag_fp_int_builtin_inexact) || opt_for_fn (callee->decl, flag_errno_math) != opt_for_fn (to->decl, flag_errno_math)) { @@ -393,6 +395,8 @@ inline_call (struct cgraph_edge *e, bool update_original, = opt_for_fn (callee->decl, flag_associative_math); opts.x_flag_reciprocal_math = opt_for_fn (callee->decl, flag_reciprocal_math); + opts.x_flag_fp_int_builtin_inexact + = opt_for_fn (callee->decl, flag_fp_int_builtin_inexact); opts.x_flag_errno_math = opt_for_fn (callee->decl, flag_errno_math); if (dump_file) diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index db394d71e2a..5c9366a7cdd 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -429,6 +429,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, || check_maybe_up (flag_signed_zeros) || check_maybe_down (flag_associative_math) || check_maybe_down (flag_reciprocal_math) + || check_maybe_down (flag_fp_int_builtin_inexact) /* Strictly speaking only when the callee contains function calls that may end up setting errno. */ || check_maybe_up (flag_errno_math))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd05a0e9af5..2822de1620a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2016-06-03 Joseph Myers + + PR target/71276 + PR target/71277 + * gcc.dg/torture/builtin-fp-int-inexact.c, + gcc.target/i386/387-builtin-fp-int-inexact.c, + gcc.target/i386/387-rint-inline-1.c, + gcc.target/i386/387-rint-inline-2.c, + gcc.target/i386/sse2-builtin-fp-int-inexact.c, + gcc.target/i386/sse2-rint-inline-1.c, + gcc.target/i386/sse2-rint-inline-2.c, + gcc.target/i386/sse4_1-builtin-fp-int-inexact.c, + gcc.target/i386/sse4_1-rint-inline.c: New tests. + 2016-06-03 H.J. Lu Julia Koval diff --git a/gcc/testsuite/gcc.dg/torture/builtin-fp-int-inexact.c b/gcc/testsuite/gcc.dg/torture/builtin-fp-int-inexact.c new file mode 100644 index 00000000000..80458fa6274 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/builtin-fp-int-inexact.c @@ -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 + +/* 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 diff --git a/gcc/testsuite/gcc.target/i386/387-builtin-fp-int-inexact.c b/gcc/testsuite/gcc.target/i386/387-builtin-fp-int-inexact.c new file mode 100644 index 00000000000..752b487825e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/387-builtin-fp-int-inexact.c @@ -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" diff --git a/gcc/testsuite/gcc.target/i386/387-rint-inline-1.c b/gcc/testsuite/gcc.target/i386/387-rint-inline-1.c new file mode 100644 index 00000000000..522edff611a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/387-rint-inline-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/i386/387-rint-inline-2.c b/gcc/testsuite/gcc.target/i386/387-rint-inline-2.c new file mode 100644 index 00000000000..be765a7a39f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/387-rint-inline-2.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse2-builtin-fp-int-inexact.c b/gcc/testsuite/gcc.target/i386/sse2-builtin-fp-int-inexact.c new file mode 100644 index 00000000000..10015972049 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-builtin-fp-int-inexact.c @@ -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" diff --git a/gcc/testsuite/gcc.target/i386/sse2-rint-inline-1.c b/gcc/testsuite/gcc.target/i386/sse2-rint-inline-1.c new file mode 100644 index 00000000000..06baed2046a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-rint-inline-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse2-rint-inline-2.c b/gcc/testsuite/gcc.target/i386/sse2-rint-inline-2.c new file mode 100644 index 00000000000..3ebf7a7af69 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-rint-inline-2.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-builtin-fp-int-inexact.c b/gcc/testsuite/gcc.target/i386/sse4_1-builtin-fp-int-inexact.c new file mode 100644 index 00000000000..4c9244d0544 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-builtin-fp-int-inexact.c @@ -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" diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-rint-inline.c b/gcc/testsuite/gcc.target/i386/sse4_1-rint-inline.c new file mode 100644 index 00000000000..6d60da33cb7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse4_1-rint-inline.c @@ -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" } } */