diff options
Diffstat (limited to 'test/Transforms')
48 files changed, 1548 insertions, 183 deletions
diff --git a/test/Transforms/ArgumentPromotion/crash.ll b/test/Transforms/ArgumentPromotion/crash.ll new file mode 100644 index 000000000000..e2d3d4de9edb --- /dev/null +++ b/test/Transforms/ArgumentPromotion/crash.ll @@ -0,0 +1,38 @@ +; rdar://7879828 +; RUN: opt -inline -argpromotion %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" + +define void @foo() { + invoke void @foo2() + to label %if.end432 unwind label %for.end520 + +if.end432: + unreachable + +for.end520: + unreachable +} + +define internal void @foo2() ssp { + %call7 = call fastcc i8* @foo3(i1 (i8*)* @foo4) + %call58 = call fastcc i8* @foo3(i1 (i8*)* @foo5) + unreachable +} + +define internal fastcc i8* @foo3(i1 (i8*)* %Pred) { +entry: + unreachable +} + +define internal i1 @foo4(i8* %O) nounwind { +entry: + %call = call zeroext i1 @foo5(i8* %O) ; <i1> [#uses=0] + unreachable +} + +define internal i1 @foo5(i8* %O) nounwind { +entry: + ret i1 undef +} + diff --git a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll index f251d6ce882c..161821f3f8f7 100644 --- a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll +++ b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll @@ -23,4 +23,4 @@ T: ret i32 %y T2: unreachable -}
\ No newline at end of file +} diff --git a/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll new file mode 100644 index 000000000000..2f820bad8474 --- /dev/null +++ b/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll @@ -0,0 +1,68 @@ +; RUN: opt -S -deadargelim < %s | FileCheck %s + +@.str = private constant [1 x i8] zeroinitializer, align 1 ; <[1 x i8]*> [#uses=1] + +define i8* @vfs_addname(i8* %name, i32 %len, i32 %hash, i32 %flags) nounwind ssp { +entry: + call void @llvm.dbg.value(metadata !{i8* %name}, i64 0, metadata !0) + call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !10) + call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !11) + call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !12) +; CHECK: call fastcc i8* @add_name_internal(i8* %name, i32 %hash) nounwind, !dbg !13 + %0 = call fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext 0, i32 %flags) nounwind, !dbg !13 ; <i8*> [#uses=1] + ret i8* %0, !dbg !13 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +define internal fastcc i8* @add_name_internal(i8* %name, i32 %len, i32 %hash, i8 zeroext %extra, i32 %flags) nounwind noinline ssp { +entry: + call void @llvm.dbg.value(metadata !{i8* %name}, i64 0, metadata !15) + call void @llvm.dbg.value(metadata !{i32 %len}, i64 0, metadata !20) + call void @llvm.dbg.value(metadata !{i32 %hash}, i64 0, metadata !21) + call void @llvm.dbg.value(metadata !{i8 %extra}, i64 0, metadata !22) + call void @llvm.dbg.value(metadata !{i32 %flags}, i64 0, metadata !23) + %0 = icmp eq i32 %hash, 0, !dbg !24 ; <i1> [#uses=1] + br i1 %0, label %bb, label %bb1, !dbg !24 + +bb: ; preds = %entry + br label %bb2, !dbg !26 + +bb1: ; preds = %entry + br label %bb2, !dbg !27 + +bb2: ; preds = %bb1, %bb + %.0 = phi i8* [ getelementptr inbounds ([1 x i8]* @.str, i64 0, i64 0), %bb ], [ %name, %bb1 ] ; <i8*> [#uses=1] + ret i8* %.0, !dbg !27 +} + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!0 = metadata !{i32 524545, metadata !1, metadata !"name", metadata !2, i32 8, metadata !6} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 524334, i32 0, metadata !2, metadata !"vfs_addname", metadata !"vfs_addname", metadata !"vfs_addname", metadata !2, i32 12, metadata !4, i1 false, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 524329, metadata !"tail.c", metadata !"/Users/echeng/LLVM/radars/r7927803/", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 524305, i32 0, i32 1, metadata !"tail.c", metadata !"/Users/echeng/LLVM/radars/r7927803/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build 9999)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !5, i32 0, null} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{metadata !6, metadata !6, metadata !9, metadata !9, metadata !9} +!6 = metadata !{i32 524303, metadata !2, metadata !"", metadata !2, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !7} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 524326, metadata !2, metadata !"", metadata !2, i32 0, i64 8, i64 8, i64 0, i32 0, metadata !8} ; [ DW_TAG_const_type ] +!8 = metadata !{i32 524324, metadata !2, metadata !"char", metadata !2, i32 0, i64 8, i64 8, i64 0, i32 0, i32 6} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 524324, metadata !2, metadata !"unsigned int", metadata !2, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!10 = metadata !{i32 524545, metadata !1, metadata !"len", metadata !2, i32 9, metadata !9} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 524545, metadata !1, metadata !"hash", metadata !2, i32 10, metadata !9} ; [ DW_TAG_arg_variable ] +!12 = metadata !{i32 524545, metadata !1, metadata !"flags", metadata !2, i32 11, metadata !9} ; [ DW_TAG_arg_variable ] +!13 = metadata !{i32 13, i32 0, metadata !14, null} +!14 = metadata !{i32 524299, metadata !1, i32 12, i32 0} ; [ DW_TAG_lexical_block ] +!15 = metadata !{i32 524545, metadata !16, metadata !"name", metadata !2, i32 17, metadata !6} ; [ DW_TAG_arg_variable ] +!16 = metadata !{i32 524334, i32 0, metadata !2, metadata !"add_name_internal", metadata !"add_name_internal", metadata !"add_name_internal", metadata !2, i32 22, metadata !17, i1 true, i1 true, i32 0, i32 0, null, i1 false} ; [ DW_TAG_subprogram ] +!17 = metadata !{i32 524309, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !18, i32 0, null} ; [ DW_TAG_subroutine_type ] +!18 = metadata !{metadata !6, metadata !6, metadata !9, metadata !9, metadata !19, metadata !9} +!19 = metadata !{i32 524324, metadata !2, metadata !"unsigned char", metadata !2, i32 0, i64 8, i64 8, i64 0, i32 0, i32 8} ; [ DW_TAG_base_type ] +!20 = metadata !{i32 524545, metadata !16, metadata !"len", metadata !2, i32 18, metadata !9} ; [ DW_TAG_arg_variable ] +!21 = metadata !{i32 524545, metadata !16, metadata !"hash", metadata !2, i32 19, metadata !9} ; [ DW_TAG_arg_variable ] +!22 = metadata !{i32 524545, metadata !16, metadata !"extra", metadata !2, i32 20, metadata !19} ; [ DW_TAG_arg_variable ] +!23 = metadata !{i32 524545, metadata !16, metadata !"flags", metadata !2, i32 21, metadata !9} ; [ DW_TAG_arg_variable ] +!24 = metadata !{i32 23, i32 0, metadata !25, null} +!25 = metadata !{i32 524299, metadata !16, i32 22, i32 0} ; [ DW_TAG_lexical_block ] +!26 = metadata !{i32 24, i32 0, metadata !25, null} +!27 = metadata !{i32 26, i32 0, metadata !25, null} diff --git a/test/Transforms/DeadArgElim/deadexternal.ll b/test/Transforms/DeadArgElim/deadexternal.ll new file mode 100644 index 000000000000..7256b93af1a2 --- /dev/null +++ b/test/Transforms/DeadArgElim/deadexternal.ll @@ -0,0 +1,13 @@ +; RUN: opt -deadargelim -S %s | FileCheck %s +; XFAIL: * + +define void @test(i32) { + ret void +} + +define void @foo() { + call void @test(i32 0) + ret void +; CHECK: @foo +; CHECK: i32 undef +} diff --git a/test/Transforms/DeadStoreElimination/crash.ll b/test/Transforms/DeadStoreElimination/crash.ll index 6d8ba71b2094..5aac877a9ecf 100644 --- a/test/Transforms/DeadStoreElimination/crash.ll +++ b/test/Transforms/DeadStoreElimination/crash.ll @@ -54,4 +54,4 @@ dead: store i32 4, i32* %P2 store i32 4, i32* %Q2 br label %dead -}
\ No newline at end of file +} diff --git a/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll b/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll new file mode 100644 index 000000000000..066e3038b087 --- /dev/null +++ b/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll @@ -0,0 +1,46 @@ +; RUN: opt < %s -gvn -enable-full-load-pre -S | FileCheck %s + +define i8* @cat(i8* %s1, ...) nounwind { +entry: + br i1 undef, label %bb, label %bb3 + +bb: ; preds = %entry + unreachable + +bb3: ; preds = %entry + store i8* undef, i8** undef, align 4 + br i1 undef, label %bb5, label %bb6 + +bb5: ; preds = %bb3 + unreachable + +bb6: ; preds = %bb3 + br label %bb12 + +bb8: ; preds = %bb12 + br i1 undef, label %bb9, label %bb10 + +bb9: ; preds = %bb8 + %0 = load i8** undef, align 4 ; <i8*> [#uses=0] + %1 = load i8** undef, align 4 ; <i8*> [#uses=0] + br label %bb11 + +bb10: ; preds = %bb8 + br label %bb11 + +bb11: ; preds = %bb10, %bb9 +; CHECK: bb11: +; CHECK: phi +; CHECK-NOT: phi + br label %bb12 + +bb12: ; preds = %bb11, %bb6 +; CHECK: bb12: +; CHECK: phi +; CHECK-NOT: phi + br i1 undef, label %bb8, label %bb13 + +bb13: ; preds = %bb12 +; CHECK: bb13: + ret i8* undef +} diff --git a/test/Transforms/GVN/invariant-simple.ll b/test/Transforms/GVN/invariant-simple.ll index 6de75f14350a..0a4182c410ae 100644 --- a/test/Transforms/GVN/invariant-simple.ll +++ b/test/Transforms/GVN/invariant-simple.ll @@ -33,4 +33,4 @@ entry: declare i32 @foo(i8*) nounwind declare i32 @bar(i8*) nounwind readonly declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly -declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P)
\ No newline at end of file +declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) diff --git a/test/Transforms/GVN/lifetime-simple.ll b/test/Transforms/GVN/lifetime-simple.ll index 8139246dcf3c..48e5bc8bb63f 100644 --- a/test/Transforms/GVN/lifetime-simple.ll +++ b/test/Transforms/GVN/lifetime-simple.ll @@ -16,5 +16,5 @@ entry: ret i8 %1 } -declare {}* @llvm.lifetime.start(i64 %S, i8* nocapture %P) readonly -declare void @llvm.lifetime.end(i64 %S, i8* nocapture %P)
\ No newline at end of file +declare void @llvm.lifetime.start(i64 %S, i8* nocapture %P) readonly +declare void @llvm.lifetime.end(i64 %S, i8* nocapture %P) diff --git a/test/Transforms/GlobalOpt/crash.ll b/test/Transforms/GlobalOpt/crash.ll index a45cbe9c0f6f..701472c059a8 100644 --- a/test/Transforms/GlobalOpt/crash.ll +++ b/test/Transforms/GlobalOpt/crash.ll @@ -9,8 +9,34 @@ target triple = "i386-apple-darwin9.8" @_ZL6vTwist = global %struct.btSimdScalar zeroinitializer ; <%struct.btSimdScalar*> [#uses=1] @llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev }] ; <[12 x %0]*> [#uses=0] -define internal void @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { +define internal void @_GLOBAL__I__ZN21btConeTwistConstraintC2Ev() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { entry: store float 1.0, float* getelementptr inbounds (%struct.btSimdScalar* @_ZL6vTwist, i32 0, i32 0, i32 0, i32 3), align 4 ret void } + + +; PR6760 +%T = type { [5 x i32] } + +@switch_inf = internal global %T* null + +define void @test(i8* %arch_file, i32 %route_type) { +entry: + %A = sext i32 1 to i64 + %B = mul i64 %A, 20 + %C = call noalias i8* @malloc(i64 %B) nounwind + %D = bitcast i8* %C to %T* + store %T* %D, %T** @switch_inf, align 8 + unreachable + +bb.nph.i: + %scevgep.i539 = getelementptr i8* %C, i64 4 + unreachable + +xx: + %E = load %T** @switch_inf, align 8 + unreachable +} + +declare noalias i8* @malloc(i64) nounwind diff --git a/test/Transforms/GlobalOpt/malloc-promote-2.ll b/test/Transforms/GlobalOpt/malloc-promote-2.ll index f989b798b45f..6cb44812d2b6 100644 --- a/test/Transforms/GlobalOpt/malloc-promote-2.ll +++ b/test/Transforms/GlobalOpt/malloc-promote-2.ll @@ -1,24 +1,19 @@ -; RUN: opt < %s -globalopt -globaldce -S | not grep malloc +; RUN: opt < %s -globalopt -S | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" -@G = internal global i32* null ; <i32**> [#uses=3] +@G = internal global i32* null -define void @init() { - %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) ; <i8*> [#uses=1] - %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1] - store i32* %P, i32** @G - %GV = load i32** @G ; <i32*> [#uses=1] - %GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1] - store i32 20, i32* %GVe - ret void +define void @t() { +; CHECK: @t() +; CHECK-NOT: call i8* @malloc +; CHECK-NEXT: ret void + %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) + %P = bitcast i8* %malloccall to i32* + store i32* %P, i32** @G + %GV = load i32** @G + %GVe = getelementptr i32* %GV, i32 40 + store i32 20, i32* %GVe + ret void } declare noalias i8* @malloc(i64) - -define i32 @get() { - %GV = load i32** @G ; <i32*> [#uses=1] - %GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1] - %V = load i32* %GVe ; <i32> [#uses=1] - ret i32 %V -} - diff --git a/test/Transforms/GlobalOpt/malloc-promote-3.ll b/test/Transforms/GlobalOpt/malloc-promote-3.ll deleted file mode 100644 index 57f937d8c929..000000000000 --- a/test/Transforms/GlobalOpt/malloc-promote-3.ll +++ /dev/null @@ -1,30 +0,0 @@ -; RUN: opt < %s -globalopt -globaldce -S | not grep malloc -target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" - -@G = internal global i32* null ; <i32**> [#uses=4] - -define void @init() { - %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) ; <i8*> [#uses=1] - %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1] - store i32* %P, i32** @G - %GV = load i32** @G ; <i32*> [#uses=1] - %GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1] - store i32 20, i32* %GVe - ret void -} - -declare noalias i8* @malloc(i64) - -define i32 @get() { - %GV = load i32** @G ; <i32*> [#uses=1] - %GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1] - %V = load i32* %GVe ; <i32> [#uses=1] - ret i32 %V -} - -define i1 @check() { - %GV = load i32** @G ; <i32*> [#uses=1] - %V = icmp eq i32* %GV, null ; <i1> [#uses=1] - ret i1 %V -} - diff --git a/test/Transforms/GlobalOpt/metadata.ll b/test/Transforms/GlobalOpt/metadata.ll new file mode 100644 index 000000000000..a09ba72439fc --- /dev/null +++ b/test/Transforms/GlobalOpt/metadata.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -globalopt < %s | FileCheck %s + +; PR6112 - When globalopt does RAUW(@G, %G), the metadata reference should drop +; to null. +@G = internal global i8** null + +define i32 @main(i32 %argc, i8** %argv) { +; CHECK: @main +; CHECK: %G = alloca + store i8** %argv, i8*** @G + ret i32 0 +} + +!named = !{!0} + +; CHECK: !0 = metadata !{null} +!0 = metadata !{i8*** @G} + + diff --git a/test/Transforms/IndVarSimplify/casted-argument.ll b/test/Transforms/IndVarSimplify/casted-argument.ll index dfefe1dc5bbe..a5e002b4578f 100644 --- a/test/Transforms/IndVarSimplify/casted-argument.ll +++ b/test/Transforms/IndVarSimplify/casted-argument.ll @@ -47,4 +47,4 @@ if.end54: ; preds = %if.end54, %if.else declare void @bcopy(i8* nocapture) nounwind -declare void @bcopy_4038(i8*, i32) nounwind +declare void @bcopy_4038(i8*, i8*, i32) nounwind diff --git a/test/Transforms/IndVarSimplify/crash.ll b/test/Transforms/IndVarSimplify/crash.ll index 14f79fefb180..ab438334c660 100644 --- a/test/Transforms/IndVarSimplify/crash.ll +++ b/test/Transforms/IndVarSimplify/crash.ll @@ -16,4 +16,4 @@ define void @t2(i1* %P) nounwind { ; <label>:6 ; preds = %1 ret void -}
\ No newline at end of file +} diff --git a/test/Transforms/IndVarSimplify/eliminate-comparison.ll b/test/Transforms/IndVarSimplify/eliminate-comparison.ll new file mode 100644 index 000000000000..953bbdff5c62 --- /dev/null +++ b/test/Transforms/IndVarSimplify/eliminate-comparison.ll @@ -0,0 +1,108 @@ +; RUN: opt -indvars -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" + +@X = external global [0 x double] + +; Indvars should be able to simplify simple comparisons involving +; induction variables. + +; CHECK: @foo +; CHECK: %cond = and i1 %tobool.not, true + +define void @foo(i64 %n, i32* nocapture %p) nounwind { +entry: + %cmp9 = icmp sgt i64 %n, 0 + br i1 %cmp9, label %pre, label %return + +pre: + %t3 = load i32* %p + %tobool.not = icmp ne i32 %t3, 0 + br label %loop + +loop: + %i = phi i64 [ 0, %pre ], [ %inc, %for.inc ] + %cmp6 = icmp slt i64 %i, %n + %cond = and i1 %tobool.not, %cmp6 + br i1 %cond, label %if.then, label %for.inc + +if.then: + %arrayidx = getelementptr [0 x double]* @X, i64 0, i64 %i + store double 3.200000e+00, double* %arrayidx + br label %for.inc + +for.inc: + %inc = add nsw i64 %i, 1 + %exitcond = icmp sge i64 %inc, %n + br i1 %exitcond, label %return, label %loop + +return: + ret void +} + +; Don't eliminate an icmp that's contributing to the loop exit test though. + +; CHECK: @_ZNK4llvm5APInt3ultERKS0_ +; CHECK: %tmp99 = icmp sgt i32 %i, -1 + +define i32 @_ZNK4llvm5APInt3ultERKS0_(i32 %tmp2.i1, i64** %tmp65, i64** %tmp73, i64** %tmp82, i64** %tmp90) { +entry: + br label %bb18 + +bb13: + %tmp66 = load i64** %tmp65, align 4 + %tmp68 = getelementptr inbounds i64* %tmp66, i32 %i + %tmp69 = load i64* %tmp68, align 4 + %tmp74 = load i64** %tmp73, align 4 + %tmp76 = getelementptr inbounds i64* %tmp74, i32 %i + %tmp77 = load i64* %tmp76, align 4 + %tmp78 = icmp ugt i64 %tmp69, %tmp77 + br i1 %tmp78, label %bb20.loopexit, label %bb15 + +bb15: + %tmp83 = load i64** %tmp82, align 4 + %tmp85 = getelementptr inbounds i64* %tmp83, i32 %i + %tmp86 = load i64* %tmp85, align 4 + %tmp91 = load i64** %tmp90, align 4 + %tmp93 = getelementptr inbounds i64* %tmp91, i32 %i + %tmp94 = load i64* %tmp93, align 4 + %tmp95 = icmp ult i64 %tmp86, %tmp94 + br i1 %tmp95, label %bb20.loopexit, label %bb17 + +bb17: + %tmp97 = add nsw i32 %i, -1 + br label %bb18 + +bb18: + %i = phi i32 [ %tmp2.i1, %entry ], [ %tmp97, %bb17 ] + %tmp99 = icmp sgt i32 %i, -1 + br i1 %tmp99, label %bb13, label %bb20.loopexit + +bb20.loopexit: + %tmp.0.ph = phi i32 [ 0, %bb18 ], [ 1, %bb15 ], [ 0, %bb13 ] + ret i32 %tmp.0.ph +} + +; Indvars should eliminate the icmp here. + +; CHECK: @func_10 +; CHECK-NOT: icmp +; CHECK: ret void + +define void @func_10() nounwind { +entry: + br label %loop + +loop: + %i = phi i32 [ %i.next, %loop ], [ 0, %entry ] + %t0 = icmp slt i32 %i, 0 + %t1 = zext i1 %t0 to i32 + %t2 = add i32 %t1, %i + %u3 = zext i32 %t2 to i64 + store i64 %u3, i64* null + %i.next = add i32 %i, 1 + br i1 undef, label %loop, label %return + +return: + ret void +} diff --git a/test/Transforms/IndVarSimplify/eliminate-max.ll b/test/Transforms/IndVarSimplify/eliminate-max.ll new file mode 100644 index 000000000000..c25bd0e35418 --- /dev/null +++ b/test/Transforms/IndVarSimplify/eliminate-max.ll @@ -0,0 +1,52 @@ +; RUN: opt < %s -S -indvars | grep {= icmp} | count 3 +; PR4914.ll + +; Indvars should be able to do range analysis and eliminate icmps. +; There are two here which cannot be eliminated. +; There's one that icmp which can be eliminated and which indvars currently +; cannot eliminate, because it requires analyzing more than just the +; range of the induction variable. + +@0 = private constant [4 x i8] c"%d\0A\00", align 1 ; <[4 x i8]*> [#uses=1] + +define i32 @main() nounwind { +bb: + br label %bb1 + +bb1: ; preds = %bb14, %bb + %t = phi i32 [ 0, %bb ], [ %t19, %bb14 ] ; <i32> [#uses=5] + %t2 = phi i32 [ 0, %bb ], [ %t18, %bb14 ] ; <i32> [#uses=1] + %t3 = icmp slt i32 %t, 0 ; <i1> [#uses=1] + br i1 %t3, label %bb7, label %bb4 + +bb4: ; preds = %bb1 + %t5 = icmp sgt i32 %t, 255 ; <i1> [#uses=1] + %t6 = select i1 %t5, i32 255, i32 %t ; <i32> [#uses=1] + br label %bb7 + +bb7: ; preds = %bb4, %bb1 + %t8 = phi i32 [ %t6, %bb4 ], [ 0, %bb1 ] ; <i32> [#uses=1] + %t9 = sub i32 0, %t ; <i32> [#uses=3] + %t10 = icmp slt i32 %t9, 0 ; <i1> [#uses=1] + br i1 %t10, label %bb14, label %bb11 + +bb11: ; preds = %bb7 + %t12 = icmp sgt i32 %t9, 255 ; <i1> [#uses=1] + %t13 = select i1 %t12, i32 255, i32 %t9 ; <i32> [#uses=1] + br label %bb14 + +bb14: ; preds = %bb11, %bb7 + %t15 = phi i32 [ %t13, %bb11 ], [ 0, %bb7 ] ; <i32> [#uses=1] + %t16 = add nsw i32 %t2, 255 ; <i32> [#uses=1] + %t17 = add nsw i32 %t16, %t8 ; <i32> [#uses=1] + %t18 = add nsw i32 %t17, %t15 ; <i32> [#uses=2] + %t19 = add nsw i32 %t, 1 ; <i32> [#uses=2] + %t20 = icmp slt i32 %t19, 1000000000 ; <i1> [#uses=1] + br i1 %t20, label %bb1, label %bb21 + +bb21: ; preds = %bb14 + %t22 = call i32 (i8*, ...)* @printf(i8* noalias getelementptr inbounds ([4 x i8]* @0, i32 0, i32 0), i32 %t18) nounwind + ret i32 0 +} + +declare i32 @printf(i8* noalias nocapture, ...) nounwind diff --git a/test/Transforms/IndVarSimplify/eliminate-rem.ll b/test/Transforms/IndVarSimplify/eliminate-rem.ll new file mode 100644 index 000000000000..f756389398fb --- /dev/null +++ b/test/Transforms/IndVarSimplify/eliminate-rem.ll @@ -0,0 +1,121 @@ +; RUN: opt -indvars -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" + +; Indvars should be able to eliminate this srem. +; CHECK: @simple +; CHECK-NOT: rem +; CHECK: ret + +define void @simple(i64 %arg, double* %arg3) nounwind { +bb: + %t = icmp slt i64 0, %arg ; <i1> [#uses=1] + br i1 %t, label %bb4, label %bb12 + +bb4: ; preds = %bb + br label %bb5 + +bb5: ; preds = %bb4, %bb5 + %t6 = phi i64 [ %t9, %bb5 ], [ 0, %bb4 ] ; <i64> [#uses=2] + %t7 = srem i64 %t6, %arg ; <i64> [#uses=1] + %t8 = getelementptr inbounds double* %arg3, i64 %t7 ; <double*> [#uses=1] + store double 0.000000e+00, double* %t8 + %t9 = add nsw i64 %t6, 1 ; <i64> [#uses=2] + %t10 = icmp slt i64 %t9, %arg ; <i1> [#uses=1] + br i1 %t10, label %bb5, label %bb11 + +bb11: ; preds = %bb5 + br label %bb12 + +bb12: ; preds = %bb11, %bb + ret void +} + +; Indvars should be able to eliminate the (i+1)%n. +; CHECK: @f +; CHECK-NOT: rem +; CHECK: rem +; CHECK-NOT: rem +; CHECK: ret + +define i32 @f(i64* %arg, i64 %arg1, i64 %arg2, i64 %arg3) nounwind { +bb: + %t = icmp sgt i64 %arg1, 0 ; <i1> [#uses=1] + br i1 %t, label %bb4, label %bb54 + +bb4: ; preds = %bb + br label %bb5 + +bb5: ; preds = %bb49, %bb4 + %t6 = phi i64 [ %t51, %bb49 ], [ 0, %bb4 ] ; <i64> [#uses=4] + %t7 = phi i32 [ %t50, %bb49 ], [ 0, %bb4 ] ; <i32> [#uses=2] + %t8 = add nsw i64 %t6, %arg1 ; <i64> [#uses=1] + %t9 = add nsw i64 %t8, -2 ; <i64> [#uses=1] + %t10 = srem i64 %t9, %arg1 ; <i64> [#uses=1] + %t11 = add nsw i64 %t10, 1 ; <i64> [#uses=1] + %t12 = add nsw i64 %t6, 1 ; <i64> [#uses=1] + %t13 = srem i64 %t12, %arg1 ; <i64> [#uses=1] + %t14 = icmp sgt i64 %arg1, 0 ; <i1> [#uses=1] + br i1 %t14, label %bb15, label %bb49 + +bb15: ; preds = %bb5 + br label %bb16 + +bb16: ; preds = %bb44, %bb15 + %t17 = phi i64 [ %t46, %bb44 ], [ 0, %bb15 ] ; <i64> [#uses=1] + %t18 = phi i32 [ %t45, %bb44 ], [ %t7, %bb15 ] ; <i32> [#uses=2] + %t19 = icmp sgt i64 %arg1, 0 ; <i1> [#uses=1] + br i1 %t19, label %bb20, label %bb44 + +bb20: ; preds = %bb16 + br label %bb21 + +bb21: ; preds = %bb21, %bb20 + %t22 = phi i64 [ %t41, %bb21 ], [ 0, %bb20 ] ; <i64> [#uses=4] + %t23 = phi i32 [ %t40, %bb21 ], [ %t18, %bb20 ] ; <i32> [#uses=1] + %t24 = mul i64 %t6, %arg1 ; <i64> [#uses=1] + %t25 = mul i64 %t13, %arg1 ; <i64> [#uses=1] + %t26 = add nsw i64 %t24, %t22 ; <i64> [#uses=1] + %t27 = mul i64 %t11, %arg1 ; <i64> [#uses=1] + %t28 = add nsw i64 %t25, %t22 ; <i64> [#uses=1] + %t29 = getelementptr inbounds i64* %arg, i64 %t26 ; <i64*> [#uses=1] + %t30 = add nsw i64 %t27, %t22 ; <i64> [#uses=1] + %t31 = getelementptr inbounds i64* %arg, i64 %t28 ; <i64*> [#uses=1] + %t32 = zext i32 %t23 to i64 ; <i64> [#uses=1] + %t33 = load i64* %t29 ; <i64> [#uses=1] + %t34 = getelementptr inbounds i64* %arg, i64 %t30 ; <i64*> [#uses=1] + %t35 = load i64* %t31 ; <i64> [#uses=1] + %t36 = add nsw i64 %t32, %t33 ; <i64> [#uses=1] + %t37 = add nsw i64 %t36, %t35 ; <i64> [#uses=1] + %t38 = load i64* %t34 ; <i64> [#uses=1] + %t39 = add nsw i64 %t37, %t38 ; <i64> [#uses=1] + %t40 = trunc i64 %t39 to i32 ; <i32> [#uses=2] + %t41 = add nsw i64 %t22, 1 ; <i64> [#uses=2] + %t42 = icmp slt i64 %t41, %arg1 ; <i1> [#uses=1] + br i1 %t42, label %bb21, label %bb43 + +bb43: ; preds = %bb21 + br label %bb44 + +bb44: ; preds = %bb43, %bb16 + %t45 = phi i32 [ %t18, %bb16 ], [ %t40, %bb43 ] ; <i32> [#uses=2] + %t46 = add nsw i64 %t17, 1 ; <i64> [#uses=2] + %t47 = icmp slt i64 %t46, %arg1 ; <i1> [#uses=1] + br i1 %t47, label %bb16, label %bb48 + +bb48: ; preds = %bb44 + br label %bb49 + +bb49: ; preds = %bb48, %bb5 + %t50 = phi i32 [ %t7, %bb5 ], [ %t45, %bb48 ] ; <i32> [#uses=2] + %t51 = add nsw i64 %t6, 1 ; <i64> [#uses=2] + %t52 = icmp slt i64 %t51, %arg1 ; <i1> [#uses=1] + br i1 %t52, label %bb5, label %bb53 + +bb53: ; preds = %bb49 + br label %bb54 + +bb54: ; preds = %bb53, %bb + %t55 = phi i32 [ 0, %bb ], [ %t50, %bb53 ] ; <i32> [#uses=1] + ret i32 %t55 +} diff --git a/test/Transforms/IndVarSimplify/udiv.ll b/test/Transforms/IndVarSimplify/udiv.ll new file mode 100644 index 000000000000..8260093d1c37 --- /dev/null +++ b/test/Transforms/IndVarSimplify/udiv.ll @@ -0,0 +1,162 @@ +; RUN: opt -indvars -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" + +@main.flags = internal global [8193 x i8] zeroinitializer, align 1 ; <[8193 x i8]*> [#uses=5] +@.str = private constant [11 x i8] c"Count: %d\0A\00" ; <[11 x i8]*> [#uses=1] + +; Indvars shouldn't emit a udiv here, because there's no udiv in the +; original code. This comes from SingleSource/Benchmarks/Shootout/sieve.c. + +; CHECK: @main +; CHECK-NOT: div + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { +entry: + %cmp = icmp eq i32 %argc, 2 ; <i1> [#uses=1] + br i1 %cmp, label %cond.true, label %while.cond.preheader + +cond.true: ; preds = %entry + %arrayidx = getelementptr inbounds i8** %argv, i64 1 ; <i8**> [#uses=1] + %tmp2 = load i8** %arrayidx ; <i8*> [#uses=1] + %call = tail call i32 @atoi(i8* %tmp2) nounwind readonly ; <i32> [#uses=1] + br label %while.cond.preheader + +while.cond.preheader: ; preds = %entry, %cond.true + %NUM.0.ph = phi i32 [ %call, %cond.true ], [ 170000, %entry ] ; <i32> [#uses=2] + %tobool18 = icmp eq i32 %NUM.0.ph, 0 ; <i1> [#uses=1] + br i1 %tobool18, label %while.end, label %bb.nph30 + +while.cond.loopexit: ; preds = %for.cond12.while.cond.loopexit_crit_edge, %for.cond12.loopexit + %count.2.lcssa = phi i32 [ %count.1.lcssa, %for.cond12.while.cond.loopexit_crit_edge ], [ 0, %for.cond12.loopexit ] ; <i32> [#uses=1] + br label %while.cond + +while.cond: ; preds = %while.cond.loopexit + %tobool = icmp eq i32 %dec19, 0 ; <i1> [#uses=1] + br i1 %tobool, label %while.cond.while.end_crit_edge, label %for.cond.preheader + +while.cond.while.end_crit_edge: ; preds = %while.cond + %count.2.lcssa.lcssa = phi i32 [ %count.2.lcssa, %while.cond ] ; <i32> [#uses=1] + br label %while.end + +bb.nph30: ; preds = %while.cond.preheader + br label %for.cond.preheader + +for.cond.preheader: ; preds = %bb.nph30, %while.cond + %dec19.in = phi i32 [ %NUM.0.ph, %bb.nph30 ], [ %dec19, %while.cond ] ; <i32> [#uses=1] + %dec19 = add i32 %dec19.in, -1 ; <i32> [#uses=2] + br i1 true, label %bb.nph, label %for.cond12.loopexit + +for.cond: ; preds = %for.body + %cmp8 = icmp slt i64 %inc, 8193 ; <i1> [#uses=1] + br i1 %cmp8, label %for.body, label %for.cond.for.cond12.loopexit_crit_edge + +for.cond.for.cond12.loopexit_crit_edge: ; preds = %for.cond + br label %for.cond12.loopexit + +bb.nph: ; preds = %for.cond.preheader + br label %for.body + +for.body: ; preds = %bb.nph, %for.cond + %i.02 = phi i64 [ 2, %bb.nph ], [ %inc, %for.cond ] ; <i64> [#uses=2] + %arrayidx10 = getelementptr inbounds [8193 x i8]* @main.flags, i64 0, i64 %i.02 ; <i8*> [#uses=1] + store i8 1, i8* %arrayidx10 + %inc = add nsw i64 %i.02, 1 ; <i64> [#uses=2] + br label %for.cond + +for.cond12.loopexit: ; preds = %for.cond.for.cond12.loopexit_crit_edge, %for.cond.preheader + br i1 true, label %bb.nph16, label %while.cond.loopexit + +for.cond12: ; preds = %for.inc35 + %cmp14 = icmp slt i64 %inc37, 8193 ; <i1> [#uses=1] + br i1 %cmp14, label %for.body15, label %for.cond12.while.cond.loopexit_crit_edge + +for.cond12.while.cond.loopexit_crit_edge: ; preds = %for.cond12 + %count.1.lcssa = phi i32 [ %count.1, %for.cond12 ] ; <i32> [#uses=1] + br label %while.cond.loopexit + +bb.nph16: ; preds = %for.cond12.loopexit + br label %for.body15 + +for.body15: ; preds = %bb.nph16, %for.cond12 + %count.212 = phi i32 [ 0, %bb.nph16 ], [ %count.1, %for.cond12 ] ; <i32> [#uses=2] + %i.17 = phi i64 [ 2, %bb.nph16 ], [ %inc37, %for.cond12 ] ; <i64> [#uses=4] + %arrayidx17 = getelementptr inbounds [8193 x i8]* @main.flags, i64 0, i64 %i.17 ; <i8*> [#uses=1] + %tmp18 = load i8* %arrayidx17 ; <i8> [#uses=1] + %tobool19 = icmp eq i8 %tmp18, 0 ; <i1> [#uses=1] + br i1 %tobool19, label %for.inc35, label %if.then + +if.then: ; preds = %for.body15 + %add = shl i64 %i.17, 1 ; <i64> [#uses=2] + %cmp243 = icmp slt i64 %add, 8193 ; <i1> [#uses=1] + br i1 %cmp243, label %bb.nph5, label %for.end32 + +for.cond22: ; preds = %for.body25 + %cmp24 = icmp slt i64 %add31, 8193 ; <i1> [#uses=1] + br i1 %cmp24, label %for.body25, label %for.cond22.for.end32_crit_edge + +for.cond22.for.end32_crit_edge: ; preds = %for.cond22 + br label %for.end32 + +bb.nph5: ; preds = %if.then + br label %for.body25 + +for.body25: ; preds = %bb.nph5, %for.cond22 + %k.04 = phi i64 [ %add, %bb.nph5 ], [ %add31, %for.cond22 ] ; <i64> [#uses=2] + %arrayidx27 = getelementptr inbounds [8193 x i8]* @main.flags, i64 0, i64 %k.04 ; <i8*> [#uses=1] + store i8 0, i8* %arrayidx27 + %add31 = add nsw i64 %k.04, %i.17 ; <i64> [#uses=2] + br label %for.cond22 + +for.end32: ; preds = %for.cond22.for.end32_crit_edge, %if.then + %inc34 = add nsw i32 %count.212, 1 ; <i32> [#uses=1] + br label %for.inc35 + +for.inc35: ; preds = %for.body15, %for.end32 + %count.1 = phi i32 [ %inc34, %for.end32 ], [ %count.212, %for.body15 ] ; <i32> [#uses=2] + %inc37 = add nsw i64 %i.17, 1 ; <i64> [#uses=2] + br label %for.cond12 + +while.end: ; preds = %while.cond.while.end_crit_edge, %while.cond.preheader + %count.0.lcssa = phi i32 [ %count.2.lcssa.lcssa, %while.cond.while.end_crit_edge ], [ 0, %while.cond.preheader ] ; <i32> [#uses=1] + %call40 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str, i64 0, i64 0), i32 %count.0.lcssa) nounwind ; <i32> [#uses=0] + ret i32 0 +} + +declare i32 @atoi(i8* nocapture) nounwind readonly + +declare i32 @printf(i8* nocapture, ...) nounwind + +; IndVars shouldn't be afraid to emit a udiv here, since there's a udiv in +; the original code. + +; CHECK: @foo +; CHECK: for.body.preheader: +; CHECK-NEXT: udiv + +define void @foo(double* %p, i64 %n) nounwind { +entry: + %div0 = udiv i64 %n, 7 ; <i64> [#uses=1] + %div1 = add i64 %div0, 1 + %cmp2 = icmp ult i64 0, %div1 ; <i1> [#uses=1] + br i1 %cmp2, label %for.body.preheader, label %for.end + +for.body.preheader: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.preheader, %for.body + %i.03 = phi i64 [ %inc, %for.body ], [ 0, %for.body.preheader ] ; <i64> [#uses=2] + %arrayidx = getelementptr inbounds double* %p, i64 %i.03 ; <double*> [#uses=1] + store double 0.000000e+00, double* %arrayidx + %inc = add i64 %i.03, 1 ; <i64> [#uses=2] + %divx = udiv i64 %n, 7 ; <i64> [#uses=1] + %div = add i64 %divx, 1 + %cmp = icmp ult i64 %inc, %div ; <i1> [#uses=1] + br i1 %cmp, label %for.body, label %for.end.loopexit + +for.end.loopexit: ; preds = %for.body + br label %for.end + +for.end: ; preds = %for.end.loopexit, %entry + ret void +} diff --git a/test/Transforms/Inline/2009-01-12-RecursiveInline.ll b/test/Transforms/Inline/2009-01-12-RecursiveInline.ll deleted file mode 100644 index 1a3325a68b61..000000000000 --- a/test/Transforms/Inline/2009-01-12-RecursiveInline.ll +++ /dev/null @@ -1,92 +0,0 @@ -; RUN: opt < %s -inline -S | grep {call.*fib} | count 4 -; First call to fib from fib is inlined, producing 2 instead of 1, total 3. -; Second call to fib from fib is not inlined because new body of fib exceeds -; inlining limit of 200. Plus call in main = 4 total. - -; ModuleID = '<stdin>' -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-darwin9.6" -@"\01LC" = internal constant [5 x i8] c"%ld\0A\00" ; <[5 x i8]*> [#uses=1] - -define i32 @fib(i32 %n) nounwind { -entry: - %n_addr = alloca i32 ; <i32*> [#uses=4] - %retval = alloca i32 ; <i32*> [#uses=2] - %0 = alloca i32 ; <i32*> [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] - store i32 %n, i32* %n_addr - %1 = load i32* %n_addr, align 4 ; <i32> [#uses=1] - %2 = icmp ule i32 %1, 1 ; <i1> [#uses=1] - br i1 %2, label %bb, label %bb1 - -bb: ; preds = %entry - store i32 1, i32* %0, align 4 - br label %bb2 - -bb1: ; preds = %entry - %3 = load i32* %n_addr, align 4 ; <i32> [#uses=1] - %4 = sub i32 %3, 2 ; <i32> [#uses=1] - %5 = call i32 @fib(i32 %4) nounwind ; <i32> [#uses=1] - %6 = load i32* %n_addr, align 4 ; <i32> [#uses=1] - %7 = sub i32 %6, 1 ; <i32> [#uses=1] - %8 = call i32 @fib(i32 %7) nounwind ; <i32> [#uses=1] - %9 = add i32 %5, %8 ; <i32> [#uses=1] - store i32 %9, i32* %0, align 4 - br label %bb2 - -bb2: ; preds = %bb1, %bb - %10 = load i32* %0, align 4 ; <i32> [#uses=1] - store i32 %10, i32* %retval, align 4 - br label %return - -return: ; preds = %bb2 - %retval3 = load i32* %retval ; <i32> [#uses=1] - ret i32 %retval3 -} - -define i32 @main(i32 %argc, i8** %argv) nounwind { -entry: - %argc_addr = alloca i32 ; <i32*> [#uses=2] - %argv_addr = alloca i8** ; <i8***> [#uses=2] - %retval = alloca i32 ; <i32*> [#uses=2] - %N = alloca i32 ; <i32*> [#uses=2] - %0 = alloca i32 ; <i32*> [#uses=2] - %iftmp.0 = alloca i32 ; <i32*> [#uses=3] - %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] - store i32 %argc, i32* %argc_addr - store i8** %argv, i8*** %argv_addr - %1 = load i32* %argc_addr, align 4 ; <i32> [#uses=1] - %2 = icmp eq i32 %1, 2 ; <i1> [#uses=1] - br i1 %2, label %bb, label %bb1 - -bb: ; preds = %entry - %3 = load i8*** %argv_addr, align 4 ; <i8**> [#uses=1] - %4 = getelementptr i8** %3, i32 1 ; <i8**> [#uses=1] - %5 = load i8** %4, align 4 ; <i8*> [#uses=1] - %6 = call i32 @atoi(i8* %5) nounwind ; <i32> [#uses=1] - store i32 %6, i32* %iftmp.0, align 4 - br label %bb2 - -bb1: ; preds = %entry - store i32 43, i32* %iftmp.0, align 4 - br label %bb2 - -bb2: ; preds = %bb1, %bb - %7 = load i32* %iftmp.0, align 4 ; <i32> [#uses=1] - store i32 %7, i32* %N, align 4 - %8 = load i32* %N, align 4 ; <i32> [#uses=1] - %9 = call i32 @fib(i32 %8) nounwind ; <i32> [#uses=1] - %10 = call i32 (i8*, ...)* @printf(i8* getelementptr ([5 x i8]* @"\01LC", i32 0, i32 0), i32 %9) nounwind ; <i32> [#uses=0] - store i32 0, i32* %0, align 4 - %11 = load i32* %0, align 4 ; <i32> [#uses=1] - store i32 %11, i32* %retval, align 4 - br label %return - -return: ; preds = %bb2 - %retval3 = load i32* %retval ; <i32> [#uses=1] - ret i32 %retval3 -} - -declare i32 @atoi(i8*) - -declare i32 @printf(i8*, ...) nounwind diff --git a/test/Transforms/Inline/crash.ll b/test/Transforms/Inline/crash.ll index f34b44c2aa08..1df4d6063e84 100644 --- a/test/Transforms/Inline/crash.ll +++ b/test/Transforms/Inline/crash.ll @@ -86,3 +86,34 @@ bb260: lpad: unwind } + + + +;; This exposed a crash handling devirtualized calls. +define void @f1(void ()* %f) ssp { +entry: + call void %f() + ret void +} + +define void @f4(i32 %size) ssp { +entry: + invoke void @f1(void ()* @f3) + to label %invcont3 unwind label %lpad18 + +invcont3: ; preds = %bb1 + ret void + +lpad18: ; preds = %invcont3, %bb1 + unreachable +} + +define void @f3() ssp { +entry: + unreachable +} + +declare void @f5() ssp + + + diff --git a/test/Transforms/Inline/crash2.ll b/test/Transforms/Inline/crash2.ll new file mode 100644 index 000000000000..cb1f44d5cca7 --- /dev/null +++ b/test/Transforms/Inline/crash2.ll @@ -0,0 +1,29 @@ +; RUN: opt -inline -scalarrepl -max-cg-scc-iterations=1 %s -disable-output +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" + +declare i8* @f1(i8*) ssp align 2 + +define linkonce_odr void @f2(i8* %t) inlinehint ssp { +entry: + unreachable +} + +define linkonce_odr void @f3(void (i8*)* %__f) ssp { +entry: + %__f_addr = alloca void (i8*)*, align 8 + store void (i8*)* %__f, void (i8*)** %__f_addr + + %0 = load void (i8*)** %__f_addr, align 8 + call void %0(i8* undef) + call i8* @f1(i8* undef) ssp + unreachable +} + +define linkonce_odr void @f4(i8* %this) ssp align 2 { +entry: + %0 = alloca i32 + call void @f3(void (i8*)* @f2) ssp + ret void +} + diff --git a/test/Transforms/Inline/devirtualize-2.ll b/test/Transforms/Inline/devirtualize-2.ll new file mode 100644 index 000000000000..02ff7679148d --- /dev/null +++ b/test/Transforms/Inline/devirtualize-2.ll @@ -0,0 +1,44 @@ +; RUN: opt < %s -inline -S | FileCheck %s +; PR4834 + +define i32 @test1() { + %funcall1_ = call fastcc i32 ()* ()* @f1() + %executecommandptr1_ = call i32 %funcall1_() + ret i32 %executecommandptr1_ +} + +define internal fastcc i32 ()* @f1() nounwind readnone { + ret i32 ()* @f2 +} + +define internal i32 @f2() nounwind readnone { + ret i32 1 +} + +; CHECK: @test1() +; CHECK-NEXT: ret i32 1 + + + + + +declare i8* @f1a(i8*) ssp align 2 + +define internal i32 @f2a(i8* %t) inlinehint ssp { +entry: + ret i32 41 +} + +define internal i32 @f3a(i32 (i8*)* %__f) ssp { +entry: + %A = call i32 %__f(i8* undef) + ret i32 %A +} + +define i32 @test2(i8* %this) ssp align 2 { + %X = call i32 @f3a(i32 (i8*)* @f2a) ssp + ret i32 %X +} + +; CHECK: @test2 +; CHECK-NEXT: ret i32 41 diff --git a/test/Transforms/Inline/devirtualize-3.ll b/test/Transforms/Inline/devirtualize-3.ll new file mode 100644 index 000000000000..0a50786498df --- /dev/null +++ b/test/Transforms/Inline/devirtualize-3.ll @@ -0,0 +1,79 @@ +; RUN: opt -inline -S -scalarrepl -gvn -instcombine %s | FileCheck %s +; PR5009 + +; CHECK: define i32 @main() +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @exit(i32 38) + +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" + +%struct.cont_t = type { void (i8*, i32)*, i8* } +%struct.foo_sf_t = type { %struct.cont_t*, i32 } + +define i32 @main() nounwind ssp { +entry: + %cont = alloca %struct.cont_t, align 8 ; <%struct.cont_t*> [#uses=4] + %tmp = getelementptr inbounds %struct.cont_t* %cont, i32 0, i32 0 ; <void (i8*, i32)**> [#uses=1] + %tmp1 = getelementptr inbounds %struct.cont_t* %cont, i32 0, i32 0 ; <void (i8*, i32)**> [#uses=2] + store void (i8*, i32)* bitcast (void (%struct.cont_t*, i32)* @quit to void (i8*, i32)*), void (i8*, i32)** %tmp1 + %tmp2 = load void (i8*, i32)** %tmp1 ; <void (i8*, i32)*> [#uses=1] + store void (i8*, i32)* %tmp2, void (i8*, i32)** %tmp + %tmp3 = getelementptr inbounds %struct.cont_t* %cont, i32 0, i32 1 ; <i8**> [#uses=1] + store i8* null, i8** %tmp3 + call void @foo(%struct.cont_t* %cont) + ret i32 0 +} + +define internal void @quit(%struct.cont_t* %cont, i32 %rcode) nounwind ssp { +entry: + call void @exit(i32 %rcode) noreturn + unreachable +} + +define internal void @foo(%struct.cont_t* %c) nounwind ssp { +entry: + %sf = alloca %struct.foo_sf_t, align 8 ; <%struct.foo_sf_t*> [#uses=3] + %next = alloca %struct.cont_t, align 8 ; <%struct.cont_t*> [#uses=3] + %tmp = getelementptr inbounds %struct.foo_sf_t* %sf, i32 0, i32 0 ; <%struct.cont_t**> [#uses=1] + store %struct.cont_t* %c, %struct.cont_t** %tmp + %tmp2 = getelementptr inbounds %struct.foo_sf_t* %sf, i32 0, i32 1 ; <i32*> [#uses=1] + store i32 2, i32* %tmp2 + %tmp4 = getelementptr inbounds %struct.cont_t* %next, i32 0, i32 0 ; <void (i8*, i32)**> [#uses=1] + store void (i8*, i32)* bitcast (void (%struct.foo_sf_t*, i32)* @foo2 to void (i8*, i32)*), void (i8*, i32)** %tmp4 + %tmp5 = getelementptr inbounds %struct.cont_t* %next, i32 0, i32 1 ; <i8**> [#uses=1] + %conv = bitcast %struct.foo_sf_t* %sf to i8* ; <i8*> [#uses=1] + store i8* %conv, i8** %tmp5 + call void @bar(%struct.cont_t* %next, i32 14) + ret void +} + +define internal void @foo2(%struct.foo_sf_t* %sf, i32 %y) nounwind ssp { +entry: + %tmp1 = getelementptr inbounds %struct.foo_sf_t* %sf, i32 0, i32 0 ; <%struct.cont_t**> [#uses=1] + %tmp2 = load %struct.cont_t** %tmp1 ; <%struct.cont_t*> [#uses=1] + %tmp3 = getelementptr inbounds %struct.cont_t* %tmp2, i32 0, i32 0 ; <void (i8*, i32)**> [#uses=1] + %tmp4 = load void (i8*, i32)** %tmp3 ; <void (i8*, i32)*> [#uses=1] + %tmp6 = getelementptr inbounds %struct.foo_sf_t* %sf, i32 0, i32 0 ; <%struct.cont_t**> [#uses=1] + %tmp7 = load %struct.cont_t** %tmp6 ; <%struct.cont_t*> [#uses=1] + %conv = bitcast %struct.cont_t* %tmp7 to i8* ; <i8*> [#uses=1] + %tmp9 = getelementptr inbounds %struct.foo_sf_t* %sf, i32 0, i32 1 ; <i32*> [#uses=1] + %tmp10 = load i32* %tmp9 ; <i32> [#uses=1] + %mul = mul i32 %tmp10, %y ; <i32> [#uses=1] + call void %tmp4(i8* %conv, i32 %mul) + ret void +} + +define internal void @bar(%struct.cont_t* %c, i32 %y) nounwind ssp { +entry: + %tmp1 = getelementptr inbounds %struct.cont_t* %c, i32 0, i32 0 ; <void (i8*, i32)**> [#uses=1] + %tmp2 = load void (i8*, i32)** %tmp1 ; <void (i8*, i32)*> [#uses=1] + %tmp4 = getelementptr inbounds %struct.cont_t* %c, i32 0, i32 1 ; <i8**> [#uses=1] + %tmp5 = load i8** %tmp4 ; <i8*> [#uses=1] + %add = add nsw i32 %y, 5 ; <i32> [#uses=1] + call void %tmp2(i8* %tmp5, i32 %add) + ret void +} + +declare void @exit(i32) noreturn + diff --git a/test/Transforms/Inline/devirtualize.ll b/test/Transforms/Inline/devirtualize.ll new file mode 100644 index 000000000000..9ed4b6958c38 --- /dev/null +++ b/test/Transforms/Inline/devirtualize.ll @@ -0,0 +1,182 @@ +; RUN: opt -S -inline -scalarrepl -instcombine -simplifycfg -instcombine -gvn -globaldce %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" + + +; Simple devirt testcase, requires iteration between inliner and GVN. +; rdar://6295824 +define i32 @foo(i32 ()** noalias %p, i64* noalias %q) nounwind ssp { +entry: + store i32 ()* @bar, i32 ()** %p + store i64 0, i64* %q + %tmp3 = load i32 ()** %p ; <i32 ()*> [#uses=1] + %call = call i32 %tmp3() ; <i32> [#uses=1] + %X = add i32 %call, 4 + ret i32 %X + +; CHECK: @foo +; CHECK-NEXT: entry: +; CHECK-NEXT: store +; CHECK-NEXT: store +; CHECK-NEXT: ret i32 11 +} + +define internal i32 @bar() nounwind ssp { +entry: + ret i32 7 +} + + +;; More complex devirt case, from PR6724 +; CHECK: @_Z1gv() +; CHECK-NEXT: entry: +; CHECK-NEXT: ret i32 7 + +%0 = type { i8*, i8* } +%1 = type { i8*, i8*, i32, i32, i8*, i64, i8*, i64 } +%2 = type { i8*, i8*, i8* } +%struct.A = type { i8** } +%struct.B = type { i8** } +%struct.C = type { [16 x i8] } +%struct.D = type { [16 x i8] } + +@_ZTV1D = linkonce_odr constant [6 x i8*] [i8* null, i8* bitcast (%2* @_ZTI1D to i8*), i8* bitcast (i32 (%struct.C*)* @_ZN1D1fEv to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI1D to i8*), i8* bitcast (i32 (%struct.C*)* @_ZThn8_N1D1fEv to i8*)] ; <[6 x i8*]*> [#uses=2] +@_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8* ; <i8**> [#uses=1] +@_ZTS1D = linkonce_odr constant [3 x i8] c"1D\00" ; <[3 x i8]*> [#uses=1] +@_ZTVN10__cxxabiv121__vmi_class_type_infoE = external global i8* ; <i8**> [#uses=1] +@_ZTS1C = linkonce_odr constant [3 x i8] c"1C\00" ; <[3 x i8]*> [#uses=1] +@_ZTVN10__cxxabiv117__class_type_infoE = external global i8* ; <i8**> [#uses=1] +@_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00" ; <[3 x i8]*> [#uses=1] +@_ZTI1A = linkonce_odr constant %0 { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8]* @_ZTS1A, i32 0, i32 0) } ; <%0*> [#uses=1] +@_ZTS1B = linkonce_odr constant [3 x i8] c"1B\00" ; <[3 x i8]*> [#uses=1] +@_ZTI1B = linkonce_odr constant %0 { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8]* @_ZTS1B, i32 0, i32 0) } ; <%0*> [#uses=1] +@_ZTI1C = linkonce_odr constant %1 { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8]* @_ZTS1C, i32 0, i32 0), i32 0, i32 2, i8* bitcast (%0* @_ZTI1A to i8*), i64 2, i8* bitcast (%0* @_ZTI1B to i8*), i64 2050 } ; <%1*> [#uses=1] +@_ZTI1D = linkonce_odr constant %2 { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([3 x i8]* @_ZTS1D, i32 0, i32 0), i8* bitcast (%1* @_ZTI1C to i8*) } ; <%2*> [#uses=1] +@_ZTV1C = linkonce_odr constant [6 x i8*] [i8* null, i8* bitcast (%1* @_ZTI1C to i8*), i8* bitcast (i32 (%struct.C*)* @_ZN1C1fEv to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI1C to i8*), i8* bitcast (i32 (%struct.C*)* @_ZThn8_N1C1fEv to i8*)] ; <[6 x i8*]*> [#uses=2] +@_ZTV1B = linkonce_odr constant [3 x i8*] [i8* null, i8* bitcast (%0* @_ZTI1B to i8*), i8* bitcast (i32 (%struct.A*)* @_ZN1B1fEv to i8*)] ; <[3 x i8*]*> [#uses=1] +@_ZTV1A = linkonce_odr constant [3 x i8*] [i8* null, i8* bitcast (%0* @_ZTI1A to i8*), i8* bitcast (i32 (%struct.A*)* @_ZN1A1fEv to i8*)] ; <[3 x i8*]*> [#uses=1] + +define i32 @_Z1gv() ssp { +entry: + %d = alloca %struct.C, align 8 ; <%struct.C*> [#uses=2] + call void @_ZN1DC1Ev(%struct.C* %d) + %call = call i32 @_Z1fP1D(%struct.C* %d) ; <i32> [#uses=1] + %X = add i32 %call, 3 + ret i32 %X +} + +define linkonce_odr void @_ZN1DC1Ev(%struct.C* %this) inlinehint ssp align 2 { +entry: + call void @_ZN1DC2Ev(%struct.C* %this) + ret void +} + +define internal i32 @_Z1fP1D(%struct.C* %d) ssp { +entry: + %0 = icmp eq %struct.C* %d, null ; <i1> [#uses=1] + br i1 %0, label %cast.end, label %cast.notnull + +cast.notnull: ; preds = %entry + %1 = bitcast %struct.C* %d to i8* ; <i8*> [#uses=1] + %add.ptr = getelementptr i8* %1, i64 8 ; <i8*> [#uses=1] + %2 = bitcast i8* %add.ptr to %struct.A* ; <%struct.A*> [#uses=1] + br label %cast.end + +cast.end: ; preds = %entry, %cast.notnull + %3 = phi %struct.A* [ %2, %cast.notnull ], [ null, %entry ] ; <%struct.A*> [#uses=2] + %4 = bitcast %struct.A* %3 to i32 (%struct.A*)*** ; <i32 (%struct.A*)***> [#uses=1] + %5 = load i32 (%struct.A*)*** %4 ; <i32 (%struct.A*)**> [#uses=1] + %vfn = getelementptr inbounds i32 (%struct.A*)** %5, i64 0 ; <i32 (%struct.A*)**> [#uses=1] + %6 = load i32 (%struct.A*)** %vfn ; <i32 (%struct.A*)*> [#uses=1] + %call = call i32 %6(%struct.A* %3) ; <i32> [#uses=1] + ret i32 %call +} + +define linkonce_odr i32 @_ZN1D1fEv(%struct.C* %this) ssp align 2 { +entry: + ret i32 4 +} + +define linkonce_odr i32 @_ZThn8_N1D1fEv(%struct.C* %this) { +entry: + %0 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %1 = getelementptr inbounds i8* %0, i64 -8 ; <i8*> [#uses=1] + %2 = bitcast i8* %1 to %struct.C* ; <%struct.C*> [#uses=1] + %call = call i32 @_ZN1D1fEv(%struct.C* %2) ; <i32> [#uses=1] + ret i32 %call +} + +define linkonce_odr void @_ZN1DC2Ev(%struct.C* %this) inlinehint ssp align 2 { +entry: + call void @_ZN1CC2Ev(%struct.C* %this) + %0 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %1 = getelementptr inbounds i8* %0, i64 0 ; <i8*> [#uses=1] + %2 = bitcast i8* %1 to i8*** ; <i8***> [#uses=1] + store i8** getelementptr inbounds ([6 x i8*]* @_ZTV1D, i64 0, i64 2), i8*** %2 + %3 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %4 = getelementptr inbounds i8* %3, i64 8 ; <i8*> [#uses=1] + %5 = bitcast i8* %4 to i8*** ; <i8***> [#uses=1] + store i8** getelementptr inbounds ([6 x i8*]* @_ZTV1D, i64 0, i64 5), i8*** %5 + ret void +} + +define linkonce_odr void @_ZN1CC2Ev(%struct.C* %this) inlinehint ssp align 2 { +entry: + %0 = bitcast %struct.C* %this to %struct.A* ; <%struct.A*> [#uses=1] + call void @_ZN1AC2Ev(%struct.A* %0) + %1 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %2 = getelementptr inbounds i8* %1, i64 8 ; <i8*> [#uses=1] + %3 = bitcast i8* %2 to %struct.A* ; <%struct.A*> [#uses=1] + call void @_ZN1BC2Ev(%struct.A* %3) + %4 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %5 = getelementptr inbounds i8* %4, i64 0 ; <i8*> [#uses=1] + %6 = bitcast i8* %5 to i8*** ; <i8***> [#uses=1] + store i8** getelementptr inbounds ([6 x i8*]* @_ZTV1C, i64 0, i64 2), i8*** %6 + %7 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %8 = getelementptr inbounds i8* %7, i64 8 ; <i8*> [#uses=1] + %9 = bitcast i8* %8 to i8*** ; <i8***> [#uses=1] + store i8** getelementptr inbounds ([6 x i8*]* @_ZTV1C, i64 0, i64 5), i8*** %9 + ret void +} + +define linkonce_odr i32 @_ZN1C1fEv(%struct.C* %this) ssp align 2 { +entry: + ret i32 3 +} + +define linkonce_odr i32 @_ZThn8_N1C1fEv(%struct.C* %this) { +entry: + %0 = bitcast %struct.C* %this to i8* ; <i8*> [#uses=1] + %1 = getelementptr inbounds i8* %0, i64 -8 ; <i8*> [#uses=1] + %2 = bitcast i8* %1 to %struct.C* ; <%struct.C*> [#uses=1] + %call = call i32 @_ZN1C1fEv(%struct.C* %2) ; <i32> [#uses=1] + ret i32 %call +} + +define linkonce_odr void @_ZN1AC2Ev(%struct.A* %this) inlinehint ssp align 2 { +entry: + %0 = bitcast %struct.A* %this to i8* ; <i8*> [#uses=1] + %1 = getelementptr inbounds i8* %0, i64 0 ; <i8*> [#uses=1] + %2 = bitcast i8* %1 to i8*** ; <i8***> [#uses=1] + store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2), i8*** %2 + ret void +} + +define linkonce_odr void @_ZN1BC2Ev(%struct.A* %this) inlinehint ssp align 2 { +entry: + %0 = bitcast %struct.A* %this to i8* ; <i8*> [#uses=1] + %1 = getelementptr inbounds i8* %0, i64 0 ; <i8*> [#uses=1] + %2 = bitcast i8* %1 to i8*** ; <i8***> [#uses=1] + store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2), i8*** %2 + ret void +} + +define linkonce_odr i32 @_ZN1B1fEv(%struct.A* %this) ssp align 2 { +entry: + ret i32 2 +} + +define linkonce_odr i32 @_ZN1A1fEv(%struct.A* %this) ssp align 2 { +entry: + ret i32 1 +} diff --git a/test/Transforms/Inline/externally_available.ll b/test/Transforms/Inline/externally_available.ll index 43fe5d37f9e8..08b56385ac07 100644 --- a/test/Transforms/Inline/externally_available.ll +++ b/test/Transforms/Inline/externally_available.ll @@ -13,4 +13,4 @@ define i32 @result() { %A = call i32 @test_function() %B = add i32 %A, 1 ret i32 %B -}
\ No newline at end of file +} diff --git a/test/Transforms/Inline/gvn-inline-iteration.ll b/test/Transforms/Inline/gvn-inline-iteration.ll new file mode 100644 index 000000000000..32144d4ebba5 --- /dev/null +++ b/test/Transforms/Inline/gvn-inline-iteration.ll @@ -0,0 +1,23 @@ +; RUN: opt -inline -gvn %s -S -max-cg-scc-iterations=1 | 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" +target triple = "x86_64-apple-darwin10.0.0" + +define i32 @foo(i32 ()** noalias nocapture %p, i64* noalias nocapture %q) nounwind ssp { +entry: + store i32 ()* @bar, i32 ()** %p + store i64 0, i64* %q + %tmp3 = load i32 ()** %p ; <i32 ()*> [#uses=1] + %call = tail call i32 %tmp3() nounwind ; <i32> [#uses=1] + ret i32 %call +} +; CHECK: @foo +; CHECK: ret i32 7 +; CHECK: @bar +; CHECK: ret i32 7 + +define internal i32 @bar() nounwind readnone ssp { +entry: + ret i32 7 +} diff --git a/test/Transforms/Inline/indirect_resolve.ll b/test/Transforms/Inline/indirect_resolve.ll deleted file mode 100644 index 76182e2fe4f6..000000000000 --- a/test/Transforms/Inline/indirect_resolve.ll +++ /dev/null @@ -1,16 +0,0 @@ -; RUN: opt < %s -inline | llvm-dis -; PR4834 - -define i32 @main() { - %funcall1_ = call fastcc i32 ()* ()* @f1() - %executecommandptr1_ = call i32 %funcall1_() - ret i32 %executecommandptr1_ -} - -define internal fastcc i32 ()* @f1() nounwind readnone { - ret i32 ()* @f2 -} - -define internal i32 @f2() nounwind readnone { - ret i32 1 -} diff --git a/test/Transforms/Inline/noinline-recursive-fn.ll b/test/Transforms/Inline/noinline-recursive-fn.ll new file mode 100644 index 000000000000..1d5ebbbf0fa9 --- /dev/null +++ b/test/Transforms/Inline/noinline-recursive-fn.ll @@ -0,0 +1,73 @@ +; The inliner should never inline recursive functions into other functions. +; 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 + +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" + +@g = common global i32 0 ; <i32*> [#uses=1] + +define internal void @foo(i32 %x) nounwind ssp { +entry: + %0 = icmp slt i32 %x, 0 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +bb: ; preds = %entry + %1 = sub nsw i32 %x, 1 ; <i32> [#uses=1] + call void @foo(i32 %1) nounwind ssp + volatile store i32 1, i32* @g, align 4 + ret void + +return: ; preds = %entry + ret void +} + + +;; CHECK: @bonk +;; CHECK: call void @foo(i32 42) +define void @bonk() nounwind ssp { +entry: + call void @foo(i32 42) nounwind ssp + ret void +} + + + +;; Here is an indirect case that should not be infinitely inlined. + +define internal void @f1(i32 %x, i8* %Foo, i8* %Bar) nounwind ssp { +entry: + %0 = bitcast i8* %Bar to void (i32, i8*, i8*)* + %1 = sub nsw i32 %x, 1 + call void %0(i32 %1, i8* %Foo, i8* %Bar) nounwind + volatile store i32 42, i32* @g, align 4 + ret void +} + +define internal void @f2(i32 %x, i8* %Foo, i8* %Bar) nounwind ssp { +entry: + %0 = icmp slt i32 %x, 0 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb + +bb: ; preds = %entry + %1 = bitcast i8* %Foo to void (i32, i8*, i8*)* ; <void (i32, i8*, i8*)*> [#uses=1] + call void %1(i32 %x, i8* %Foo, i8* %Bar) nounwind + volatile store i32 13, i32* @g, align 4 + ret void + +return: ; preds = %entry + ret void +} + + +; CHECK: @top_level +; CHECK: call void @f2(i32 122 +; Here we inline one instance of the cycle, but we don't want to completely +; unroll it. +define void @top_level() nounwind ssp { +entry: + call void @f2(i32 123, i8* bitcast (void (i32, i8*, i8*)* @f1 to i8*), i8* bitcast (void (i32, i8*, i8*)* @f2 to i8*)) nounwind ssp + ret void +} diff --git a/test/Transforms/InstCombine/2007-12-28-IcmpSub2.ll b/test/Transforms/InstCombine/2007-12-28-IcmpSub2.ll index b59548fd8e6f..8721c83521bf 100644 --- a/test/Transforms/InstCombine/2007-12-28-IcmpSub2.ll +++ b/test/Transforms/InstCombine/2007-12-28-IcmpSub2.ll @@ -86,4 +86,4 @@ entry: %cmp = icmp ne i32 %sub, 0 %retval = select i1 %cmp, i32 1, i32 0 ret i32 %retval -}
\ No newline at end of file +} diff --git a/test/Transforms/InstCombine/invariant.ll b/test/Transforms/InstCombine/invariant.ll index c67ad3319593..383238022692 100644 --- a/test/Transforms/InstCombine/invariant.ll +++ b/test/Transforms/InstCombine/invariant.ll @@ -3,13 +3,13 @@ declare void @g(i8*) -declare { }* @llvm.invariant.start(i64, i8* nocapture) nounwind readonly +declare {}* @llvm.invariant.start(i64, i8* nocapture) nounwind readonly define i8 @f() { %a = alloca i8 ; <i8*> [#uses=4] store i8 0, i8* %a - %i = call { }* @llvm.invariant.start(i64 1, i8* %a) ; <{ }*> [#uses=0] - ; CHECK: call { }* @llvm.invariant.start + %i = call {}* @llvm.invariant.start(i64 1, i8* %a) ; <{}*> [#uses=0] + ; CHECK: call {}* @llvm.invariant.start call void @g(i8* %a) %r = load i8* %a ; <i8> [#uses=1] ret i8 %r diff --git a/test/Transforms/InstCombine/objsize.ll b/test/Transforms/InstCombine/objsize.ll index d74312d2e7e9..664701bf2114 100644 --- a/test/Transforms/InstCombine/objsize.ll +++ b/test/Transforms/InstCombine/objsize.ll @@ -111,10 +111,10 @@ define i32 @test4() nounwind ssp { entry: %0 = alloca %struct.data, align 8 %1 = bitcast %struct.data* %0 to i8* - %2 = call i64 @llvm.objectsize.i64(i8* %1, i1 false) nounwind + %2 = call i32 @llvm.objectsize.i32(i8* %1, i1 false) nounwind ; CHECK-NOT: @llvm.objectsize -; CHECK: @llvm.memset.p0i8.i64(i8* %1, i8 0, i64 1824, i32 8, i1 false) - %3 = call i8* @__memset_chk(i8* %1, i32 0, i64 1824, i64 %2) nounwind +; CHECK: @llvm.memset.p0i8.i32(i8* %1, i8 0, i32 1824, i32 8, i1 false) + %3 = call i8* @__memset_chk(i8* %1, i32 0, i32 1824, i32 %2) nounwind ret i32 0 } @@ -145,10 +145,8 @@ entry: ret void } -declare i8* @__memset_chk(i8*, i32, i64, i64) nounwind +declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind declare noalias i8* @malloc(i32) nounwind declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly - -declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly diff --git a/test/Transforms/InstCombine/odr-linkage.ll b/test/Transforms/InstCombine/odr-linkage.ll index a64ef289a4b6..61365b4848ab 100644 --- a/test/Transforms/InstCombine/odr-linkage.ll +++ b/test/Transforms/InstCombine/odr-linkage.ll @@ -16,4 +16,4 @@ define i32 @test() { %c = add i32 %b, %D ret i32 %c } -
\ No newline at end of file + diff --git a/test/Transforms/InstCombine/strcpy_chk.ll b/test/Transforms/InstCombine/strcpy_chk.ll index a20a13c78b23..8835a0ba467c 100644 --- a/test/Transforms/InstCombine/strcpy_chk.ll +++ b/test/Transforms/InstCombine/strcpy_chk.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -instcombine -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" @a = common global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*> [#uses=1] @.str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*> [#uses=1] diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll index 29adc1e20890..5132a8ff9bd1 100644 --- a/test/Transforms/InstCombine/vec_shuffle.ll +++ b/test/Transforms/InstCombine/vec_shuffle.ll @@ -86,4 +86,4 @@ define <4 x i8> @test9(<16 x i8> %tmp6) nounwind { %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 > ; <<4 x i8>> [#uses=1] %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 > ; <<4 x i8>> [#uses=1] ret <4 x i8> %tmp9 -}
\ No newline at end of file +} diff --git a/test/Transforms/JumpThreading/crash.ll b/test/Transforms/JumpThreading/crash.ll index c65fd1014be4..21620bef9ccc 100644 --- a/test/Transforms/JumpThreading/crash.ll +++ b/test/Transforms/JumpThreading/crash.ll @@ -324,3 +324,20 @@ A: ; preds = %entry call void undef(i64 ptrtoint (i8* blockaddress(@test11, %A) to i64)) nounwind unreachable } + +; PR6743 +define void @test12() nounwind ssp { +entry: + br label %lbl_51 + +lbl_51: ; preds = %if.then, %entry + %tmp3 = phi i1 [ false, %if.then ], [ undef, %entry ] ; <i1> [#uses=2] + br i1 %tmp3, label %if.end12, label %if.then + +if.then: ; preds = %lbl_51 + br i1 %tmp3, label %lbl_51, label %if.end12 + +if.end12: ; preds = %if.then, %lbl_51 + ret void +} + diff --git a/test/Transforms/LoopIndexSplit/2008-02-08-Crash.ll b/test/Transforms/LoopIndexSplit/2008-02-08-Crash.ll index 084746494357..3cfd6c96b7b2 100644 --- a/test/Transforms/LoopIndexSplit/2008-02-08-Crash.ll +++ b/test/Transforms/LoopIndexSplit/2008-02-08-Crash.ll @@ -45,4 +45,4 @@ bb39: ; preds = %bb12, %bb3, %bb17 return: ; preds = %bb39 ret void -}
\ No newline at end of file +} diff --git a/test/Transforms/LoopIndexSplit/PR4174-2.ll b/test/Transforms/LoopIndexSplit/PR4174-2.ll new file mode 100644 index 000000000000..cc17bc0a9337 --- /dev/null +++ b/test/Transforms/LoopIndexSplit/PR4174-2.ll @@ -0,0 +1,38 @@ +; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | not grep clone + +declare void @f() + +define fastcc i32 @main() nounwind { +entry: + br label %bb1552 + +bb1552: + %j295.0.reg2mem.0 = phi i32 [ %storemerge110, %bb1669 ], [ 0, %entry ] + br label %bb1553 + +bb1553: + call void @f() + %tmp1628 = icmp sgt i32 %j295.0.reg2mem.0, -3 + br i1 %tmp1628, label %bb1588, label %bb1616 + +bb1588: + br label %bb1616 + +bb1616: + %tmp1629 = icmp sgt i32 %j295.0.reg2mem.0, -3 + br i1 %tmp1629, label %bb1649, label %bb1632 + +bb1632: + br label %bb1669 + +bb1649: + br label %bb1669 + +bb1669: + %storemerge110 = add i32 %j295.0.reg2mem.0, 1 + %tmp1672 = icmp sgt i32 %storemerge110, 3 + br i1 %tmp1672, label %bb1678, label %bb1552 + +bb1678: + ret i32 0 +} diff --git a/test/Transforms/LoopIndexSplit/PR4174.ll b/test/Transforms/LoopIndexSplit/PR4174.ll new file mode 100644 index 000000000000..e8f5a737f05b --- /dev/null +++ b/test/Transforms/LoopIndexSplit/PR4174.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | opt -loop-index-split | llvm-dis | not grep clone + +declare void @f() + +define i32 @main() { +entry: + br label %head +head: + %i = phi i32 [0, %entry], [%i1, %tail] + call void @f() + %splitcond = icmp slt i32 %i, 2 + br i1 %splitcond, label %yes, label %no +yes: + br label %tail +no: + br label %tail +tail: + %i1 = add i32 %i, 1 + %exitcond = icmp slt i32 %i1, 4 + br i1 %exitcond, label %head, label %exit +exit: + ret i32 0 +} diff --git a/test/Transforms/LoopStrengthReduce/insert-positions.ll b/test/Transforms/LoopStrengthReduce/insert-positions.ll new file mode 100644 index 000000000000..1a695f35e3b0 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/insert-positions.ll @@ -0,0 +1,69 @@ +; RUN: llc < %s -march=x86-64 >/dev/null + +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" + +define void @test0() nounwind { +if.end90.i.i: + br label %while.body.i.i221.i + +while.body.i.i221.i: ; preds = %while.cond.backedge.i.i.i, %if.end90.i.i + br i1 undef, label %if.then.i.i224.i, label %while.cond.backedge.i.i.i + +while.cond.backedge.i.i.i: ; preds = %for.end.i.i.i, %while.body.i.i221.i + br label %while.body.i.i221.i + +if.then.i.i224.i: ; preds = %while.body.i.i221.i + switch i32 undef, label %for.cond.i.i226.i [ + i32 92, label %sw.bb.i.i225.i + i32 34, label %sw.bb.i.i225.i + i32 110, label %sw.bb21.i.i.i + ] + +sw.bb.i.i225.i: ; preds = %if.then.i.i224.i, %if.then.i.i224.i + unreachable + +sw.bb21.i.i.i: ; preds = %if.then.i.i224.i + unreachable + +for.cond.i.i226.i: ; preds = %for.body.i.i.i, %if.then.i.i224.i + %0 = phi i64 [ %tmp154.i.i.i, %for.body.i.i.i ], [ 0, %if.then.i.i224.i ] ; <i64> [#uses=2] + %tmp154.i.i.i = add i64 %0, 1 ; <i64> [#uses=2] + %i.0.i.i.i = trunc i64 %0 to i32 ; <i32> [#uses=1] + br i1 undef, label %land.rhs.i.i.i, label %for.end.i.i.i + +land.rhs.i.i.i: ; preds = %for.cond.i.i226.i + br i1 undef, label %for.body.i.i.i, label %for.end.i.i.i + +for.body.i.i.i: ; preds = %land.rhs.i.i.i + br label %for.cond.i.i226.i + +for.end.i.i.i: ; preds = %land.rhs.i.i.i, %for.cond.i.i226.i + %idx.ext.i.i.i = sext i32 %i.0.i.i.i to i64 ; <i64> [#uses=1] + %sub.ptr72.sum.i.i.i = xor i64 %idx.ext.i.i.i, -1 ; <i64> [#uses=1] + %pos.addr.1.sum155.i.i.i = add i64 %tmp154.i.i.i, %sub.ptr72.sum.i.i.i ; <i64> [#uses=1] + %arrayidx76.i.i.i = getelementptr inbounds i8* undef, i64 %pos.addr.1.sum155.i.i.i ; <i8*> [#uses=0] + br label %while.cond.backedge.i.i.i +} + +define void @test1() nounwind { +entry: + %t = shl i32 undef, undef ; <i32> [#uses=1] + %t9 = sub nsw i32 0, %t ; <i32> [#uses=1] + br label %outer + +outer: ; preds = %bb18, %bb + %i12 = phi i32 [ %t21, %bb18 ], [ 0, %entry ] ; <i32> [#uses=2] + %i13 = phi i32 [ %t20, %bb18 ], [ 0, %entry ] ; <i32> [#uses=2] + br label %inner + +inner: ; preds = %bb16, %bb11 + %t17 = phi i32 [ %i13, %outer ], [ undef, %inner ] ; <i32> [#uses=1] + store i32 %t17, i32* undef + br i1 undef, label %bb18, label %inner + +bb18: ; preds = %bb16 + %t19 = add i32 %i13, %t9 ; <i32> [#uses=1] + %t20 = add i32 %t19, %i12 ; <i32> [#uses=1] + %t21 = add i32 %i12, 1 ; <i32> [#uses=1] + br label %outer +} diff --git a/test/Transforms/LoopStrengthReduce/pr2537.ll b/test/Transforms/LoopStrengthReduce/pr2537.ll index 73c3152d30e7..46ad70e736d8 100644 --- a/test/Transforms/LoopStrengthReduce/pr2537.ll +++ b/test/Transforms/LoopStrengthReduce/pr2537.ll @@ -18,4 +18,4 @@ afterdo: ; preds = %dobody ret void } -declare void @b(i128 %add)
\ No newline at end of file +declare void @b(i128 %add) diff --git a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll index 8959c1774099..59f14fcd1ce5 100644 --- a/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll +++ b/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -analyze -iv-users | grep {\{1,+,3,+,2\}<%loop> (post-inc)} +; RUN: opt < %s -analyze -iv-users | grep {\{1,+,3,+,2\}<%loop> (post-inc with loop %loop)} ; The value of %r is dependent on a polynomial iteration expression. diff --git a/test/Transforms/LoopStrengthReduce/uglygep.ll b/test/Transforms/LoopStrengthReduce/uglygep.ll new file mode 100644 index 000000000000..dca97e9ad187 --- /dev/null +++ b/test/Transforms/LoopStrengthReduce/uglygep.ll @@ -0,0 +1,67 @@ +; RUN: opt < %s -loop-reduce -S | not grep uglygep + +; LSR shouldn't consider %t8 to be an interesting user of %t6, and it +; should be able to form pretty GEPs. + +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" + +define void @Z4() nounwind { +bb: + br label %bb3 + +bb1: ; preds = %bb3 + br i1 undef, label %bb10, label %bb2 + +bb2: ; preds = %bb1 + %t = add i64 %t4, 1 ; <i64> [#uses=1] + br label %bb3 + +bb3: ; preds = %bb2, %bb + %t4 = phi i64 [ %t, %bb2 ], [ 0, %bb ] ; <i64> [#uses=3] + br label %bb1 + +bb10: ; preds = %bb9 + %t7 = icmp eq i64 %t4, 0 ; <i1> [#uses=1] + %t3 = add i64 %t4, 16 ; <i64> [#uses=1] + br label %bb14 + +bb14: ; preds = %bb14, %bb10 + %t2 = getelementptr inbounds i8* undef, i64 %t4 ; <i8*> [#uses=1] + store i8 undef, i8* %t2 + %t6 = load float** undef + %t8 = bitcast float* %t6 to i8* ; <i8*> [#uses=1] + %t9 = getelementptr inbounds i8* %t8, i64 %t3 ; <i8*> [#uses=1] + store i8 undef, i8* %t9 + br label %bb14 +} + +define fastcc void @TransformLine() nounwind { +bb: + br label %loop0 + +loop0: ; preds = %loop0, %bb + %i0 = phi i32 [ %i0.next, %loop0 ], [ 0, %bb ] ; <i32> [#uses=2] + %i0.next = add i32 %i0, 1 ; <i32> [#uses=1] + br i1 false, label %loop0, label %bb0 + +bb0: ; preds = %loop0 + br label %loop1 + +loop1: ; preds = %bb5, %bb0 + %i1 = phi i32 [ 0, %bb0 ], [ %i1.next, %bb5 ] ; <i32> [#uses=4] + %t0 = add i32 %i0, %i1 ; <i32> [#uses=1] + br i1 false, label %bb2, label %bb6 + +bb2: ; preds = %loop1 + br i1 true, label %bb6, label %bb5 + +bb5: ; preds = %bb2 + %i1.next = add i32 %i1, 1 ; <i32> [#uses=1] + br i1 true, label %bb6, label %loop1 + +bb6: ; preds = %bb5, %bb2, %loop1 + %p8 = phi i32 [ %t0, %bb5 ], [ undef, %loop1 ], [ undef, %bb2 ] ; <i32> [#uses=0] + %p9 = phi i32 [ undef, %bb5 ], [ %i1, %loop1 ], [ %i1, %bb2 ] ; <i32> [#uses=0] + unreachable +} diff --git a/test/Transforms/LoopUnswitch/crash.ll b/test/Transforms/LoopUnswitch/crash.ll index fac55a6bb1a7..101fb7a2c2ce 100644 --- a/test/Transforms/LoopUnswitch/crash.ll +++ b/test/Transforms/LoopUnswitch/crash.ll @@ -45,3 +45,22 @@ for.body: ; preds = %for.body, %bb.nph for.end: ; preds = %for.body, %entry ret void } + +; PR6879 +define i32* @test3(i32** %p_45, i16 zeroext %p_46, i64 %p_47, i64 %p_48, i16 signext %p_49) nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond4, %entry + br i1 false, label %for.cond4, label %for.end88 + +for.cond4: ; preds = %for.cond + %conv46 = trunc i32 0 to i8 ; <i8> [#uses=2] + %cmp60 = icmp sgt i8 %conv46, 124 ; <i1> [#uses=1] + %or.cond = and i1 undef, %cmp60 ; <i1> [#uses=1] + %cond = select i1 %or.cond, i8 %conv46, i8 undef ; <i8> [#uses=0] + br label %for.cond + +for.end88: ; preds = %for.cond + ret i32* undef +} diff --git a/test/Transforms/PruneEH/2008-09-05-CGUpdate.ll b/test/Transforms/PruneEH/2008-09-05-CGUpdate.ll index 347af8f8463c..33e0cfa3ce53 100644 --- a/test/Transforms/PruneEH/2008-09-05-CGUpdate.ll +++ b/test/Transforms/PruneEH/2008-09-05-CGUpdate.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -prune-eh -inline -print-callgraph \ ; RUN: -disable-output |& \ -; RUN: grep {Calls.*ce3806g__fxio__put__put_int64__4.1339} | count 2 +; RUN: grep {calls.*ce3806g__fxio__put__put_int64__4.1339} | count 2 %struct.FRAME.ce3806g = type { %struct.string___XUB, %struct.string___XUB, %struct.string___XUB, %struct.string___XUB } %struct.FRAME.ce3806g__fxio__put__4 = type { i32, i32, i32, %struct.system__file_control_block__pstring*, i32, i32, i8 } %struct.RETURN = type { i8, i32 } diff --git a/test/Transforms/SCCP/ipsccp-basic.ll b/test/Transforms/SCCP/ipsccp-basic.ll index e3699209a35b..a3c7637f986b 100644 --- a/test/Transforms/SCCP/ipsccp-basic.ll +++ b/test/Transforms/SCCP/ipsccp-basic.ll @@ -188,7 +188,7 @@ define void @test8b(i32* %P) { %X = call {} @test8a(i32 5, i32* %P) ret void ; CHECK: define void @test8b -; CHECK-NEXT: call { } @test8a +; CHECK-NEXT: call {} @test8a ; CHECK-NEXT: ret void } diff --git a/test/Transforms/SCCP/undef-resolve.ll b/test/Transforms/SCCP/undef-resolve.ll new file mode 100644 index 000000000000..bed561c8e4f2 --- /dev/null +++ b/test/Transforms/SCCP/undef-resolve.ll @@ -0,0 +1,106 @@ +; RUN: opt %s -sccp -S | FileCheck %s + + +; PR6940 +define double @test1() { + %t = sitofp i32 undef to double + ret double %t +; CHECK: @test1 +; CHECK: ret double 0.0 +} + + +; rdar://7832370 +; Check that lots of stuff doesn't get turned into undef. +define i32 @test2() nounwind readnone ssp { +; CHECK: @test2 +init: + br label %control.outer.outer + +control.outer.loopexit.us-lcssa: ; preds = %control + br label %control.outer.loopexit + +control.outer.loopexit: ; preds = %control.outer.loopexit.us-lcssa.us, %control.outer.loopexit.us-lcssa + br label %control.outer.outer.backedge + +control.outer.outer: ; preds = %control.outer.outer.backedge, %init + %switchCond.0.ph.ph = phi i32 [ 2, %init ], [ 3, %control.outer.outer.backedge ] ; <i32> [#uses=2] + %i.0.ph.ph = phi i32 [ undef, %init ], [ %i.0.ph.ph.be, %control.outer.outer.backedge ] ; <i32> [#uses=1] + %tmp4 = icmp eq i32 %i.0.ph.ph, 0 ; <i1> [#uses=1] + br i1 %tmp4, label %control.outer.outer.split.us, label %control.outer.outer.control.outer.outer.split_crit_edge + +control.outer.outer.control.outer.outer.split_crit_edge: ; preds = %control.outer.outer + br label %control.outer + +control.outer.outer.split.us: ; preds = %control.outer.outer + br label %control.outer.us + +control.outer.us: ; preds = %bb3.us, %control.outer.outer.split.us + %A.0.ph.us = phi i32 [ %switchCond.0.us, %bb3.us ], [ 4, %control.outer.outer.split.us ] ; <i32> [#uses=2] + %switchCond.0.ph.us = phi i32 [ %A.0.ph.us, %bb3.us ], [ %switchCond.0.ph.ph, %control.outer.outer.split.us ] ; <i32> [#uses=1] + br label %control.us + +bb3.us: ; preds = %control.us + br label %control.outer.us + +bb0.us: ; preds = %control.us + br label %control.us + +; CHECK: control.us: ; preds = %bb0.us, %control.outer.us +; CHECK-NEXT: %switchCond.0.us = phi i32 +; CHECK-NEXT: switch i32 %switchCond.0.us +control.us: ; preds = %bb0.us, %control.outer.us + %switchCond.0.us = phi i32 [ %A.0.ph.us, %bb0.us ], [ %switchCond.0.ph.us, %control.outer.us ] ; <i32> [#uses=2] + switch i32 %switchCond.0.us, label %control.outer.loopexit.us-lcssa.us [ + i32 0, label %bb0.us + i32 1, label %bb1.us-lcssa.us + i32 3, label %bb3.us + i32 4, label %bb4.us-lcssa.us + ] + +control.outer.loopexit.us-lcssa.us: ; preds = %control.us + br label %control.outer.loopexit + +bb1.us-lcssa.us: ; preds = %control.us + br label %bb1 + +bb4.us-lcssa.us: ; preds = %control.us + br label %bb4 + +control.outer: ; preds = %bb3, %control.outer.outer.control.outer.outer.split_crit_edge + %A.0.ph = phi i32 [ %nextId17, %bb3 ], [ 4, %control.outer.outer.control.outer.outer.split_crit_edge ] ; <i32> [#uses=1] + %switchCond.0.ph = phi i32 [ 0, %bb3 ], [ %switchCond.0.ph.ph, %control.outer.outer.control.outer.outer.split_crit_edge ] ; <i32> [#uses=1] + br label %control + +control: ; preds = %bb0, %control.outer + %switchCond.0 = phi i32 [ %A.0.ph, %bb0 ], [ %switchCond.0.ph, %control.outer ] ; <i32> [#uses=2] + switch i32 %switchCond.0, label %control.outer.loopexit.us-lcssa [ + i32 0, label %bb0 + i32 1, label %bb1.us-lcssa + i32 3, label %bb3 + i32 4, label %bb4.us-lcssa + ] + +bb4.us-lcssa: ; preds = %control + br label %bb4 + +bb4: ; preds = %bb4.us-lcssa, %bb4.us-lcssa.us + br label %control.outer.outer.backedge + +control.outer.outer.backedge: ; preds = %bb4, %control.outer.loopexit + %i.0.ph.ph.be = phi i32 [ 1, %bb4 ], [ 0, %control.outer.loopexit ] ; <i32> [#uses=1] + br label %control.outer.outer + +bb3: ; preds = %control + %nextId17 = add i32 %switchCond.0, -2 ; <i32> [#uses=1] + br label %control.outer + +bb0: ; preds = %control + br label %control + +bb1.us-lcssa: ; preds = %control + br label %bb1 + +bb1: ; preds = %bb1.us-lcssa, %bb1.us-lcssa.us + ret i32 0 +} diff --git a/test/Transforms/ScalarRepl/memcpy-align.ll b/test/Transforms/ScalarRepl/memcpy-align.ll new file mode 100644 index 000000000000..91d354d31a3b --- /dev/null +++ b/test/Transforms/ScalarRepl/memcpy-align.ll @@ -0,0 +1,32 @@ +; RUN: opt %s -scalarrepl -S | FileCheck %s +; PR6832 +target datalayout = +"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" +target triple = "arm-u-u" + +%0 = type { %struct.anon, %struct.anon } +%struct.anon = type { [4 x i8] } + +@c = external global %0 ; <%0*> [#uses=1] + +define arm_aapcscc void @good() nounwind { +entry: + %x0 = alloca %struct.anon, align 4 ; <%struct.anon*> [#uses=2] + %tmp = bitcast %struct.anon* %x0 to i8* ; <i8*> [#uses=1] + call void @llvm.memset.p0i8.i32(i8* %tmp, i8 0, i32 4, i32 4, i1 false) + %tmp1 = bitcast %struct.anon* %x0 to i8* ; <i8*> [#uses=1] + call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds (%0* @c, i32 +0, i32 0, i32 0, i32 0), i8* %tmp1, i32 4, i32 4, i1 false) + ret void + +; CHECK: store i8 0, i8*{{.*}}, align 4 +; CHECK: store i8 0, i8*{{.*}}, align 1 +; CHECK: store i8 0, i8*{{.*}}, align 2 +; CHECK: store i8 0, i8*{{.*}}, align 1 +} + +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, +i1) nounwind + diff --git a/test/Transforms/TailCallElim/inf-recursion.ll b/test/Transforms/TailCallElim/inf-recursion.ll index a5f246d36ce1..e4ac9283aec5 100644 --- a/test/Transforms/TailCallElim/inf-recursion.ll +++ b/test/Transforms/TailCallElim/inf-recursion.ll @@ -1,6 +1,10 @@ -; RUN: opt < %s -tailcallelim -S | grep call +; RUN: opt < %s -tailcallelim -S | FileCheck %s + ; Don't turn this into an infinite loop, this is probably the implementation ; of fabs and we expect the codegen to lower fabs. +; CHECK: @fabs(double %f) +; CHECK: call +; CHECK: ret define double @fabs(double %f) { entry: @@ -8,3 +12,23 @@ entry: ret double %tmp2 } +; Do turn other calls into infinite loops though. + +; CHECK: define double @foo +; CHECK-NOT: call +; CHECK: } +define double @foo(double %f) { + %t= call double @foo(double %f) + ret double %t +} + +; CHECK: define float @fabsf +; CHECK-NOT: call +; CHECK: } +define float @fabsf(float %f) { + %t= call float @fabsf(float 2.0) + ret float %t +} + +declare float @fabsf(float %f) +declare x86_fp80 @fabsl(x86_fp80 %f) |
