d: Refactor matching and lowering of intrinsic functions.

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.

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.
This commit is contained in:
Iain Buclaw 2020-07-14 18:45:42 +02:00
parent 2c558d2655
commit 6ee874f135
4 changed files with 361 additions and 276 deletions

View File

@ -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"

View File

@ -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;
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);
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;
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_BSWAP32:
case INTRINSIC_BSWAP64:
case INTRINSIC_CEIL:
case INTRINSIC_CEILF:
case INTRINSIC_CEILL:
case INTRINSIC_COSL:
case INTRINSIC_EXP:
case INTRINSIC_EXP2:
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:
case INTRINSIC_LOG10:
case INTRINSIC_LOG2:
case INTRINSIC_RINTL:
case INTRINSIC_RNDTOLL:
case INTRINSIC_ROUND:
case INTRINSIC_SINL:
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_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_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_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_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_FMIN:
return call_builtin_fn (callexp, BUILT_IN_FMINL, 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_FMIN:
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_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, 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:

View File

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

View File

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