diff options
Diffstat (limited to 'test/Transforms/Inline')
-rw-r--r-- | test/Transforms/Inline/2010-05-31-ByvalTailcall.ll | 24 | ||||
-rw-r--r-- | test/Transforms/Inline/always-inline.ll | 11 | ||||
-rw-r--r-- | test/Transforms/Inline/byval-tail-call.ll | 38 | ||||
-rw-r--r-- | test/Transforms/Inline/byval_lifetime.ll | 26 | ||||
-rw-r--r-- | test/Transforms/Inline/inline-cold.ll | 116 | ||||
-rw-r--r-- | test/Transforms/Inline/inline-tail.ll | 185 | ||||
-rw-r--r-- | test/Transforms/Inline/inline-vla.ll | 38 | ||||
-rw-r--r-- | test/Transforms/Inline/optimization-remarks.ll | 60 | ||||
-rw-r--r-- | test/Transforms/Inline/switch.ll | 60 |
9 files changed, 523 insertions, 35 deletions
diff --git a/test/Transforms/Inline/2010-05-31-ByvalTailcall.ll b/test/Transforms/Inline/2010-05-31-ByvalTailcall.ll deleted file mode 100644 index b37b9f2..0000000 --- a/test/Transforms/Inline/2010-05-31-ByvalTailcall.ll +++ /dev/null @@ -1,24 +0,0 @@ -; RUN: opt < %s -tailcallelim -inline -instcombine -dse -S | FileCheck %s -; PR7272 - -; When inlining through a byval call site, the inliner creates allocas which may -; be used by inlined calls, so any inlined calls need to have their 'tail' flags -; cleared. If not then you can get nastiness like with this testcase, where the -; (inlined) call to 'ext' in 'foo' was being passed an uninitialized value. - -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-n8:16:32" -target triple = "i386-pc-linux-gnu" - -declare void @ext(i32*) - -define void @bar(i32* byval %x) { - call void @ext(i32* %x) - ret void -} - -define void @foo(i32* %x) { -; CHECK-LABEL: define void @foo( -; CHECK: store i32 %1, i32* %x - call void @bar(i32* byval %x) - ret void -} diff --git a/test/Transforms/Inline/always-inline.ll b/test/Transforms/Inline/always-inline.ll index a8703b8..5ad1bde 100644 --- a/test/Transforms/Inline/always-inline.ll +++ b/test/Transforms/Inline/always-inline.ll @@ -122,3 +122,14 @@ entry: ret void } +define i32 @inner7() { + ret i32 1 +} +define i32 @outer7() { +; CHECK-LABEL: @outer7( +; CHECK-NOT: call +; CHECK: ret + + %r = call i32 @inner7() alwaysinline + ret i32 %r +} diff --git a/test/Transforms/Inline/byval-tail-call.ll b/test/Transforms/Inline/byval-tail-call.ll new file mode 100644 index 0000000..3a8906a --- /dev/null +++ b/test/Transforms/Inline/byval-tail-call.ll @@ -0,0 +1,38 @@ +; RUN: opt < %s -tailcallelim -inline -instcombine -dse -S | FileCheck %s +; PR7272 + +; Calls that capture byval parameters cannot be marked as tail calls. Other +; tails that don't capture byval parameters can still be tail calls. + +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-n8:16:32" +target triple = "i386-pc-linux-gnu" + +declare void @ext(i32*) + +define void @bar(i32* byval %x) { + call void @ext(i32* %x) + ret void +} + +define void @foo(i32* %x) { +; CHECK-LABEL: define void @foo( +; CHECK: llvm.lifetime.start +; CHECK: store i32 %2, i32* %x + call void @bar(i32* byval %x) + ret void +} + +define internal void @qux(i32* byval %x) { + call void @ext(i32* %x) + tail call void @ext(i32* null) + ret void +} +define void @frob(i32* %x) { +; CHECK-LABEL: define void @frob( +; CHECK: alloca i32 +; CHECK: {{^ *}}call void @ext( +; CHECK: tail call void @ext(i32* null) +; CHECK: ret void + tail call void @qux(i32* byval %x) + ret void +} diff --git a/test/Transforms/Inline/byval_lifetime.ll b/test/Transforms/Inline/byval_lifetime.ll new file mode 100644 index 0000000..e8dff2a --- /dev/null +++ b/test/Transforms/Inline/byval_lifetime.ll @@ -0,0 +1,26 @@ +; RUN: opt -S -inline < %s | FileCheck %s +; END. + +; By inlining foo, an alloca is created in main to hold the byval argument, so +; a lifetime marker should be generated as well by default. + +%struct.foo = type { i32, [16 x i32] } + +@gFoo = global %struct.foo zeroinitializer, align 8 + +define i32 @foo(%struct.foo* byval align 8 %f, i32 %a) { +entry: + %a1 = getelementptr inbounds %struct.foo* %f, i32 0, i32 1 + %arrayidx = getelementptr inbounds [16 x i32]* %a1, i32 0, i32 %a + %tmp2 = load i32* %arrayidx, align 1 + ret i32 %tmp2 +} + +define i32 @main(i32 %argc, i8** %argv) { +; CHECK-LABEL: @main +; CHECK: llvm.lifetime.start +; CHECK: memcpy +entry: + %call = call i32 @foo(%struct.foo* byval align 8 @gFoo, i32 %argc) + ret i32 %call +} diff --git a/test/Transforms/Inline/inline-cold.ll b/test/Transforms/Inline/inline-cold.ll index bb8c008..5743377 100644 --- a/test/Transforms/Inline/inline-cold.ll +++ b/test/Transforms/Inline/inline-cold.ll @@ -1,8 +1,15 @@ ; RUN: opt < %s -inline -S -inlinecold-threshold=75 | FileCheck %s - ; Test that functions with attribute Cold are not inlined while the ; same function without attribute Cold will be inlined. +; RUN: opt < %s -inline -S -inline-threshold=600 | FileCheck %s -check-prefix=OVERRIDE +; The command line argument for inline-threshold should override +; the default cold threshold, so a cold function with size bigger +; than the default cold threshold (225) will be inlined. + +; RUN: opt < %s -inline -S | FileCheck %s -check-prefix=DEFAULT +; The same cold function will not be inlined with the default behavior. + @a = global i32 4 ; This function should be larger than the cold threshold (75), but smaller @@ -42,6 +49,10 @@ entry: define i32 @ColdFunction(i32 %a) #1 { ; CHECK-LABEL: @ColdFunction ; CHECK: ret +; OVERRIDE-LABEL: @ColdFunction +; OVERRIDE: ret +; DEFAULT-LABEL: @ColdFunction +; DEFAULT: ret entry: %a1 = load volatile i32* @a %x1 = add i32 %a1, %a1 @@ -71,16 +82,117 @@ entry: ret i32 %add } +; This function should be larger than the default cold threshold (225). +define i32 @ColdFunction2(i32 %a) #1 { +; CHECK-LABEL: @ColdFunction2 +; CHECK: ret +; OVERRIDE-LABEL: @ColdFunction2 +; OVERRIDE: ret +; DEFAULT-LABEL: @ColdFunction2 +; DEFAULT: ret +entry: + %a1 = load volatile i32* @a + %x1 = add i32 %a1, %a1 + %a2 = load volatile i32* @a + %x2 = add i32 %x1, %a2 + %a3 = load volatile i32* @a + %x3 = add i32 %x2, %a3 + %a4 = load volatile i32* @a + %x4 = add i32 %x3, %a4 + %a5 = load volatile i32* @a + %x5 = add i32 %x4, %a5 + %a6 = load volatile i32* @a + %x6 = add i32 %x5, %a6 + %a7 = load volatile i32* @a + %x7 = add i32 %x6, %a7 + %a8 = load volatile i32* @a + %x8 = add i32 %x7, %a8 + %a9 = load volatile i32* @a + %x9 = add i32 %x8, %a9 + %a10 = load volatile i32* @a + %x10 = add i32 %x9, %a10 + %a11 = load volatile i32* @a + %x11 = add i32 %x10, %a11 + %a12 = load volatile i32* @a + %x12 = add i32 %x11, %a12 + + %a21 = load volatile i32* @a + %x21 = add i32 %x12, %a21 + %a22 = load volatile i32* @a + %x22 = add i32 %x21, %a22 + %a23 = load volatile i32* @a + %x23 = add i32 %x22, %a23 + %a24 = load volatile i32* @a + %x24 = add i32 %x23, %a24 + %a25 = load volatile i32* @a + %x25 = add i32 %x24, %a25 + %a26 = load volatile i32* @a + %x26 = add i32 %x25, %a26 + %a27 = load volatile i32* @a + %x27 = add i32 %x26, %a27 + %a28 = load volatile i32* @a + %x28 = add i32 %x27, %a28 + %a29 = load volatile i32* @a + %x29 = add i32 %x28, %a29 + %a30 = load volatile i32* @a + %x30 = add i32 %x29, %a30 + %a31 = load volatile i32* @a + %x31 = add i32 %x30, %a31 + %a32 = load volatile i32* @a + %x32 = add i32 %x31, %a32 + + %a41 = load volatile i32* @a + %x41 = add i32 %x32, %a41 + %a42 = load volatile i32* @a + %x42 = add i32 %x41, %a42 + %a43 = load volatile i32* @a + %x43 = add i32 %x42, %a43 + %a44 = load volatile i32* @a + %x44 = add i32 %x43, %a44 + %a45 = load volatile i32* @a + %x45 = add i32 %x44, %a45 + %a46 = load volatile i32* @a + %x46 = add i32 %x45, %a46 + %a47 = load volatile i32* @a + %x47 = add i32 %x46, %a47 + %a48 = load volatile i32* @a + %x48 = add i32 %x47, %a48 + %a49 = load volatile i32* @a + %x49 = add i32 %x48, %a49 + %a50 = load volatile i32* @a + %x50 = add i32 %x49, %a50 + %a51 = load volatile i32* @a + %x51 = add i32 %x50, %a51 + %a52 = load volatile i32* @a + %x52 = add i32 %x51, %a52 + + %add = add i32 %x52, %a + ret i32 %add +} + ; Function Attrs: nounwind readnone uwtable define i32 @bar(i32 %a) #0 { ; CHECK-LABEL: @bar ; CHECK: call i32 @ColdFunction(i32 5) ; CHECK-NOT: call i32 @simpleFunction(i32 6) +; CHECK: call i32 @ColdFunction2(i32 5) ; CHECK: ret +; OVERRIDE-LABEL: @bar +; OVERRIDE-NOT: call i32 @ColdFunction(i32 5) +; OVERRIDE-NOT: call i32 @simpleFunction(i32 6) +; OVERRIDE-NOT: call i32 @ColdFunction2(i32 5) +; OVERRIDE: ret +; DEFAULT-LABEL: @bar +; DEFAULT-NOT: call i32 @ColdFunction(i32 5) +; DEFAULT-NOT: call i32 @simpleFunction(i32 6) +; DEFAULT: call i32 @ColdFunction2(i32 5) +; DEFAULT: ret entry: %0 = tail call i32 @ColdFunction(i32 5) %1 = tail call i32 @simpleFunction(i32 6) - %add = add i32 %0, %1 + %2 = tail call i32 @ColdFunction2(i32 5) + %3 = add i32 %0, %1 + %add = add i32 %2, %3 ret i32 %add } diff --git a/test/Transforms/Inline/inline-tail.ll b/test/Transforms/Inline/inline-tail.ll index 8bb059d..b40328e 100644 --- a/test/Transforms/Inline/inline-tail.ll +++ b/test/Transforms/Inline/inline-tail.ll @@ -1,15 +1,182 @@ -; RUN: opt < %s -inline -S | not grep tail +; RUN: opt < %s -inline -S | FileCheck %s -declare void @bar(i32*) +; We have to apply the less restrictive TailCallKind of the call site being +; inlined and any call sites cloned into the caller. -define internal void @foo(i32* %P) { - tail call void @bar( i32* %P ) - ret void +; No tail marker after inlining, since test_capture_c captures an alloca. +; CHECK: define void @test_capture_a( +; CHECK-NOT: tail +; CHECK: call void @test_capture_c( + +declare void @test_capture_c(i32*) +define internal void @test_capture_b(i32* %P) { + tail call void @test_capture_c(i32* %P) + ret void +} +define void @test_capture_a() { + %A = alloca i32 ; captured by test_capture_b + call void @test_capture_b(i32* %A) + ret void +} + +; No musttail marker after inlining, since the prototypes don't match. +; CHECK: define void @test_proto_mismatch_a( +; CHECK-NOT: musttail +; CHECK: call void @test_proto_mismatch_c( + +declare void @test_proto_mismatch_c(i32*) +define internal void @test_proto_mismatch_b(i32* %p) { + musttail call void @test_proto_mismatch_c(i32* %p) + ret void +} +define void @test_proto_mismatch_a() { + call void @test_proto_mismatch_b(i32* null) + ret void +} + +; After inlining through a musttail call site, we need to keep musttail markers +; to prevent unbounded stack growth. +; CHECK: define void @test_musttail_basic_a( +; CHECK: musttail call void @test_musttail_basic_c( + +declare void @test_musttail_basic_c(i32* %p) +define internal void @test_musttail_basic_b(i32* %p) { + musttail call void @test_musttail_basic_c(i32* %p) + ret void +} +define void @test_musttail_basic_a(i32* %p) { + musttail call void @test_musttail_basic_b(i32* %p) + ret void +} + +; Don't insert lifetime end markers here, the lifetime is trivially over due +; the return. +; CHECK: define void @test_byval_a( +; CHECK: musttail call void @test_byval_c( +; CHECK-NEXT: ret void + +declare void @test_byval_c(i32* byval %p) +define internal void @test_byval_b(i32* byval %p) { + musttail call void @test_byval_c(i32* byval %p) + ret void +} +define void @test_byval_a(i32* byval %p) { + musttail call void @test_byval_b(i32* byval %p) + ret void } -define void @caller() { - %A = alloca i32 ; <i32*> [#uses=1] - call void @foo( i32* %A ) - ret void +; Don't insert a stack restore, we're about to return. +; CHECK: define void @test_dynalloca_a( +; CHECK: call i8* @llvm.stacksave( +; CHECK: alloca i8, i32 %n +; CHECK: musttail call void @test_dynalloca_c( +; CHECK-NEXT: ret void + +declare void @escape(i8* %buf) +declare void @test_dynalloca_c(i32* byval %p, i32 %n) +define internal void @test_dynalloca_b(i32* byval %p, i32 %n) alwaysinline { + %buf = alloca i8, i32 %n ; dynamic alloca + call void @escape(i8* %buf) ; escape it + musttail call void @test_dynalloca_c(i32* byval %p, i32 %n) + ret void +} +define void @test_dynalloca_a(i32* byval %p, i32 %n) { + musttail call void @test_dynalloca_b(i32* byval %p, i32 %n) + ret void } +; We can't merge the returns. +; CHECK: define void @test_multiret_a( +; CHECK: musttail call void @test_multiret_c( +; CHECK-NEXT: ret void +; CHECK: musttail call void @test_multiret_d( +; CHECK-NEXT: ret void + +declare void @test_multiret_c(i1 zeroext %b) +declare void @test_multiret_d(i1 zeroext %b) +define internal void @test_multiret_b(i1 zeroext %b) { + br i1 %b, label %c, label %d +c: + musttail call void @test_multiret_c(i1 zeroext %b) + ret void +d: + musttail call void @test_multiret_d(i1 zeroext %b) + ret void +} +define void @test_multiret_a(i1 zeroext %b) { + musttail call void @test_multiret_b(i1 zeroext %b) + ret void +} + +; We have to avoid bitcast chains. +; CHECK: define i32* @test_retptr_a( +; CHECK: musttail call i8* @test_retptr_c( +; CHECK-NEXT: bitcast i8* {{.*}} to i32* +; CHECK-NEXT: ret i32* + +declare i8* @test_retptr_c() +define internal i16* @test_retptr_b() { + %rv = musttail call i8* @test_retptr_c() + %v = bitcast i8* %rv to i16* + ret i16* %v +} +define i32* @test_retptr_a() { + %rv = musttail call i16* @test_retptr_b() + %v = bitcast i16* %rv to i32* + ret i32* %v +} + +; Combine the last two cases: multiple returns with pointer bitcasts. +; CHECK: define i32* @test_multiptrret_a( +; CHECK: musttail call i8* @test_multiptrret_c( +; CHECK-NEXT: bitcast i8* {{.*}} to i32* +; CHECK-NEXT: ret i32* +; CHECK: musttail call i8* @test_multiptrret_d( +; CHECK-NEXT: bitcast i8* {{.*}} to i32* +; CHECK-NEXT: ret i32* + +declare i8* @test_multiptrret_c(i1 zeroext %b) +declare i8* @test_multiptrret_d(i1 zeroext %b) +define internal i16* @test_multiptrret_b(i1 zeroext %b) { + br i1 %b, label %c, label %d +c: + %c_rv = musttail call i8* @test_multiptrret_c(i1 zeroext %b) + %c_v = bitcast i8* %c_rv to i16* + ret i16* %c_v +d: + %d_rv = musttail call i8* @test_multiptrret_d(i1 zeroext %b) + %d_v = bitcast i8* %d_rv to i16* + ret i16* %d_v +} +define i32* @test_multiptrret_a(i1 zeroext %b) { + %rv = musttail call i16* @test_multiptrret_b(i1 zeroext %b) + %v = bitcast i16* %rv to i32* + ret i32* %v +} + +; Inline a musttail call site which contains a normal return and a musttail call. +; CHECK: define i32 @test_mixedret_a( +; CHECK: br i1 %b +; CHECK: musttail call i32 @test_mixedret_c( +; CHECK-NEXT: ret i32 +; CHECK: call i32 @test_mixedret_d(i1 zeroext %b) +; CHECK: add i32 1, +; CHECK-NOT: br +; CHECK: ret i32 + +declare i32 @test_mixedret_c(i1 zeroext %b) +declare i32 @test_mixedret_d(i1 zeroext %b) +define internal i32 @test_mixedret_b(i1 zeroext %b) { + br i1 %b, label %c, label %d +c: + %c_rv = musttail call i32 @test_mixedret_c(i1 zeroext %b) + ret i32 %c_rv +d: + %d_rv = call i32 @test_mixedret_d(i1 zeroext %b) + %d_rv1 = add i32 1, %d_rv + ret i32 %d_rv1 +} +define i32 @test_mixedret_a(i1 zeroext %b) { + %rv = musttail call i32 @test_mixedret_b(i1 zeroext %b) + ret i32 %rv +} diff --git a/test/Transforms/Inline/inline-vla.ll b/test/Transforms/Inline/inline-vla.ll new file mode 100644 index 0000000..dc9deaa --- /dev/null +++ b/test/Transforms/Inline/inline-vla.ll @@ -0,0 +1,38 @@ +; RUN: opt -S -inline %s -o - | FileCheck %s + +; Check that memcpy2 is completely inlined away. +; CHECK-NOT: memcpy2 + +@.str = private unnamed_addr constant [2 x i8] c"a\00", align 1 +@.str1 = private unnamed_addr constant [3 x i8] c"ab\00", align 1 + +; Function Attrs: nounwind ssp uwtable +define i32 @main(i32 %argc, i8** nocapture readnone %argv) #0 { +entry: + %data = alloca [2 x i8], align 1 + %arraydecay = getelementptr inbounds [2 x i8]* %data, i64 0, i64 0 + call fastcc void @memcpy2(i8* %arraydecay, i8* getelementptr inbounds ([2 x i8]* @.str, i64 0, i64 0), i64 1) + call fastcc void @memcpy2(i8* %arraydecay, i8* getelementptr inbounds ([3 x i8]* @.str1, i64 0, i64 0), i64 2) + ret i32 0 +} + +; Function Attrs: inlinehint nounwind ssp uwtable +define internal fastcc void @memcpy2(i8* nocapture %dst, i8* nocapture readonly %src, i64 %size) #1 { +entry: + %vla = alloca i64, i64 %size, align 16 + %0 = bitcast i64* %vla to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %src, i64 %size, i32 1, i1 false) + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %0, i64 %size, i32 1, i1 false) + ret void +} + +; Function Attrs: nounwind +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #2 + +attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { inlinehint nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!llvm.ident = !{!0} + +!0 = metadata !{metadata !"clang version 3.5.0 (trunk 205695) (llvm/trunk 205706)"} diff --git a/test/Transforms/Inline/optimization-remarks.ll b/test/Transforms/Inline/optimization-remarks.ll new file mode 100644 index 0000000..9108f3a --- /dev/null +++ b/test/Transforms/Inline/optimization-remarks.ll @@ -0,0 +1,60 @@ +; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline -pass-remarks-analysis=inline -S 2>&1 | FileCheck %s + +; CHECK: foo should always be inlined (cost=always) +; CHECK: foo inlined into bar +; CHECK: foz should never be inlined (cost=never) +; CHECK: foz will not be inlined into bar + +; Function Attrs: alwaysinline nounwind uwtable +define i32 @foo(i32 %x, i32 %y) #0 { +entry: + %x.addr = alloca i32, align 4 + %y.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + store i32 %y, i32* %y.addr, align 4 + %0 = load i32* %x.addr, align 4 + %1 = load i32* %y.addr, align 4 + %add = add nsw i32 %0, %1 + ret i32 %add +} + +; Function Attrs: noinline nounwind uwtable +define float @foz(i32 %x, i32 %y) #1 { +entry: + %x.addr = alloca i32, align 4 + %y.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + store i32 %y, i32* %y.addr, align 4 + %0 = load i32* %x.addr, align 4 + %1 = load i32* %y.addr, align 4 + %mul = mul nsw i32 %0, %1 + %conv = sitofp i32 %mul to float + ret float %conv +} + +; Function Attrs: nounwind uwtable +define i32 @bar(i32 %j) #2 { +entry: + %j.addr = alloca i32, align 4 + store i32 %j, i32* %j.addr, align 4 + %0 = load i32* %j.addr, align 4 + %1 = load i32* %j.addr, align 4 + %sub = sub nsw i32 %1, 2 + %call = call i32 @foo(i32 %0, i32 %sub) + %conv = sitofp i32 %call to float + %2 = load i32* %j.addr, align 4 + %sub1 = sub nsw i32 %2, 2 + %3 = load i32* %j.addr, align 4 + %call2 = call float @foz(i32 %sub1, i32 %3) + %mul = fmul float %conv, %call2 + %conv3 = fptosi float %mul to i32 + ret i32 %conv3 +} + +attributes #0 = { alwaysinline nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.ident = !{!0} + +!0 = metadata !{metadata !"clang version 3.5.0 "} diff --git a/test/Transforms/Inline/switch.ll b/test/Transforms/Inline/switch.ll new file mode 100644 index 0000000..c5dab53 --- /dev/null +++ b/test/Transforms/Inline/switch.ll @@ -0,0 +1,60 @@ +; RUN: opt < %s -inline -inline-threshold=20 -S | FileCheck %s + +define i32 @callee(i32 %a) { + switch i32 %a, label %sw.default [ + i32 0, label %sw.bb0 + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + i32 4, label %sw.bb4 + i32 5, label %sw.bb5 + i32 6, label %sw.bb6 + i32 7, label %sw.bb7 + i32 8, label %sw.bb8 + i32 9, label %sw.bb9 + ] + +sw.default: + br label %return + +sw.bb0: + br label %return + +sw.bb1: + br label %return + +sw.bb2: + br label %return + +sw.bb3: + br label %return + +sw.bb4: + br label %return + +sw.bb5: + br label %return + +sw.bb6: + br label %return + +sw.bb7: + br label %return + +sw.bb8: + br label %return + +sw.bb9: + br label %return + +return: + ret i32 42 +} + +define i32 @caller(i32 %a) { +; CHECK-LABEL: @caller( +; CHECK: call i32 @callee( + + %result = call i32 @callee(i32 %a) + ret i32 %result +} |