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.
Этот коммит содержится в:
Ayke van Laethem 2022-08-27 18:41:17 +02:00 коммит произвёл Ron Evans
родитель ef912a132d
коммит b8a6a1f62b
8 изменённых файлов: 387 добавлений и 248 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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, "")
} }

12
compiler/testdata/intrinsics-cortex-m-qemu.ll предоставленный
Просмотреть файл

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