This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][4.3] Expand lrint inline for x86_64/i?86 SSE math


This is the first patch in a series to provide SSE inline expansions
for C99 rounding intrinsics (4.3 Project "x86_64/ix86 SSE C99 rounding
intrinsics", scheduled for stage2 or earlier).

In the process of adding expanders for the different intrinsics, the
existing optabs for lfloor, lceil and lrint are changed to be conversion
optabs.  Fortunately only the 386 backend uses those at the moment.

As the series is completed, 189.lucas gets a 10% improvement on x86_64,
povray improves 1.5%.  Generally microbenchmarking shows the following
numbers (time in us, x86_64 optimized glibc (library) vs. inline
intrinsics (inlined) wrapped in functions):

             library    inlined
floor:       2240000    1560000
floorf:      1840000    1500000
lfloor:      2220000     870000
lfloorf:     2020000     750000
ceil:        2270000    1350000
ceilf:       1890000    1280000
lceil:       2220000     840000
lceilf:      1970000     830000
trunc:       1450000    1200000
truncf:      1360000    1170000
round:       2300000    1470000
roundf:      1570000    1460000
lround:      1570000     830000
lroundf:     1410000     720000
lrint:        890000     610000
lrintf:       820000     600000
rint:        2900000     920000
rintf:       1930000     850000
nearbyint:  19180000     920000
nearbyintf: 18700000     840000

Correctness has been tested against glibc both with random input
and special cases such as +-0, Inf, Nan, denormals and others.

[ All the patches in a single diff can be viewed from
http://www.suse.de/~rguenther/sse-round.patch
(though not with a merged ChangeLog but individual ones concatenated)
The complete patch series is available from
http://www.suse.de/~rguenther/patches-0917.tar ]

This first patch implements expansion of lrint and lays infrastructure
for the conversion optabs.  It also adds a i386 specific torture
testsuite to cycle through the many interesting variants of i386 FP
modes.

Bootstrapped and tested on {x86_64,i686}-unknown-linux-gnu.

Ok for 4.3?

Thanks,
Richard.

--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs


2006-08-23  Richard Guenther  <rguenther@suse.de>

	* optabs.h (enum optab_index): Remove OTI_lrint.
	(enum convert_optab_index): Add COI_lrint.
	(lrint_optab): Adjust.
	(expand_sfix_optab): Declare.
	* optabs.c (expand_sfix_optab): New function.
	(init_optabs): Init lrint_optab as conversion optab.
	* genopinit.c (lrint_optab): Change to a conversion optab.
	* builtins.c (expand_builtin_int_roundingfn_2): New function.
	(expand_builtin_mathfn): Remove lrint case.
	(expand_builtin): Use expand_builtin_int_roundingfn_2 to
	expand BUILT_IN_LRINT and BUILT_IN_LLRINT.
	* config/i386/i386.md (*fistdi2_1): Remove
	flag_unsafe_math_optimizations guard.
	(fistdi2, fistdi2_with_temp, *fist<mode>2_1, fist<mode>2,
	fist<mode>2_with_temp): Likewise.
	(lrint<mode>2): Split into...
	(lrintxf<mode>2): ... x87 part
	(lrint<mode>di2, lrint<mode>si2): ... and SSE parts.
	* config/i386/sse.md (sse_cvtss2si_2, sse_cvtss2_siq_2,
	sse2_cvtsd2si_2, sse2_cvtsd2siq_2): New insns for
	UNSPEC_FIX_NOTRUNC matching non-vector float modes.
	* doc/md.texi (lrintMN2): Document.

	* gcc.target/i386/math-torture/math-torture.exp: Torture
	for interesting ia32 math options.
	* gcc.target.i386/math-torture/lrint.c: New testcase.

Index: gcc/builtins.c
===================================================================
--- gcc.orig/builtins.c
+++ gcc/builtins.c
@@ -96,6 +96,7 @@ static rtx expand_builtin_mathfn_2 (tree
 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
 static rtx expand_builtin_sincos (tree);
 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
+static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
 static rtx expand_builtin_args_info (tree);
 static rtx expand_builtin_next_arg (void);
 static rtx expand_builtin_va_start (tree);
@@ -1851,9 +1852,6 @@ expand_builtin_mathfn (tree exp, rtx tar
       builtin_optab = nearbyint_optab; break;
     CASE_FLT_FN (BUILT_IN_RINT):
       builtin_optab = rint_optab; break;
-    CASE_FLT_FN (BUILT_IN_LRINT):
-    CASE_FLT_FN (BUILT_IN_LLRINT):
-      builtin_optab = lrint_optab; break;
     default:
       gcc_unreachable ();
     }
@@ -2226,7 +2224,9 @@ expand_builtin_sincos (tree exp)
   return const0_rtx;
 }
 
-/* Expand a call to one of the builtin rounding functions (lfloor).
+/* Expand a call to one of the builtin rounding functions gcc defines
+   as an extension (lfloor and lceil).  As these are gcc extensions we
+   do not need to worry about setting errno to EDOM.
    If expanding via optab fails, lower expression to (int)(floor(x)).
    EXP is the expression that is a call to the builtin function;
    if convenient, the result should be placed in TARGET.  SUBTARGET may
@@ -2325,6 +2325,80 @@ expand_builtin_int_roundingfn (tree exp,
   return target;
 }
 
+/* Expand a call to one of the builtin math functions doing integer
+   conversion (lrint).
+   Return 0 if a normal call should be emitted rather than expanding the
+   function in-line.  EXP is the expression that is a call to the builtin
+   function; if convenient, the result should be placed in TARGET.
+   SUBTARGET may be used as the target for computing one of EXP's operands.  */
+
+static rtx
+expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
+{
+  convert_optab builtin_optab;
+  rtx op0, insns;
+  tree fndecl = get_callee_fndecl (exp);
+  tree arglist = TREE_OPERAND (exp, 1);
+  enum machine_mode mode;
+  tree arg, narg;
+
+  /* There's no easy way to detect the case we need to set EDOM.  */
+  if (flag_errno_math)
+    return NULL_RTX;
+
+  if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+    return NULL_RTX;
+
+  arg = TREE_VALUE (arglist);
+
+  switch (DECL_FUNCTION_CODE (fndecl))
+    {
+    CASE_FLT_FN (BUILT_IN_LRINT):
+    CASE_FLT_FN (BUILT_IN_LLRINT):
+      builtin_optab = lrint_optab; break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Make a suitable register to place result in.  */
+  mode = TYPE_MODE (TREE_TYPE (exp));
+
+  target = gen_reg_rtx (mode);
+
+  /* Wrap the computation of the argument in a SAVE_EXPR, as we may
+     need to expand the argument again.  This way, we will not perform
+     side-effects more the once.  */
+  narg = builtin_save_expr (arg);
+  if (narg != arg)
+    {
+      arg = narg;
+      arglist = build_tree_list (NULL_TREE, arg);
+      exp = build_function_call_expr (fndecl, arglist);
+    }
+
+  op0 = expand_expr (arg, subtarget, VOIDmode, 0);
+
+  start_sequence ();
+
+  if (expand_sfix_optab (target, op0, builtin_optab))
+    {
+      /* Output the entire sequence.  */
+      insns = get_insns ();
+      end_sequence ();
+      emit_insn (insns);
+      return target;
+    }
+
+  /* If we were unable to expand via the builtin, stop the sequence
+     (without outputting the insns) and call to the library function
+     with the stabilized argument list.  */
+  end_sequence ();
+
+  target = expand_call (exp, target, target == const0_rtx);
+
+  return target;
+}
+
 /* To evaluate powi(x,n), the floating point value x raised to the
    constant integer exponent n, we use a hybrid algorithm that
    combines the "window method" with look-up tables.  For an
@@ -5685,8 +5759,6 @@ expand_builtin (tree exp, rtx target, rt
     CASE_FLT_FN (BUILT_IN_ROUND):
     CASE_FLT_FN (BUILT_IN_NEARBYINT):
     CASE_FLT_FN (BUILT_IN_RINT):
-    CASE_FLT_FN (BUILT_IN_LRINT):
-    CASE_FLT_FN (BUILT_IN_LLRINT):
       target = expand_builtin_mathfn (exp, target, subtarget);
       if (target)
 	return target;
@@ -5701,6 +5773,13 @@ expand_builtin (tree exp, rtx target, rt
 	return target;
       break;
 
+    CASE_FLT_FN (BUILT_IN_LRINT):
+    CASE_FLT_FN (BUILT_IN_LLRINT):
+      target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
+      if (target)
+	return target;
+      break;
+
     CASE_FLT_FN (BUILT_IN_POW):
       target = expand_builtin_pow (exp, target, subtarget);
       if (target)
Index: gcc/config/i386/i386.md
===================================================================
--- gcc.orig/config/i386/i386.md
+++ gcc/config/i386/i386.md
@@ -16758,7 +16758,6 @@
 	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
 	 UNSPEC_FIST))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations
    && !(reload_completed || reload_in_progress)"
   "#"
   "&& 1"
@@ -16782,8 +16781,7 @@
 	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
 	 UNSPEC_FIST))
    (clobber (match_scratch:XF 2 "=&1f"))]
-  "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+  "TARGET_USE_FANCY_MATH_387"
   "* return output_fix_trunc (insn, operands, 0);"
   [(set_attr "type" "fpspc")
    (set_attr "mode" "DI")])
@@ -16794,8 +16792,7 @@
 	 UNSPEC_FIST))
    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
-  "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+  "TARGET_USE_FANCY_MATH_387"
   "#"
   [(set_attr "type" "fpspc")
    (set_attr "mode" "DI")])
@@ -16828,7 +16825,6 @@
 	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
 	 UNSPEC_FIST))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations
    && !(reload_completed || reload_in_progress)"
   "#"
   "&& 1"
@@ -16846,8 +16842,7 @@
   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
 	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
 	 UNSPEC_FIST))]
-  "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+  "TARGET_USE_FANCY_MATH_387"
   "* return output_fix_trunc (insn, operands, 0);"
   [(set_attr "type" "fpspc")
    (set_attr "mode" "<MODE>")])
@@ -16857,8 +16852,7 @@
 	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
 	 UNSPEC_FIST))
    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
-  "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+  "TARGET_USE_FANCY_MATH_387"
   "#"
   [(set_attr "type" "fpspc")
    (set_attr "mode" "<MODE>")])
@@ -16884,13 +16878,25 @@
 		       UNSPEC_FIST))]
   "")
 
-(define_expand "lrint<mode>2"
+(define_expand "lrintxf<mode>2"
   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
-	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
-	 UNSPEC_FIST))]
-  "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
-   && flag_unsafe_math_optimizations"
+     (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
+      UNSPEC_FIST))]
+  "TARGET_USE_FANCY_MATH_387"
+  "")
+
+(define_expand "lrint<mode>di2"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+     (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
+      UNSPEC_FIX_NOTRUNC))]
+  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
+  "")
+
+(define_expand "lrint<mode>si2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+     (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
+      UNSPEC_FIX_NOTRUNC))]
+  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
   "")
 
 ;; Rounding mode control word calculation could clobber FLAGS_REG.
Index: gcc/config/i386/sse.md
===================================================================
--- gcc.orig/config/i386/sse.md
+++ gcc/config/i386/sse.md
@@ -974,6 +974,16 @@
    (set_attr "athlon_decode" "double,vector")
    (set_attr "mode" "SI")])
 
+(define_insn "sse_cvtss2si_2"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
+	 UNSPEC_FIX_NOTRUNC))]
+  "TARGET_SSE"
+  "cvtss2si\t{%1, %0|%0, %1}"
+  [(set_attr "type" "sseicvt")
+   (set_attr "athlon_decode" "double,vector")
+   (set_attr "mode" "SI")])
+
 (define_insn "sse_cvtss2siq"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
 	(unspec:DI
@@ -987,6 +997,16 @@
    (set_attr "athlon_decode" "double,vector")
    (set_attr "mode" "DI")])
 
+(define_insn "sse_cvtss2siq_2"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+	(unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
+	 UNSPEC_FIX_NOTRUNC))]
+  "TARGET_SSE && TARGET_64BIT"
+  "cvtss2siq\t{%1, %0|%0, %1}"
+  [(set_attr "type" "sseicvt")
+   (set_attr "athlon_decode" "double,vector")
+   (set_attr "mode" "DI")])
+
 (define_insn "sse_cvttss2si"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(fix:SI
@@ -1932,6 +1952,16 @@
    (set_attr "athlon_decode" "double,vector")
    (set_attr "mode" "SI")])
 
+(define_insn "sse2_cvtsd2si_2"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
+	 UNSPEC_FIX_NOTRUNC))]
+  "TARGET_SSE2"
+  "cvtsd2si\t{%1, %0|%0, %1}"
+  [(set_attr "type" "sseicvt")
+   (set_attr "athlon_decode" "double,vector")
+   (set_attr "mode" "SI")])
+
 (define_insn "sse2_cvtsd2siq"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
 	(unspec:DI
@@ -1945,6 +1975,16 @@
    (set_attr "athlon_decode" "double,vector")
    (set_attr "mode" "DI")])
 
+(define_insn "sse2_cvtsd2siq_2"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+	(unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
+	 UNSPEC_FIX_NOTRUNC))]
+  "TARGET_SSE2 && TARGET_64BIT"
+  "cvtsd2siq\t{%1, %0|%0, %1}"
+  [(set_attr "type" "sseicvt")
+   (set_attr "athlon_decode" "double,vector")
+   (set_attr "mode" "DI")])
+
 (define_insn "sse2_cvttsd2si"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(fix:SI
Index: gcc/doc/md.texi
===================================================================
--- gcc.orig/doc/md.texi
+++ gcc/doc/md.texi
@@ -3601,6 +3601,12 @@ corresponds to the C data type @code{dou
 built-in function uses the mode which corresponds to the C data
 type @code{float}.
 
+@cindex @code{lrint@var{m}@var{n}2}
+@item @samp{lrint@var{m}2}
+Convert operand 1 (valid for floating point mode @var{m}) to fixed
+point mode @var{n} as a signed number according to the current
+rounding mode and store in operand 0 (which has mode @var{n}).
+
 @cindex @code{copysign@var{m}3} instruction pattern
 @item @samp{copysign@var{m}3}
 Store a value with the magnitude of operand 1 and the sign of operand
Index: gcc/genopinit.c
===================================================================
--- gcc.orig/genopinit.c
+++ gcc/genopinit.c
@@ -127,7 +127,7 @@ static const char * const optabs[] =
   "btrunc_optab->handlers[$A].insn_code = CODE_FOR_$(btrunc$a2$)",
   "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
   "rint_optab->handlers[$A].insn_code = CODE_FOR_$(rint$a2$)",
-  "lrint_optab->handlers[$A].insn_code = CODE_FOR_$(lrint$a2$)",
+  "lrint_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lrint$F$a$I$b2$)",
   "sincos_optab->handlers[$A].insn_code = CODE_FOR_$(sincos$a3$)",
   "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
   "asin_optab->handlers[$A].insn_code = CODE_FOR_$(asin$a2$)",
Index: gcc/optabs.c
===================================================================
--- gcc.orig/optabs.c
+++ gcc/optabs.c
@@ -4861,6 +4861,46 @@ expand_fix (rtx to, rtx from, int unsign
         convert_move (to, target, 0);
     }
 }
+
+/* Generate code to convert FROM to fixed point and store in TO.  FROM
+   must be floating point, TO must be signed.  Use the conversion optab
+   TAB to do the conversion.  */
+
+bool
+expand_sfix_optab (rtx to, rtx from, convert_optab tab)
+{
+  enum insn_code icode;
+  rtx target = to;
+  enum machine_mode fmode, imode;
+
+  /* We first try to find a pair of modes, one real and one integer, at
+     least as wide as FROM and TO, respectively, in which we can open-code
+     this conversion.  If the integer mode is wider than the mode of TO,
+     we can do the conversion either signed or unsigned.  */
+
+  for (fmode = GET_MODE (from); fmode != VOIDmode;
+       fmode = GET_MODE_WIDER_MODE (fmode))
+    for (imode = GET_MODE (to); imode != VOIDmode;
+	 imode = GET_MODE_WIDER_MODE (imode))
+      {
+	icode = tab->handlers[imode][fmode].insn_code;
+	if (icode != CODE_FOR_nothing)
+	  {
+	    if (fmode != GET_MODE (from))
+	      from = convert_to_mode (fmode, from, 0);
+
+	    if (imode != GET_MODE (to))
+	      target = gen_reg_rtx (imode);
+
+	    emit_unop_insn (icode, target, from, UNKNOWN);
+	    if (target != to)
+	      convert_move (to, target, 0);
+	    return true;
+	  }
+      }
+
+  return false;
+}
 
 /* Report whether we have an instruction to perform the operation
    specified by CODE on operands of mode MODE.  */
@@ -5266,7 +5306,6 @@ init_optabs (void)
   btrunc_optab = init_optab (UNKNOWN);
   nearbyint_optab = init_optab (UNKNOWN);
   rint_optab = init_optab (UNKNOWN);
-  lrint_optab = init_optab (UNKNOWN);
   sincos_optab = init_optab (UNKNOWN);
   sin_optab = init_optab (UNKNOWN);
   asin_optab = init_optab (UNKNOWN);
@@ -5325,6 +5364,7 @@ init_optabs (void)
   ufixtrunc_optab = init_convert_optab (UNKNOWN);
   sfloat_optab = init_convert_optab (FLOAT);
   ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
+  lrint_optab = init_convert_optab (UNKNOWN);
 
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
@@ -5444,6 +5484,8 @@ init_optabs (void)
 				 MODE_DECIMAL_FLOAT, MODE_INT);
   init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
 				 MODE_INT, MODE_DECIMAL_FLOAT);
+  init_interclass_conv_libfuncs (lrint_optab, "lrint",
+				 MODE_INT, MODE_FLOAT);
 
   /* sext_optab is also used for FLOAT_EXTEND.  */
   init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
Index: gcc/optabs.h
===================================================================
--- gcc.orig/optabs.h
+++ gcc/optabs.h
@@ -196,7 +196,6 @@ enum optab_index
   OTI_round,
   OTI_nearbyint,
   OTI_rint,
-  OTI_lrint,
   /* Tangent */
   OTI_tan,
   /* Inverse tangent */
@@ -345,7 +344,6 @@ extern GTY(()) optab optab_table[OTI_MAX
 #define round_optab (optab_table[OTI_round])
 #define nearbyint_optab (optab_table[OTI_nearbyint])
 #define rint_optab (optab_table[OTI_rint])
-#define lrint_optab (optab_table[OTI_lrint])
 #define tan_optab (optab_table[OTI_tan])
 #define atan_optab (optab_table[OTI_atan])
 #define copysign_optab (optab_table[OTI_copysign])
@@ -407,6 +405,8 @@ enum convert_optab_index
   COI_sfloat,
   COI_ufloat,
 
+  COI_lrint,
+
   COI_MAX
 };
 
@@ -421,6 +421,7 @@ extern GTY(()) convert_optab convert_opt
 #define ufixtrunc_optab (convert_optab_table[COI_ufixtrunc])
 #define sfloat_optab (convert_optab_table[COI_sfloat])
 #define ufloat_optab (convert_optab_table[COI_ufloat])
+#define lrint_optab (convert_optab_table[COI_lrint])
 
 /* These arrays record the insn_code of insns that may be needed to
    perform input and output reloads of special objects.  They provide a
@@ -597,6 +598,9 @@ extern void expand_float (rtx, rtx, int)
 /* Generate code for a FIX_EXPR.  */
 extern void expand_fix (rtx, rtx, int);
 
+/* Generate code for float to integral conversion.  */
+extern bool expand_sfix_optab (rtx, rtx, convert_optab);
+
 /* Return tree if target supports vector operations for COND_EXPR.  */
 bool expand_vec_cond_expr_p (tree, enum machine_mode);
 
Index: gcc/testsuite/gcc.target/i386/math-torture/lrint.c
===================================================================
--- /dev/null
+++ gcc/testsuite/gcc.target/i386/math-torture/lrint.c
@@ -0,0 +1,26 @@
+/* { dg-do assemble } */
+
+long testlf (float x)
+{
+  return __builtin_lrintf (x);
+}
+long testl (double x)
+{
+  return __builtin_lrint (x);
+}
+long testll (long double x)
+{
+  return __builtin_lrintl (x);
+}
+long long testllf (float x)
+{
+  return __builtin_llrintf (x);
+}
+long long testll_ (double x)
+{
+  return __builtin_llrint (x);
+}
+long long testlll (long double x)
+{
+  return __builtin_llrintl (x);
+}
Index: gcc/testsuite/gcc.target/i386/math-torture/math-torture.exp
===================================================================
--- /dev/null
+++ gcc/testsuite/gcc.target/i386/math-torture/math-torture.exp
@@ -0,0 +1,27 @@
+# This harness is for tests that should be run at all optimisation levels.
+
+set TORTURE_OPTIONS [list \
+        { -O0 } \
+        { -O0 -msse -mno-sse2 -mfpmath=sse } \
+        { -O0 -msse -msse2 -mfpmath=sse } \
+        { -O0 -msse -mno-sse2 -mfpmath=sse,387 } \
+        { -O0 -msse -msse2 -mfpmath=sse,387 } \
+        { -O0 -msse -mno-sse2 -mfpmath=sse -ffast-math } \
+        { -O0 -msse -msse2 -mfpmath=sse -ffast-math } \
+        { -O0 -msse -mno-sse2 -mfpmath=sse,387 -ffast-math } \
+        { -O0 -msse -msse2 -mfpmath=sse,387 -ffast-math } \
+        { -O2 } \
+        { -O2 -msse -mno-sse2 -mfpmath=sse } \
+        { -O2 -msse -msse2 -mfpmath=sse } \
+        { -O2 -msse -mno-sse2 -mfpmath=sse,387 } \
+        { -O2 -msse -msse2 -mfpmath=sse,387 } \
+        { -O2 -msse -mno-sse2 -mfpmath=sse -ffast-math } \
+        { -O2 -msse -msse2 -mfpmath=sse -ffast-math } \
+        { -O2 -msse -mno-sse2 -mfpmath=sse,387 -ffast-math } \
+        { -O2 -msse -msse2 -mfpmath=sse,387 -ffast-math } \
+]
+load_lib gcc-dg.exp
+
+dg-init
+gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] ""
+dg-finish


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]