compiler: use the LLVM builtins everywhere

This gives some more optimization opportunities to LLVM, because it
understands these intrinsics. For example, it might convert
llvm.sqrt.f64 to llvm.sqrt.f32 if possible.
This commit is contained in:
Ayke van Laethem
2022-08-27 18:41:17 +02:00
committed by Ron Evans
parent ef912a132d
commit b8a6a1f62b
8 changed files with 387 additions and 248 deletions
+2
View File
@@ -761,6 +761,7 @@ endif
@cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src @cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src
@@ -779,6 +780,7 @@ endif
@cp -rp lib/picolibc/newlib/libc/string build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libc/string build/release/tinygo/lib/picolibc/newlib/libc
@cp -rp lib/picolibc/newlib/libc/tinystdio build/release/tinygo/lib/picolibc/newlib/libc @cp -rp lib/picolibc/newlib/libc/tinystdio build/release/tinygo/lib/picolibc/newlib/libc
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm @cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib @cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot @cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins @cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
+5 -1
View File
@@ -156,7 +156,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
} }
} }
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") { if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables") if strings.Split(target, "-")[2] == "linux" {
args = append(args, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
} else {
args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
}
} }
if strings.HasPrefix(target, "avr") { if strings.HasPrefix(target, "avr") {
// AVR defaults to C float and double both being 32-bit. This deviates // AVR defaults to C float and double both being 32-bit. This deviates
+1 -1
View File
@@ -78,7 +78,7 @@ func makeMinGWExtraLibs(tmpdir string) []*compileJob {
// .in files need to be preprocessed by a preprocessor (-E) // .in files need to be preprocessed by a preprocessor (-E)
// first. // first.
defpath = outpath + ".def" defpath = outpath + ".def"
err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/") err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-DDATA", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/")
if err != nil { if err != nil {
return err return err
} }
+2
View File
@@ -89,6 +89,7 @@ var Musl = Library{
"-Wno-shift-op-parentheses", "-Wno-shift-op-parentheses",
"-Wno-ignored-attributes", "-Wno-ignored-attributes",
"-Wno-string-plus-int", "-Wno-string-plus-int",
"-Wno-ignored-pragmas",
"-Qunused-arguments", "-Qunused-arguments",
// Select include dirs. Don't include standard library includes // Select include dirs. Don't include standard library includes
// (that would introduce host dependencies and other complications), // (that would introduce host dependencies and other complications),
@@ -117,6 +118,7 @@ var Musl = Library{
"legacy/*.c", "legacy/*.c",
"malloc/*.c", "malloc/*.c",
"mman/*.c", "mman/*.c",
"math/*.c",
"signal/*.c", "signal/*.c",
"stdio/*.c", "stdio/*.c",
"string/*.c", "string/*.c",
+360 -204
View File
@@ -19,7 +19,7 @@ var Picolibc = Library{
return f.Close() return f.Close()
}, },
cflags: func(target, headerPath string) []string { cflags: func(target, headerPath string) []string {
picolibcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc") newlibDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib")
return []string{ return []string{
"-Werror", "-Werror",
"-Wall", "-Wall",
@@ -27,219 +27,375 @@ var Picolibc = Library{
"-D_COMPILING_NEWLIB", "-D_COMPILING_NEWLIB",
"-DHAVE_ALIAS_ATTRIBUTE", "-DHAVE_ALIAS_ATTRIBUTE",
"-DTINY_STDIO", "-DTINY_STDIO",
"-D_IEEE_LIBM",
"-nostdlibinc", "-nostdlibinc",
"-isystem", picolibcDir + "/include", "-isystem", newlibDir + "/libc/include",
"-I" + picolibcDir + "/tinystdio", "-I" + newlibDir + "/libc/tinystdio",
"-I" + newlibDir + "/libm/common",
"-I" + headerPath, "-I" + headerPath,
} }
}, },
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc") }, sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib") },
librarySources: func(target string) []string { librarySources: func(target string) []string {
return picolibcSources return picolibcSources
}, },
} }
var picolibcSources = []string{ var picolibcSources = []string{
"../../../picolibc-stdio.c", "../../picolibc-stdio.c",
"tinystdio/asprintf.c", "libc/tinystdio/asprintf.c",
"tinystdio/atod_engine.c", "libc/tinystdio/atod_engine.c",
"tinystdio/atod_ryu.c", "libc/tinystdio/atod_ryu.c",
"tinystdio/atof_engine.c", "libc/tinystdio/atof_engine.c",
"tinystdio/atof_ryu.c", "libc/tinystdio/atof_ryu.c",
//"tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double //"libc/tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
"tinystdio/clearerr.c", "libc/tinystdio/clearerr.c",
"tinystdio/compare_exchange.c", "libc/tinystdio/compare_exchange.c",
"tinystdio/dtoa_data.c", "libc/tinystdio/dtoa_data.c",
"tinystdio/dtoa_engine.c", "libc/tinystdio/dtoa_engine.c",
"tinystdio/dtoa_ryu.c", "libc/tinystdio/dtoa_ryu.c",
"tinystdio/ecvtbuf.c", "libc/tinystdio/ecvtbuf.c",
"tinystdio/ecvt.c", "libc/tinystdio/ecvt.c",
"tinystdio/ecvt_data.c", "libc/tinystdio/ecvt_data.c",
"tinystdio/ecvtfbuf.c", "libc/tinystdio/ecvtfbuf.c",
"tinystdio/ecvtf.c", "libc/tinystdio/ecvtf.c",
"tinystdio/ecvtf_data.c", "libc/tinystdio/ecvtf_data.c",
"tinystdio/exchange.c", "libc/tinystdio/exchange.c",
//"tinystdio/fclose.c", // posix-io //"libc/tinystdio/fclose.c", // posix-io
"tinystdio/fcvtbuf.c", "libc/tinystdio/fcvtbuf.c",
"tinystdio/fcvt.c", "libc/tinystdio/fcvt.c",
"tinystdio/fcvtfbuf.c", "libc/tinystdio/fcvtfbuf.c",
"tinystdio/fcvtf.c", "libc/tinystdio/fcvtf.c",
"tinystdio/fdevopen.c", "libc/tinystdio/fdevopen.c",
//"tinystdio/fdopen.c", // posix-io //"libc/tinystdio/fdopen.c", // posix-io
"tinystdio/feof.c", "libc/tinystdio/feof.c",
"tinystdio/ferror.c", "libc/tinystdio/ferror.c",
"tinystdio/fflush.c", "libc/tinystdio/fflush.c",
"tinystdio/fgetc.c", "libc/tinystdio/fgetc.c",
"tinystdio/fgets.c", "libc/tinystdio/fgets.c",
"tinystdio/fileno.c", "libc/tinystdio/fileno.c",
"tinystdio/filestrget.c", "libc/tinystdio/filestrget.c",
"tinystdio/filestrputalloc.c", "libc/tinystdio/filestrputalloc.c",
"tinystdio/filestrput.c", "libc/tinystdio/filestrput.c",
//"tinystdio/fopen.c", // posix-io //"libc/tinystdio/fopen.c", // posix-io
"tinystdio/fprintf.c", "libc/tinystdio/fprintf.c",
"tinystdio/fputc.c", "libc/tinystdio/fputc.c",
"tinystdio/fputs.c", "libc/tinystdio/fputs.c",
"tinystdio/fread.c", "libc/tinystdio/fread.c",
"tinystdio/fscanf.c", "libc/tinystdio/fscanf.c",
"tinystdio/fseek.c", "libc/tinystdio/fseek.c",
"tinystdio/ftell.c", "libc/tinystdio/ftell.c",
"tinystdio/ftoa_data.c", "libc/tinystdio/ftoa_data.c",
"tinystdio/ftoa_engine.c", "libc/tinystdio/ftoa_engine.c",
"tinystdio/ftoa_ryu.c", "libc/tinystdio/ftoa_ryu.c",
"tinystdio/fwrite.c", "libc/tinystdio/fwrite.c",
"tinystdio/gcvtbuf.c", "libc/tinystdio/gcvtbuf.c",
"tinystdio/gcvt.c", "libc/tinystdio/gcvt.c",
"tinystdio/gcvtfbuf.c", "libc/tinystdio/gcvtfbuf.c",
"tinystdio/gcvtf.c", "libc/tinystdio/gcvtf.c",
"tinystdio/getchar.c", "libc/tinystdio/getchar.c",
"tinystdio/gets.c", "libc/tinystdio/gets.c",
"tinystdio/matchcaseprefix.c", "libc/tinystdio/matchcaseprefix.c",
"tinystdio/perror.c", "libc/tinystdio/perror.c",
//"tinystdio/posixiob.c", // posix-io //"libc/tinystdio/posixiob.c", // posix-io
//"tinystdio/posixio.c", // posix-io //"libc/tinystdio/posixio.c", // posix-io
"tinystdio/printf.c", "libc/tinystdio/printf.c",
"tinystdio/putchar.c", "libc/tinystdio/putchar.c",
"tinystdio/puts.c", "libc/tinystdio/puts.c",
"tinystdio/ryu_divpow2.c", "libc/tinystdio/ryu_divpow2.c",
"tinystdio/ryu_log10.c", "libc/tinystdio/ryu_log10.c",
"tinystdio/ryu_log2pow5.c", "libc/tinystdio/ryu_log2pow5.c",
"tinystdio/ryu_pow5bits.c", "libc/tinystdio/ryu_pow5bits.c",
"tinystdio/ryu_table.c", "libc/tinystdio/ryu_table.c",
"tinystdio/ryu_umul128.c", "libc/tinystdio/ryu_umul128.c",
"tinystdio/scanf.c", "libc/tinystdio/scanf.c",
"tinystdio/setbuf.c", "libc/tinystdio/setbuf.c",
"tinystdio/setvbuf.c", "libc/tinystdio/setvbuf.c",
//"tinystdio/sflags.c", // posix-io //"libc/tinystdio/sflags.c", // posix-io
"tinystdio/snprintf.c", "libc/tinystdio/snprintf.c",
"tinystdio/snprintfd.c", "libc/tinystdio/snprintfd.c",
"tinystdio/snprintff.c", "libc/tinystdio/snprintff.c",
"tinystdio/sprintf.c", "libc/tinystdio/sprintf.c",
"tinystdio/sprintfd.c", "libc/tinystdio/sprintfd.c",
"tinystdio/sprintff.c", "libc/tinystdio/sprintff.c",
"tinystdio/sscanf.c", "libc/tinystdio/sscanf.c",
"tinystdio/strfromd.c", "libc/tinystdio/strfromd.c",
"tinystdio/strfromf.c", "libc/tinystdio/strfromf.c",
"tinystdio/strtod.c", "libc/tinystdio/strtod.c",
"tinystdio/strtod_l.c", "libc/tinystdio/strtod_l.c",
"tinystdio/strtof.c", "libc/tinystdio/strtof.c",
//"tinystdio/strtold.c", // have_long_double and not long_double_equals_double //"libc/tinystdio/strtold.c", // have_long_double and not long_double_equals_double
//"tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double //"libc/tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double
"tinystdio/ungetc.c", "libc/tinystdio/ungetc.c",
"tinystdio/vasprintf.c", "libc/tinystdio/vasprintf.c",
"tinystdio/vfiprintf.c", "libc/tinystdio/vfiprintf.c",
"tinystdio/vfiscanf.c", "libc/tinystdio/vfiscanf.c",
"tinystdio/vfprintf.c", "libc/tinystdio/vfprintf.c",
"tinystdio/vfprintff.c", "libc/tinystdio/vfprintff.c",
"tinystdio/vfscanf.c", "libc/tinystdio/vfscanf.c",
"tinystdio/vfscanff.c", "libc/tinystdio/vfscanff.c",
"tinystdio/vprintf.c", "libc/tinystdio/vprintf.c",
"tinystdio/vscanf.c", "libc/tinystdio/vscanf.c",
"tinystdio/vsnprintf.c", "libc/tinystdio/vsnprintf.c",
"tinystdio/vsprintf.c", "libc/tinystdio/vsprintf.c",
"tinystdio/vsscanf.c", "libc/tinystdio/vsscanf.c",
"string/bcmp.c", "libc/string/bcmp.c",
"string/bcopy.c", "libc/string/bcopy.c",
"string/bzero.c", "libc/string/bzero.c",
"string/explicit_bzero.c", "libc/string/explicit_bzero.c",
"string/ffsl.c", "libc/string/ffsl.c",
"string/ffsll.c", "libc/string/ffsll.c",
"string/fls.c", "libc/string/fls.c",
"string/flsl.c", "libc/string/flsl.c",
"string/flsll.c", "libc/string/flsll.c",
"string/gnu_basename.c", "libc/string/gnu_basename.c",
"string/index.c", "libc/string/index.c",
"string/memccpy.c", "libc/string/memccpy.c",
"string/memchr.c", "libc/string/memchr.c",
"string/memcmp.c", "libc/string/memcmp.c",
"string/memcpy.c", "libc/string/memcpy.c",
"string/memmem.c", "libc/string/memmem.c",
"string/memmove.c", "libc/string/memmove.c",
"string/mempcpy.c", "libc/string/mempcpy.c",
"string/memrchr.c", "libc/string/memrchr.c",
"string/memset.c", "libc/string/memset.c",
"string/rawmemchr.c", "libc/string/rawmemchr.c",
"string/rindex.c", "libc/string/rindex.c",
"string/stpcpy.c", "libc/string/stpcpy.c",
"string/stpncpy.c", "libc/string/stpncpy.c",
"string/strcasecmp.c", "libc/string/strcasecmp.c",
"string/strcasecmp_l.c", "libc/string/strcasecmp_l.c",
"string/strcasestr.c", "libc/string/strcasestr.c",
"string/strcat.c", "libc/string/strcat.c",
"string/strchr.c", "libc/string/strchr.c",
"string/strchrnul.c", "libc/string/strchrnul.c",
"string/strcmp.c", "libc/string/strcmp.c",
"string/strcoll.c", "libc/string/strcoll.c",
"string/strcoll_l.c", "libc/string/strcoll_l.c",
"string/strcpy.c", "libc/string/strcpy.c",
"string/strcspn.c", "libc/string/strcspn.c",
"string/strdup.c", "libc/string/strdup.c",
"string/strerror.c", "libc/string/strerror.c",
"string/strerror_r.c", "libc/string/strerror_r.c",
"string/strlcat.c", "libc/string/strlcat.c",
"string/strlcpy.c", "libc/string/strlcpy.c",
"string/strlen.c", "libc/string/strlen.c",
"string/strlwr.c", "libc/string/strlwr.c",
"string/strncasecmp.c", "libc/string/strncasecmp.c",
"string/strncasecmp_l.c", "libc/string/strncasecmp_l.c",
"string/strncat.c", "libc/string/strncat.c",
"string/strncmp.c", "libc/string/strncmp.c",
"string/strncpy.c", "libc/string/strncpy.c",
"string/strndup.c", "libc/string/strndup.c",
"string/strnlen.c", "libc/string/strnlen.c",
"string/strnstr.c", "libc/string/strnstr.c",
"string/strpbrk.c", "libc/string/strpbrk.c",
"string/strrchr.c", "libc/string/strrchr.c",
"string/strsep.c", "libc/string/strsep.c",
"string/strsignal.c", "libc/string/strsignal.c",
"string/strspn.c", "libc/string/strspn.c",
"string/strstr.c", "libc/string/strstr.c",
"string/strtok.c", "libc/string/strtok.c",
"string/strtok_r.c", "libc/string/strtok_r.c",
"string/strupr.c", "libc/string/strupr.c",
"string/strverscmp.c", "libc/string/strverscmp.c",
"string/strxfrm.c", "libc/string/strxfrm.c",
"string/strxfrm_l.c", "libc/string/strxfrm_l.c",
"string/swab.c", "libc/string/swab.c",
"string/timingsafe_bcmp.c", "libc/string/timingsafe_bcmp.c",
"string/timingsafe_memcmp.c", "libc/string/timingsafe_memcmp.c",
"string/u_strerr.c", "libc/string/u_strerr.c",
"string/wcpcpy.c", "libc/string/wcpcpy.c",
"string/wcpncpy.c", "libc/string/wcpncpy.c",
"string/wcscasecmp.c", "libc/string/wcscasecmp.c",
"string/wcscasecmp_l.c", "libc/string/wcscasecmp_l.c",
"string/wcscat.c", "libc/string/wcscat.c",
"string/wcschr.c", "libc/string/wcschr.c",
"string/wcscmp.c", "libc/string/wcscmp.c",
"string/wcscoll.c", "libc/string/wcscoll.c",
"string/wcscoll_l.c", "libc/string/wcscoll_l.c",
"string/wcscpy.c", "libc/string/wcscpy.c",
"string/wcscspn.c", "libc/string/wcscspn.c",
"string/wcsdup.c", "libc/string/wcsdup.c",
"string/wcslcat.c", "libc/string/wcslcat.c",
"string/wcslcpy.c", "libc/string/wcslcpy.c",
"string/wcslen.c", "libc/string/wcslen.c",
"string/wcsncasecmp.c", "libc/string/wcsncasecmp.c",
"string/wcsncasecmp_l.c", "libc/string/wcsncasecmp_l.c",
"string/wcsncat.c", "libc/string/wcsncat.c",
"string/wcsncmp.c", "libc/string/wcsncmp.c",
"string/wcsncpy.c", "libc/string/wcsncpy.c",
"string/wcsnlen.c", "libc/string/wcsnlen.c",
"string/wcspbrk.c", "libc/string/wcspbrk.c",
"string/wcsrchr.c", "libc/string/wcsrchr.c",
"string/wcsspn.c", "libc/string/wcsspn.c",
"string/wcsstr.c", "libc/string/wcsstr.c",
"string/wcstok.c", "libc/string/wcstok.c",
"string/wcswidth.c", "libc/string/wcswidth.c",
"string/wcsxfrm.c", "libc/string/wcsxfrm.c",
"string/wcsxfrm_l.c", "libc/string/wcsxfrm_l.c",
"string/wcwidth.c", "libc/string/wcwidth.c",
"string/wmemchr.c", "libc/string/wmemchr.c",
"string/wmemcmp.c", "libc/string/wmemcmp.c",
"string/wmemcpy.c", "libc/string/wmemcpy.c",
"string/wmemmove.c", "libc/string/wmemmove.c",
"string/wmempcpy.c", "libc/string/wmempcpy.c",
"string/wmemset.c", "libc/string/wmemset.c",
"string/xpg_strerror_r.c", "libc/string/xpg_strerror_r.c",
"libm/common/sf_finite.c",
"libm/common/sf_copysign.c",
"libm/common/sf_modf.c",
"libm/common/sf_scalbn.c",
"libm/common/sf_cbrt.c",
"libm/common/sf_exp10.c",
"libm/common/sf_expm1.c",
"libm/common/sf_ilogb.c",
"libm/common/sf_infinity.c",
"libm/common/sf_isinf.c",
"libm/common/sf_isinff.c",
"libm/common/sf_isnan.c",
"libm/common/sf_isnanf.c",
"libm/common/sf_issignaling.c",
"libm/common/sf_log1p.c",
"libm/common/sf_nan.c",
"libm/common/sf_nextafter.c",
"libm/common/sf_pow10.c",
"libm/common/sf_rint.c",
"libm/common/sf_logb.c",
"libm/common/sf_fdim.c",
"libm/common/sf_fma.c",
"libm/common/sf_fmax.c",
"libm/common/sf_fmin.c",
"libm/common/sf_fpclassify.c",
"libm/common/sf_lrint.c",
"libm/common/sf_llrint.c",
"libm/common/sf_lround.c",
"libm/common/sf_llround.c",
"libm/common/sf_nearbyint.c",
"libm/common/sf_remquo.c",
"libm/common/sf_round.c",
"libm/common/sf_scalbln.c",
"libm/common/sf_trunc.c",
"libm/common/sf_exp.c",
"libm/common/sf_exp2.c",
"libm/common/sf_exp2_data.c",
"libm/common/sf_log.c",
"libm/common/sf_log_data.c",
"libm/common/sf_log2.c",
"libm/common/sf_log2_data.c",
"libm/common/sf_pow_log2_data.c",
"libm/common/sf_pow.c",
"libm/common/s_finite.c",
"libm/common/s_copysign.c",
"libm/common/s_modf.c",
"libm/common/s_scalbn.c",
"libm/common/s_cbrt.c",
"libm/common/s_exp10.c",
"libm/common/s_expm1.c",
"libm/common/s_ilogb.c",
"libm/common/s_infinity.c",
"libm/common/s_isinf.c",
"libm/common/s_isinfd.c",
"libm/common/s_isnan.c",
"libm/common/s_isnand.c",
"libm/common/s_issignaling.c",
"libm/common/s_log1p.c",
"libm/common/s_nan.c",
"libm/common/s_nextafter.c",
"libm/common/s_pow10.c",
"libm/common/s_rint.c",
"libm/common/s_logb.c",
"libm/common/s_log2.c",
"libm/common/s_fdim.c",
"libm/common/s_fma.c",
"libm/common/s_fmax.c",
"libm/common/s_fmin.c",
"libm/common/s_fpclassify.c",
"libm/common/s_lrint.c",
"libm/common/s_llrint.c",
"libm/common/s_lround.c",
"libm/common/s_llround.c",
"libm/common/s_nearbyint.c",
"libm/common/s_remquo.c",
"libm/common/s_round.c",
"libm/common/s_scalbln.c",
"libm/common/s_signbit.c",
"libm/common/s_trunc.c",
"libm/math/e_acos.c",
"libm/math/e_acosh.c",
"libm/math/e_asin.c",
"libm/math/e_atan2.c",
"libm/math/e_atanh.c",
"libm/math/e_cosh.c",
"libm/math/e_exp.c",
"libm/math/ef_acos.c",
"libm/math/ef_acosh.c",
"libm/math/ef_asin.c",
"libm/math/ef_atan2.c",
"libm/math/ef_atanh.c",
"libm/math/ef_cosh.c",
"libm/math/ef_exp.c",
"libm/math/ef_fmod.c",
"libm/math/ef_hypot.c",
"libm/math/ef_j0.c",
"libm/math/ef_j1.c",
"libm/math/ef_jn.c",
"libm/math/ef_lgamma.c",
"libm/math/ef_log10.c",
"libm/math/ef_log.c",
"libm/math/e_fmod.c",
"libm/math/ef_pow.c",
"libm/math/ef_remainder.c",
"libm/math/ef_rem_pio2.c",
"libm/math/ef_scalb.c",
"libm/math/ef_sinh.c",
"libm/math/ef_sqrt.c",
"libm/math/ef_tgamma.c",
"libm/math/e_hypot.c",
"libm/math/e_j0.c",
"libm/math/e_j1.c",
"libm/math/e_jn.c",
"libm/math/e_lgamma.c",
"libm/math/e_log10.c",
"libm/math/e_log.c",
"libm/math/e_pow.c",
"libm/math/e_remainder.c",
"libm/math/e_rem_pio2.c",
"libm/math/erf_lgamma.c",
"libm/math/er_lgamma.c",
"libm/math/e_scalb.c",
"libm/math/e_sinh.c",
"libm/math/e_sqrt.c",
"libm/math/e_tgamma.c",
"libm/math/s_asinh.c",
"libm/math/s_atan.c",
"libm/math/s_ceil.c",
"libm/math/s_cos.c",
"libm/math/s_erf.c",
"libm/math/s_fabs.c",
"libm/math/sf_asinh.c",
"libm/math/sf_atan.c",
"libm/math/sf_ceil.c",
"libm/math/sf_cos.c",
"libm/math/sf_erf.c",
"libm/math/sf_fabs.c",
"libm/math/sf_floor.c",
"libm/math/sf_frexp.c",
"libm/math/sf_ldexp.c",
"libm/math/s_floor.c",
"libm/math/s_frexp.c",
"libm/math/sf_signif.c",
"libm/math/sf_sin.c",
"libm/math/sf_tan.c",
"libm/math/sf_tanh.c",
"libm/math/s_ldexp.c",
"libm/math/s_signif.c",
"libm/math/s_sin.c",
"libm/math/s_tan.c",
"libm/math/s_tanh.c",
} }
+1 -4
View File
@@ -1657,10 +1657,7 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
name := fn.RelString(nil) name := fn.RelString(nil)
switch { switch {
case name == "math.Ceil" || name == "math.Floor" || name == "math.Sqrt" || name == "math.Trunc": case name == "math.Ceil" || name == "math.Floor" || name == "math.Sqrt" || name == "math.Trunc":
result, ok := b.createMathOp(instr) return b.createMathOp(instr), nil
if ok {
return result, nil
}
case name == "device.Asm" || name == "device/arm.Asm" || name == "device/arm64.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm": case name == "device.Asm" || name == "device/arm.Asm" || name == "device/arm64.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
return b.createInlineAsm(instr.Args) return b.createInlineAsm(instr.Args)
case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull": case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
+9 -33
View File
@@ -88,49 +88,25 @@ var mathToLLVMMapping = map[string]string{
"math.Trunc": "llvm.trunc.f64", "math.Trunc": "llvm.trunc.f64",
} }
// createMathOp tries to lower the given call as a LLVM math intrinsic, if // createMathOp lowers the given call as a LLVM math intrinsic. It returns the
// possible. It returns the call result if possible, and a boolean whether it // resulting value.
// succeeded. If it doesn't succeed, the architecture doesn't support the given func (b *builder) createMathOp(call *ssa.CallCommon) llvm.Value {
// intrinsic. llvmName := mathToLLVMMapping[call.StaticCallee().RelString(nil)]
func (b *builder) createMathOp(call *ssa.CallCommon) (llvm.Value, bool) { if llvmName == "" {
// Check whether this intrinsic is supported on the given GOARCH. panic("unreachable: unknown math operation") // sanity check
// If it is unsupported, this can have two reasons:
//
// 1. LLVM can expand the intrinsic inline (using float instructions), but
// the result doesn't pass the tests of the math package.
// 2. LLVM cannot expand the intrinsic inline, will therefore lower it as a
// libm function call, but the libm function call also fails the math
// package tests.
//
// Whatever the implementation, it must pass the tests in the math package
// so unfortunately only the below intrinsic+architecture combinations are
// supported.
name := call.StaticCallee().RelString(nil)
switch name {
case "math.Ceil", "math.Floor", "math.Trunc":
if b.GOARCH != "wasm" && b.GOARCH != "arm64" {
return llvm.Value{}, false
}
case "math.Sqrt":
if b.GOARCH != "wasm" && b.GOARCH != "amd64" && b.GOARCH != "386" {
return llvm.Value{}, false
}
default:
return llvm.Value{}, false // only the above functions are supported.
} }
llvmFn := b.mod.NamedFunction(llvmName)
llvmFn := b.mod.NamedFunction(mathToLLVMMapping[name])
if llvmFn.IsNil() { if llvmFn.IsNil() {
// The intrinsic doesn't exist yet, so declare it. // The intrinsic doesn't exist yet, so declare it.
// At the moment, all supported intrinsics have the form "double // At the moment, all supported intrinsics have the form "double
// foo(double %x)" so we can hardcode the signature here. // foo(double %x)" so we can hardcode the signature here.
llvmType := llvm.FunctionType(b.ctx.DoubleType(), []llvm.Type{b.ctx.DoubleType()}, false) llvmType := llvm.FunctionType(b.ctx.DoubleType(), []llvm.Type{b.ctx.DoubleType()}, false)
llvmFn = llvm.AddFunction(b.mod, mathToLLVMMapping[name], llvmType) llvmFn = llvm.AddFunction(b.mod, llvmName, llvmType)
} }
// Create a call to the intrinsic. // Create a call to the intrinsic.
args := make([]llvm.Value, len(call.Args)) args := make([]llvm.Value, len(call.Args))
for i, arg := range call.Args { for i, arg := range call.Args {
args[i] = b.getValue(arg) args[i] = b.getValue(arg)
} }
return b.CreateCall(llvmFn, args, ""), true return b.CreateCall(llvmFn, args, "")
} }
+7 -5
View File
@@ -14,21 +14,23 @@ entry:
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 { define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 {
entry: entry:
%0 = call double @math.Sqrt(double %x, i8* undef) #2 %0 = call double @llvm.sqrt.f64(double %x)
ret double %0 ret double %0
} }
declare double @math.Sqrt(double, i8*) #0 ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare double @llvm.sqrt.f64(double) #2
; Function Attrs: nounwind ; Function Attrs: nounwind
define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 { define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 {
entry: entry:
%0 = call double @math.Trunc(double %x, i8* undef) #2 %0 = call double @llvm.trunc.f64(double %x)
ret double %0 ret double %0
} }
declare double @math.Trunc(double, i8*) #0 ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare double @llvm.trunc.f64(double) #2
attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" } attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
attributes #2 = { nounwind } attributes #2 = { nofree nosync nounwind readnone speculatable willreturn }