Add SwiftShader dump from Feb 6 2013
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2005-05-20-sprintf-crash.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2005-05-20-sprintf-crash.ll new file mode 100644 index 0000000..9d57167 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2005-05-20-sprintf-crash.ll
@@ -0,0 +1,11 @@ +; RUN: opt < %s -simplify-libcalls -disable-output + +@G = constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1] + +declare i32 @sprintf(i8*, i8*, ...) + +define void @foo(i8* %P, i32* %X) { + call i32 (i8*, i8*, ...)* @sprintf( i8* %P, i8* getelementptr ([3 x i8]* @G, i32 0, i32 0), i32* %X ) ; <i32>:1 [#uses=0] + ret void +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2007-04-06-strchr-miscompile.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2007-04-06-strchr-miscompile.ll new file mode 100644 index 0000000..81de2dd --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2007-04-06-strchr-miscompile.ll
@@ -0,0 +1,29 @@ +; PR1307 +; RUN: opt < %s -simplify-libcalls -instcombine -S > %t +; RUN: grep {@str,.*i64 3} %t +; RUN: grep {@str1,.*i64 7} %t +; RUN: grep {ret i8.*null} %t +; END. + +@str = internal constant [5 x i8] c"foog\00" +@str1 = internal constant [8 x i8] c"blahhh!\00" +@str2 = internal constant [5 x i8] c"Ponk\00" + +define i8* @test1() { + %tmp3 = tail call i8* @strchr( i8* getelementptr ([5 x i8]* @str, i32 0, i32 2), i32 103 ) ; <i8*> [#uses=1] + ret i8* %tmp3 +} + +declare i8* @strchr(i8*, i32) + +define i8* @test2() { + %tmp3 = tail call i8* @strchr( i8* getelementptr ([8 x i8]* @str1, i32 0, i32 2), i32 0 ) ; <i8*> [#uses=1] + ret i8* %tmp3 +} + +define i8* @test3() { +entry: + %tmp3 = tail call i8* @strchr( i8* getelementptr ([5 x i8]* @str2, i32 0, i32 1), i32 80 ) ; <i8*> [#uses=1] + ret i8* %tmp3 +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2008-05-19-memcmp.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2008-05-19-memcmp.ll new file mode 100644 index 0000000..b687432 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2008-05-19-memcmp.ll
@@ -0,0 +1,14 @@ +; RUN: opt < %s -simplify-libcalls -S | grep i32 +; PR2341 + +@_2E_str = external constant [5 x i8] ; <[5 x i8]*> [#uses=1] + +declare i32 @memcmp(i8*, i8*, i32) nounwind readonly + +define i1 @f(i8** %start_addr) { +entry: + %tmp4 = load i8** %start_addr, align 4 ; <i8*> [#uses=1] + %tmp5 = call i32 @memcmp( i8* %tmp4, i8* getelementptr ([5 x i8]* @_2E_str, i32 0, i32 0), i32 4 ) nounwind readonly ; <i32> [#uses=1] + %tmp6 = icmp eq i32 %tmp5, 0 ; <i1> [#uses=1] + ret i1 %tmp6 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2009-01-04-Annotate.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-01-04-Annotate.ll new file mode 100644 index 0000000..73eb05b --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-01-04-Annotate.ll
@@ -0,0 +1,12 @@ +; RUN: opt < %s -simplify-libcalls -S > %t +; RUN: grep noalias %t | count 2 +; RUN: grep nocapture %t | count 3 +; RUN: grep nounwind %t | count 3 +; RUN: grep readonly %t | count 1 + +declare i8* @fopen(i8*, i8*) +declare i8 @strlen(i8*) +declare i32* @realloc(i32*, i32) + +; Test deliberately wrong declaration +declare i32 @strcpy(...)
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2009-02-11-NotInitialized.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-02-11-NotInitialized.ll new file mode 100644 index 0000000..ac89199 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-02-11-NotInitialized.ll
@@ -0,0 +1,13 @@ +; RUN: opt < %s -inline -simplify-libcalls -functionattrs | \ +; RUN: llvm-dis | grep nocapture | count 2 +; Check that nocapture attributes are added when run after an SCC pass. +; PR3520 + +define i32 @use(i8* %x) nounwind readonly { +entry: + %0 = tail call i64 @strlen(i8* %x) nounwind readonly ; <i64> [#uses=1] + %1 = trunc i64 %0 to i32 ; <i32> [#uses=1] + ret i32 %1 +} + +declare i64 @strlen(i8*) nounwind readonly
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2009-02-12-StrTo.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-02-12-StrTo.ll new file mode 100644 index 0000000..f8a0c88 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-02-12-StrTo.ll
@@ -0,0 +1,14 @@ +; RUN: opt < %s -simplify-libcalls -S > %t +; RUN: grep nocapture %t | count 2 +; RUN: grep null %t | grep nocapture | count 1 +; RUN: grep null %t | grep call | not grep readonly + +; Test that we add nocapture to the declaration, and to the second call only. + +declare float @strtol(i8* %s, i8** %endptr, i32 %base) + +define void @foo(i8* %x, i8** %endptr) { + call float @strtol(i8* %x, i8** %endptr, i32 10) + call float @strtol(i8* %x, i8** null, i32 10) + ret void +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2009-05-30-memcmp-byte.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-05-30-memcmp-byte.ll new file mode 100644 index 0000000..9056499 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-05-30-memcmp-byte.ll
@@ -0,0 +1,14 @@ +; RUN: opt < %s -simplify-libcalls -instcombine -S | grep {ret i32 -65} +; PR4284 + +define i32 @test() nounwind { +entry: + %c0 = alloca i8, align 1 ; <i8*> [#uses=2] + %c2 = alloca i8, align 1 ; <i8*> [#uses=2] + store i8 64, i8* %c0 + store i8 -127, i8* %c2 + %call = call i32 @memcmp(i8* %c0, i8* %c2, i32 1) ; <i32> [#uses=1] + ret i32 %call +} + +declare i32 @memcmp(i8*, i8*, i32)
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2009-07-28-Exit.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-07-28-Exit.ll new file mode 100644 index 0000000..7af0a26 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-07-28-Exit.ll
@@ -0,0 +1,22 @@ +; RUN: opt < %s -simplify-libcalls -disable-output +; PR4641 + + %struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, i8*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64, %struct.pthread_mutex*, %struct.pthread*, i32, i32, %union.anon } + %struct.__sbuf = type { i8*, i32, [4 x i8] } + %struct.pthread = type opaque + %struct.pthread_mutex = type opaque + %union.anon = type { i64, [120 x i8] } +@.str13 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] +@.str14 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + call void @exit(i32 0) nounwind + %cond392 = select i1 undef, i8* getelementptr ([2 x i8]* @.str13, i32 0, i32 0), i8* getelementptr ([2 x i8]* @.str14, i32 0, i32 0) ; <i8*> [#uses=1] + %call393 = call %struct.__sFILE* @fopen(i8* undef, i8* %cond392) nounwind ; <%struct.__sFILE*> [#uses=0] + unreachable +} + +declare %struct.__sFILE* @fopen(i8*, i8*) + +declare void @exit(i32)
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2009-07-29-Exit2.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-07-29-Exit2.ll new file mode 100644 index 0000000..b5a788e --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2009-07-29-Exit2.ll
@@ -0,0 +1,24 @@ +; RUN: opt < %s -simplify-libcalls -disable-output +; PR4645 + +define i32 @main() { +entry: + br label %if.then + +lor.lhs.false: ; preds = %while.body + br i1 undef, label %if.then, label %for.cond + +if.then: ; preds = %lor.lhs.false, %while.body + call void @exit(i32 1) + br label %for.cond + +for.cond: ; preds = %for.end, %if.then, %lor.lhs.false + %j.0 = phi i32 [ %inc47, %for.end ], [ 0, %if.then ], [ 0, %lor.lhs.false ] ; <i32> [#uses=1] + unreachable + +for.end: ; preds = %for.cond20 + %inc47 = add i32 %j.0, 1 ; <i32> [#uses=1] + br label %for.cond +} + +declare void @exit(i32)
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/2010-05-30-memcpy-Struct.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/2010-05-30-memcpy-Struct.ll new file mode 100644 index 0000000..f67bae7 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/2010-05-30-memcpy-Struct.ll
@@ -0,0 +1,20 @@ +; RUN: opt -simplify-libcalls %s -S -o - | FileCheck %s +; PR7265 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +%union.anon = type { i32, [4 x i8] } + +@.str = private constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=2] + +define void @CopyEventArg(%union.anon* %ev) nounwind { +entry: + %call = call i32 (i8*, i8*, ...)* @sprintf(i8* undef, i8* getelementptr inbounds ([3 x i8]* @.str, i64 0, i64 0), %union.anon* %ev) nounwind ; <i32> [#uses=0] +; CHECK: bitcast %union.anon* %ev to i8* +; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + ret void +} + +declare i32 @sprintf(i8*, i8*, ...) +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/FFS.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/FFS.ll new file mode 100644 index 0000000..2e1dbe9 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/FFS.ll
@@ -0,0 +1,36 @@ +; Test that the ToAsciiOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*@ffs} + +@non_const = external global i32 ; <i32*> [#uses=1] + +declare i32 @ffs(i32) + +declare i32 @ffsl(i32) + +declare i32 @ffsll(i64) + +define i32 @main() { + %arg = load i32* @non_const ; <i32> [#uses=1] + %val0 = call i32 @ffs( i32 %arg ) ; <i32> [#uses=1] + %val1 = call i32 @ffs( i32 1 ) ; <i32> [#uses=1] + %val2 = call i32 @ffs( i32 2048 ) ; <i32> [#uses=1] + %val3 = call i32 @ffsl( i32 65536 ) ; <i32> [#uses=1] + %val4 = call i32 @ffsll( i64 1024 ) ; <i32> [#uses=1] + %val5 = call i32 @ffsll( i64 17179869184 ) ; <i32> [#uses=1] + %val6 = call i32 @ffsll( i64 1152921504606846976 ) ; <i32> [#uses=1] + %rslt1 = add i32 %val1, %val2 ; <i32> [#uses=1] + %rslt2 = add i32 %val3, %val4 ; <i32> [#uses=1] + %rslt3 = add i32 %val5, %val6 ; <i32> [#uses=1] + %rslt4 = add i32 %rslt1, %rslt2 ; <i32> [#uses=1] + %rslt5 = add i32 %rslt4, %rslt3 ; <i32> [#uses=2] + %rslt6 = add i32 %rslt5, %val0 ; <i32> [#uses=0] + ret i32 %rslt5 +} + + +; PR4206 +define i32 @a(i64) nounwind { + %2 = call i32 @ffsll(i64 %0) ; <i32> [#uses=1] + ret i32 %2 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/FPrintF.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/FPrintF.ll new file mode 100644 index 0000000..81a2f3e --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/FPrintF.ll
@@ -0,0 +1,28 @@ +; Test that the FPrintFOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*fprintf} + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + + %struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i32, [52 x i8] } + %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 } +@str = constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1] +@chr = constant [3 x i8] c"%c\00" ; <[3 x i8]*> [#uses=1] +@hello = constant [13 x i8] c"hello world\0A\00" ; <[13 x i8]*> [#uses=1] +@stdout = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=3] + +declare i32 @fprintf(%struct._IO_FILE*, i8*, ...) + +define i32 @foo() { +entry: + %tmp.1 = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1] + %tmp.0 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf( %struct._IO_FILE* %tmp.1, i8* getelementptr ([13 x i8]* @hello, i32 0, i32 0) ) ; <i32> [#uses=0] + %tmp.4 = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1] + %tmp.3 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf( %struct._IO_FILE* %tmp.4, i8* getelementptr ([3 x i8]* @str, i32 0, i32 0), i8* getelementptr ([13 x i8]* @hello, i32 0, i32 0) ) ; <i32> [#uses=0] + %tmp.8 = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1] + %tmp.7 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf( %struct._IO_FILE* %tmp.8, i8* getelementptr ([3 x i8]* @chr, i32 0, i32 0), i32 33 ) ; <i32> [#uses=0] + ret i32 0 +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/FPuts.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/FPuts.ll new file mode 100644 index 0000000..25a984d --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/FPuts.ll
@@ -0,0 +1,29 @@ +; Test that the FPutsOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*fputs} + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + + %struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i32, [52 x i8] } + %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 } +@stdout = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=1] +@empty = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@len1 = constant [2 x i8] c"A\00" ; <[2 x i8]*> [#uses=1] +@long = constant [7 x i8] c"hello\0A\00" ; <[7 x i8]*> [#uses=1] + +declare i32 @fputs(i8*, %struct._IO_FILE*) + +define i32 @main() { +entry: + %out = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=3] + %s1 = getelementptr [1 x i8]* @empty, i32 0, i32 0 ; <i8*> [#uses=1] + %s2 = getelementptr [2 x i8]* @len1, i32 0, i32 0 ; <i8*> [#uses=1] + %s3 = getelementptr [7 x i8]* @long, i32 0, i32 0 ; <i8*> [#uses=1] + %a = call i32 @fputs( i8* %s1, %struct._IO_FILE* %out ) ; <i32> [#uses=0] + %b = call i32 @fputs( i8* %s2, %struct._IO_FILE* %out ) ; <i32> [#uses=0] + %c = call i32 @fputs( i8* %s3, %struct._IO_FILE* %out ) ; <i32> [#uses=0] + ret i32 0 +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/IsDigit.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/IsDigit.ll new file mode 100644 index 0000000..dedae3c --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/IsDigit.ll
@@ -0,0 +1,21 @@ +; Test that the IsDigitOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep call + +declare i32 @isdigit(i32) + +declare i32 @isascii(i32) + +define i32 @main() { + %val1 = call i32 @isdigit( i32 47 ) ; <i32> [#uses=1] + %val2 = call i32 @isdigit( i32 48 ) ; <i32> [#uses=1] + %val3 = call i32 @isdigit( i32 57 ) ; <i32> [#uses=1] + %val4 = call i32 @isdigit( i32 58 ) ; <i32> [#uses=1] + %rslt1 = add i32 %val1, %val2 ; <i32> [#uses=1] + %rslt2 = add i32 %val3, %val4 ; <i32> [#uses=1] + %sum = add i32 %rslt1, %rslt2 ; <i32> [#uses=1] + %rslt = call i32 @isdigit( i32 %sum ) ; <i32> [#uses=1] + %tmp = call i32 @isascii( i32 %rslt ) ; <i32> [#uses=1] + ret i32 %tmp +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/MemCpy.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/MemCpy.ll new file mode 100644 index 0000000..4c5d90f --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/MemCpy.ll
@@ -0,0 +1,19 @@ +; RUN: opt < %s -constprop -instcombine -S | not grep {call.*llvm.memcpy.i32} + +@h = constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=1] +@hel = constant [4 x i8] c"hel\00" ; <[4 x i8]*> [#uses=1] +@hello_u = constant [8 x i8] c"hello_u\00" ; <[8 x i8]*> [#uses=1] + +define i32 @main() { + %h_p = getelementptr [2 x i8]* @h, i32 0, i32 0 + %hel_p = getelementptr [4 x i8]* @hel, i32 0, i32 0 + %hello_u_p = getelementptr [8 x i8]* @hello_u, i32 0, i32 0 + %target = alloca [1024 x i8] + %target_p = getelementptr [1024 x i8]* %target, i32 0, i32 0 + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %target_p, i8* %h_p, i32 2, i32 2, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %target_p, i8* %hel_p, i32 4, i32 4, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %target_p, i8* %hello_u_p, i32 8, i32 8, i1 false) + ret i32 0 +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/PR7357.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/PR7357.ll new file mode 100644 index 0000000..6d5c1d5 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/PR7357.ll
@@ -0,0 +1,16 @@ +; RUN: opt < %s -default-data-layout="e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32" -simplify-libcalls -S | FileCheck %s +@.str1 = private constant [11 x i8] c"(){};[]&|:\00", align 4 + +; check that simplify libcalls will not replace a call with one calling +; convention with a new call with a different calling convention. + +; CHECK: define arm_aapcscc i32 @foo(i32 %argc) +; CHECK: call arm_aapcscc i8* @strchr +define arm_aapcscc i32 @foo(i32 %argc) nounwind { +bb.nph: + call arm_aapcscc i8* @strchr(i8* getelementptr ([11 x i8]* @.str1, i32 0, +i32 0), i32 %argc) nounwind readonly + ret i32 0 +} + +declare arm_aapcscc i8* @strchr(i8*, i32) nounwind readonly
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/Printf.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/Printf.ll new file mode 100644 index 0000000..544ad8d --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/Printf.ll
@@ -0,0 +1,36 @@ +; RUN: opt < %s -simplify-libcalls -S -o %t +; RUN: FileCheck < %t %s + +@str = internal constant [13 x i8] c"hello world\0A\00" ; <[13 x i8]*> [#uses=1] +@str1 = internal constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=1] + +declare i32 @printf(i8*, ...) + +; CHECK: define void @f0 +; CHECK-NOT: printf +; CHECK: } +define void @f0() { +entry: + %tmp1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([13 x i8]* @str, i32 0, i32 0) ) ; <i32> [#uses=0] + ret void +} + +; CHECK: define void @f1 +; CHECK-NOT: printf +; CHECK: } +define void @f1() { +entry: + %tmp1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([2 x i8]* @str1, i32 0, i32 0) ) ; <i32> [#uses=0] + ret void +} + +; Verify that we don't turn this into a putchar call (thus changing the return +; value). +; +; CHECK: define i32 @f2 +; CHECK: printf +; CHECK: } +define i32 @f2() { + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([2 x i8]* @str1, i32 0, i32 0)) + ret i32 %call +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/Puts.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/Puts.ll new file mode 100644 index 0000000..4843143 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/Puts.ll
@@ -0,0 +1,15 @@ +; Test that the PutsOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "-p:64:64:64" + +@.str = private constant [1 x i8] zeroinitializer + +declare i32 @puts(i8*) + +define void @foo() { +entry: +; CHECK: call i32 @putchar(i32 10) + %call = call i32 @puts(i8* getelementptr inbounds ([1 x i8]* @.str, i32 0, i32 0)) + ret void +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/SPrintF.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/SPrintF.ll new file mode 100644 index 0000000..7b74915 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/SPrintF.ll
@@ -0,0 +1,40 @@ +; Test that the SPrintFOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*sprintf} + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@null_hello = constant [7 x i8] c"\00hello\00" ; <[7 x i8]*> [#uses=1] +@fmt1 = constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1] +@fmt2 = constant [3 x i8] c"%c\00" ; <[3 x i8]*> [#uses=1] + +declare i32 @sprintf(i8*, i8*, ...) + +declare i32 @puts(i8*) + +define i32 @foo(i8* %p) { + %target = alloca [1024 x i8] ; <[1024 x i8]*> [#uses=1] + %target_p = getelementptr [1024 x i8]* %target, i32 0, i32 0 ; <i8*> [#uses=7] + %hello_p = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=2] + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %nh_p = getelementptr [7 x i8]* @null_hello, i32 0, i32 0 ; <i8*> [#uses=1] + %fmt1_p = getelementptr [3 x i8]* @fmt1, i32 0, i32 0 ; <i8*> [#uses=2] + %fmt2_p = getelementptr [3 x i8]* @fmt2, i32 0, i32 0 ; <i8*> [#uses=1] + store i8 0, i8* %target_p + %r1 = call i32 (i8*, i8*, ...)* @sprintf( i8* %target_p, i8* %hello_p ) ; <i32> [#uses=1] + %r2 = call i32 (i8*, i8*, ...)* @sprintf( i8* %target_p, i8* %null_p ) ; <i32> [#uses=1] + %r3 = call i32 (i8*, i8*, ...)* @sprintf( i8* %target_p, i8* %nh_p ) ; <i32> [#uses=1] + %r4 = call i32 (i8*, i8*, ...)* @sprintf( i8* %target_p, i8* %fmt1_p, i8* %hello_p ) ; <i32> [#uses=1] + %r4.1 = call i32 (i8*, i8*, ...)* @sprintf( i8* %target_p, i8* %fmt1_p, i8* %p ) ; <i32> [#uses=1] + %r5 = call i32 (i8*, i8*, ...)* @sprintf( i8* %target_p, i8* %fmt2_p, i32 82 ) ; <i32> [#uses=1] + %r6 = add i32 %r1, %r2 ; <i32> [#uses=1] + %r7 = add i32 %r3, %r6 ; <i32> [#uses=1] + %r8 = add i32 %r5, %r7 ; <i32> [#uses=1] + %r9 = add i32 %r8, %r4 ; <i32> [#uses=1] + %r10 = add i32 %r9, %r4.1 ; <i32> [#uses=1] + ret i32 %r10 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrCat.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrCat.ll new file mode 100644 index 0000000..1e904ee --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrCat.ll
@@ -0,0 +1,33 @@ +; Test that the StrCatOptimizer works correctly +; PR3661 +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*strcat} +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: grep {puts.*%arg1} + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@null_hello = constant [7 x i8] c"\00hello\00" ; <[7 x i8]*> [#uses=1] + +declare i8* @strcat(i8*, i8*) + +declare i32 @puts(i8*) + +define i32 @main() { + %target = alloca [1024 x i8] ; <[1024 x i8]*> [#uses=1] + %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0 ; <i8*> [#uses=2] + store i8 0, i8* %arg1 + %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt1 = call i8* @strcat( i8* %arg1, i8* %arg2 ) ; <i8*> [#uses=1] + %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt2 = call i8* @strcat( i8* %rslt1, i8* %arg3 ) ; <i8*> [#uses=1] + %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt3 = call i8* @strcat( i8* %rslt2, i8* %arg4 ) ; <i8*> [#uses=1] + call i32 @puts( i8* %rslt3 ) ; <i32>:1 [#uses=0] + ret i32 0 +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrChr.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrChr.ll new file mode 100644 index 0000000..661654b --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrChr.ll
@@ -0,0 +1,26 @@ +; Test that the StrChrOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + +@hello = constant [14 x i8] c"hello world\5Cn\00" +@null = constant [1 x i8] zeroinitializer + +declare i8* @strchr(i8*, i32) + +define i32 @foo(i32 %index) { + %hello_p = getelementptr [14 x i8]* @hello, i32 0, i32 0 + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 + %world = call i8* @strchr(i8* %hello_p, i32 119) +; CHECK: getelementptr i8* %hello_p, i64 6 + %ignore = call i8* @strchr(i8* %null_p, i32 119) +; CHECK-NOT: call i8* strchr + %null = call i8* @strchr(i8* %hello_p, i32 0) +; CHECK: getelementptr i8* %hello_p, i64 13 + %result = call i8* @strchr(i8* %hello_p, i32 %index) +; CHECK: call i8* @memchr(i8* %hello_p, i32 %index, i64 14) + ret i32 %index +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrCmp.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrCmp.ll new file mode 100644 index 0000000..965b0ca --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrCmp.ll
@@ -0,0 +1,65 @@ +; Test that the StrCmpOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" + +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] +@hell = constant [5 x i8] c"hell\00" ; <[5 x i8]*> [#uses=1] +@bell = constant [5 x i8] c"bell\00" ; <[5 x i8]*> [#uses=1] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] + +declare i32 @strcmp(i8*, i8*) + +; strcmp("", x) -> -*x +define i32 @test1(i8* %str) { + %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i8* %str) + ret i32 %temp1 + ; CHECK: @test1 + ; CHECK: %strcmpload = load i8* %str + ; CHECK: %1 = zext i8 %strcmpload to i32 + ; CHECK: %temp1 = sub i32 0, %1 + ; CHECK: ret i32 %temp1 +} + +; strcmp(x, "") -> *x +define i32 @test2(i8* %str) { + %temp1 = call i32 @strcmp(i8* %str, i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0)) + ret i32 %temp1 + ; CHECK: @test2 + ; CHECK: %strcmpload = load i8* %str + ; CHECK: %temp1 = zext i8 %strcmpload to i32 + ; CHECK: ret i32 %temp1 +} + +; strcmp(x, y) -> cnst +define i32 @test3() { + %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0)) + ret i32 %temp1 + ; CHECK: @test3 + ; CHECK: ret i32 -1 +} +define i32 @test4() { + %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0)) + ret i32 %temp1 + ; CHECK: @test4 + ; CHECK: ret i32 1 +} + +; strcmp(x, y) -> memcmp(x, y, <known length>) +; (This transform is rather difficult to trigger in a useful manner) +define i32 @test5(i1 %b) { + %sel = select i1 %b, i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8]* @bell, i32 0, i32 0) + %temp1 = call i32 @strcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %sel) + ret i32 %temp1 + ; CHECK: @test5 + ; CHECK: %memcmp = call i32 @memcmp(i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i8* %sel, i32 5) + ; CHECK: ret i32 %memcmp +} + +; strcmp(x,x) -> 0 +define i32 @test6(i8* %str) { + %temp1 = call i32 @strcmp(i8* %str, i8* %str) + ret i32 %temp1 + ; CHECK: @test6 + ; CHECK: ret i32 0 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrCpy.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrCpy.ll new file mode 100644 index 0000000..8d34377 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrCpy.ll
@@ -0,0 +1,37 @@ +; Test that the StrCpyOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" + +@hello = constant [6 x i8] c"hello\00" + +declare i8* @strcpy(i8*, i8*) + +declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind + +declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly + +; rdar://6839935 + +define i32 @t1() { +; CHECK: @t1 + %target = alloca [1024 x i8] + %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0 + %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0 + %rslt1 = call i8* @strcpy( i8* %arg1, i8* %arg2 ) +; CHECK: @llvm.memcpy.p0i8.p0i8.i32 + ret i32 0 +} + +define i32 @t2() { +; CHECK: @t2 + %target = alloca [1024 x i8] + %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0 + %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0 + %tmp1 = call i32 @llvm.objectsize.i32(i8* %arg1, i1 false) + %rslt1 = call i8* @__strcpy_chk(i8* %arg1, i8* %arg2, i32 %tmp1) +; CHECK: @__memcpy_chk + ret i32 0 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrLen.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrLen.ll new file mode 100644 index 0000000..1ea64b4 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrLen.ll
@@ -0,0 +1,56 @@ +; Test that the StrCatOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*strlen} + +target datalayout = "e-p:32:32" +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=3] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=3] +@null_hello = constant [7 x i8] c"\00hello\00" ; <[7 x i8]*> [#uses=1] + +declare i32 @strlen(i8*) + +define i32 @test1() { + %hello_p = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=1] + %hello_l = call i32 @strlen( i8* %hello_p ) ; <i32> [#uses=1] + ret i32 %hello_l +} + +define i32 @test2() { + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %null_l = call i32 @strlen( i8* %null_p ) ; <i32> [#uses=1] + ret i32 %null_l +} + +define i32 @test3() { + %null_hello_p = getelementptr [7 x i8]* @null_hello, i32 0, i32 0 ; <i8*> [#uses=1] + %null_hello_l = call i32 @strlen( i8* %null_hello_p ) ; <i32> [#uses=1] + ret i32 %null_hello_l +} + +define i1 @test4() { + %hello_p = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=1] + %hello_l = call i32 @strlen( i8* %hello_p ) ; <i32> [#uses=1] + %eq_hello = icmp eq i32 %hello_l, 0 ; <i1> [#uses=1] + ret i1 %eq_hello +} + +define i1 @test5() { + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %null_l = call i32 @strlen( i8* %null_p ) ; <i32> [#uses=1] + %eq_null = icmp eq i32 %null_l, 0 ; <i1> [#uses=1] + ret i1 %eq_null +} + +define i1 @test6() { + %hello_p = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=1] + %hello_l = call i32 @strlen( i8* %hello_p ) ; <i32> [#uses=1] + %ne_hello = icmp ne i32 %hello_l, 0 ; <i1> [#uses=1] + ret i1 %ne_hello +} + +define i1 @test7() { + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %null_l = call i32 @strlen( i8* %null_p ) ; <i32> [#uses=1] + %ne_null = icmp ne i32 %null_l, 0 ; <i1> [#uses=1] + ret i1 %ne_null +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCat.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCat.ll new file mode 100644 index 0000000..d09c022 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCat.ll
@@ -0,0 +1,31 @@ +; Test that the StrNCatOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*strncat} +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: grep {puts.*%arg1} + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@null_hello = constant [7 x i8] c"\00hello\00" ; <[7 x i8]*> [#uses=1] + +declare i8* @strncat(i8*, i8*, i32) + +declare i32 @puts(i8*) + +define i32 @main() { + %target = alloca [1024 x i8] ; <[1024 x i8]*> [#uses=1] + %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0 ; <i8*> [#uses=2] + store i8 0, i8* %arg1 + %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt1 = call i8* @strncat( i8* %arg1, i8* %arg2, i32 6 ) ; <i8*> [#uses=1] + %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt2 = call i8* @strncat( i8* %rslt1, i8* %arg3, i32 42 ) ; <i8*> [#uses=1] + %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt3 = call i8* @strncat( i8* %rslt2, i8* %arg4, i32 42 ) ; <i8*> [#uses=1] + call i32 @puts( i8* %rslt3 ) ; <i32>:1 [#uses=0] + ret i32 0 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCmp.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCmp.ll new file mode 100644 index 0000000..f8a29f8 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCmp.ll
@@ -0,0 +1,78 @@ +; Test that the StrCmpOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" + +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] +@hell = constant [5 x i8] c"hell\00" ; <[5 x i8]*> [#uses=1] +@bell = constant [5 x i8] c"bell\00" ; <[5 x i8]*> [#uses=1] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] + +declare i32 @strncmp(i8*, i8*, i32) + +; strcmp("", x) -> -*x +define i32 @test1(i8* %str) { + %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i8* %str, i32 10) + ret i32 %temp1 + ; CHECK: @test1 + ; CHECK: %strcmpload = load i8* %str + ; CHECK: %1 = zext i8 %strcmpload to i32 + ; CHECK: %temp1 = sub i32 0, %1 + ; CHECK: ret i32 %temp1 +} + +; strcmp(x, "") -> *x +define i32 @test2(i8* %str) { + %temp1 = call i32 @strncmp(i8* %str, i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i32 10) + ret i32 %temp1 + ; CHECK: @test2 + ; CHECK: %strcmpload = load i8* %str + ; CHECK: %temp1 = zext i8 %strcmpload to i32 + ; CHECK: ret i32 %temp1 +} + +; strncmp(x, y, n) -> cnst +define i32 @test3() { + %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i32 10) + ret i32 %temp1 + ; CHECK: @test3 + ; CHECK: ret i32 -1 +} +define i32 @test4() { + %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @null, i32 0, i32 0), i32 10) + ret i32 %temp1 + ; CHECK: @test4 + ; CHECK: ret i32 1 +} +define i32 @test5() { + %temp1 = call i32 @strncmp(i8* getelementptr inbounds ([5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8]* @hello, i32 0, i32 0), i32 4) + ret i32 %temp1 + ; CHECK: @test5 + ; CHECK: ret i32 0 +} + +; strncmp(x,y,1) -> memcmp(x,y,1) +define i32 @test6(i8* %str1, i8* %str2) { + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1) + ret i32 %temp1 + ; CHECK: @test6 + ; CHECK: load i8* + ; CHECK: load i8* + ; CHECK: sub i32 +} + +; strncmp(x,y,0) -> 0 +define i32 @test7(i8* %str1, i8* %str2) { + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 0) + ret i32 %temp1 + ; CHECK: @test7 + ; CHECK: ret i32 0 +} + +; strncmp(x,x,n) -> 0 +define i32 @test8(i8* %str, i32 %n) { + %temp1 = call i32 @strncmp(i8* %str, i8* %str, i32 %n) + ret i32 %temp1 + ; CHECK: @test8 + ; CHECK: ret i32 0 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCpy.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCpy.ll new file mode 100644 index 0000000..c8af3ca --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrNCpy.ll
@@ -0,0 +1,29 @@ +; Test that the StrNCpyOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*strncpy} + +; This transformation requires the pointer size, as it assumes that size_t is +; the size of a pointer. +target datalayout = "-p:64:64:64" + +@hello = constant [6 x i8] c"hello\00" ; <[6 x i8]*> [#uses=1] +@null = constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@null_hello = constant [7 x i8] c"\00hello\00" ; <[7 x i8]*> [#uses=1] + +declare i8* @strncpy(i8*, i8*, i32) + +declare i32 @puts(i8*) + +define i32 @main() { + %target = alloca [1024 x i8] ; <[1024 x i8]*> [#uses=1] + %arg1 = getelementptr [1024 x i8]* %target, i32 0, i32 0 ; <i8*> [#uses=2] + store i8 0, i8* %arg1 + %arg2 = getelementptr [6 x i8]* @hello, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt1 = call i8* @strncpy( i8* %arg1, i8* %arg2, i32 6 ) ; <i8*> [#uses=1] + %arg3 = getelementptr [1 x i8]* @null, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt2 = call i8* @strncpy( i8* %rslt1, i8* %arg3, i32 42 ) ; <i8*> [#uses=1] + %arg4 = getelementptr [7 x i8]* @null_hello, i32 0, i32 0 ; <i8*> [#uses=1] + %rslt3 = call i8* @strncpy( i8* %rslt2, i8* %arg4, i32 42 ) ; <i8*> [#uses=1] + call i32 @puts( i8* %rslt3 ) ; <i32>:1 [#uses=0] + ret i32 0 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrPBrk.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrPBrk.ll new file mode 100644 index 0000000..29c3b74 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrPBrk.ll
@@ -0,0 +1,25 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "-p:64:64:64" + +@hello = constant [12 x i8] c"hello world\00" +@w = constant [2 x i8] c"w\00" +@null = constant [1 x i8] zeroinitializer + +declare i8* @strpbrk(i8*, i8*) + +define void @test(i8* %s1, i8* %s2) { + %hello_p = getelementptr [12 x i8]* @hello, i32 0, i32 0 + %w_p = getelementptr [2 x i8]* @w, i32 0, i32 0 + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 + %test1 = call i8* @strpbrk(i8* %null_p, i8* %s2) + %test2 = call i8* @strpbrk(i8* %s1, i8* %null_p) +; CHECK-NOT: call i8* @strpbrk + %test3 = call i8* @strpbrk(i8* %s1, i8* %w_p) +; CHECK: call i8* @strchr(i8* %s1, i32 119) + %test4 = call i8* @strpbrk(i8* %hello_p, i8* %w_p) +; CHECK: getelementptr i8* %hello_p, i64 6 + %test5 = call i8* @strpbrk(i8* %s1, i8* %s2) +; CHECK: call i8* @strpbrk(i8* %s1, i8* %s2) + ret void +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrRChr.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrRChr.ll new file mode 100644 index 0000000..2259fc0 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrRChr.ll
@@ -0,0 +1,23 @@ +; Test that the StrRChrOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "-p:64:64:64" + +@hello = constant [14 x i8] c"hello world\5Cn\00" +@null = constant [1 x i8] zeroinitializer + +declare i8* @strrchr(i8*, i32) + +define void @foo(i8* %bar) { + %hello_p = getelementptr [14 x i8]* @hello, i32 0, i32 0 + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 + %world = call i8* @strrchr(i8* %hello_p, i32 119) +; CHECK: getelementptr i8* %hello_p, i64 6 + %ignore = call i8* @strrchr(i8* %null_p, i32 119) +; CHECK-NOT: call i8* strrchr + %null = call i8* @strrchr(i8* %hello_p, i32 0) +; CHECK: getelementptr i8* %hello_p, i64 13 + %strchr = call i8* @strrchr(i8* %bar, i32 0) +; CHECK: call i8* @strchr(i8* %bar, i32 0) + ret void +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrSpn.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrSpn.ll new file mode 100644 index 0000000..800c190 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrSpn.ll
@@ -0,0 +1,41 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +target datalayout = "-p:64:64:64" + +@abcba = constant [6 x i8] c"abcba\00" +@abc = constant [4 x i8] c"abc\00" +@null = constant [1 x i8] zeroinitializer + +declare i64 @strspn(i8*, i8*) + +define i64 @testspn(i8* %s1, i8* %s2) { + %abcba_p = getelementptr [6 x i8]* @abcba, i32 0, i32 0 + %abc_p = getelementptr [4 x i8]* @abc, i32 0, i32 0 + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 + %test1 = call i64 @strspn(i8* %s1, i8* %null_p) + %test2 = call i64 @strspn(i8* %null_p, i8* %s2) + %test3 = call i64 @strspn(i8* %abcba_p, i8* %abc_p) +; CHECK-NOT: call i64 @strspn + %test4 = call i64 @strspn(i8* %s1, i8* %s2) +; CHECK: call i64 @strspn(i8* %s1, i8* %s2) + ret i64 %test3 +; CHECK: ret i64 5 +} + +declare i64 @strcspn(i8*, i8*) + +define i64 @testcspn(i8* %s1, i8* %s2) { + %abcba_p = getelementptr [6 x i8]* @abcba, i32 0, i32 0 + %abc_p = getelementptr [4 x i8]* @abc, i32 0, i32 0 + %null_p = getelementptr [1 x i8]* @null, i32 0, i32 0 + %test1 = call i64 @strcspn(i8* %s1, i8* %null_p) +; CHECK: call i64 @strlen(i8* %s1) + %test2 = call i64 @strcspn(i8* %null_p, i8* %s2) + %test3 = call i64 @strcspn(i8* %abcba_p, i8* %abc_p) +; CHECK-NOT: call i64 @strcspn + %test4 = call i64 @strcspn(i8* %s1, i8* %s2) +; CHECK: call i64 @strcspn(i8* %s1, i8* %s2) + %add0 = add i64 %test1, %test3 +; CHECK: add i64 %{{.+}}, 0 + ret i64 %add0 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/StrStr.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/StrStr.ll new file mode 100644 index 0000000..eefd2e8 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/StrStr.ll
@@ -0,0 +1,60 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s +; PR5783 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin9.0" + +@.str = private constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@.str1 = private constant [2 x i8] c"a\00" ; <[2 x i8]*> [#uses=1] +@.str2 = private constant [6 x i8] c"abcde\00" ; <[6 x i8]*> [#uses=1] +@.str3 = private constant [4 x i8] c"bcd\00" ; <[4 x i8]*> [#uses=1] + +define i8* @test1(i8* %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* getelementptr inbounds ([1 x i8]* @.str, i32 0, i32 0)) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr(P, "") -> P +; CHECK: @test1 +; CHECK: ret i8* %P +} + +declare i8* @strstr(i8*, i8* nocapture) nounwind readonly + +define i8* @test2(i8* %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0)) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr(P, "a") -> strchr(P, 'a') +; CHECK: @test2 +; CHECK: @strchr(i8* %P, i32 97) +} + +define i8* @test3(i8* nocapture %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* getelementptr inbounds ([6 x i8]* @.str2, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8]* @.str3, i32 0, i32 0)) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr("abcde", "bcd") -> "abcde"+1 +; CHECK: @test3 +; CHECK: getelementptr inbounds ([6 x i8]* @.str2, i32 0, i64 1) +} + +define i8* @test4(i8* %P) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* %P) nounwind ; <i8*> [#uses=1] + ret i8* %call +; strstr(P, P) -> P +; CHECK: @test4 +; CHECK: ret i8* %P +} + +define i1 @test5(i8* %P, i8* %Q) nounwind readonly { +entry: + %call = tail call i8* @strstr(i8* %P, i8* %Q) nounwind ; <i8*> [#uses=1] + %cmp = icmp eq i8* %call, %P + ret i1 %cmp +; CHECK: @test5 +; CHECK: [[LEN:%[a-z]+]] = call {{i[0-9]+}} @strlen(i8* %Q) +; CHECK: [[NCMP:%[a-z]+]] = call {{i[0-9]+}} @strncmp(i8* %P, i8* %Q, {{i[0-9]+}} [[LEN]]) +; CHECK: icmp eq {{i[0-9]+}} [[NCMP]], 0 +; CHECK: ret i1 +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/ToAscii.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/ToAscii.ll new file mode 100644 index 0000000..79182f8 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/ToAscii.ll
@@ -0,0 +1,21 @@ +; Test that the ToAsciiOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | \ +; RUN: not grep {call.*toascii} + +declare i32 @toascii(i32) + +define i32 @main() { + %val1 = call i32 @toascii( i32 1 ) ; <i32> [#uses=1] + %val2 = call i32 @toascii( i32 0 ) ; <i32> [#uses=1] + %val3 = call i32 @toascii( i32 127 ) ; <i32> [#uses=1] + %val4 = call i32 @toascii( i32 128 ) ; <i32> [#uses=1] + %val5 = call i32 @toascii( i32 255 ) ; <i32> [#uses=1] + %val6 = call i32 @toascii( i32 256 ) ; <i32> [#uses=1] + %rslt1 = add i32 %val1, %val2 ; <i32> [#uses=1] + %rslt2 = add i32 %val3, %val4 ; <i32> [#uses=1] + %rslt3 = add i32 %val5, %val6 ; <i32> [#uses=1] + %rslt4 = add i32 %rslt1, %rslt2 ; <i32> [#uses=1] + %rslt5 = add i32 %rslt4, %rslt3 ; <i32> [#uses=1] + ret i32 %rslt5 +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/abs.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/abs.ll new file mode 100644 index 0000000..6fbe0b9 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/abs.ll
@@ -0,0 +1,11 @@ +; RUN: opt < %s -simplify-libcalls -S | grep {select i1 %ispos} +; PR2337 + +define i32 @test(i32 %x) { +entry: + %call = call i32 @abs( i32 %x ) ; <i32> [#uses=1] + ret i32 %call +} + +declare i32 @abs(i32) +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/debug-line.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/debug-line.ll new file mode 100644 index 0000000..b668e4b --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/debug-line.ll
@@ -0,0 +1,24 @@ +; RUN: opt -simplify-libcalls -S < %s | FileCheck %s + + +@.str = private constant [3 x i8] c"%c\00" + +define void @foo() nounwind ssp { +;CHECK: call i32 @putchar{{.+}} !dbg + %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32 97), !dbg !5 + ret void, !dbg !7 +} + +declare i32 @printf(i8*, ...) + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, void ()* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"m.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"m.c", metadata !"/private/tmp", metadata !"clang", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 5, i32 2, metadata !6, null} +!6 = metadata !{i32 589835, metadata !0, i32 4, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!7 = metadata !{i32 6, i32 1, metadata !6, null} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/dg.exp b/src/LLVM/test/Transforms/SimplifyLibCalls/dg.exp new file mode 100644 index 0000000..f2e8f3b --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/dg.exp
@@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/exp2.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/exp2.ll new file mode 100644 index 0000000..2f5d910 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/exp2.ll
@@ -0,0 +1,38 @@ +; RUN: opt < %s -simplify-libcalls -S | grep {call.*ldexp} | count 4 +; rdar://5852514 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin8" + +define double @t1(i32 %x) nounwind { +entry: + %tmp12 = sitofp i32 %x to double ; <double> [#uses=1] + %exp2 = tail call double @exp2( double %tmp12 ) ; <double> [#uses=1] + ret double %exp2 +} + +define float @t4(i8 zeroext %x) nounwind { +entry: + %tmp12 = uitofp i8 %x to float ; <float> [#uses=1] + %tmp3 = tail call float @exp2f( float %tmp12 ) nounwind readonly ; <float> [#uses=1] + ret float %tmp3 +} + +declare float @exp2f(float) nounwind readonly + +define double @t3(i16 zeroext %x) nounwind { +entry: + %tmp12 = uitofp i16 %x to double ; <double> [#uses=1] + %exp2 = tail call double @exp2( double %tmp12 ) ; <double> [#uses=1] + ret double %exp2 +} + +define double @t2(i16 signext %x) nounwind { +entry: + %tmp12 = sitofp i16 %x to double ; <double> [#uses=1] + %exp2 = tail call double @exp2( double %tmp12 ) ; <double> [#uses=1] + ret double %exp2 +} + +declare double @exp2(double) +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/floor.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/floor.ll new file mode 100644 index 0000000..2aa8025 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/floor.ll
@@ -0,0 +1,41 @@ +; RUN: opt < %s -simplify-libcalls -S > %t +; RUN: not grep {call.*floor(} %t +; RUN: grep {call.*floorf(} %t +; RUN: not grep {call.*ceil(} %t +; RUN: grep {call.*ceilf(} %t +; RUN: not grep {call.*nearbyint(} %t +; RUN: grep {call.*nearbyintf(} %t +; XFAIL: sparc + +declare double @floor(double) + +declare double @ceil(double) + +declare double @nearbyint(double) + +define float @test_floor(float %C) { + %D = fpext float %C to double ; <double> [#uses=1] + ; --> floorf + %E = call double @floor( double %D ) ; <double> [#uses=1] + %F = fptrunc double %E to float ; <float> [#uses=1] + ret float %F +} + +define float @test_ceil(float %C) { + %D = fpext float %C to double ; <double> [#uses=1] + ; --> ceilf + %E = call double @ceil( double %D ) ; <double> [#uses=1] + %F = fptrunc double %E to float ; <float> [#uses=1] + ret float %F +} + +; PR8466 +; XFAIL: win32 +define float @test_nearbyint(float %C) { + %D = fpext float %C to double ; <double> [#uses=1] + ; --> nearbyintf + %E = call double @nearbyint( double %D ) ; <double> [#uses=1] + %F = fptrunc double %E to float ; <float> [#uses=1] + ret float %F +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/iprintf.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/iprintf.ll new file mode 100644 index 0000000..7f036fe --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/iprintf.ll
@@ -0,0 +1,71 @@ +; RUN: opt < %s -simplify-libcalls -S -o %t +; RUN: FileCheck < %t %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32" +target triple = "xcore-xmos-elf" + +@.str = internal constant [4 x i8] c"%f\0A\00" ; <[4 x i8]*> [#uses=1] +@.str1 = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + +; Verify printf with no floating point arguments is transformed to iprintf +define i32 @f0(i32 %x) nounwind { +entry: +; CHECK: define i32 @f0 +; CHECK: @iprintf +; CHECK: } + %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) ; <i32> [#uses=0] + ret i32 %0 +} + +; Verify we don't turn this into an iprintf call +define void @f1(double %x) nounwind { +entry: +; CHECK: define void @f1 +; CHECK: @printf +; CHECK: } + %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) nounwind ; <i32> [#uses=0] + ret void +} + +; Verify sprintf with no floating point arguments is transformed to siprintf +define i32 @f2(i8* %p, i32 %x) nounwind { +entry: +; CHECK: define i32 @f2 +; CHECK: @siprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @sprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) + ret i32 %0 +} + +; Verify we don't turn this into an siprintf call +define i32 @f3(i8* %p, double %x) nounwind { +entry: +; CHECK: define i32 @f3 +; CHECK: @sprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @sprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) + ret i32 %0 +} + +; Verify fprintf with no floating point arguments is transformed to fiprintf +define i32 @f4(i8* %p, i32 %x) nounwind { +entry: +; CHECK: define i32 @f4 +; CHECK: @fiprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @fprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) + ret i32 %0 +} + +; Verify we don't turn this into an fiprintf call +define i32 @f5(i8* %p, double %x) nounwind { +entry: +; CHECK: define i32 @f5 +; CHECK: @fprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @fprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) + ret i32 %0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind +declare i32 @sprintf(i8* nocapture, i8* nocapture, ...) nounwind +declare i32 @fprintf(i8* nocapture, i8* nocapture, ...) nounwind
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/memcmp.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/memcmp.ll new file mode 100644 index 0000000..ce1622c --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/memcmp.ll
@@ -0,0 +1,35 @@ +; Test that the memcmpOptimizer works correctly +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s + +@h = constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=0] +@hel = constant [4 x i8] c"hel\00" ; <[4 x i8]*> [#uses=0] +@hello_u = constant [8 x i8] c"hello_u\00" ; <[8 x i8]*> [#uses=0] + +declare i32 @memcmp(i8*, i8*, i32) + +define void @test(i8* %P, i8* %Q, i32 %N, i32* %IP, i1* %BP) { + %A = call i32 @memcmp( i8* %P, i8* %P, i32 %N ) ; <i32> [#uses=1] +; CHECK-NOT: call {{.*}} memcmp +; CHECK: store volatile + store volatile i32 %A, i32* %IP + %B = call i32 @memcmp( i8* %P, i8* %Q, i32 0 ) ; <i32> [#uses=1] +; CHECK-NOT: call {{.*}} memcmp +; CHECK: store volatile + store volatile i32 %B, i32* %IP + %C = call i32 @memcmp( i8* %P, i8* %Q, i32 1 ) ; <i32> [#uses=1] +; CHECK: load +; CHECK: zext +; CHECK: load +; CHECK: zext +; CHECK: sub +; CHECK: store volatile + store volatile i32 %C, i32* %IP + %F = call i32 @memcmp(i8* getelementptr ([4 x i8]* @hel, i32 0, i32 0), + i8* getelementptr ([8 x i8]* @hello_u, i32 0, i32 0), + i32 3) +; CHECK-NOT: call {{.*}} memcmp +; CHECK: store volatile + store volatile i32 %F, i32* %IP + ret void +} +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/memmove.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/memmove.ll new file mode 100644 index 0000000..c0c0050 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/memmove.ll
@@ -0,0 +1,12 @@ +; RUN: opt < %s -simplify-libcalls -S | grep {llvm.memmove} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define i8* @test(i8* %a, i8* %b, i32 %x) { +entry: + %call = call i8* @memmove(i8* %a, i8* %b, i32 %x ) + ret i8* %call +} + +declare i8* @memmove(i8*,i8*,i32) +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/memset-64.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/memset-64.ll new file mode 100644 index 0000000..fb752c4 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/memset-64.ll
@@ -0,0 +1,12 @@ +; RUN: opt < %s -simplify-libcalls -S | grep {llvm.memset} +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-pc-linux-gnu" + +define void @a(i8* %x) nounwind { +entry: + %call = call i8* @memset(i8* %x, i32 1, i64 100) ; <i8*> [#uses=0] + ret void +} + +declare i8* @memset(i8*, i32, i64) +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/memset.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/memset.ll new file mode 100644 index 0000000..0aede06 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/memset.ll
@@ -0,0 +1,12 @@ +; RUN: opt < %s -simplify-libcalls -S | grep {llvm.memset} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define i8* @test(i8* %a, i32 %b, i32 %x) { +entry: + %call = call i8* @memset(i8* %a, i32 %b, i32 %x ) + ret i8* %call +} + +declare i8* @memset(i8*,i32,i32) +
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll new file mode 100644 index 0000000..0480fdd --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll
@@ -0,0 +1,33 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s +; rdar://7251832 + +; SimplifyLibcalls should optimize pow(x, 0.5) to sqrt plus code to handle +; special cases. The readonly attribute on the call should be preserved. + +; CHECK: define float @foo(float %x) nounwind { +; CHECK: %sqrtf = call float @sqrtf(float %x) nounwind readonly +; CHECK: %fabsf = call float @fabsf(float %sqrtf) nounwind readonly +; CHECK: %1 = fcmp oeq float %x, 0xFFF0000000000000 +; CHECK: %retval = select i1 %1, float 0x7FF0000000000000, float %fabsf +; CHECK: ret float %retval + +define float @foo(float %x) nounwind { + %retval = call float @powf(float %x, float 0.5) + ret float %retval +} + +; CHECK: define double @doo(double %x) nounwind { +; CHECK: %sqrt = call double @sqrt(double %x) nounwind readonly +; CHECK: %fabs = call double @fabs(double %sqrt) nounwind readonly +; CHECK: %1 = fcmp oeq double %x, 0xFFF0000000000000 +; CHECK: %retval = select i1 %1, double 0x7FF0000000000000, double %fabs +; CHECK: ret double %retval +; CHECK: } + +define double @doo(double %x) nounwind { + %retval = call double @pow(double %x, double 0.5) + ret double %retval +} + +declare float @powf(float, float) nounwind readonly +declare double @pow(double, double) nounwind readonly
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/pow2.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/pow2.ll new file mode 100644 index 0000000..f04156c --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/pow2.ll
@@ -0,0 +1,37 @@ +; Testcase for calls to the standard C "pow" function +; +; RUN: opt < %s -simplify-libcalls -S | not grep {call .pow} + + +declare double @pow(double, double) +declare float @powf(float, float) + +define double @test1(double %X) { + %Y = call double @pow( double %X, double 0.000000e+00 ) ; <double> [#uses=1] + ret double %Y +} + +define double @test2(double %X) { + %Y = call double @pow( double %X, double -0.000000e+00 ) ; <double> [#uses=1] + ret double %Y +} + +define double @test3(double %X) { + %Y = call double @pow( double 1.000000e+00, double %X ) ; <double> [#uses=1] + ret double %Y +} + +define double @test4(double %X) { + %Y = call double @pow( double %X, double 2.0) + ret double %Y +} + +define float @test4f(float %X) { + %Y = call float @powf( float %X, float 2.0) + ret float %Y +} + +define float @test5f(float %X) { + %Y = call float @powf(float 2.0, float %X) ;; exp2 + ret float %Y +}
diff --git a/src/LLVM/test/Transforms/SimplifyLibCalls/weak-symbols.ll b/src/LLVM/test/Transforms/SimplifyLibCalls/weak-symbols.ll new file mode 100644 index 0000000..5875b21 --- /dev/null +++ b/src/LLVM/test/Transforms/SimplifyLibCalls/weak-symbols.ll
@@ -0,0 +1,26 @@ +; RUN: opt < %s -simplify-libcalls -S | FileCheck %s +; PR4738 + +; SimplifyLibcalls shouldn't assume anything about weak symbols. + +@real_init = weak_odr constant [2 x i8] c"y\00" +@fake_init = weak constant [2 x i8] c"y\00" +@.str = private constant [2 x i8] c"y\00" + +; CHECK: define i32 @foo +; CHECK: call i32 @strcmp +define i32 @foo() nounwind { +entry: + %t0 = call i32 @strcmp(i8* getelementptr inbounds ([2 x i8]* @fake_init, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8]* @.str, i64 0, i64 0)) nounwind readonly + ret i32 %t0 +} + +; CHECK: define i32 @bar +; CHECK: ret i32 0 +define i32 @bar() nounwind { +entry: + %t0 = call i32 @strcmp(i8* getelementptr inbounds ([2 x i8]* @real_init, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8]* @.str, i64 0, i64 0)) nounwind readonly + ret i32 %t0 +} + +declare i32 @strcmp(i8*, i8*) nounwind readonly