summaryrefslogtreecommitdiffstats
path: root/test/Transforms/Inline
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/Inline')
-rw-r--r--test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll10
-rw-r--r--test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll4
-rw-r--r--test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll1
-rw-r--r--test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll1
-rw-r--r--test/Transforms/Inline/2010-05-12-ValueMap.ll2
-rw-r--r--test/Transforms/Inline/alloca_test.ll2
-rw-r--r--test/Transforms/Inline/basictest.ll45
-rw-r--r--test/Transforms/Inline/crash2.ll2
-rw-r--r--test/Transforms/Inline/delete-call.ll8
-rw-r--r--test/Transforms/Inline/devirtualize-3.ll2
-rw-r--r--test/Transforms/Inline/devirtualize.ll2
-rw-r--r--test/Transforms/Inline/gvn-inline-iteration.ll2
-rw-r--r--test/Transforms/Inline/inline-optsize.ll4
-rw-r--r--test/Transforms/Inline/inline_constprop.ll76
-rw-r--r--test/Transforms/Inline/inline_invoke.ll12
-rw-r--r--test/Transforms/Inline/inline_minisize.ll232
-rw-r--r--test/Transforms/Inline/inline_ssp.ll160
-rw-r--r--test/Transforms/Inline/lifetime-no-datalayout.ll23
-rw-r--r--test/Transforms/Inline/lifetime.ll46
-rw-r--r--test/Transforms/Inline/noinline-recursive-fn.ll2
-rw-r--r--test/Transforms/Inline/noinline.ll2
-rw-r--r--test/Transforms/Inline/recursive.ll2
22 files changed, 609 insertions, 31 deletions
diff --git a/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll b/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll
index 5ced3b8..b8ca560 100644
--- a/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll
+++ b/test/Transforms/Inline/2003-09-22-PHINodeInlineFail.ll
@@ -3,10 +3,15 @@
define i32 @main() {
entry:
invoke void @__main( )
- to label %LongJmpBlkPre unwind label %LongJmpBlkPre
+ to label %LongJmpBlkPost unwind label %LongJmpBlkPre
-LongJmpBlkPre: ; preds = %entry, %entry
+LongJmpBlkPost:
+ ret i32 0
+
+LongJmpBlkPre:
%i.3 = phi i32 [ 0, %entry ], [ 0, %entry ] ; <i32> [#uses=0]
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 0
}
@@ -14,3 +19,4 @@ define void @__main() {
ret void
}
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll b/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll
index 1bd5529..43bdd30 100644
--- a/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll
+++ b/test/Transforms/Inline/2003-09-22-PHINodesInNormalInvokeDest.ll
@@ -13,6 +13,8 @@ LJDecisionBB: ; preds = %else
br label %else
RethrowExcept: ; preds = %entry
+ %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0
+ cleanup
ret i32 0
}
@@ -20,4 +22,4 @@ define void @__main() {
ret void
}
-
+declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll b/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll
index b4380d0..ee5a378 100644
--- a/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll
+++ b/test/Transforms/Inline/2006-11-09-InlineCGUpdate-2.ll
@@ -2,7 +2,6 @@
; PR993
target datalayout = "e-p:32:32"
target triple = "i386-unknown-openbsd3.9"
-deplibs = [ "stdc++", "c", "crtend" ]
%"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { i8* }
%"struct.__gnu_cxx::char_producer<char>" = type { i32 (...)** }
%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 }
diff --git a/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll b/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll
index b754d9f..fb5a4b5 100644
--- a/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll
+++ b/test/Transforms/Inline/2006-11-09-InlineCGUpdate.ll
@@ -2,7 +2,6 @@
; PR992
target datalayout = "e-p:32:32"
target triple = "i686-pc-linux-gnu"
-deplibs = [ "stdc++", "c", "crtend" ]
%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 }
%"struct.__cxxabiv1::__array_type_info" = type { %"struct.std::type_info" }
diff --git a/test/Transforms/Inline/2010-05-12-ValueMap.ll b/test/Transforms/Inline/2010-05-12-ValueMap.ll
index f9cc13f..f452907 100644
--- a/test/Transforms/Inline/2010-05-12-ValueMap.ll
+++ b/test/Transforms/Inline/2010-05-12-ValueMap.ll
@@ -1,4 +1,4 @@
-; RUN: opt %s -inline -mergefunc -disable-output
+; RUN: opt -inline -mergefunc -disable-output < %s
; This tests for a bug where the inliner kept the functions in a ValueMap after
; it had completed and a ModulePass started to run. LLVM would crash deleting
diff --git a/test/Transforms/Inline/alloca_test.ll b/test/Transforms/Inline/alloca_test.ll
index e5791d5..8464259 100644
--- a/test/Transforms/Inline/alloca_test.ll
+++ b/test/Transforms/Inline/alloca_test.ll
@@ -1,7 +1,7 @@
; This test ensures that alloca instructions in the entry block for an inlined
; function are moved to the top of the function they are inlined into.
;
-; RUN: opt -S -inline %s | FileCheck %s
+; RUN: opt -S -inline < %s | FileCheck %s
define i32 @func(i32 %i) {
%X = alloca i32 ; <i32*> [#uses=1]
diff --git a/test/Transforms/Inline/basictest.ll b/test/Transforms/Inline/basictest.ll
index 609a3d4..39e25cb 100644
--- a/test/Transforms/Inline/basictest.ll
+++ b/test/Transforms/Inline/basictest.ll
@@ -45,3 +45,48 @@ define i32 @test2(i1 %cond) {
; CHECK-NOT: = alloca
; CHECK: ret i32
}
+
+declare void @barrier() noduplicate
+
+define internal i32 @f() {
+ call void @barrier() noduplicate
+ ret i32 1
+}
+
+define i32 @g() {
+ call void @barrier() noduplicate
+ ret i32 2
+}
+
+define internal i32 @h() {
+ call void @barrier() noduplicate
+ ret i32 3
+}
+
+define i32 @test3() {
+ %b = call i32 @f()
+ ret i32 %b
+}
+
+; The call to @f cannot be inlined as there is another callsite
+; calling @f, and @f contains a noduplicate call.
+;
+; The call to @g cannot be inlined as it has external linkage.
+;
+; The call to @h *can* be inlined.
+
+; CHECK: @test
+define i32 @test() {
+; CHECK: call i32 @f()
+ %a = call i32 @f()
+; CHECK: call i32 @g()
+ %b = call i32 @g()
+; CHECK-NOT: call i32 @h()
+ %c = call i32 @h()
+
+ %d = add i32 %a, %b
+ %e = add i32 %d, %c
+
+ ret i32 %e
+; CHECK: }
+}
diff --git a/test/Transforms/Inline/crash2.ll b/test/Transforms/Inline/crash2.ll
index cb1f44d..be634f6 100644
--- a/test/Transforms/Inline/crash2.ll
+++ b/test/Transforms/Inline/crash2.ll
@@ -1,4 +1,4 @@
-; RUN: opt -inline -scalarrepl -max-cg-scc-iterations=1 %s -disable-output
+; RUN: opt -inline -scalarrepl -max-cg-scc-iterations=1 -disable-output < %s
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-apple-darwin10.3"
diff --git a/test/Transforms/Inline/delete-call.ll b/test/Transforms/Inline/delete-call.ll
index 7716d6a..97c52af 100644
--- a/test/Transforms/Inline/delete-call.ll
+++ b/test/Transforms/Inline/delete-call.ll
@@ -1,5 +1,9 @@
-; RUN: opt %s -S -inline -functionattrs -stats 2>&1 | grep "Number of call sites deleted, not inlined"
-; RUN: opt %s -S -inline -stats 2>&1 | grep "Number of functions inlined"
+; REQUIRES: asserts
+; RUN: opt -S -inline -stats < %s 2>&1 | FileCheck %s
+; CHECK: Number of functions inlined
+
+; RUN: opt -S -inline -functionattrs -stats < %s 2>&1 | FileCheck -check-prefix=FUNCTIONATTRS %s
+; CHECK-FUNCTIONATTRS: Number of call sites deleted, not inlined
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.8"
diff --git a/test/Transforms/Inline/devirtualize-3.ll b/test/Transforms/Inline/devirtualize-3.ll
index c32be4e..3f01967 100644
--- a/test/Transforms/Inline/devirtualize-3.ll
+++ b/test/Transforms/Inline/devirtualize-3.ll
@@ -1,4 +1,4 @@
-; RUN: opt -basicaa -inline -S -scalarrepl -gvn -instcombine %s | FileCheck %s
+; RUN: opt -basicaa -inline -S -scalarrepl -gvn -instcombine < %s | FileCheck %s
; PR5009
; CHECK: define i32 @main()
diff --git a/test/Transforms/Inline/devirtualize.ll b/test/Transforms/Inline/devirtualize.ll
index 51ea4ba..d46154e 100644
--- a/test/Transforms/Inline/devirtualize.ll
+++ b/test/Transforms/Inline/devirtualize.ll
@@ -1,4 +1,4 @@
-; RUN: opt -S -basicaa -inline -scalarrepl -instcombine -simplifycfg -instcombine -gvn -globaldce %s | FileCheck %s
+; RUN: opt -S -Os < %s | FileCheck %s
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-apple-darwin10.0.0"
diff --git a/test/Transforms/Inline/gvn-inline-iteration.ll b/test/Transforms/Inline/gvn-inline-iteration.ll
index e502fd5..526ed79 100644
--- a/test/Transforms/Inline/gvn-inline-iteration.ll
+++ b/test/Transforms/Inline/gvn-inline-iteration.ll
@@ -1,4 +1,4 @@
-; RUN: opt -basicaa -inline -gvn %s -S -max-cg-scc-iterations=1 | FileCheck %s
+; RUN: opt -basicaa -inline -gvn -S -max-cg-scc-iterations=1 < %s | FileCheck %s
; rdar://6295824 and PR6724
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"
diff --git a/test/Transforms/Inline/inline-optsize.ll b/test/Transforms/Inline/inline-optsize.ll
index 20d7426..3ad573a 100644
--- a/test/Transforms/Inline/inline-optsize.ll
+++ b/test/Transforms/Inline/inline-optsize.ll
@@ -1,5 +1,5 @@
-; RUN: opt -S -Oz %s | FileCheck %s -check-prefix=OZ
-; RUN: opt -S -O2 %s | FileCheck %s -check-prefix=O2
+; RUN: opt -S -Oz < %s | FileCheck %s -check-prefix=OZ
+; RUN: opt -S -O2 < %s | FileCheck %s -check-prefix=O2
; The inline threshold for a function with the optsize attribute is currently
; the same as the global inline threshold for -Os. Check that the optsize
diff --git a/test/Transforms/Inline/inline_constprop.ll b/test/Transforms/Inline/inline_constprop.ll
index 0b48a72..77bc378 100644
--- a/test/Transforms/Inline/inline_constprop.ll
+++ b/test/Transforms/Inline/inline_constprop.ll
@@ -111,6 +111,82 @@ bb.false:
ret i32 %sub
}
+declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
+
+define i8 @caller4(i8 %z) {
+; Check that we can constant fold through intrinsics such as the
+; overflow-detecting arithmetic instrinsics. These are particularly important
+; as they are used heavily in standard library code and generic C++ code where
+; the arguments are oftent constant but complete generality is required.
+;
+; CHECK: @caller4
+; CHECK-NOT: call
+; CHECK: ret i8 -1
+
+entry:
+ %x = call i8 @callee4(i8 254, i8 14, i8 %z)
+ ret i8 %x
+}
+
+define i8 @callee4(i8 %x, i8 %y, i8 %z) {
+ %uadd = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %x, i8 %y)
+ %o = extractvalue {i8, i1} %uadd, 1
+ br i1 %o, label %bb.true, label %bb.false
+
+bb.true:
+ ret i8 -1
+
+bb.false:
+ ; This block musn't be counted in the inline cost.
+ %z1 = add i8 %z, 1
+ %z2 = add i8 %z1, 1
+ %z3 = add i8 %z2, 1
+ %z4 = add i8 %z3, 1
+ %z5 = add i8 %z4, 1
+ %z6 = add i8 %z5, 1
+ %z7 = add i8 %z6, 1
+ %z8 = add i8 %z7, 1
+ ret i8 %z8
+}
+
+define i64 @caller5(i64 %y) {
+; Check that we can round trip constants through various kinds of casts etc w/o
+; losing track of the constant prop in the inline cost analysis.
+;
+; CHECK: @caller5
+; CHECK-NOT: call
+; CHECK: ret i64 -1
+
+entry:
+ %x = call i64 @callee5(i64 42, i64 %y)
+ ret i64 %x
+}
+
+define i64 @callee5(i64 %x, i64 %y) {
+ %inttoptr = inttoptr i64 %x to i8*
+ %bitcast = bitcast i8* %inttoptr to i32*
+ %ptrtoint = ptrtoint i32* %bitcast to i64
+ %trunc = trunc i64 %ptrtoint to i32
+ %zext = zext i32 %trunc to i64
+ %cmp = icmp eq i64 %zext, 42
+ br i1 %cmp, label %bb.true, label %bb.false
+
+bb.true:
+ ret i64 -1
+
+bb.false:
+ ; This block musn't be counted in the inline cost.
+ %y1 = add i64 %y, 1
+ %y2 = add i64 %y1, 1
+ %y3 = add i64 %y2, 1
+ %y4 = add i64 %y3, 1
+ %y5 = add i64 %y4, 1
+ %y6 = add i64 %y5, 1
+ %y7 = add i64 %y6, 1
+ %y8 = add i64 %y7, 1
+ ret i64 %y8
+}
+
define i32 @PR13412.main() {
; This is a somewhat complicated three layer subprogram that was reported to
diff --git a/test/Transforms/Inline/inline_invoke.ll b/test/Transforms/Inline/inline_invoke.ll
index 9f5f670..c394138 100644
--- a/test/Transforms/Inline/inline_invoke.ll
+++ b/test/Transforms/Inline/inline_invoke.ll
@@ -96,6 +96,7 @@ eh.resume:
; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: cleanup
; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
; CHECK-NEXT: to label %[[LBL:[^\s]+]] unwind
; CHECK: [[LBL]]:
@@ -166,6 +167,7 @@ eh.resume:
; CHECK-NEXT: [[LPADVAL1:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: cleanup
; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A1]])
; CHECK-NEXT: to label %[[RESUME1:[^\s]+]] unwind
; CHECK: [[RESUME1]]:
@@ -185,6 +187,7 @@ eh.resume:
; CHECK-NEXT: [[LPADVAL2:%.*]] = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: cleanup
; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(%struct.A* [[A2]])
; CHECK-NEXT: to label %[[RESUME2:[^\s]+]] unwind
; CHECK: [[RESUME2]]:
@@ -272,6 +275,7 @@ lpad.cont:
; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: cleanup
; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(
; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
; CHECK: [[L]]:
@@ -318,6 +322,7 @@ terminate:
; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: cleanup
; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
+; CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*)
; CHECK-NEXT: invoke void @_ZN1AD1Ev(
; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
; CHECK: [[L]]:
@@ -330,7 +335,7 @@ terminate:
; CHECK-NEXT: br label %[[JOIN]]
; CHECK: [[JOIN]]:
; CHECK-NEXT: phi { i8*, i32 }
-; CHECK-NEXT: call void @opaque() nounwind
+; CHECK-NEXT: call void @opaque() [[NUW:#[0-9]+]]
; CHECK-NEXT: br label %[[FIX:[^\s]+]]
; CHECK: lpad:
; CHECK-NEXT: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
@@ -340,3 +345,8 @@ terminate:
; CHECK-NEXT: [[T1:%.*]] = phi i32 [ 0, %[[JOIN]] ], [ 1, %lpad ]
; CHECK-NEXT: call void @use(i32 [[T1]])
; CHECK-NEXT: call void @_ZSt9terminatev()
+
+; CHECK: attributes [[NUW]] = { nounwind }
+; CHECK: attributes #1 = { nounwind readnone }
+; CHECK: attributes #2 = { ssp uwtable }
+; CHECK: attributes #3 = { noreturn nounwind }
diff --git a/test/Transforms/Inline/inline_minisize.ll b/test/Transforms/Inline/inline_minisize.ll
new file mode 100644
index 0000000..3dddbcf
--- /dev/null
+++ b/test/Transforms/Inline/inline_minisize.ll
@@ -0,0 +1,232 @@
+; RUN: opt -O2 -S < %s | FileCheck %s
+
+@data = common global i32* null, align 8
+
+define i32 @fct1(i32 %a) nounwind uwtable ssp {
+entry:
+ %a.addr = alloca i32, align 4
+ %res = alloca i32, align 4
+ %i = alloca i32, align 4
+ store i32 %a, i32* %a.addr, align 4
+ %tmp = load i32* %a.addr, align 4
+ %idxprom = sext i32 %tmp to i64
+ %tmp1 = load i32** @data, align 8
+ %arrayidx = getelementptr inbounds i32* %tmp1, i64 %idxprom
+ %tmp2 = load i32* %arrayidx, align 4
+ %tmp3 = load i32* %a.addr, align 4
+ %add = add nsw i32 %tmp3, 1
+ %idxprom1 = sext i32 %add to i64
+ %tmp4 = load i32** @data, align 8
+ %arrayidx2 = getelementptr inbounds i32* %tmp4, i64 %idxprom1
+ %tmp5 = load i32* %arrayidx2, align 4
+ %mul = mul nsw i32 %tmp2, %tmp5
+ store i32 %mul, i32* %res, align 4
+ store i32 0, i32* %i, align 4
+ store i32 0, i32* %i, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %tmp6 = load i32* %i, align 4
+ %tmp7 = load i32* %res, align 4
+ %cmp = icmp slt i32 %tmp6, %tmp7
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp8 = load i32* %i, align 4
+ %idxprom3 = sext i32 %tmp8 to i64
+ %tmp9 = load i32** @data, align 8
+ %arrayidx4 = getelementptr inbounds i32* %tmp9, i64 %idxprom3
+ call void @fct0(i32* %arrayidx4)
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %tmp10 = load i32* %i, align 4
+ %inc = add nsw i32 %tmp10, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ store i32 0, i32* %i, align 4
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc10, %for.end
+ %tmp11 = load i32* %i, align 4
+ %tmp12 = load i32* %res, align 4
+ %cmp6 = icmp slt i32 %tmp11, %tmp12
+ br i1 %cmp6, label %for.body7, label %for.end12
+
+for.body7: ; preds = %for.cond5
+ %tmp13 = load i32* %i, align 4
+ %idxprom8 = sext i32 %tmp13 to i64
+ %tmp14 = load i32** @data, align 8
+ %arrayidx9 = getelementptr inbounds i32* %tmp14, i64 %idxprom8
+ call void @fct0(i32* %arrayidx9)
+ br label %for.inc10
+
+for.inc10: ; preds = %for.body7
+ %tmp15 = load i32* %i, align 4
+ %inc11 = add nsw i32 %tmp15, 1
+ store i32 %inc11, i32* %i, align 4
+ br label %for.cond5
+
+for.end12: ; preds = %for.cond5
+ store i32 0, i32* %i, align 4
+ br label %for.cond13
+
+for.cond13: ; preds = %for.inc18, %for.end12
+ %tmp16 = load i32* %i, align 4
+ %tmp17 = load i32* %res, align 4
+ %cmp14 = icmp slt i32 %tmp16, %tmp17
+ br i1 %cmp14, label %for.body15, label %for.end20
+
+for.body15: ; preds = %for.cond13
+ %tmp18 = load i32* %i, align 4
+ %idxprom16 = sext i32 %tmp18 to i64
+ %tmp19 = load i32** @data, align 8
+ %arrayidx17 = getelementptr inbounds i32* %tmp19, i64 %idxprom16
+ call void @fct0(i32* %arrayidx17)
+ br label %for.inc18
+
+for.inc18: ; preds = %for.body15
+ %tmp20 = load i32* %i, align 4
+ %inc19 = add nsw i32 %tmp20, 1
+ store i32 %inc19, i32* %i, align 4
+ br label %for.cond13
+
+for.end20: ; preds = %for.cond13
+ %tmp21 = load i32* %res, align 4
+ ret i32 %tmp21
+}
+
+declare void @fct0(i32*)
+
+define i32 @fct2(i32 %a) nounwind uwtable inlinehint ssp {
+entry:
+ %a.addr = alloca i32, align 4
+ %res = alloca i32, align 4
+ %i = alloca i32, align 4
+ store i32 %a, i32* %a.addr, align 4
+ %tmp = load i32* %a.addr, align 4
+ %shl = shl i32 %tmp, 1
+ %idxprom = sext i32 %shl to i64
+ %tmp1 = load i32** @data, align 8
+ %arrayidx = getelementptr inbounds i32* %tmp1, i64 %idxprom
+ %tmp2 = load i32* %arrayidx, align 4
+ %tmp3 = load i32* %a.addr, align 4
+ %shl1 = shl i32 %tmp3, 1
+ %add = add nsw i32 %shl1, 13
+ %idxprom2 = sext i32 %add to i64
+ %tmp4 = load i32** @data, align 8
+ %arrayidx3 = getelementptr inbounds i32* %tmp4, i64 %idxprom2
+ %tmp5 = load i32* %arrayidx3, align 4
+ %mul = mul nsw i32 %tmp2, %tmp5
+ store i32 %mul, i32* %res, align 4
+ store i32 0, i32* %i, align 4
+ store i32 0, i32* %i, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %tmp6 = load i32* %i, align 4
+ %tmp7 = load i32* %res, align 4
+ %cmp = icmp slt i32 %tmp6, %tmp7
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp8 = load i32* %i, align 4
+ %idxprom4 = sext i32 %tmp8 to i64
+ %tmp9 = load i32** @data, align 8
+ %arrayidx5 = getelementptr inbounds i32* %tmp9, i64 %idxprom4
+ call void @fct0(i32* %arrayidx5)
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %tmp10 = load i32* %i, align 4
+ %inc = add nsw i32 %tmp10, 1
+ store i32 %inc, i32* %i, align 4
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ store i32 0, i32* %i, align 4
+ br label %for.cond6
+
+for.cond6: ; preds = %for.inc11, %for.end
+ %tmp11 = load i32* %i, align 4
+ %tmp12 = load i32* %res, align 4
+ %cmp7 = icmp slt i32 %tmp11, %tmp12
+ br i1 %cmp7, label %for.body8, label %for.end13
+
+for.body8: ; preds = %for.cond6
+ %tmp13 = load i32* %i, align 4
+ %idxprom9 = sext i32 %tmp13 to i64
+ %tmp14 = load i32** @data, align 8
+ %arrayidx10 = getelementptr inbounds i32* %tmp14, i64 %idxprom9
+ call void @fct0(i32* %arrayidx10)
+ br label %for.inc11
+
+for.inc11: ; preds = %for.body8
+ %tmp15 = load i32* %i, align 4
+ %inc12 = add nsw i32 %tmp15, 1
+ store i32 %inc12, i32* %i, align 4
+ br label %for.cond6
+
+for.end13: ; preds = %for.cond6
+ store i32 0, i32* %i, align 4
+ br label %for.cond14
+
+for.cond14: ; preds = %for.inc19, %for.end13
+ %tmp16 = load i32* %i, align 4
+ %tmp17 = load i32* %res, align 4
+ %cmp15 = icmp slt i32 %tmp16, %tmp17
+ br i1 %cmp15, label %for.body16, label %for.end21
+
+for.body16: ; preds = %for.cond14
+ %tmp18 = load i32* %i, align 4
+ %idxprom17 = sext i32 %tmp18 to i64
+ %tmp19 = load i32** @data, align 8
+ %arrayidx18 = getelementptr inbounds i32* %tmp19, i64 %idxprom17
+ call void @fct0(i32* %arrayidx18)
+ br label %for.inc19
+
+for.inc19: ; preds = %for.body16
+ %tmp20 = load i32* %i, align 4
+ %inc20 = add nsw i32 %tmp20, 1
+ store i32 %inc20, i32* %i, align 4
+ br label %for.cond14
+
+for.end21: ; preds = %for.cond14
+ %tmp21 = load i32* %res, align 4
+ ret i32 %tmp21
+}
+
+define i32 @fct3(i32 %c) nounwind uwtable ssp {
+entry:
+ ;CHECK: @fct3
+ ;CHECK: call i32 @fct1
+ ; The inline keyword gives a sufficient benefits to inline fct2
+ ;CHECK-NOT: call i32 @fct2
+ %c.addr = alloca i32, align 4
+ store i32 %c, i32* %c.addr, align 4
+ %tmp = load i32* %c.addr, align 4
+ %call = call i32 @fct1(i32 %tmp)
+ %tmp1 = load i32* %c.addr, align 4
+ %call1 = call i32 @fct2(i32 %tmp1)
+ %add = add nsw i32 %call, %call1
+ ret i32 %add
+}
+
+define i32 @fct4(i32 %c) minsize nounwind uwtable ssp {
+entry:
+ ;CHECK: @fct4
+ ;CHECK: call i32 @fct1
+ ; With Oz (minsize attribute), the benefit of inlining fct2
+ ; is the same as fct1, thus no inlining for fct2
+ ;CHECK: call i32 @fct2
+ %c.addr = alloca i32, align 4
+ store i32 %c, i32* %c.addr, align 4
+ %tmp = load i32* %c.addr, align 4
+ %call = call i32 @fct1(i32 %tmp)
+ %tmp1 = load i32* %c.addr, align 4
+ %call1 = call i32 @fct2(i32 %tmp1)
+ %add = add nsw i32 %call, %call1
+ ret i32 %add
+}
diff --git a/test/Transforms/Inline/inline_ssp.ll b/test/Transforms/Inline/inline_ssp.ll
new file mode 100644
index 0000000..a4b43a7
--- /dev/null
+++ b/test/Transforms/Inline/inline_ssp.ll
@@ -0,0 +1,160 @@
+; RUN: opt -inline %s -S | FileCheck %s
+; Ensure SSP attributes are propagated correctly when inlining.
+
+@.str = private unnamed_addr constant [11 x i8] c"fun_nossp\0A\00", align 1
+@.str1 = private unnamed_addr constant [9 x i8] c"fun_ssp\0A\00", align 1
+@.str2 = private unnamed_addr constant [15 x i8] c"fun_sspstrong\0A\00", align 1
+@.str3 = private unnamed_addr constant [12 x i8] c"fun_sspreq\0A\00", align 1
+
+; These first four functions (@fun_sspreq, @fun_sspstrong, @fun_ssp, @fun_nossp)
+; are used by the remaining functions to ensure that the SSP attributes are
+; propagated correctly. The caller should have its SSP attribute set as:
+; strictest(caller-ssp-attr, callee-ssp-attr), where strictness is ordered as:
+; sspreq > sspstrong > ssp > [no ssp]
+define internal void @fun_sspreq() nounwind sspreq uwtable {
+entry:
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str3, i32 0, i32 0))
+ ret void
+}
+
+define internal void @fun_sspstrong() nounwind sspstrong uwtable {
+entry:
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str2, i32 0, i32 0))
+ ret void
+}
+
+define internal void @fun_ssp() nounwind ssp uwtable {
+entry:
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0))
+ ret void
+}
+
+define internal void @fun_nossp() nounwind uwtable {
+entry:
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str, i32 0, i32 0))
+ ret void
+}
+
+; Tests start below
+
+define void @inline_req_req() nounwind sspreq uwtable {
+entry:
+; CHECK: @inline_req_req() #0
+ call void @fun_sspreq()
+ ret void
+}
+
+define void @inline_req_strong() nounwind sspstrong uwtable {
+entry:
+; CHECK: @inline_req_strong() #0
+ call void @fun_sspreq()
+ ret void
+}
+
+define void @inline_req_ssp() nounwind ssp uwtable {
+entry:
+; CHECK: @inline_req_ssp() #0
+ call void @fun_sspreq()
+ ret void
+}
+
+define void @inline_req_nossp() nounwind uwtable {
+entry:
+; CHECK: @inline_req_nossp() #0
+ call void @fun_sspreq()
+ ret void
+}
+
+define void @inline_strong_req() nounwind sspreq uwtable {
+entry:
+; CHECK: @inline_strong_req() #0
+ call void @fun_sspstrong()
+ ret void
+}
+
+
+define void @inline_strong_strong() nounwind sspstrong uwtable {
+entry:
+; CHECK: @inline_strong_strong() #1
+ call void @fun_sspstrong()
+ ret void
+}
+
+define void @inline_strong_ssp() nounwind ssp uwtable {
+entry:
+; CHECK: @inline_strong_ssp() #1
+ call void @fun_sspstrong()
+ ret void
+}
+
+define void @inline_strong_nossp() nounwind uwtable {
+entry:
+; CHECK: @inline_strong_nossp() #1
+ call void @fun_sspstrong()
+ ret void
+}
+
+define void @inline_ssp_req() nounwind sspreq uwtable {
+entry:
+; CHECK: @inline_ssp_req() #0
+ call void @fun_ssp()
+ ret void
+}
+
+
+define void @inline_ssp_strong() nounwind sspstrong uwtable {
+entry:
+; CHECK: @inline_ssp_strong() #1
+ call void @fun_ssp()
+ ret void
+}
+
+define void @inline_ssp_ssp() nounwind ssp uwtable {
+entry:
+; CHECK: @inline_ssp_ssp() #2
+ call void @fun_ssp()
+ ret void
+}
+
+define void @inline_ssp_nossp() nounwind uwtable {
+entry:
+; CHECK: @inline_ssp_nossp() #2
+ call void @fun_ssp()
+ ret void
+}
+
+define void @inline_nossp_req() nounwind uwtable sspreq {
+entry:
+; CHECK: @inline_nossp_req() #0
+ call void @fun_nossp()
+ ret void
+}
+
+
+define void @inline_nossp_strong() nounwind sspstrong uwtable {
+entry:
+; CHECK: @inline_nossp_strong() #1
+ call void @fun_nossp()
+ ret void
+}
+
+define void @inline_nossp_ssp() nounwind ssp uwtable {
+entry:
+; CHECK: @inline_nossp_ssp() #2
+ call void @fun_nossp()
+ ret void
+}
+
+define void @inline_nossp_nossp() nounwind uwtable {
+entry:
+; CHECK: @inline_nossp_nossp() #3
+ call void @fun_nossp()
+ ret void
+}
+
+declare i32 @printf(i8*, ...)
+
+; CHECK: attributes #0 = { nounwind sspreq uwtable }
+; CHECK: attributes #1 = { nounwind sspstrong uwtable }
+; CHECK: attributes #2 = { nounwind ssp uwtable }
+; CHECK: attributes #3 = { nounwind uwtable }
diff --git a/test/Transforms/Inline/lifetime-no-datalayout.ll b/test/Transforms/Inline/lifetime-no-datalayout.ll
new file mode 100644
index 0000000..f4ffef3
--- /dev/null
+++ b/test/Transforms/Inline/lifetime-no-datalayout.ll
@@ -0,0 +1,23 @@
+; RUN: opt -inline -S < %s | FileCheck %s
+
+declare void @use(i8* %a)
+
+define void @helper() {
+ %a = alloca i8
+ call void @use(i8* %a)
+ ret void
+}
+
+; Size in llvm.lifetime.X should be -1 (unknown).
+define void @test() {
+; CHECK: @test
+; CHECK-NOT: lifetime
+; CHECK: llvm.lifetime.start(i64 -1
+; CHECK-NOT: lifetime
+; CHECK: llvm.lifetime.end(i64 -1
+ call void @helper()
+; CHECK-NOT: lifetime
+; CHECK: ret void
+ ret void
+}
+
diff --git a/test/Transforms/Inline/lifetime.ll b/test/Transforms/Inline/lifetime.ll
index a95c836..fc73385 100644
--- a/test/Transforms/Inline/lifetime.ll
+++ b/test/Transforms/Inline/lifetime.ll
@@ -1,22 +1,25 @@
-; RUN: opt -inline %s -S -o - | FileCheck %s
+; RUN: opt -inline -S < %s | FileCheck %s
+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-S128"
declare void @llvm.lifetime.start(i64, i8*)
declare void @llvm.lifetime.end(i64, i8*)
define void @helper_both_markers() {
%a = alloca i8
- call void @llvm.lifetime.start(i64 1, i8* %a)
- call void @llvm.lifetime.end(i64 1, i8* %a)
+ ; Size in llvm.lifetime.start / llvm.lifetime.end differs from
+ ; allocation size. We should use the former.
+ call void @llvm.lifetime.start(i64 2, i8* %a)
+ call void @llvm.lifetime.end(i64 2, i8* %a)
ret void
}
define void @test_both_markers() {
; CHECK: @test_both_markers
-; CHECK: llvm.lifetime.start(i64 1
-; CHECK-NEXT: llvm.lifetime.end(i64 1
+; CHECK: llvm.lifetime.start(i64 2
+; CHECK-NEXT: llvm.lifetime.end(i64 2
call void @helper_both_markers()
-; CHECK-NEXT: llvm.lifetime.start(i64 1
-; CHECK-NEXT: llvm.lifetime.end(i64 1
+; CHECK-NEXT: llvm.lifetime.start(i64 2
+; CHECK-NEXT: llvm.lifetime.end(i64 2
call void @helper_both_markers()
; CHECK-NEXT: ret void
ret void
@@ -27,7 +30,7 @@ define void @test_both_markers() {
declare void @use(i8* %a)
define void @helper_no_markers() {
- %a = alloca i8
+ %a = alloca i8 ; Allocation size is 1 byte.
call void @use(i8* %a)
ret void
}
@@ -37,14 +40,14 @@ define void @helper_no_markers() {
define void @test_no_marker() {
; CHECK: @test_no_marker
; CHECK-NOT: lifetime
-; CHECK: llvm.lifetime.start(i64 -1
+; CHECK: llvm.lifetime.start(i64 1
; CHECK-NOT: lifetime
-; CHECK: llvm.lifetime.end(i64 -1
+; CHECK: llvm.lifetime.end(i64 1
call void @helper_no_markers()
; CHECK-NOT: lifetime
-; CHECK: llvm.lifetime.start(i64 -1
+; CHECK: llvm.lifetime.start(i64 1
; CHECK-NOT: lifetime
-; CHECK: llvm.lifetime.end(i64 -1
+; CHECK: llvm.lifetime.end(i64 1
call void @helper_no_markers()
; CHECK-NOT: lifetime
; CHECK: ret void
@@ -76,3 +79,22 @@ define void @test_two_casts() {
; CHECK: ret void
ret void
}
+
+define void @helper_arrays_alloca() {
+ %a = alloca [10 x i32], align 16
+ %1 = bitcast [10 x i32]* %a to i8*
+ call void @use(i8* %1)
+ ret void
+}
+
+define void @test_arrays_alloca() {
+; CHECK: @test_arrays_alloca
+; CHECK-NOT: lifetime
+; CHECK: llvm.lifetime.start(i64 40,
+; CHECK-NOT: lifetime
+; CHECK: llvm.lifetime.end(i64 40,
+ call void @helper_arrays_alloca()
+; CHECK-NOT: lifetime
+; CHECK: ret void
+ ret void
+}
diff --git a/test/Transforms/Inline/noinline-recursive-fn.ll b/test/Transforms/Inline/noinline-recursive-fn.ll
index 6cde0e2..5520093 100644
--- a/test/Transforms/Inline/noinline-recursive-fn.ll
+++ b/test/Transforms/Inline/noinline-recursive-fn.ll
@@ -2,7 +2,7 @@
; This effectively is just peeling off the first iteration of a loop, and the
; inliner heuristics are not set up for this.
-; RUN: opt -inline %s -S | FileCheck %s
+; RUN: opt -inline -S < %s | FileCheck %s
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-apple-darwin10.3"
diff --git a/test/Transforms/Inline/noinline.ll b/test/Transforms/Inline/noinline.ll
index dc3f6e0..7667114 100644
--- a/test/Transforms/Inline/noinline.ll
+++ b/test/Transforms/Inline/noinline.ll
@@ -1,4 +1,4 @@
-; RUN: opt %s -inline -S | FileCheck %s
+; RUN: opt -inline -S < %s | FileCheck %s
; PR6682
declare void @foo() nounwind
diff --git a/test/Transforms/Inline/recursive.ll b/test/Transforms/Inline/recursive.ll
index 5fe8d16..fe1c041 100644
--- a/test/Transforms/Inline/recursive.ll
+++ b/test/Transforms/Inline/recursive.ll
@@ -1,4 +1,4 @@
-; RUN: opt %s -inline -S | FileCheck %s
+; RUN: opt -inline -S < %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"
target triple = "i386-apple-darwin10.0"
OpenPOWER on IntegriCloud