diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-11-26 10:46:36 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2020-11-27 21:27:13 +0100 |
commit | 9285e0f694969dc2d1d9257378ddf6c8ef42de3c (patch) | |
tree | 438e40733f271a6c62e4df462073b45e16cd249d /gcc | |
parent | 67138ea1b041fe1637da6b3568f064f172d9358c (diff) | |
download | gcc-9285e0f694969dc2d1d9257378ddf6c8ef42de3c.zip gcc-9285e0f694969dc2d1d9257378ddf6c8ef42de3c.tar.gz gcc-9285e0f694969dc2d1d9257378ddf6c8ef42de3c.tar.bz2 |
d: Add float and double overloads for all core.math intrinsics
For the math intrinsics: cos, fabs, ldexp, rint, rndtol, and sin, new
overloads have been added to the core.math module for matching float and
double types. These have been implemented in the compiler.
A recent change to dump_function_to_file started triggering some
scan-tree-dump tests to FAIL, these have been adjusted as well when
updating the test.
gcc/d/ChangeLog:
* intrinsics.cc (maybe_expand_intrinsic): Handle new intrinsics.
* intrinsics.def (INTRINSIC_COS): Add float and double overloads.
(INTRINSIC_FABS): Likewise.
(INTRINSIC_LDEXP): Likewise.
(INTRINSIC_RINT): Likewise.
(INTRINSIC_RNDTOL): Likewise.
(INTRINSIC_SIN): Likewise.
(INTRINSIC_TOPREC): Adjust signature.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 5e4492c4.
gcc/testsuite/ChangeLog:
* gdc.dg/intrinsics.d: Adjust patterns in scan-tree-dump.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/d/intrinsics.cc | 12 | ||||
-rw-r--r-- | gcc/d/intrinsics.def | 20 | ||||
-rw-r--r-- | gcc/testsuite/gdc.dg/intrinsics.d | 92 |
3 files changed, 86 insertions, 38 deletions
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index a7de910..4196ed3 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -814,10 +814,14 @@ maybe_expand_intrinsic (tree callexp) case INTRINSIC_CEIL: case INTRINSIC_CEILF: case INTRINSIC_CEILL: + case INTRINSIC_COS: + case INTRINSIC_COSF: case INTRINSIC_COSL: case INTRINSIC_EXP: case INTRINSIC_EXP2: case INTRINSIC_EXPM1: + case INTRINSIC_FABS: + case INTRINSIC_FABSF: case INTRINSIC_FABSL: case INTRINSIC_FLOOR: case INTRINSIC_FLOORF: @@ -828,9 +832,15 @@ maybe_expand_intrinsic (tree callexp) case INTRINSIC_LOG: case INTRINSIC_LOG10: case INTRINSIC_LOG2: + case INTRINSIC_RINT: + case INTRINSIC_RINTF: case INTRINSIC_RINTL: + case INTRINSIC_RNDTOL: + case INTRINSIC_RNDTOLF: case INTRINSIC_RNDTOLL: case INTRINSIC_ROUND: + case INTRINSIC_SIN: + case INTRINSIC_SINF: case INTRINSIC_SINL: case INTRINSIC_SQRT: case INTRINSIC_SQRTF: @@ -844,6 +854,8 @@ maybe_expand_intrinsic (tree callexp) case INTRINSIC_FMAX: case INTRINSIC_FMIN: + case INTRINSIC_LDEXP: + case INTRINSIC_LDEXPF: case INTRINSIC_LDEXPL: code = intrinsic_decls[intrinsic].built_in; gcc_assert (code != BUILT_IN_NONE); diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def index 5b8cb71..c05a666 100644 --- a/gcc/d/intrinsics.def +++ b/gcc/d/intrinsics.def @@ -93,22 +93,34 @@ DEF_D_BUILTIN (NEGSL, NONE, "negs", "core.checkedint", "FNaNbNiNflKbZl") /* core.math intrinsics. */ +DEF_D_BUILTIN (COSF, COSF, "cos", "core.math", "FNaNbNiNffZf") +DEF_D_BUILTIN (COS, COS, "cos", "core.math", "FNaNbNiNfdZd") DEF_D_BUILTIN (COSL, COSL, "cos", "core.math", "FNaNbNiNfeZe") +DEF_D_BUILTIN (FABSF, FABSL, "fabs", "core.math", "FNaNbNiNffZf") +DEF_D_BUILTIN (FABS, FABS, "fabs", "core.math", "FNaNbNiNfdZd") DEF_D_BUILTIN (FABSL, FABSL, "fabs", "core.math", "FNaNbNiNfeZe") +DEF_D_BUILTIN (LDEXPF, LDEXPF, "ldexp", "core.math", "FNaNbNiNffiZf") +DEF_D_BUILTIN (LDEXP, LDEXP, "ldexp", "core.math", "FNaNbNiNfdiZd") DEF_D_BUILTIN (LDEXPL, LDEXPL, "ldexp", "core.math", "FNaNbNiNfeiZe") +DEF_D_BUILTIN (RINTF, RINTF, "rint", "core.math", "FNaNbNiNffZf") +DEF_D_BUILTIN (RINT, RINT, "rint", "core.math", "FNaNbNiNfdZd") DEF_D_BUILTIN (RINTL, RINTL, "rint", "core.math", "FNaNbNiNfeZe") -/* Not sure if `llroundl' stands as a good replacement for the expected +/* Not sure if `llround{f,l}' stands as a good replacement for the expected behavior of `rndtol()'. */ +DEF_D_BUILTIN (RNDTOLF, LLROUNDF, "rndtol", "core.math", "FNaNbNiNffZl") +DEF_D_BUILTIN (RNDTOL, LLROUND, "rndtol", "core.math", "FNaNbNiNfdZl") DEF_D_BUILTIN (RNDTOLL, LLROUNDL, "rndtol", "core.math", "FNaNbNiNfeZl") +DEF_D_BUILTIN (SINF, SINF, "sin", "core.math", "FNaNbNiNffZf") +DEF_D_BUILTIN (SIN, SIN, "sin", "core.math", "FNaNbNiNfdZd") 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, NONE, "toPrec", "core.math", "FNaNbNffZI1T") -DEF_D_BUILTIN (TOPREC, NONE, "toPrec", "core.math", "FNaNbNfdZI1T") -DEF_D_BUILTIN (TOPRECL, NONE, "toPrec", "core.math", "FNaNbNfeZI1T") +DEF_D_BUILTIN (TOPRECF, NONE, "toPrec", "core.math", "FfZI1T") +DEF_D_BUILTIN (TOPREC, NONE, "toPrec", "core.math", "FdZI1T") +DEF_D_BUILTIN (TOPRECL, NONE, "toPrec", "core.math", "FeZI1T") /* std.math intrinsics. */ diff --git a/gcc/testsuite/gdc.dg/intrinsics.d b/gcc/testsuite/gdc.dg/intrinsics.d index 5888361..a775237 100644 --- a/gcc/testsuite/gdc.dg/intrinsics.d +++ b/gcc/testsuite/gdc.dg/intrinsics.d @@ -8,65 +8,77 @@ import core.stdc.stdarg; ////////////////////////////////////////////////////// // core.bitop -// { dg-final { scan-tree-dump-not " bsf " "original" } } +// { dg-final { scan-tree-dump " __builtin_ctz " "original" } } int test_bsf(uint a) { return bsf(a); } +// { dg-final { scan-tree-dump " __builtin_ctz(l|ll) " "original" } } int test_bsf(ulong a) { return bsf(a); } -// { dg-final { scan-tree-dump-not " bsr " "original" } } +// { dg-final { scan-tree-dump " __builtin_clz " "original" } } int test_bsr(uint a) { return bsr(a); } +// { dg-final { scan-tree-dump " __builtin_clz(l|ll) " "original" } } int test_bsr(ulong a) { return bsr(a); } -// { dg-final { scan-tree-dump-not " bt " "original" } } +// { dg-final { scan-tree-dump-not " <retval> = bt " "original" } } int test_bt(size_t *a, size_t b) { return bt(a, b); } -// { dg-final { scan-tree-dump-not " btc " "original" } } +// { dg-final { scan-tree-dump-not " <retval> = btc " "original" } } int test_btc(size_t *a, size_t b) { return btc(a, b); } -// { dg-final { scan-tree-dump-not " btr " "original" } } +// { dg-final { scan-tree-dump-not " <retval> = btr " "original" } } int test_btr(size_t *a, size_t b) { return btr(a, b); } -// { dg-final { scan-tree-dump-not " bts " "original" } } +// { dg-final { scan-tree-dump-not " <retval> = bts " "original" } } int test_bts(size_t *a, size_t b) { return bts(a, b); } -// { dg-final { scan-tree-dump-not " bswap " "original" } } +// { dg-final { scan-tree-dump " __builtin_bswap32 " "original" } } uint test_bswap(uint a) { return bswap(a); } +// { dg-final { scan-tree-dump " __builtin_bswap64 " "original" } } ulong test_bswap(ulong a) { return bswap(a); } -// { dg-final { scan-tree-dump-not " popcnt " "original" } } +// { dg-final { scan-tree-dump " __builtin_popcount " "original" } } int test_popcnt(uint a) { return popcnt(a); } +// { dg-final { scan-tree-dump " __builtin_popcount(l|ll) " "original" } } int test_popcnt(ulong a) { return popcnt(a); } -// { dg-final { scan-tree-dump-not " volatileLoad " "original" } } +// { dg-final { scan-tree-dump "\\(volatile ubyte \\*\\) a;" "original" } } ubyte test_volatileLoad(ubyte *a) { return volatileLoad(a); } +// { dg-final { scan-tree-dump "\\(volatile ushort \\*\\) a;" "original" } } ushort test_volatileLoad(ushort *a) { return volatileLoad(a); } +// { dg-final { scan-tree-dump "\\(volatile uint \\*\\) a;" "original" } } uint test_volatileLoad(uint *a) { return volatileLoad(a); } +// { dg-final { scan-tree-dump "\\(volatile ulong \\*\\) a;" "original" } } ulong test_volatileLoad(ulong *a) { return volatileLoad(a); } -// { dg-final { scan-tree-dump-not " volatileStore " "original" } } +// { dg-final { scan-tree-dump "\\(volatile ubyte \\*\\) a = b" "original" } } void test_volatileStore(ubyte *a, ubyte b) { return volatileStore(a, b); } +// { dg-final { scan-tree-dump "\\(volatile ushort \\*\\) a = b" "original" } } void test_volatileStore(ushort *a, ushort b) { return volatileStore(a, b); } +// { dg-final { scan-tree-dump "\\(volatile uint \\*\\) a = b" "original" } } void test_volatileStore(uint *a, uint b) { return volatileStore(a, b); } +// { dg-final { scan-tree-dump "\\(volatile ulong \\*\\) a = b" "original" } } void test_volatileStore(ulong *a, ulong b) { return volatileStore(a, b); } -// { dg-final { scan-tree-dump-not " rol " "original" } } +// { dg-final { scan-tree-dump " a r<< b;" "original" } } ubyte test_rol(ubyte a, uint b) { return rol!ubyte(a, b); } +// { dg-final { scan-tree-dump " a r>> 31;" "original" } } uint test_rol(uint a) { return rol!(1, uint)(a); } -// { dg-final { scan-tree-dump-not " ror " "original" } } +// { dg-final { scan-tree-dump " a r>> b;" "original" } } ushort test_ror(ushort a, uint b) { return ror!ushort(a, b); } +// { dg-final { scan-tree-dump " a r>> 1;" "original" } } ulong test_ror(ulong a) { return ror!(1, ulong)(a); } ////////////////////////////////////////////////////// // core.checkedint -// { dg-final { scan-tree-dump-not " adds " "original" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump-not " <retval> = 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); } @@ -74,50 +86,62 @@ 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" } } +// { dg-final { scan-tree-dump " __builtin_cosf " "original" } } float test_cos(float a) { return cos(a); } +// { dg-final { scan-tree-dump " __builtin_cos " "original" } } double test_cos(double a) { return cos(a); } +// { dg-final { scan-tree-dump " __builtin_cosl " "original" } } real test_cos(real a) { return cos(a); } -// { dg-final { scan-tree-dump-not " sin " "original" } } +// { dg-final { scan-tree-dump " __builtin_sinf " "original" } } float test_sin(float a) { return sin(a); } +// { dg-final { scan-tree-dump " __builtin_sin " "original" } } double test_sin(double a) { return sin(a); } +// { dg-final { scan-tree-dump " __builtin_sinl " "original" } } real test_sin(real a) { return sin(a); } -// { dg-final { scan-tree-dump-not " rndtol " "original" } } +// { dg-final { scan-tree-dump " __builtin_llroundf " "original" } } long test_rndtol(float a) { return rndtol(a); } +// { dg-final { scan-tree-dump " __builtin_llround " "original" } } long test_rndtol(double a) { return rndtol(a); } +// { dg-final { scan-tree-dump " __builtin_llroundl " "original" } } long test_rndtol(real a) { return rndtol(a); } -// { dg-final { scan-tree-dump-not " sqrt " "original" } } +// { dg-final { scan-tree-dump " __builtin_sqrtf " "original" } } float test_sqrt(float a) { return sqrt(a); } +// { dg-final { scan-tree-dump " __builtin_sqrt " "original" } } double test_sqrt(double a) { return sqrt(a); } +// { dg-final { scan-tree-dump " __builtin_sqrtl " "original" } } real test_sqrt(real a) { return sqrt(a); } -// { dg-final { scan-tree-dump-not " ldexp " "original" } } +// { dg-final { scan-tree-dump " __builtin_ldexpf " "original" } } float test_ldexp(float a, int b) { return ldexp(a, b); } +// { dg-final { scan-tree-dump " __builtin_ldexp " "original" } } double test_ldexp(double a, int b) { return ldexp(a, b); } +// { dg-final { scan-tree-dump " __builtin_ldexpl " "original" } } real test_ldexp(real a, int b) { return ldexp(a, b); } -// { dg-final { scan-tree-dump-not " fabs " "original" } } +// { dg-final { scan-tree-dump-not " <retval> = 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" } } +// { dg-final { scan-tree-dump " __builtin_rintf " "original" } } float test_rint(float a) { return rint(a); } +// { dg-final { scan-tree-dump " __builtin_rint " "original" } } double test_rint(double a) { return rint(a); } +// { dg-final { scan-tree-dump " __builtin_rintl " "original" } } 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); } +// { dg-final { scan-tree-dump-not " <retval> = toPrec " "original" } } +float test_toPrecf(float a) { return toPrec!float(a); } +float test_toPrecf(double a) { return toPrec!float(a); } +float test_toPrecf(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); } +real test_toPrecl(float a) { return toPrec!real(a); } +real test_toPrecl(double a) { return toPrec!real(a); } +real test_toPrecl(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); } +void test_va_argc(...) { 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); } |