summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetLibraryInfo.h24
-rw-r--r--lib/Target/TargetLibraryInfo.cpp47
-rw-r--r--test/Transforms/InstCombine/disable-simplify-libcalls.ll99
3 files changed, 170 insertions, 0 deletions
diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h
index a2c97d782e..f1dd1f4bbe 100644
--- a/include/llvm/Target/TargetLibraryInfo.h
+++ b/include/llvm/Target/TargetLibraryInfo.h
@@ -49,6 +49,8 @@ namespace llvm {
cxa_guard_release,
/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
memcpy_chk,
+ /// int abs(int j);
+ abs,
/// double acos(double x);
acos,
/// float acosf(float x);
@@ -153,6 +155,12 @@ namespace llvm {
fabsf,
/// long double fabsl(long double x);
fabsl,
+ /// int ffs(int i);
+ ffs,
+ /// int ffsl(long int i);
+ ffsl,
+ /// int ffsll(long long int i);
+ ffsll,
/// int fiprintf(FILE *stream, const char *format, ...);
fiprintf,
/// double floor(double x);
@@ -167,6 +175,8 @@ namespace llvm {
fmodf,
/// long double fmodl(long double x, long double y);
fmodl,
+ /// int fprintf(FILE *stream, const char *format, ...);
+ fprintf,
/// int fputc(int c, FILE *stream);
fputc,
/// int fputs(const char *s, FILE *stream);
@@ -178,6 +188,14 @@ namespace llvm {
fwrite,
/// int iprintf(const char *format, ...);
iprintf,
+ /// int isascii(int c);
+ isascii,
+ /// int isdigit(int c);
+ isdigit,
+ /// long int labs(long int j);
+ labs,
+ /// long long int llabs(long long int j);
+ llabs,
/// double log(double x);
log,
/// double log10(double x);
@@ -236,6 +254,8 @@ namespace llvm {
powf,
/// long double powl(long double x, long double y);
powl,
+ /// int printf(const char *format, ...);
+ printf,
/// int putchar(int c);
putchar,
/// int puts(const char *s);
@@ -270,6 +290,8 @@ namespace llvm {
sinl,
/// int siprintf(char *str, const char *format, ...);
siprintf,
+ /// int sprintf(char *str, const char *format, ...);
+ sprintf,
/// double sqrt(double x);
sqrt,
/// float sqrtf(float x);
@@ -337,6 +359,8 @@ namespace llvm {
tanhl,
/// long double tanl(long double x);
tanl,
+ /// int toascii(int c);
+ toascii,
/// double trunc(double x);
trunc,
/// float truncf(float x);
diff --git a/lib/Target/TargetLibraryInfo.cpp b/lib/Target/TargetLibraryInfo.cpp
index 6d4eab1204..3a9ace4c52 100644
--- a/lib/Target/TargetLibraryInfo.cpp
+++ b/lib/Target/TargetLibraryInfo.cpp
@@ -39,6 +39,7 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"__cxa_guard_acquire",
"__cxa_guard_release",
"__memcpy_chk",
+ "abs",
"acos",
"acosf",
"acosh",
@@ -91,6 +92,9 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"fabs",
"fabsf",
"fabsl",
+ "ffs",
+ "ffsl",
+ "ffsll",
"fiprintf",
"floor",
"floorf",
@@ -98,11 +102,16 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"fmod",
"fmodf",
"fmodl",
+ "fprintf",
"fputc",
"fputs",
"free",
"fwrite",
"iprintf",
+ "isascii",
+ "isdigit",
+ "labs",
+ "llabs",
"log",
"log10",
"log10f",
@@ -132,6 +141,7 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"pow",
"powf",
"powl",
+ "printf",
"putchar",
"puts",
"realloc",
@@ -149,6 +159,7 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"sinhl",
"sinl",
"siprintf",
+ "sprintf",
"sqrt",
"sqrtf",
"sqrtl",
@@ -182,6 +193,7 @@ const char* TargetLibraryInfo::StandardNames[LibFunc::NumLibFuncs] =
"tanhf",
"tanhl",
"tanl",
+ "toascii",
"trunc",
"truncf",
"truncl",
@@ -327,6 +339,41 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T,
// Win32 does *not* provide stpcpy. It is provided on POSIX systems:
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/stpcpy.html
TLI.setUnavailable(LibFunc::stpcpy);
+
+ // Win32 does *not* provide ffs. It is provided on POSIX systems:
+ // http://pubs.opengroup.org/onlinepubs/009695399/functions/ffs.html
+ TLI.setUnavailable(LibFunc::ffs);
+
+ // Win32 does *not* provide llabs. It is defined in ISO/IEC 9899:1999,
+ // but Visual C++ does not support it.
+ TLI.setUnavailable(LibFunc::llabs);
+ }
+
+ // ffsl is available on at least Darwin, Mac OS X, iOS, FreeBSD, and
+ // Linux (GLIBC):
+ // http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/ffsl.3.html
+ // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsl.c
+ // http://www.gnu.org/software/gnulib/manual/html_node/ffsl.html
+ switch (T.getOS()) {
+ case Triple::Darwin:
+ case Triple::MacOSX:
+ case Triple::IOS:
+ case Triple::FreeBSD:
+ case Triple::Linux:
+ break;
+ default:
+ TLI.setUnavailable(LibFunc::ffsl);
+ }
+
+ // ffsll is available on at least FreeBSD and Linux (GLIBC):
+ // http://svn.freebsd.org/base/user/eri/pf45/head/lib/libc/string/ffsll.c
+ // http://www.gnu.org/software/gnulib/manual/html_node/ffsll.html
+ switch (T.getOS()) {
+ case Triple::FreeBSD:
+ case Triple::Linux:
+ break;
+ default:
+ TLI.setUnavailable(LibFunc::ffsll);
}
}
diff --git a/test/Transforms/InstCombine/disable-simplify-libcalls.ll b/test/Transforms/InstCombine/disable-simplify-libcalls.ll
index d81e9ae5bd..c2c29368b1 100644
--- a/test/Transforms/InstCombine/disable-simplify-libcalls.ll
+++ b/test/Transforms/InstCombine/disable-simplify-libcalls.ll
@@ -37,6 +37,18 @@ declare i64 @strtoll(i8*, i8**, i32)
declare i64 @strtoul(i8*, i8**, i32)
declare i64 @strtoull(i8*, i8**, i32)
declare i64 @strcspn(i8*, i8*)
+declare i32 @abs(i32)
+declare i32 @ffs(i32)
+declare i32 @ffsl(i64)
+declare i32 @ffsll(i64)
+declare i32 @fprintf(i8*, i8*)
+declare i32 @isascii(i32)
+declare i32 @isdigit(i32)
+declare i32 @toascii(i32)
+declare i64 @labs(i64)
+declare i64 @llabs(i64)
+declare i32 @printf(i8*)
+declare i32 @sprintf(i8*, i8*)
define double @t1(double %x) {
; CHECK: @t1
@@ -234,3 +246,90 @@ define i64 @t25(i8* %y) {
ret i64 %ret
; CHECK: call i64 @strcspn
}
+
+define i32 @t26(i32 %y) {
+; CHECK: @t26
+ %ret = call i32 @abs(i32 %y)
+ ret i32 %ret
+; CHECK: call i32 @abs
+}
+
+define i32 @t27(i32 %y) {
+; CHECK: @t27
+ %ret = call i32 @ffs(i32 %y)
+ ret i32 %ret
+; CHECK: call i32 @ffs
+}
+
+define i32 @t28(i64 %y) {
+; CHECK: @t28
+ %ret = call i32 @ffsl(i64 %y)
+ ret i32 %ret
+; CHECK: call i32 @ffsl
+}
+
+define i32 @t29(i64 %y) {
+; CHECK: @t29
+ %ret = call i32 @ffsll(i64 %y)
+ ret i32 %ret
+; CHECK: call i32 @ffsll
+}
+
+define void @t30() {
+; CHECK: @t30
+ %x = getelementptr inbounds [13 x i8]* @.str1, i32 0, i32 0
+ call i32 @fprintf(i8* null, i8* %x)
+ ret void
+; CHECK: call i32 @fprintf
+}
+
+define i32 @t31(i32 %y) {
+; CHECK: @t31
+ %ret = call i32 @isascii(i32 %y)
+ ret i32 %ret
+; CHECK: call i32 @isascii
+}
+
+define i32 @t32(i32 %y) {
+; CHECK: @t32
+ %ret = call i32 @isdigit(i32 %y)
+ ret i32 %ret
+; CHECK: call i32 @isdigit
+}
+
+define i32 @t33(i32 %y) {
+; CHECK: @t33
+ %ret = call i32 @toascii(i32 %y)
+ ret i32 %ret
+; CHECK: call i32 @toascii
+}
+
+define i64 @t34(i64 %y) {
+; CHECK: @t34
+ %ret = call i64 @labs(i64 %y)
+ ret i64 %ret
+; CHECK: call i64 @labs
+}
+
+define i64 @t35(i64 %y) {
+; CHECK: @t35
+ %ret = call i64 @llabs(i64 %y)
+ ret i64 %ret
+; CHECK: call i64 @llabs
+}
+
+define void @t36() {
+; CHECK: @t36
+ %x = getelementptr inbounds [1 x i8]* @empty, i32 0, i32 0
+ call i32 @printf(i8* %x)
+ ret void
+; CHECK: call i32 @printf
+}
+
+define void @t37(i8* %x) {
+; CHECK: @t37
+ %y = getelementptr inbounds [13 x i8]* @.str1, i32 0, i32 0
+ call i32 @sprintf(i8* %x, i8* %y)
+ ret void
+; CHECK: call i32 @sprintf
+}