diff mbox series

[committed] d: Refactor matching and lowering of intrinsic functions.

Message ID 20200730110615.1095824-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Refactor matching and lowering of intrinsic functions. | expand

Commit Message

Iain Buclaw July 30, 2020, 11:06 a.m. UTC
Hi,

This patch cleans up D intrinsic handling in the front-end.

Intrinsics are now matched explicitly, rather than through a common
alias where there are multiple overrides for a common intrinsic.
Where there is a corresponding DECL_FUNCTION_CODE, that is now stored in
the D intrinsic array.  All run-time std.math intrinsics have been
removed, as the library implementation already forwards to core.math.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain

---
gcc/d/ChangeLog:

	* d-tree.h (DEF_D_INTRINSIC): Rename second argument from A to B.
	* intrinsics.cc (intrinsic_decl): Add built_in field.
	(DEF_D_INTRINSIC): Rename second argument from ALIAS to BUILTIN.
	(maybe_set_intrinsic): Handle new intrinsic codes.
	(expand_intrinsic_bt): Likewise.
	(expand_intrinsic_checkedint): Likewise.
	(expand_intrinsic_bswap): Remove.
	(expand_intrinsic_sqrt): Remove.
	(maybe_expand_intrinsic): Group together intrinsic cases that map
	directly to gcc built-ins.
	* intrinsics.def (DEF_D_BUILTIN): Rename second argument from A to B.
	Update all callers to pass equivalent DECL_FUNCTION_CODE.
	(DEF_CTFE_BUILTIN): Likewise.
	(STD_COS): Remove intrinsic.
	(STD_FABS): Remove intrinsic.
	(STD_LDEXP): Remove intrinsic.
	(STD_RINT): Remove intrinsic.
	(STD_RNDTOL): Remove intrinsic.
	(STD_SIN): Remove intrinsic.
	(STD_SQRTF): Remove intrinsic.
	(STD_SQRT): Remove intrinsic.
	(STD_SQRTL): Remove intrinsic.

gcc/testsuite/ChangeLog:

	* gdc.dg/intrinsics.d: New test.
---
 gcc/d/d-tree.h                    |   2 +-
 gcc/d/intrinsics.cc               | 342 ++++++++++++++----------------
 gcc/d/intrinsics.def              | 170 +++++++--------
 gcc/testsuite/gdc.dg/intrinsics.d | 117 ++++++++++
 4 files changed, 358 insertions(+), 273 deletions(-)
 create mode 100644 gcc/testsuite/gdc.dg/intrinsics.d
diff mbox series

Patch

diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index b4b832f9ad8..d92418a55c9 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -80,7 +80,7 @@  enum level_kind
 
 enum intrinsic_code
 {
-#define DEF_D_INTRINSIC(CODE, A, N, M, D, C) INTRINSIC_ ## CODE,
+#define DEF_D_INTRINSIC(CODE, B, N, M, D, C) INTRINSIC_ ## CODE,
 
 #include "intrinsics.def"
 
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index ba7e6aef6ed..7ef1ec5ea20 100644
--- a/gcc/d/intrinsics.cc
+++ b/gcc/d/intrinsics.cc
@@ -40,9 +40,12 @@  along with GCC; see the file COPYING3.  If not see
 
 struct intrinsic_decl
 {
-  /* The DECL_FUNCTION_CODE of this decl.  */
+  /* The DECL_INTRINSIC_CODE of this decl.  */
   intrinsic_code code;
 
+  /* The DECL_FUNCTION_CODE of this decl, if it directly maps to any.  */
+  built_in_function built_in;
+
   /* The name of the intrinsic.  */
   const char *name;
 
@@ -58,8 +61,8 @@  struct intrinsic_decl
 
 static const intrinsic_decl intrinsic_decls[] =
 {
-#define DEF_D_INTRINSIC(CODE, ALIAS, NAME, MODULE, DECO, CTFE) \
-    { INTRINSIC_ ## ALIAS, NAME, MODULE, DECO, CTFE },
+#define DEF_D_INTRINSIC(CODE, BUILTIN, NAME, MODULE, DECO, CTFE) \
+    { INTRINSIC_ ## CODE, BUILT_IN_ ## BUILTIN, NAME, MODULE, DECO, CTFE },
 
 #include "intrinsics.def"
 
@@ -144,11 +147,28 @@  maybe_set_intrinsic (FuncDeclaration *decl)
 	    case INTRINSIC_C_VA_ARG:
 	    case INTRINSIC_VASTART:
 	    case INTRINSIC_ADDS:
+	    case INTRINSIC_ADDSL:
+	    case INTRINSIC_ADDU:
+	    case INTRINSIC_ADDUL:
 	    case INTRINSIC_SUBS:
+	    case INTRINSIC_SUBSL:
+	    case INTRINSIC_SUBU:
+	    case INTRINSIC_SUBUL:
 	    case INTRINSIC_MULS:
+	    case INTRINSIC_MULSL:
+	    case INTRINSIC_MULU:
+	    case INTRINSIC_MULUI:
+	    case INTRINSIC_MULUL:
 	    case INTRINSIC_NEGS:
-	    case INTRINSIC_VLOAD:
-	    case INTRINSIC_VSTORE:
+	    case INTRINSIC_NEGSL:
+	    case INTRINSIC_VLOAD8:
+	    case INTRINSIC_VLOAD16:
+	    case INTRINSIC_VLOAD32:
+	    case INTRINSIC_VLOAD64:
+	    case INTRINSIC_VSTORE8:
+	    case INTRINSIC_VSTORE16:
+	    case INTRINSIC_VSTORE32:
+	    case INTRINSIC_VSTORE64:
 	      break;
 
 	    case INTRINSIC_POW:
@@ -302,14 +322,33 @@  expand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)
 			 integer_minus_one_node, integer_zero_node);
 
   /* Update the bit as needed, only testing the bit for bt().  */
-  if (intrinsic == INTRINSIC_BT)
-    return cond;
+  tree_code code;
+
+  switch (intrinsic)
+    {
+    case INTRINSIC_BT:
+    case INTRINSIC_BT64:
+      return cond;
+
+    case INTRINSIC_BTC:
+    case INTRINSIC_BTC64:
+      code = BIT_XOR_EXPR;
+      break;
+
+    case INTRINSIC_BTR:
+    case INTRINSIC_BTR64:
+      bitnum = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (bitnum), bitnum);
+      code = BIT_AND_EXPR;
+      break;
+
+    case INTRINSIC_BTS:
+    case INTRINSIC_BTS64:
+      code = BIT_IOR_EXPR;
+      break;
 
-  tree_code code = (intrinsic == INTRINSIC_BTC) ? BIT_XOR_EXPR
-    : (intrinsic == INTRINSIC_BTR) ? BIT_AND_EXPR
-    : (intrinsic == INTRINSIC_BTS) ? BIT_IOR_EXPR
-    : ERROR_MARK;
-  gcc_assert (code != ERROR_MARK);
+    default:
+      gcc_unreachable ();
+    }
 
   /* ptr[bitnum / size] op= mask;  */
   if (intrinsic == INTRINSIC_BTR)
@@ -325,31 +364,6 @@  expand_intrinsic_bt (intrinsic_code intrinsic, tree callexp)
   return compound_expr (cond, compound_expr (ptr, tmp));
 }
 
-/* Expand a front-end intrinsic call to bswap().  This takes one argument, the
-   signature to which can be either:
-
-	int bswap (uint arg);
-	int bswap (ulong arg);
-
-   This swaps all bytes in an N byte type end-to-end.  The original call
-   expression is held in CALLEXP.  */
-
-static tree
-expand_intrinsic_bswap (tree callexp)
-{
-  tree arg = CALL_EXPR_ARG (callexp, 0);
-  int argsize = TYPE_PRECISION (TREE_TYPE (arg));
-
-  /* Which variant of __builtin_bswap* should we call?  */
-  built_in_function code = (argsize == 32) ? BUILT_IN_BSWAP32
-    : (argsize == 64) ? BUILT_IN_BSWAP64
-    : END_BUILTINS;
-
-  gcc_assert (code != END_BUILTINS);
-
-  return call_builtin_fn (callexp, code, 1, arg);
-}
-
 /* Expand a front-end intrinsic call to popcnt().  This takes one argument, the
    signature to which can be either:
 
@@ -376,32 +390,6 @@  expand_intrinsic_popcnt (tree callexp)
   return call_builtin_fn (callexp, code, 1, arg);
 }
 
-/* Expand a front-end intrinsic call to INTRINSIC, which is either a call to
-   sqrt(), sqrtf(), sqrtl().  These intrinsics expect to take one argument,
-   the signature to which can be either:
-
-	float sqrt (float arg);
-	double sqrt (double arg);
-	real sqrt (real arg);
-
-   This computes the square root of the given argument.  The original call
-   expression is held in CALLEXP.  */
-
-static tree
-expand_intrinsic_sqrt (intrinsic_code intrinsic, tree callexp)
-{
-  tree arg = CALL_EXPR_ARG (callexp, 0);
-
-  /* Which variant of __builtin_sqrt* should we call?  */
-  built_in_function code = (intrinsic == INTRINSIC_SQRT) ? BUILT_IN_SQRT
-    : (intrinsic == INTRINSIC_SQRTF) ? BUILT_IN_SQRTF
-    : (intrinsic == INTRINSIC_SQRTL) ? BUILT_IN_SQRTL
-    : END_BUILTINS;
-
-  gcc_assert (code != END_BUILTINS);
-  return call_builtin_fn (callexp, code, 1, arg);
-}
-
 /* Expand a front-end intrinsic call to copysign().  This takes two arguments,
    the signature to which can be either:
 
@@ -575,28 +563,54 @@  expand_intrinsic_checkedint (intrinsic_code intrinsic, tree callexp)
   tree x;
   tree y;
   tree overflow;
+  internal_fn icode;
 
-  /* The negs() intrinsic gets turned into SUB_OVERFLOW (0, y).  */
-  if (intrinsic == INTRINSIC_NEGS)
-    {
-      x = fold_convert (type, integer_zero_node);
-      y = CALL_EXPR_ARG (callexp, 0);
-      overflow = CALL_EXPR_ARG (callexp, 1);
-    }
-  else
+  /* Which variant of *_OVERFLOW should we generate?  */
+  switch (intrinsic)
     {
+    case INTRINSIC_ADDS:
+    case INTRINSIC_ADDSL:
+    case INTRINSIC_ADDU:
+    case INTRINSIC_ADDUL:
       x = CALL_EXPR_ARG (callexp, 0);
       y = CALL_EXPR_ARG (callexp, 1);
       overflow = CALL_EXPR_ARG (callexp, 2);
-    }
+      icode = IFN_ADD_OVERFLOW;
+      break;
 
-  /* Which variant of *_OVERFLOW should we generate?  */
-  internal_fn icode = (intrinsic == INTRINSIC_ADDS) ? IFN_ADD_OVERFLOW
-    : (intrinsic == INTRINSIC_SUBS) ? IFN_SUB_OVERFLOW
-    : (intrinsic == INTRINSIC_MULS) ? IFN_MUL_OVERFLOW
-    : (intrinsic == INTRINSIC_NEGS) ? IFN_SUB_OVERFLOW
-    : IFN_LAST;
-  gcc_assert (icode != IFN_LAST);
+    case INTRINSIC_SUBS:
+    case INTRINSIC_SUBSL:
+    case INTRINSIC_SUBU:
+    case INTRINSIC_SUBUL:
+      x = CALL_EXPR_ARG (callexp, 0);
+      y = CALL_EXPR_ARG (callexp, 1);
+      overflow = CALL_EXPR_ARG (callexp, 2);
+      icode = IFN_SUB_OVERFLOW;
+      break;
+
+    case INTRINSIC_MULS:
+    case INTRINSIC_MULSL:
+    case INTRINSIC_MULU:
+    case INTRINSIC_MULUI:
+    case INTRINSIC_MULUL:
+      x = CALL_EXPR_ARG (callexp, 0);
+      y = CALL_EXPR_ARG (callexp, 1);
+      overflow = CALL_EXPR_ARG (callexp, 2);
+      icode = IFN_MUL_OVERFLOW;
+      break;
+
+    case INTRINSIC_NEGS:
+    case INTRINSIC_NEGSL:
+      /* The negs() intrinsic gets turned into SUB_OVERFLOW (0, y).  */
+      x = fold_convert (type, integer_zero_node);
+      y = CALL_EXPR_ARG (callexp, 0);
+      overflow = CALL_EXPR_ARG (callexp, 1);
+      icode = IFN_SUB_OVERFLOW;
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
 
   tree result
     = build_call_expr_internal_loc (EXPR_LOCATION (callexp), icode,
@@ -702,142 +716,87 @@  maybe_expand_intrinsic (tree callexp)
       return callexp;
 
     case INTRINSIC_BSF:
+    case INTRINSIC_BSF64:
       return expand_intrinsic_bsf (callexp);
 
     case INTRINSIC_BSR:
+    case INTRINSIC_BSR64:
       return expand_intrinsic_bsr (callexp);
 
     case INTRINSIC_BT:
+    case INTRINSIC_BT64:
     case INTRINSIC_BTC:
+    case INTRINSIC_BTC64:
     case INTRINSIC_BTR:
+    case INTRINSIC_BTR64:
     case INTRINSIC_BTS:
+    case INTRINSIC_BTS64:
       return expand_intrinsic_bt (intrinsic, callexp);
 
-    case INTRINSIC_BSWAP:
-      return expand_intrinsic_bswap (callexp);
-
-    case INTRINSIC_POPCNT:
+    case INTRINSIC_POPCNT32:
+    case INTRINSIC_POPCNT64:
       return expand_intrinsic_popcnt (callexp);
 
-    case INTRINSIC_COS:
-      return call_builtin_fn (callexp, BUILT_IN_COSL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_SIN:
-      return call_builtin_fn (callexp, BUILT_IN_SINL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_RNDTOL:
-      /* Not sure if llroundl stands as a good replacement for the
-	 expected behavior of rndtol.  */
-      return call_builtin_fn (callexp, BUILT_IN_LLROUNDL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_SQRT:
-    case INTRINSIC_SQRTF:
-    case INTRINSIC_SQRTL:
-      return expand_intrinsic_sqrt (intrinsic, callexp);
-
-    case INTRINSIC_LDEXP:
-      return call_builtin_fn (callexp, BUILT_IN_LDEXPL, 2,
-			      CALL_EXPR_ARG (callexp, 0),
-			      CALL_EXPR_ARG (callexp, 1));
-
-    case INTRINSIC_FABS:
-      return call_builtin_fn (callexp, BUILT_IN_FABSL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_RINT:
-      return call_builtin_fn (callexp, BUILT_IN_RINTL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_TAN:
-      return call_builtin_fn (callexp, BUILT_IN_TANL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_ISNAN:
-      return call_builtin_fn (callexp, BUILT_IN_ISNAN, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_ISINFINITY:
-      return call_builtin_fn (callexp, BUILT_IN_ISINF, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_ISFINITE:
-      return call_builtin_fn (callexp, BUILT_IN_ISFINITE, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
+    case INTRINSIC_BSWAP32:
+    case INTRINSIC_BSWAP64:
+    case INTRINSIC_CEIL:
+    case INTRINSIC_CEILF:
+    case INTRINSIC_CEILL:
+    case INTRINSIC_COSL:
     case INTRINSIC_EXP:
-      return call_builtin_fn (callexp, BUILT_IN_EXPL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_EXPM1:
-      return call_builtin_fn (callexp, BUILT_IN_EXPM1L, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
     case INTRINSIC_EXP2:
-      return call_builtin_fn (callexp, BUILT_IN_EXP2L, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
+    case INTRINSIC_EXPM1:
+    case INTRINSIC_FABSL:
+    case INTRINSIC_FLOOR:
+    case INTRINSIC_FLOORF:
+    case INTRINSIC_FLOORL:
+    case INTRINSIC_ISFINITE:
+    case INTRINSIC_ISINFINITY:
+    case INTRINSIC_ISNAN:
     case INTRINSIC_LOG:
-      return call_builtin_fn (callexp, BUILT_IN_LOGL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_LOG2:
-      return call_builtin_fn (callexp, BUILT_IN_LOG2L, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
     case INTRINSIC_LOG10:
-      return call_builtin_fn (callexp, BUILT_IN_LOG10L, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
+    case INTRINSIC_LOG2:
+    case INTRINSIC_RINTL:
+    case INTRINSIC_RNDTOLL:
     case INTRINSIC_ROUND:
-      return call_builtin_fn (callexp, BUILT_IN_ROUNDL, 1,
-			      CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_FLOORF:
-    case INTRINSIC_FLOOR:
-    case INTRINSIC_FLOORL:
-      code = (intrinsic == INTRINSIC_FLOOR) ? BUILT_IN_FLOOR
-	: (intrinsic == INTRINSIC_FLOORF) ? BUILT_IN_FLOORF
-	: BUILT_IN_FLOORL;
-      return call_builtin_fn (callexp, code, 1, CALL_EXPR_ARG (callexp, 0));
-
-    case INTRINSIC_CEILF:
-    case INTRINSIC_CEIL:
-    case INTRINSIC_CEILL:
-      code = (intrinsic == INTRINSIC_CEIL) ? BUILT_IN_CEIL
-	: (intrinsic == INTRINSIC_CEILF) ? BUILT_IN_CEILF
-	: BUILT_IN_CEILL;
-      return call_builtin_fn (callexp, code, 1, CALL_EXPR_ARG (callexp, 0));
-
+    case INTRINSIC_SINL:
+    case INTRINSIC_SQRT:
+    case INTRINSIC_SQRTF:
+    case INTRINSIC_SQRTL:
+    case INTRINSIC_TAN:
     case INTRINSIC_TRUNC:
-      return call_builtin_fn (callexp, BUILT_IN_TRUNCL, 1,
+      code = intrinsic_decls[intrinsic].built_in;
+      gcc_assert (code != BUILT_IN_NONE);
+      return call_builtin_fn (callexp, code, 1,
 			      CALL_EXPR_ARG (callexp, 0));
 
+    case INTRINSIC_FMAX:
     case INTRINSIC_FMIN:
-      return call_builtin_fn (callexp, BUILT_IN_FMINL, 2,
+    case INTRINSIC_LDEXPL:
+      code = intrinsic_decls[intrinsic].built_in;
+      gcc_assert (code != BUILT_IN_NONE);
+      return call_builtin_fn (callexp, code, 2,
 			      CALL_EXPR_ARG (callexp, 0),
 			      CALL_EXPR_ARG (callexp, 1));
 
-    case INTRINSIC_FMAX:
-      return call_builtin_fn (callexp, BUILT_IN_FMAXL, 2,
+    case INTRINSIC_FMA:
+      code = intrinsic_decls[intrinsic].built_in;
+      gcc_assert (code != BUILT_IN_NONE);
+      return call_builtin_fn (callexp, code, 3,
 			      CALL_EXPR_ARG (callexp, 0),
-			      CALL_EXPR_ARG (callexp, 1));
+			      CALL_EXPR_ARG (callexp, 1),
+			      CALL_EXPR_ARG (callexp, 2));
 
     case INTRINSIC_COPYSIGN:
+    case INTRINSIC_COPYSIGNI:
       return expand_intrinsic_copysign (callexp);
 
     case INTRINSIC_POW:
       return expand_intrinsic_pow (callexp);
 
-    case INTRINSIC_FMA:
-      return call_builtin_fn (callexp, BUILT_IN_FMAL, 3,
-			      CALL_EXPR_ARG (callexp, 0),
-			      CALL_EXPR_ARG (callexp, 1),
-			      CALL_EXPR_ARG (callexp, 2));
-
     case INTRINSIC_TOPREC:
+    case INTRINSIC_TOPRECF:
+    case INTRINSIC_TOPRECL:
       return expand_intrinsic_toprec (callexp);
 
     case INTRINSIC_VA_ARG:
@@ -848,15 +807,32 @@  maybe_expand_intrinsic (tree callexp)
       return expand_intrinsic_vastart (callexp);
 
     case INTRINSIC_ADDS:
+    case INTRINSIC_ADDSL:
+    case INTRINSIC_ADDU:
+    case INTRINSIC_ADDUL:
     case INTRINSIC_SUBS:
+    case INTRINSIC_SUBSL:
+    case INTRINSIC_SUBU:
+    case INTRINSIC_SUBUL:
     case INTRINSIC_MULS:
+    case INTRINSIC_MULSL:
+    case INTRINSIC_MULU:
+    case INTRINSIC_MULUI:
+    case INTRINSIC_MULUL:
     case INTRINSIC_NEGS:
+    case INTRINSIC_NEGSL:
       return expand_intrinsic_checkedint (intrinsic, callexp);
 
-    case INTRINSIC_VLOAD:
+    case INTRINSIC_VLOAD8:
+    case INTRINSIC_VLOAD16:
+    case INTRINSIC_VLOAD32:
+    case INTRINSIC_VLOAD64:
       return expand_volatile_load (callexp);
 
-    case INTRINSIC_VSTORE:
+    case INTRINSIC_VSTORE8:
+    case INTRINSIC_VSTORE16:
+    case INTRINSIC_VSTORE32:
+    case INTRINSIC_VSTORE64:
       return expand_volatile_store (callexp);
 
     default:
diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def
index 1782cd7f507..0c32126b1fa 100644
--- a/gcc/d/intrinsics.def
+++ b/gcc/d/intrinsics.def
@@ -15,11 +15,10 @@  You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-/* DEF_D_INTRINSIC (CODE, ALIAS, NAME, MODULE, DECO, CTFE)
+/* DEF_D_INTRINSIC (CODE, BUILTIN, NAME, MODULE, DECO, CTFE)
    CODE	    The enum code used to refer to this intrinsic.
-   ALIAS    The enum code used to reference the function DECL_FUNCTION_CODE,
-	    if there are multiple modules or decos for a single intrinsic,
-	    they would all refer to this code.
+   BUILTIN  The enum code used to reference the function DECL_FUNCTION_CODE,
+	    if the intrinsic can be mapped 1:1 to a GCC built-in.
    NAME	    The name of this intrinsic as a string.
    MODULE   The name of the module which the intrinsic belongs to as a string.
    DECO	    The function signature decoration of the intrinsic.
@@ -30,102 +29,98 @@  along with GCC; see the file COPYING3.  If not see
    GCC builtin, or are specially handled by the compiler.  */
 
 /* A D built-in that has no runtime implementation.  */
-#define DEF_D_BUILTIN(C, A, N, M, D) \
-  DEF_D_INTRINSIC (C, A, N, M, D, false)
+#define DEF_D_BUILTIN(C, B, N, M, D) \
+  DEF_D_INTRINSIC (C, B, N, M, D, false)
 
 /* A D built-in that is specially recognized only during CTFE.  */
-#define DEF_CTFE_BUILTIN(C, A, N, M, D) \
-  DEF_D_INTRINSIC (C, A, N, M, D, true)
+#define DEF_CTFE_BUILTIN(C, B, N, M, D) \
+  DEF_D_INTRINSIC (C, B, N, M, D, true)
 
 DEF_D_BUILTIN (NONE, NONE, 0, 0, 0)
 
 /* core.bitop intrinsics.  */
 
-DEF_D_BUILTIN (BSF, BSF, "bsf", "core.bitop", "FNaNbNiNfkZi")
-DEF_D_BUILTIN (BSR, BSR, "bsr", "core.bitop", "FNaNbNiNfkZi")
-DEF_D_BUILTIN (BT, BT, "bt", "core.bitop", "FNaNbNixPkkZi")
-DEF_D_BUILTIN (BTC, BTC, "btc", "core.bitop", "FNaNbNiPkkZi")
-DEF_D_BUILTIN (BTR, BTR, "btr", "core.bitop", "FNaNbNiPkkZi")
-DEF_D_BUILTIN (BTS, BTS, "bts", "core.bitop", "FNaNbNiPkkZi")
-DEF_D_BUILTIN (BSF64, BSF, "bsf", "core.bitop", "FNaNbNiNfmZi")
-DEF_D_BUILTIN (BSR64, BSR, "bsr", "core.bitop", "FNaNbNiNfmZi")
-DEF_D_BUILTIN (BT64, BT, "bt", "core.bitop", "FNaNbNixPmmZi")
-DEF_D_BUILTIN (BTC64, BTC, "btc", "core.bitop", "FNaNbNiPmmZi")
-DEF_D_BUILTIN (BTR64, BTR, "btr", "core.bitop", "FNaNbNiPmmZi")
-DEF_D_BUILTIN (BTS64, BTS, "bts", "core.bitop", "FNaNbNiPmmZi")
-DEF_D_BUILTIN (BSWAP, BSWAP, "bswap", "core.bitop", "FNaNbNiNfkZk")
-DEF_D_BUILTIN (BSWAP64, BSWAP, "bswap", "core.bitop", "FNaNbNiNfmZm")
-DEF_D_BUILTIN (POPCNT, POPCNT, "popcnt", "core.bitop", "FNaNbNiNfkZi")
-DEF_D_BUILTIN (POPCNT64, POPCNT, "popcnt", "core.bitop", "FNaNbNiNfmZi")
-DEF_D_BUILTIN (VLOAD, VLOAD, "volatileLoad", "core.bitop", "FNbNiNfPhZh")
-DEF_D_BUILTIN (VLOAD16, VLOAD, "volatileLoad", "core.bitop", "FNbNiNfPtZt")
-DEF_D_BUILTIN (VLOAD32, VLOAD, "volatileLoad", "core.bitop", "FNbNiNfPkZk")
-DEF_D_BUILTIN (VLOAD64, VLOAD, "volatileLoad", "core.bitop", "FNbNiNfPmZm")
-DEF_D_BUILTIN (VSTORE, VSTORE, "volatileStore", "core.bitop", "FNbNiNfPhhZv")
-DEF_D_BUILTIN (VSTORE16, VSTORE, "volatileStore", "core.bitop", "FNbNiNfPttZv")
-DEF_D_BUILTIN (VSTORE32, VSTORE, "volatileStore", "core.bitop", "FNbNiNfPkkZv")
-DEF_D_BUILTIN (VSTORE64, VSTORE, "volatileStore", "core.bitop", "FNbNiNfPmmZv")
+DEF_D_BUILTIN (BSF, NONE, "bsf", "core.bitop", "FNaNbNiNfkZi")
+DEF_D_BUILTIN (BSR, NONE, "bsr", "core.bitop", "FNaNbNiNfkZi")
+DEF_D_BUILTIN (BT, NONE, "bt", "core.bitop", "FNaNbNixPkkZi")
+DEF_D_BUILTIN (BTC, NONE, "btc", "core.bitop", "FNaNbNiPkkZi")
+DEF_D_BUILTIN (BTR, NONE, "btr", "core.bitop", "FNaNbNiPkkZi")
+DEF_D_BUILTIN (BTS, NONE, "bts", "core.bitop", "FNaNbNiPkkZi")
+DEF_D_BUILTIN (BSF64, NONE, "bsf", "core.bitop", "FNaNbNiNfmZi")
+DEF_D_BUILTIN (BSR64, NONE, "bsr", "core.bitop", "FNaNbNiNfmZi")
+DEF_D_BUILTIN (BT64, NONE, "bt", "core.bitop", "FNaNbNixPmmZi")
+DEF_D_BUILTIN (BTC64, NONE, "btc", "core.bitop", "FNaNbNiPmmZi")
+DEF_D_BUILTIN (BTR64, NONE, "btr", "core.bitop", "FNaNbNiPmmZi")
+DEF_D_BUILTIN (BTS64, NONE, "bts", "core.bitop", "FNaNbNiPmmZi")
+
+DEF_D_BUILTIN (BSWAP32, BSWAP32, "bswap", "core.bitop", "FNaNbNiNfkZk")
+DEF_D_BUILTIN (BSWAP64, BSWAP64, "bswap", "core.bitop", "FNaNbNiNfmZm")
+
+DEF_D_BUILTIN (POPCNT32, NONE, "popcnt", "core.bitop", "FNaNbNiNfkZi")
+DEF_D_BUILTIN (POPCNT64, NONE, "popcnt", "core.bitop", "FNaNbNiNfmZi")
+
+DEF_D_BUILTIN (VLOAD8, NONE, "volatileLoad", "core.bitop", "FNbNiNfPhZh")
+DEF_D_BUILTIN (VLOAD16, NONE, "volatileLoad", "core.bitop", "FNbNiNfPtZt")
+DEF_D_BUILTIN (VLOAD32, NONE, "volatileLoad", "core.bitop", "FNbNiNfPkZk")
+DEF_D_BUILTIN (VLOAD64, NONE, "volatileLoad", "core.bitop", "FNbNiNfPmZm")
+DEF_D_BUILTIN (VSTORE8, NONE, "volatileStore", "core.bitop", "FNbNiNfPhhZv")
+DEF_D_BUILTIN (VSTORE16, NONE, "volatileStore", "core.bitop", "FNbNiNfPttZv")
+DEF_D_BUILTIN (VSTORE32, NONE, "volatileStore", "core.bitop", "FNbNiNfPkkZv")
+DEF_D_BUILTIN (VSTORE64, NONE, "volatileStore", "core.bitop", "FNbNiNfPmmZv")
 
 /* core.checkedint intrinsics.  */
 
-DEF_D_BUILTIN (ADDS, ADDS, "adds", "core.checkedint", "FNaNbNiNfiiKbZi")
-DEF_D_BUILTIN (ADDSL, ADDS, "adds", "core.checkedint", "FNaNbNiNfllKbZl")
-DEF_D_BUILTIN (ADDU, ADDS, "addu", "core.checkedint", "FNaNbNiNfkkKbZk")
-DEF_D_BUILTIN (ADDUL, ADDS, "addu", "core.checkedint", "FNaNbNiNfmmKbZm")
-DEF_D_BUILTIN (SUBS, SUBS, "subs", "core.checkedint", "FNaNbNiNfiiKbZi")
-DEF_D_BUILTIN (SUBSL, SUBS, "subs", "core.checkedint", "FNaNbNiNfllKbZl")
-DEF_D_BUILTIN (SUBU, SUBS, "subu", "core.checkedint", "FNaNbNiNfkkKbZk")
-DEF_D_BUILTIN (SUBUL, SUBS, "subu", "core.checkedint", "FNaNbNiNfmmKbZm")
-DEF_D_BUILTIN (MULS, MULS, "muls", "core.checkedint", "FNaNbNiNfiiKbZi")
-DEF_D_BUILTIN (MULSL, MULS, "muls", "core.checkedint", "FNaNbNiNfllKbZl")
-DEF_D_BUILTIN (MULU, MULS, "mulu", "core.checkedint", "FNaNbNiNfkkKbZk")
-DEF_D_BUILTIN (MULUI, MULS, "mulu", "core.checkedint", "FNaNbNiNfmkKbZm")
-DEF_D_BUILTIN (MULUL, MULS, "mulu", "core.checkedint", "FNaNbNiNfmmKbZm")
-DEF_D_BUILTIN (NEGS, NEGS, "negs", "core.checkedint", "FNaNbNiNfiKbZi")
-DEF_D_BUILTIN (NEGSL, NEGS, "negs", "core.checkedint", "FNaNbNiNflKbZl")
+DEF_D_BUILTIN (ADDS, NONE, "adds", "core.checkedint", "FNaNbNiNfiiKbZi")
+DEF_D_BUILTIN (ADDSL, NONE, "adds", "core.checkedint", "FNaNbNiNfllKbZl")
+DEF_D_BUILTIN (ADDU, NONE, "addu", "core.checkedint", "FNaNbNiNfkkKbZk")
+DEF_D_BUILTIN (ADDUL, NONE, "addu", "core.checkedint", "FNaNbNiNfmmKbZm")
+DEF_D_BUILTIN (SUBS, NONE, "subs", "core.checkedint", "FNaNbNiNfiiKbZi")
+DEF_D_BUILTIN (SUBSL, NONE, "subs", "core.checkedint", "FNaNbNiNfllKbZl")
+DEF_D_BUILTIN (SUBU, NONE, "subu", "core.checkedint", "FNaNbNiNfkkKbZk")
+DEF_D_BUILTIN (SUBUL, NONE, "subu", "core.checkedint", "FNaNbNiNfmmKbZm")
+DEF_D_BUILTIN (MULS, NONE, "muls", "core.checkedint", "FNaNbNiNfiiKbZi")
+DEF_D_BUILTIN (MULSL, NONE, "muls", "core.checkedint", "FNaNbNiNfllKbZl")
+DEF_D_BUILTIN (MULU, NONE, "mulu", "core.checkedint", "FNaNbNiNfkkKbZk")
+DEF_D_BUILTIN (MULUI, NONE, "mulu", "core.checkedint", "FNaNbNiNfmkKbZm")
+DEF_D_BUILTIN (MULUL, NONE, "mulu", "core.checkedint", "FNaNbNiNfmmKbZm")
+DEF_D_BUILTIN (NEGS, NONE, "negs", "core.checkedint", "FNaNbNiNfiKbZi")
+DEF_D_BUILTIN (NEGSL, NONE, "negs", "core.checkedint", "FNaNbNiNflKbZl")
 
 /* core.math intrinsics.  */
 
-DEF_D_BUILTIN (COS, COS, "cos", "core.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (FABS, FABS, "fabs", "core.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (LDEXP, LDEXP, "ldexp", "core.math", "FNaNbNiNfeiZe")
-DEF_D_BUILTIN (RINT, RINT, "rint", "core.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (RNDTOL, RNDTOL, "rndtol", "core.math", "FNaNbNiNfeZl")
-DEF_D_BUILTIN (SIN, SIN, "sin", "core.math", "FNaNbNiNfeZe")
+DEF_D_BUILTIN (COSL, COSL, "cos", "core.math", "FNaNbNiNfeZe")
+DEF_D_BUILTIN (FABSL, FABSL, "fabs", "core.math", "FNaNbNiNfeZe")
+DEF_D_BUILTIN (LDEXPL, LDEXPL, "ldexp", "core.math", "FNaNbNiNfeiZe")
+DEF_D_BUILTIN (RINTL, RINTL, "rint", "core.math", "FNaNbNiNfeZe")
+
+/* Not sure if `llroundl' stands as a good replacement for the expected
+   behavior of `rndtol()'.  */
+DEF_D_BUILTIN (RNDTOLL, LLROUNDL, "rndtol", "core.math", "FNaNbNiNfeZl")
+
+DEF_D_BUILTIN (SINL, SINL, "sin", "core.math", "FNaNbNiNfeZe")
 DEF_D_BUILTIN (SQRTF, SQRTF, "sqrt", "core.math", "FNaNbNiNffZf")
 DEF_D_BUILTIN (SQRT, SQRT, "sqrt", "core.math", "FNaNbNiNfdZd")
 DEF_D_BUILTIN (SQRTL, SQRTL, "sqrt", "core.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (TOPRECF, TOPREC, "toPrec", "core.math", "FNaNbNffZI1T")
-DEF_D_BUILTIN (TOPREC, TOPREC, "toPrec", "core.math", "FNaNbNfdZI1T")
-DEF_D_BUILTIN (TOPRECL, TOPREC, "toPrec", "core.math", "FNaNbNfeZI1T")
+DEF_D_BUILTIN (TOPRECF, NONE, "toPrec", "core.math", "FNaNbNffZI1T")
+DEF_D_BUILTIN (TOPREC, NONE, "toPrec", "core.math", "FNaNbNfdZI1T")
+DEF_D_BUILTIN (TOPRECL, NONE, "toPrec", "core.math", "FNaNbNfeZI1T")
 
 /* std.math intrinsics.  */
 
-DEF_D_BUILTIN (STD_COS, COS, "cos", "std.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (STD_FABS, FABS, "fabs", "std.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (STD_LDEXP, LDEXP, "ldexp", "std.math", "FNaNbNiNfeiZe")
-DEF_D_BUILTIN (STD_RINT, RINT, "rint", "std.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (STD_RNDTOL, RNDTOL, "rndtol", "std.math", "FNaNbNiNfeZl")
-DEF_D_BUILTIN (STD_SIN, SIN, "sin", "std.math", "FNaNbNiNfeZe")
-DEF_D_BUILTIN (STD_SQRTF, SQRTF, "sqrt", "std.math", "FNaNbNiNffZf")
-DEF_D_BUILTIN (STD_SQRT, SQRT, "sqrt", "std.math", "FNaNbNiNfdZd")
-DEF_D_BUILTIN (STD_SQRTL, SQRTL, "sqrt", "std.math", "FNaNbNiNfeZe")
-
-DEF_CTFE_BUILTIN (TAN, TAN, "tan", "std.math", "FNaNbNiNeeZe")
+DEF_CTFE_BUILTIN (TAN, TANL, "tan", "std.math", "FNaNbNiNeeZe")
 DEF_CTFE_BUILTIN (ISNAN, ISNAN, "isNaN", "std.math", "FNaNbNiNeI1XZb")
-DEF_CTFE_BUILTIN (ISINFINITY, ISINFINITY, "isInfinity", "std.math",
-		  "FNaNbNiNeI1XZb")
+DEF_CTFE_BUILTIN (ISINFINITY, ISINF, "isInfinity", "std.math", "FNaNbNiNeI1XZb")
 DEF_CTFE_BUILTIN (ISFINITE, ISFINITE, "isFinite", "std.math", "FNaNbNiNeI1XZb")
 
-DEF_CTFE_BUILTIN (EXP, EXP, "exp", "std.math", "FNaNbNiNeeZe")
-DEF_CTFE_BUILTIN (EXPM1, EXPM1, "expm1", "std.math", "FNaNbNiNeeZe")
-DEF_CTFE_BUILTIN (EXP2, EXP2, "exp2", "std.math", "FNaNbNiNeeZe")
+DEF_CTFE_BUILTIN (EXP, EXPL, "exp", "std.math", "FNaNbNiNeeZe")
+DEF_CTFE_BUILTIN (EXPM1, EXPM1L, "expm1", "std.math", "FNaNbNiNeeZe")
+DEF_CTFE_BUILTIN (EXP2, EXP2L, "exp2", "std.math", "FNaNbNiNeeZe")
 
-DEF_CTFE_BUILTIN (LOG, LOG, "log", "std.math", "FNaNbNiNfeZe")
-DEF_CTFE_BUILTIN (LOG2, LOG2, "log2", "std.math", "FNaNbNiNfeZe")
-DEF_CTFE_BUILTIN (LOG10, LOG10, "log10", "std.math", "FNaNbNiNfeZe")
+DEF_CTFE_BUILTIN (LOG, LOGL, "log", "std.math", "FNaNbNiNfeZe")
+DEF_CTFE_BUILTIN (LOG2, LOG2L, "log2", "std.math", "FNaNbNiNfeZe")
+DEF_CTFE_BUILTIN (LOG10, LOG10L, "log10", "std.math", "FNaNbNiNfeZe")
 
-DEF_CTFE_BUILTIN (ROUND, ROUND, "round", "std.math", "FNbNiNeeZe")
+DEF_CTFE_BUILTIN (ROUND, ROUNDL, "round", "std.math", "FNbNiNeeZe")
 DEF_CTFE_BUILTIN (FLOORF, FLOORF, "floor", "std.math", "FNaNbNiNefZf")
 DEF_CTFE_BUILTIN (FLOOR, FLOOR, "floor", "std.math", "FNaNbNiNedZd")
 DEF_CTFE_BUILTIN (FLOORL, FLOORL, "floor", "std.math", "FNaNbNiNeeZe")
@@ -133,24 +128,21 @@  DEF_CTFE_BUILTIN (CEILF, CEILF, "ceil", "std.math", "FNaNbNiNefZf")
 DEF_CTFE_BUILTIN (CEIL, CEIL, "ceil", "std.math", "FNaNbNiNedZd")
 DEF_CTFE_BUILTIN (CEILL, CEILL, "ceil", "std.math", "FNaNbNiNeeZe")
 
-DEF_CTFE_BUILTIN (TRUNC, TRUNC, "trunc", "std.math", "FNbNiNeeZe")
-DEF_CTFE_BUILTIN (FMIN, FMIN, "fmin", "std.math", "FNaNbNiNfeeZe")
-DEF_CTFE_BUILTIN (FMAX, FMAX, "fmax", "std.math", "FNaNbNiNfeeZe")
-DEF_CTFE_BUILTIN (COPYSIGN, COPYSIGN, "copysign", "std.math",
-		  "FNaNbNiNeI1RI1XZI1R")
-DEF_CTFE_BUILTIN (COPYSIGNI, COPYSIGN, "copysign", "std.math",
+DEF_CTFE_BUILTIN (TRUNC, TRUNCL, "trunc", "std.math", "FNbNiNeeZe")
+DEF_CTFE_BUILTIN (FMIN, FMINL, "fmin", "std.math", "FNaNbNiNfeeZe")
+DEF_CTFE_BUILTIN (FMAX, FMAXL, "fmax", "std.math", "FNaNbNiNfeeZe")
+DEF_CTFE_BUILTIN (COPYSIGN, NONE, "copysign", "std.math", "FNaNbNiNeI1RI1XZI1R")
+DEF_CTFE_BUILTIN (COPYSIGNI, NONE, "copysign", "std.math",
 		  "FNaNbNiNeI1XI1RZI1R")
 
-DEF_CTFE_BUILTIN (POW, POW, "pow", "std.math", "FNaNbNiNeI1FI1GZ@")
-DEF_CTFE_BUILTIN (FMA, FMA, "fma", "std.math", "FNaNbNiNfeeeZe")
+DEF_CTFE_BUILTIN (POW, NONE, "pow", "std.math", "FNaNbNiNeI1FI1GZ@")
+DEF_CTFE_BUILTIN (FMA, FMAL, "fma", "std.math", "FNaNbNiNfeeeZe")
 
 /* core.stdc.stdarg intrinsics.  */
 
-DEF_D_BUILTIN (VA_ARG, VA_ARG, "va_arg", "core.stdc.stdarg",
-	       "FKI7va_listKI1TZv")
-DEF_D_BUILTIN (C_VA_ARG, C_VA_ARG, "va_arg", "core.stdc.stdarg",
-	       "FKI7va_listZI1T")
-DEF_D_BUILTIN (VASTART, VASTART, "va_start", "core.stdc.stdarg",
+DEF_D_BUILTIN (VA_ARG, NONE, "va_arg", "core.stdc.stdarg", "FKI7va_listKI1TZv")
+DEF_D_BUILTIN (C_VA_ARG, NONE, "va_arg", "core.stdc.stdarg", "FKI7va_listZI1T")
+DEF_D_BUILTIN (VASTART, NONE, "va_start", "core.stdc.stdarg",
 	       "FJI7va_listKI1TZv")
 
 #undef DEF_D_BUILTIN
diff --git a/gcc/testsuite/gdc.dg/intrinsics.d b/gcc/testsuite/gdc.dg/intrinsics.d
new file mode 100644
index 00000000000..e10c06dd41a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/intrinsics.d
@@ -0,0 +1,117 @@ 
+// { dg-do compile }
+// { dg-options "-fdump-tree-original" }
+import core.bitop;
+import core.checkedint;
+import core.math;
+import core.stdc.stdarg;
+
+//////////////////////////////////////////////////////
+// core.bitop
+
+// { dg-final { scan-tree-dump-not " bsf " "original" } }
+int test_bsf(uint a) { return bsf(a); }
+int test_bsf(ulong a) { return bsf(a); }
+// { dg-final { scan-tree-dump-not " bsr " "original" } }
+int test_bsr(uint a) { return bsr(a); }
+int test_bsr(ulong a) { return bsr(a); }
+// { dg-final { scan-tree-dump-not " bt " "original" } }
+int test_bt(size_t *a, size_t b) { return bt(a, b); }
+// { dg-final { scan-tree-dump-not " btc " "original" } }
+int test_btc(size_t *a, size_t b) { return btc(a, b); }
+// { dg-final { scan-tree-dump-not " btr " "original" } }
+int test_btr(size_t *a, size_t b) { return btr(a, b); }
+// { dg-final { scan-tree-dump-not " bts " "original" } }
+int test_bts(size_t *a, size_t b) { return bts(a, b); }
+// { dg-final { scan-tree-dump-not " bswap " "original" } }
+uint test_bswap(uint a) { return bswap(a); }
+ulong test_bswap(ulong a) { return bswap(a); }
+// { dg-final { scan-tree-dump-not " popcnt " "original" } }
+int test_popcnt(uint a) { return popcnt(a); }
+int test_popcnt(ulong a) { return popcnt(a); }
+// { dg-final { scan-tree-dump-not " volatileLoad " "original" } }
+ubyte test_volatileLoad(ubyte *a) { return volatileLoad(a); }
+ushort test_volatileLoad(ushort *a) { return volatileLoad(a); }
+uint test_volatileLoad(uint *a) { return volatileLoad(a); }
+ulong test_volatileLoad(ulong *a) { return volatileLoad(a); }
+// { dg-final { scan-tree-dump-not " volatileStore " "original" } }
+void test_volatileStore(ubyte *a, ubyte b) { return volatileStore(a, b); }
+void test_volatileStore(ushort *a, ushort b) { return volatileStore(a, b); }
+void test_volatileStore(uint *a, uint b) { return volatileStore(a, b); }
+void test_volatileStore(ulong *a, ulong b) { return volatileStore(a, b); }
+
+//////////////////////////////////////////////////////
+// core.checkedint
+
+// { dg-final { scan-tree-dump-not " adds " "original" } }
+int test_adds(int a, int b, ref bool c) { return adds(a, b, c); }
+long test_adds(long a, long b, ref bool c) { return adds(a, b, c); }
+// { dg-final { scan-tree-dump-not " addu " "original" } }
+uint test_addu(uint a, uint b, ref bool c) { return addu(a, b, c); }
+ulong test_addu(ulong a, ulong b, ref bool c) { return addu(a, b, c); }
+// { dg-final { scan-tree-dump-not " subs " "original" } }
+int test_subs(int a, int b, ref bool c) { return subs(a, b, c); }
+long test_subs(long a, long b, ref bool c) { return subs(a, b, c); }
+// { dg-final { scan-tree-dump-not " subu " "original" } }
+uint test_subu(uint a, uint b, ref bool c) { return subu(a, b, c); }
+ulong test_subu(ulong a, ulong b, ref bool c) { return subu(a, b, c); }
+// { dg-final { scan-tree-dump-not " negs " "original" } }
+int test_negs(int a, ref bool b) { return negs(a, b); }
+long test_negs(long a, ref bool b) { return negs(a, b); }
+// { dg-final { scan-tree-dump-not " muls " "original" } }
+int test_muls(int a, int b, ref bool c) { return muls(a, b, c); }
+long test_muls(long a, long b, ref bool c) { return muls(a, b, c); }
+// { dg-final { scan-tree-dump-not " mulu " "original" } }
+uint test_mulu(uint a, uint b, ref bool c) { return mulu(a, b, c); }
+ulong test_mulu(ulong a, uint b, ref bool c) { return mulu(a, b, c); }
+ulong test_mulu(ulong a, ulong b, ref bool c) { return mulu(a, b, c); }
+
+//////////////////////////////////////////////////////
+// core.math
+
+// { dg-final { scan-tree-dump-not " cos " "original" } }
+float test_cos(float a) { return cos(a); }
+double test_cos(double a) { return cos(a); }
+real test_cos(real a) { return cos(a); }
+// { dg-final { scan-tree-dump-not " sin " "original" } }
+float test_sin(float a) { return sin(a); }
+double test_sin(double a) { return sin(a); }
+real test_sin(real a) { return sin(a); }
+// { dg-final { scan-tree-dump-not " rndtol " "original" } }
+long test_rndtol(float a) { return rndtol(a); }
+long test_rndtol(double a) { return rndtol(a); }
+long test_rndtol(real a) { return rndtol(a); }
+// { dg-final { scan-tree-dump-not " sqrt " "original" } }
+float test_sqrt(float a) { return sqrt(a); }
+double test_sqrt(double a) { return sqrt(a); }
+real test_sqrt(real a) { return sqrt(a); }
+// { dg-final { scan-tree-dump-not " ldexp " "original" } }
+float test_ldexp(float a, int b) { return ldexp(a, b); }
+double test_ldexp(double a, int b) { return ldexp(a, b); }
+real test_ldexp(real a, int b) { return ldexp(a, b); }
+// { dg-final { scan-tree-dump-not " fabs " "original" } }
+float test_fabs(float a) { return fabs(a); }
+double test_fabs(double a) { return fabs(a); }
+real test_fabs(real a) { return fabs(a); }
+// { dg-final { scan-tree-dump-not " rint " "original" } }
+float test_rint(float a) { return rint(a); }
+double test_rint(double a) { return rint(a); }
+real test_rint(real a) { return rint(a); }
+// { dg-final { scan-tree-dump-not " toPrec " "original" } }
+float test_toPrec(float a) { return toPrec!float(a); }
+float test_toPrec(double a) { return toPrec!float(a); }
+float test_toPrec(real a) { return toPrec!float(a); }
+double test_toPrec(float a) { return toPrec!double(a); }
+double test_toPrec(double a) { return toPrec!double(a); }
+double test_toPrec(real a) { return toPrec!double(a); }
+real test_toPrec(float a) { return toPrec!real(a); }
+real test_toPrec(double a) { return toPrec!real(a); }
+real test_toPrec(real a) { return toPrec!real(a); }
+
+//////////////////////////////////////////////////////
+// core.stdc.stdarg
+
+// { dg-final { scan-tree-dump-not " va_arg " "original" } }
+void test_va_arg(...) { int a; return va_arg!int(_argptr, a); }
+int test_va_arg(...) { return va_arg!int(_argptr); }
+// { dg-final { scan-tree-dump-not " va_start " "original" } }
+void test_va_start(int a, ...) { return va_start(_argptr, a); }