diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 |
commit | 6b943ff3a3f8617113ecbf611cf0f8957e4e19d2 (patch) | |
tree | fc5f365fb9035b2d0c622bbf06c9bbe8627d7279 /test/Transforms | |
parent | d0e4e96dc17a6c1c6de3340842c80f0e187ba349 (diff) |
Notes
Diffstat (limited to 'test/Transforms')
100 files changed, 2528 insertions, 257 deletions
diff --git a/test/Transforms/CodeGenPrepare/basic.ll b/test/Transforms/CodeGenPrepare/basic.ll index 3b1fca328c5bc..ebf10f0e9df2a 100644 --- a/test/Transforms/CodeGenPrepare/basic.ll +++ b/test/Transforms/CodeGenPrepare/basic.ll @@ -14,13 +14,14 @@ entry: br i1 %1, label %T, label %trap ; CHECK: entry: -; HECK-NEXT: ret i32 4 +; CHECK-NEXT: br label %T trap: ; preds = %0, %entry tail call void @llvm.trap() noreturn nounwind unreachable T: +; CHECK: ret i32 4 ret i32 4 } diff --git a/test/Transforms/ConstProp/2002-05-03-NotOperator.ll b/test/Transforms/ConstProp/2002-05-03-NotOperator.ll index d9cd67406b06c..b957220aa9cc7 100644 --- a/test/Transforms/ConstProp/2002-05-03-NotOperator.ll +++ b/test/Transforms/ConstProp/2002-05-03-NotOperator.ll @@ -1,4 +1,4 @@ -; This bug has to do with the fact that constant propogation was implemented in +; This bug has to do with the fact that constant propagation was implemented in ; terms of _logical_ not (! in C) instead of _bitwise_ not (~ in C). This was ; due to a spec change. diff --git a/test/Transforms/ConstProp/basictest.ll b/test/Transforms/ConstProp/basictest.ll index df57fb6870b8a..d0d0a5bb3352c 100644 --- a/test/Transforms/ConstProp/basictest.ll +++ b/test/Transforms/ConstProp/basictest.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -constprop -die -S | FileCheck %s -; This is a basic sanity check for constant propogation. The add instruction +; This is a basic sanity check for constant propagation. The add instruction ; should be eliminated. define i32 @test1(i1 %B) { br i1 %B, label %BB1, label %BB2 diff --git a/test/Transforms/ConstProp/logicaltest.ll b/test/Transforms/ConstProp/logicaltest.ll index c74296aa2c0c2..abd3275a4f744 100644 --- a/test/Transforms/ConstProp/logicaltest.ll +++ b/test/Transforms/ConstProp/logicaltest.ll @@ -1,4 +1,4 @@ -; Ensure constant propogation of logical instructions is working correctly. +; Ensure constant propagation of logical instructions is working correctly. ; RUN: opt < %s -constprop -die -S | FileCheck %s ; CHECK-NOT: {{and|or|xor}} diff --git a/test/Transforms/ConstProp/overflow-ops.ll b/test/Transforms/ConstProp/overflow-ops.ll index 5587e9b623300..d1cc2eb90a8e6 100644 --- a/test/Transforms/ConstProp/overflow-ops.ll +++ b/test/Transforms/ConstProp/overflow-ops.ll @@ -2,6 +2,14 @@ %i8i1 = type {i8, i1} +declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) +declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) +declare {i8, i1} @llvm.umul.with.overflow.i8(i8, i8) + +declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) +declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) +declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) + ;;----------------------------- ;; uadd ;;----------------------------- @@ -47,6 +55,28 @@ entry: } ;;----------------------------- +;; umul +;;----------------------------- + +define {i8, i1} @umul_1() nounwind { +entry: + %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 100, i8 3) + ret {i8, i1} %t + +; CHECK: @umul_1 +; CHECK: ret %i8i1 { i8 44, i1 true } +} + +define {i8, i1} @umul_2() nounwind { +entry: + %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 100, i8 2) + ret {i8, i1} %t + +; CHECK: @umul_2 +; CHECK: ret %i8i1 { i8 -56, i1 false } +} + +;;----------------------------- ;; sadd ;;----------------------------- @@ -163,14 +193,9 @@ entry: ; CHECK: ret %i8i1 { i8 -10, i1 false } } - - -declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) -declare {i8, i1} @llvm.usub.with.overflow.i8(i8, i8) - -declare {i8, i1} @llvm.sadd.with.overflow.i8(i8, i8) -declare {i8, i1} @llvm.ssub.with.overflow.i8(i8, i8) -declare {i8, i1} @llvm.smul.with.overflow.i8(i8, i8) +;;----------------------------- +;; smul +;;----------------------------- ; rdar://8501501 define {i8, i1} @smul_1() nounwind { diff --git a/test/Transforms/ConstProp/phi.ll b/test/Transforms/ConstProp/phi.ll index 3d9e284457cf6..c65d34cc933ae 100644 --- a/test/Transforms/ConstProp/phi.ll +++ b/test/Transforms/ConstProp/phi.ll @@ -1,4 +1,4 @@ -; This is a basic sanity check for constant propogation. The add instruction +; This is a basic sanity check for constant propagation. The add instruction ; should be eliminated. ; RUN: opt < %s -constprop -die -S | not grep phi diff --git a/test/Transforms/DeadArgElim/deadexternal.ll b/test/Transforms/DeadArgElim/deadexternal.ll index 5a80aba6e2db0..84092613130b7 100644 --- a/test/Transforms/DeadArgElim/deadexternal.ll +++ b/test/Transforms/DeadArgElim/deadexternal.ll @@ -37,3 +37,16 @@ entry: call void @f(i32 %tmp) ret void } + +; Check that callers are not transformed for weak definitions. +define weak i32 @weak_f(i32 %x) nounwind { +entry: + ret i32 0 +} +define void @weak_f_caller() nounwind { +entry: +; CHECK: call i32 @weak_f(i32 10) + %call = tail call i32 @weak_f(i32 10) + ret void +} + diff --git a/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll b/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll new file mode 100644 index 0000000000000..079eec43bf853 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/2011-03-25-DSEMiscompile.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -basicaa -dse -S | FileCheck %s +; PR9561 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target triple = "i386-apple-darwin9.8" + +@A = external global [0 x i32] + +declare cc10 void @Func2(i32*, i32*, i32*, i32) + +define cc10 void @Func1(i32* noalias %Arg1, i32* noalias %Arg2, i32* %Arg3, i32 %Arg4) { +entry: + store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2 +; CHECK: store i32 add (i32 ptrtoint ([0 x i32]* @A to i32), i32 1), i32* %Arg2 + %ln2gz = getelementptr i32* %Arg1, i32 14 + %ln2gA = bitcast i32* %ln2gz to double* + %ln2gB = load double* %ln2gA + %ln2gD = getelementptr i32* %Arg2, i32 -3 + %ln2gE = bitcast i32* %ln2gD to double* + store double %ln2gB, double* %ln2gE +; CHECK: store double %ln2gB, double* %ln2gE + tail call cc10 void @Func2(i32* %Arg1, i32* %Arg2, i32* %Arg3, i32 %Arg4) nounwind + ret void +} diff --git a/test/Transforms/GVN/invariant-simple.ll b/test/Transforms/GVN/invariant-simple.ll deleted file mode 100644 index 98ea48cdde324..0000000000000 --- a/test/Transforms/GVN/invariant-simple.ll +++ /dev/null @@ -1,36 +0,0 @@ -; RUN: opt < %s -basicaa -gvn -S | FileCheck %s - -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" -target triple = "i386-apple-darwin7" - -define i8 @test(i8* %P) nounwind { -; CHECK: @test -; CHECK-NOT: load -; CHECK: ret i8 -entry: - store i8 1, i8* %P - %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) - %1 = tail call i32 @foo(i8* %P) - call void @llvm.invariant.end({}* %0, i64 32, i8* %P) - %2 = load i8* %P - ret i8 %2 -} - -define i8 @test2(i8* %P) nounwind { -; CHECK: @test2 -; CHECK: store i8 1 -; CHECK: store i8 2 -; CHECK: ret i8 0 -entry: - store i8 1, i8* %P - %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) - %1 = tail call i32 @bar(i8* %P) - call void @llvm.invariant.end({}* %0, i64 32, i8* %P) - store i8 2, i8* %P - ret i8 0 -} - -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) diff --git a/test/Transforms/GVN/rle.ll b/test/Transforms/GVN/rle.ll index 2e43321750706..4ff5becb2064a 100644 --- a/test/Transforms/GVN/rle.ll +++ b/test/Transforms/GVN/rle.ll @@ -1,7 +1,7 @@ -; RUN: opt < %s -basicaa -gvn -S | FileCheck %s +; RUN: opt < %s -basicaa -gvn -S -die | FileCheck %s ; 32-bit little endian target. -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 datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" ;; Trivial RLE test. define i32 @test0(i32 %V, i32* %P) { @@ -544,3 +544,99 @@ entry: ; CHECK: ret i32 0 } + +;;===----------------------------------------------------------------------===;; +;; Load -> Load forwarding in partial alias case. +;;===----------------------------------------------------------------------===;; + +define i32 @load_load_partial_alias(i8* %P) nounwind ssp { +entry: + %0 = bitcast i8* %P to i32* + %tmp2 = load i32* %0 + %add.ptr = getelementptr inbounds i8* %P, i64 1 + %tmp5 = load i8* %add.ptr + %conv = zext i8 %tmp5 to i32 + %add = add nsw i32 %tmp2, %conv + ret i32 %add + +; CHECK: @load_load_partial_alias +; CHECK: load i32* +; CHECK-NOT: load +; CHECK: lshr i32 {{.*}}, 8 +; CHECK-NOT: load +; CHECK: trunc i32 {{.*}} to i8 +; CHECK-NOT: load +; CHECK: ret i32 +} + + +; Cross block partial alias case. +define i32 @load_load_partial_alias_cross_block(i8* %P) nounwind ssp { +entry: + %xx = bitcast i8* %P to i32* + %x1 = load i32* %xx, align 4 + %cmp = icmp eq i32 %x1, 127 + br i1 %cmp, label %land.lhs.true, label %if.end + +land.lhs.true: ; preds = %entry + %arrayidx4 = getelementptr inbounds i8* %P, i64 1 + %tmp5 = load i8* %arrayidx4, align 1 + %conv6 = zext i8 %tmp5 to i32 + ret i32 %conv6 + +if.end: + ret i32 52 +; CHECK: @load_load_partial_alias_cross_block +; CHECK: land.lhs.true: +; CHECK-NOT: load i8 +; CHECK: ret i32 %conv6 +} + + +;;===----------------------------------------------------------------------===;; +;; Load Widening +;;===----------------------------------------------------------------------===;; + +%widening1 = type { i32, i8, i8, i8, i8 } + +@f = global %widening1 zeroinitializer, align 4 + +define i32 @test_widening1(i8* %P) nounwind ssp noredzone { +entry: + %tmp = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 1), align 4 + %conv = zext i8 %tmp to i32 + %tmp1 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 2), align 1 + %conv2 = zext i8 %tmp1 to i32 + %add = add nsw i32 %conv, %conv2 + ret i32 %add +; CHECK: @test_widening1 +; CHECK-NOT: load +; CHECK: load i16* +; CHECK-NOT: load +; CHECK-ret i32 +} + +define i32 @test_widening2() nounwind ssp noredzone { +entry: + %tmp = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 1), align 4 + %conv = zext i8 %tmp to i32 + %tmp1 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 2), align 1 + %conv2 = zext i8 %tmp1 to i32 + %add = add nsw i32 %conv, %conv2 + + %tmp2 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 3), align 2 + %conv3 = zext i8 %tmp2 to i32 + %add2 = add nsw i32 %add, %conv3 + + %tmp3 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 4), align 1 + %conv4 = zext i8 %tmp3 to i32 + %add3 = add nsw i32 %add2, %conv3 + + ret i32 %add3 +; CHECK: @test_widening2 +; CHECK-NOT: load +; CHECK: load i32* +; CHECK-NOT: load +; CHECK-ret i32 +} + diff --git a/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll b/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll new file mode 100644 index 0000000000000..321a487cc82f9 --- /dev/null +++ b/test/Transforms/GlobalOpt/2011-04-09-EmptyGlobalCtors.ll @@ -0,0 +1,5 @@ +; RUN: opt < %s -globalopt -disable-output + +%0 = type { i32, void ()* } +@llvm.global_ctors = appending global [0 x %0] zeroinitializer + diff --git a/test/Transforms/GlobalOpt/cxx-dtor.ll b/test/Transforms/GlobalOpt/cxx-dtor.ll new file mode 100644 index 0000000000000..22635620baad6 --- /dev/null +++ b/test/Transforms/GlobalOpt/cxx-dtor.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -globalopt -S | FileCheck %s + +%0 = type { i32, void ()* } +%struct.A = type { i8 } + +@a = global %struct.A zeroinitializer, align 1 +@__dso_handle = external global i8* +@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I_a }] + +; CHECK-NOT: call i32 @__cxa_atexit + +define internal void @__cxx_global_var_init() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { + %1 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) + ret void +} + +define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { + call void @_ZN1AD2Ev(%struct.A* %this) + ret void +} + +declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) + +define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { + ret void +} + +define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" { + call void @__cxx_global_var_init() + ret void +} diff --git a/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll b/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll index 37ad63a9a7729..0f6267bd17991 100644 --- a/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll +++ b/test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -indvars -S | not grep {sext} ; ModuleID = '<stdin>' -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" target triple = "x86_64-apple-darwin9.6" @a = external global i32* ; <i32**> [#uses=3] @b = external global i32* ; <i32**> [#uses=3] diff --git a/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll b/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll index 803b540606e5c..46d6b380f0000 100644 --- a/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll +++ b/test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll @@ -13,7 +13,7 @@ ; d[(i+2)&15] = e[(i+2)&15]+f[(i+2)&15]+K[i+2]; ; } ;} -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" target triple = "x86_64-apple-darwin9.6" @a = external global i32* ; <i32**> [#uses=3] @b = external global i32* ; <i32**> [#uses=3] diff --git a/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll b/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll index 9fd2d2f04f725..47164d86047e6 100644 --- a/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll +++ b/test/Transforms/IndVarSimplify/2009-04-27-Floating.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -indvars -S | grep icmp | grep next +; RUN: opt < %s -indvars -S | FileCheck %s ; PR4086 declare void @foo() @@ -6,13 +6,14 @@ define void @test() { entry: br label %loop_body -loop_body: - %i = phi float [ %nexti, %loop_body ], [ 0.0, %entry ] +loop_body: + %i = phi float [ %nexti, %loop_body ], [ 0.0, %entry ] tail call void @foo() %nexti = fadd float %i, 1.0 - %less = fcmp olt float %nexti, 2.0 + ; CHECK: icmp ne i32 %{{[a-zA-Z$._0-9]+}}, 2 + %less = fcmp olt float %nexti, 2.0 br i1 %less, label %loop_body, label %done -done: +done: ret void } diff --git a/test/Transforms/IndVarSimplify/ada-loops.ll b/test/Transforms/IndVarSimplify/ada-loops.ll index 436840ae90750..4a07d997e7d72 100644 --- a/test/Transforms/IndVarSimplify/ada-loops.ll +++ b/test/Transforms/IndVarSimplify/ada-loops.ll @@ -11,7 +11,7 @@ ; count without casting. ; ModuleID = 'ada.bc' -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" +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-n:8:16:32" target triple = "i686-pc-linux-gnu" define void @kinds__sbytezero([256 x i32]* nocapture %a) nounwind { diff --git a/test/Transforms/IndVarSimplify/addrec-gep.ll b/test/Transforms/IndVarSimplify/addrec-gep.ll index 345f666c3b2ea..58cba6057045d 100644 --- a/test/Transforms/IndVarSimplify/addrec-gep.ll +++ b/test/Transforms/IndVarSimplify/addrec-gep.ll @@ -9,7 +9,7 @@ ; be able to reconstruct the full getelementptr, despite it having a few ; obstacles set in its way. -target datalayout = "e-p:64:64:64" +target datalayout = "e-p:64:64:64-n:32:64" define void @foo(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind { entry: diff --git a/test/Transforms/IndVarSimplify/ashr-tripcount.ll b/test/Transforms/IndVarSimplify/ashr-tripcount.ll index baaefdc2bc51d..09d559fe51149 100644 --- a/test/Transforms/IndVarSimplify/ashr-tripcount.ll +++ b/test/Transforms/IndVarSimplify/ashr-tripcount.ll @@ -4,7 +4,7 @@ ; Indvars should be able to eliminate all of the sign extensions ; inside the loop. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" @pow_2_tab = external constant [0 x float] ; <[0 x float]*> [#uses=1] @pow_2_025_tab = external constant [0 x float] ; <[0 x float]*> [#uses=1] @i_pow_2_tab = external constant [0 x float] ; <[0 x float]*> [#uses=1] diff --git a/test/Transforms/IndVarSimplify/iv-sext.ll b/test/Transforms/IndVarSimplify/iv-sext.ll index 55165022109a6..3e90873992493 100644 --- a/test/Transforms/IndVarSimplify/iv-sext.ll +++ b/test/Transforms/IndVarSimplify/iv-sext.ll @@ -6,7 +6,7 @@ ; inner loop to i64. ; TODO: it should promote hiPart to i64 in the outer loop too. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" define void @t(float* %pTmp1, float* %peakWeight, float* %nrgReducePeakrate, i32 %bandEdgeIndex, float %tmp1) nounwind { entry: diff --git a/test/Transforms/IndVarSimplify/iv-zext.ll b/test/Transforms/IndVarSimplify/iv-zext.ll index 1cc559fd79f1b..80a77b6e9365f 100644 --- a/test/Transforms/IndVarSimplify/iv-zext.ll +++ b/test/Transforms/IndVarSimplify/iv-zext.ll @@ -2,7 +2,7 @@ ; RUN: not grep and %t ; RUN: not grep zext %t -target datalayout = "-p:64:64:64" +target datalayout = "-p:64:64:64-n:32:64" define void @foo(double* %d, i64 %n) nounwind { entry: diff --git a/test/Transforms/IndVarSimplify/max-pointer.ll b/test/Transforms/IndVarSimplify/max-pointer.ll index f18f968f595d5..46ac2d89b5043 100644 --- a/test/Transforms/IndVarSimplify/max-pointer.ll +++ b/test/Transforms/IndVarSimplify/max-pointer.ll @@ -2,7 +2,7 @@ ; RUN: grep {icmp ugt i8\\\*} %t | count 1 ; RUN: grep {icmp sgt i8\\\*} %t | count 1 -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" %struct.CKenCodeCodec = type <{ i8 }> diff --git a/test/Transforms/IndVarSimplify/pointer.ll b/test/Transforms/IndVarSimplify/pointer.ll index 5eee655d4225b..d55bf98d31362 100644 --- a/test/Transforms/IndVarSimplify/pointer.ll +++ b/test/Transforms/IndVarSimplify/pointer.ll @@ -9,7 +9,7 @@ ; Indvars should be able to expand the pointer-arithmetic ; IV into an integer IV indexing into a simple getelementptr. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64" +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-n:32:64" define void @foo(i8* %A, i64 %n) nounwind { entry: diff --git a/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll b/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll index 3a5c0b650ffeb..26f05c4b1ee91 100644 --- a/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll +++ b/test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll @@ -2,7 +2,7 @@ ; RUN: not grep inttoptr %t ; RUN: not grep ptrtoint %t ; RUN: grep scevgep %t -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" +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-n:32:64" ; Indvars shouldn't need inttoptr/ptrtoint to expand an address here. diff --git a/test/Transforms/IndVarSimplify/preserve-gep-nested.ll b/test/Transforms/IndVarSimplify/preserve-gep-nested.ll index bb0993c88eabd..b41de5828a9dd 100644 --- a/test/Transforms/IndVarSimplify/preserve-gep-nested.ll +++ b/test/Transforms/IndVarSimplify/preserve-gep-nested.ll @@ -13,7 +13,7 @@ ; FIXME: This test should pass with or without TargetData. Until opt ; supports running tests without targetdata, just hardware this in. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" %struct.Q = type { [10 x %struct.N] } %struct.N = type { %struct.S } diff --git a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll index e17368b04ccfa..ca0c399927602 100644 --- a/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll +++ b/test/Transforms/IndVarSimplify/preserve-gep-remainder.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -indvars -S \ ; RUN: | grep {\[%\]p.2.ip.1 = getelementptr \\\[3 x \\\[3 x double\\\]\\\]\\* \[%\]p, i64 2, i64 \[%\]tmp, i64 1} -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" +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-n:32:64" ; Indvars shouldn't expand this to ; %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 0, i64 %tmp, i64 19 diff --git a/test/Transforms/IndVarSimplify/preserve-gep.ll b/test/Transforms/IndVarSimplify/preserve-gep.ll index a27d20dc96531..82eda0386e7fd 100644 --- a/test/Transforms/IndVarSimplify/preserve-gep.ll +++ b/test/Transforms/IndVarSimplify/preserve-gep.ll @@ -6,7 +6,7 @@ ; Indvars shouldn't leave getelementptrs expanded out as ; inttoptr+ptrtoint in its output in common cases. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" target triple = "x86_64-unknown-linux-gnu" %struct.Foo = type { i32, i32, [10 x i32], i32 } diff --git a/test/Transforms/InstCombine/2011-03-08-SRemMinusOneBadOpt.ll b/test/Transforms/InstCombine/2011-03-08-SRemMinusOneBadOpt.ll new file mode 100644 index 0000000000000..6a3e3e40e6d44 --- /dev/null +++ b/test/Transforms/InstCombine/2011-03-08-SRemMinusOneBadOpt.ll @@ -0,0 +1,12 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +; PR9346 + +define i32 @test(i64 %x) nounwind { +; CHECK: ret i32 0 +entry: + %or = or i64 %x, 4294967294 + %conv = trunc i64 %or to i32 + %rem.i = srem i32 %conv, -1 + ret i32 %rem.i +} + diff --git a/test/Transforms/InstCombine/ExtractCast.ll b/test/Transforms/InstCombine/ExtractCast.ll new file mode 100644 index 0000000000000..5ebbefd97b3e2 --- /dev/null +++ b/test/Transforms/InstCombine/ExtractCast.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -instcombine -S -o - | FileCheck %s + +; CHECK: @a +define i32 @a(<4 x i64> %I) { +entry: +; CHECK-NOT: trunc <4 x i64> + %J = trunc <4 x i64> %I to <4 x i32> + %K = extractelement <4 x i32> %J, i32 3 +; CHECK: extractelement <4 x i64> +; CHECK: trunc i64 +; CHECK: ret + ret i32 %K +} + + +; CHECK: @b +define i32 @b(<4 x float> %I) { +entry: +; CHECK-NOT: fptosi <4 x float> + %J = fptosi <4 x float> %I to <4 x i32> + %K = extractelement <4 x i32> %J, i32 3 +; CHECK: extractelement <4 x float> +; CHECK: fptosi float +; CHECK: ret + ret i32 %K +} + diff --git a/test/Transforms/InstCombine/and-or-not.ll b/test/Transforms/InstCombine/and-or-not.ll index 37ec3bc1aabbe..bd878b04a3503 100644 --- a/test/Transforms/InstCombine/and-or-not.ll +++ b/test/Transforms/InstCombine/and-or-not.ll @@ -4,7 +4,7 @@ ; PR1510 -; These are all equivelent to A^B +; These are all equivalent to A^B define i32 @test1(i32 %a, i32 %b) { entry: diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll index d898ea3b037a8..a8881522eac4b 100644 --- a/test/Transforms/InstCombine/and2.ll +++ b/test/Transforms/InstCombine/and2.ll @@ -26,3 +26,12 @@ define i32 @test3(i32 %X, i32 %Y) { ; CHECK-NEXT: and i32 %X, %Y ; CHECK-NEXT: ret } + +define i1 @test4(i32 %X) { + %a = icmp ult i32 %X, 31 + %b = icmp slt i32 %X, 0 + %c = and i1 %a, %b + ret i1 %c +; CHECK: @test4 +; CHECK-NEXT: ret i1 false +} diff --git a/test/Transforms/InstCombine/debuginfo.ll b/test/Transforms/InstCombine/debuginfo.ll new file mode 100644 index 0000000000000..f6892fc3e1f9c --- /dev/null +++ b/test/Transforms/InstCombine/debuginfo.ll @@ -0,0 +1,57 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readnone + +declare i8* @foo(i8*, i32, i64, i64) nounwind + +define hidden i8* @foobar(i8* %__dest, i32 %__val, i64 %__len) nounwind inlinehint ssp { +entry: + %__dest.addr = alloca i8*, align 8 + %__val.addr = alloca i32, align 4 + %__len.addr = alloca i64, align 8 + store i8* %__dest, i8** %__dest.addr, align 8, !tbaa !1 +; CHECK-NOT: call void @llvm.dbg.declare +; CHECK: call void @llvm.dbg.value + call void @llvm.dbg.declare(metadata !{i8** %__dest.addr}, metadata !0), !dbg !16 + store i32 %__val, i32* %__val.addr, align 4, !tbaa !17 + call void @llvm.dbg.declare(metadata !{i32* %__val.addr}, metadata !7), !dbg !18 + store i64 %__len, i64* %__len.addr, align 8, !tbaa !19 + call void @llvm.dbg.declare(metadata !{i64* %__len.addr}, metadata !9), !dbg !20 + %tmp = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13 + %tmp1 = load i32* %__val.addr, align 4, !dbg !21, !tbaa !17 + %tmp2 = load i64* %__len.addr, align 8, !dbg !21, !tbaa !19 + %tmp3 = load i8** %__dest.addr, align 8, !dbg !21, !tbaa !13 + %0 = call i64 @llvm.objectsize.i64(i8* %tmp3, i1 false), !dbg !21 + %call = call i8* @foo(i8* %tmp, i32 %tmp1, i64 %tmp2, i64 %0), !dbg !21 + ret i8* %call, !dbg !21 +} + +!llvm.dbg.lv.foobar = !{!0, !7, !9} +!llvm.dbg.sp = !{!1} + +!0 = metadata !{i32 590081, metadata !1, metadata !"__dest", metadata !2, i32 16777294, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foobar", metadata !"foobar", metadata !"", metadata !2, i32 79, metadata !4, i1 true, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i8* (i8*, i32, i64)* @foobar} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 589865, metadata !"string.h", metadata !"Game", metadata !3} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 589841, i32 0, i32 12, metadata !"bits.c", metadata !"Game", metadata !"clang version 3.0 (trunk 127710)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!4 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !5, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!5 = metadata !{metadata !6} +!6 = metadata !{i32 589839, metadata !3, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, null} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 590081, metadata !1, metadata !"__val", metadata !2, i32 33554510, metadata !8, i32 0} ; [ DW_TAG_arg_variable ] +!8 = metadata !{i32 589860, metadata !3, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!9 = metadata !{i32 590081, metadata !1, metadata !"__len", metadata !2, i32 50331726, metadata !10, i32 0} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 589846, metadata !3, metadata !"size_t", metadata !2, i32 80, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_typedef ] +!11 = metadata !{i32 589846, metadata !3, metadata !"__darwin_size_t", metadata !2, i32 90, i64 0, i64 0, i64 0, i32 0, metadata !12} ; [ DW_TAG_typedef ] +!12 = metadata !{i32 589860, metadata !3, metadata !"long unsigned int", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!13 = metadata !{metadata !"any pointer", metadata !14} +!14 = metadata !{metadata !"omnipotent char", metadata !15} +!15 = metadata !{metadata !"Simple C/C++ TBAA", null} +!16 = metadata !{i32 78, i32 28, metadata !1, null} +!17 = metadata !{metadata !"int", metadata !14} +!18 = metadata !{i32 78, i32 40, metadata !1, null} +!19 = metadata !{metadata !"long", metadata !14} +!20 = metadata !{i32 78, i32 54, metadata !1, null} +!21 = metadata !{i32 80, i32 3, metadata !22, null} +!22 = metadata !{i32 589835, metadata !23, i32 80, i32 3, metadata !2, i32 7} ; [ DW_TAG_lexical_block ] +!23 = metadata !{i32 589835, metadata !1, i32 79, i32 1, metadata !2, i32 6} ; [ DW_TAG_lexical_block ] diff --git a/test/Transforms/InstCombine/div.ll b/test/Transforms/InstCombine/div.ll index 0d1398082601e..2e24f19dce4ca 100644 --- a/test/Transforms/InstCombine/div.ll +++ b/test/Transforms/InstCombine/div.ll @@ -1,34 +1,44 @@ ; This test makes sure that div instructions are properly eliminated. -; RUN: opt < %s -instcombine -S | not grep div +; RUN: opt < %s -instcombine -S | FileCheck %s define i32 @test1(i32 %A) { %B = sdiv i32 %A, 1 ; <i32> [#uses=1] ret i32 %B +; CHECK: @test1 +; CHECK-NEXT: ret i32 %A } define i32 @test2(i32 %A) { ; => Shift %B = udiv i32 %A, 8 ; <i32> [#uses=1] ret i32 %B +; CHECK: @test2 +; CHECK-NEXT: lshr i32 %A, 3 } define i32 @test3(i32 %A) { ; => 0, don't need to keep traps %B = sdiv i32 0, %A ; <i32> [#uses=1] ret i32 %B +; CHECK: @test3 +; CHECK-NEXT: ret i32 0 } define i32 @test4(i32 %A) { ; 0-A %B = sdiv i32 %A, -1 ; <i32> [#uses=1] ret i32 %B +; CHECK: @test4 +; CHECK-NEXT: sub i32 0, %A } define i32 @test5(i32 %A) { %B = udiv i32 %A, -16 ; <i32> [#uses=1] %C = udiv i32 %B, -4 ; <i32> [#uses=1] ret i32 %C +; CHECK: @test5 +; CHECK-NEXT: ret i32 0 } define i1 @test6(i32 %A) { @@ -36,6 +46,8 @@ define i1 @test6(i32 %A) { ; A < 123 %C = icmp eq i32 %B, 0 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test6 +; CHECK-NEXT: icmp ult i32 %A, 123 } define i1 @test7(i32 %A) { @@ -43,6 +55,9 @@ define i1 @test7(i32 %A) { ; A >= 20 && A < 30 %C = icmp eq i32 %B, 2 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test7 +; CHECK-NEXT: add i32 %A, -20 +; CHECK-NEXT: icmp ult i32 } define i1 @test8(i8 %A) { @@ -50,6 +65,8 @@ define i1 @test8(i8 %A) { ; A >= 246 %C = icmp eq i8 %B, 2 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test8 +; CHECK-NEXT: icmp ugt i8 %A, -11 } define i1 @test9(i8 %A) { @@ -57,28 +74,47 @@ define i1 @test9(i8 %A) { ; A < 246 %C = icmp ne i8 %B, 2 ; <i1> [#uses=1] ret i1 %C +; CHECK: @test9 +; CHECK-NEXT: icmp ult i8 %A, -10 } define i32 @test10(i32 %X, i1 %C) { %V = select i1 %C, i32 64, i32 8 ; <i32> [#uses=1] %R = udiv i32 %X, %V ; <i32> [#uses=1] ret i32 %R +; CHECK: @test10 +; CHECK-NEXT: select i1 %C, i32 6, i32 3 +; CHECK-NEXT: lshr i32 %X } define i32 @test11(i32 %X, i1 %C) { %A = select i1 %C, i32 1024, i32 32 ; <i32> [#uses=1] %B = udiv i32 %X, %A ; <i32> [#uses=1] ret i32 %B +; CHECK: @test11 +; CHECK-NEXT: select i1 %C, i32 10, i32 5 +; CHECK-NEXT: lshr i32 %X } ; PR2328 define i32 @test12(i32 %x) nounwind { %tmp3 = udiv i32 %x, %x ; 1 ret i32 %tmp3 +; CHECK: @test12 +; CHECK-NEXT: ret i32 1 } define i32 @test13(i32 %x) nounwind { %tmp3 = sdiv i32 %x, %x ; 1 ret i32 %tmp3 +; CHECK: @test13 +; CHECK-NEXT: ret i32 1 } +define i32 @test14(i8 %x) nounwind { + %zext = zext i8 %x to i32 + %div = udiv i32 %zext, 257 ; 0 + ret i32 %div +; CHECK: @test14 +; CHECK-NEXT: ret i32 0 +} diff --git a/test/Transforms/InstCombine/fcmp.ll b/test/Transforms/InstCombine/fcmp.ll new file mode 100644 index 0000000000000..2eb4f058692d9 --- /dev/null +++ b/test/Transforms/InstCombine/fcmp.ll @@ -0,0 +1,60 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define i1 @test1(float %x, float %y) nounwind { + %ext1 = fpext float %x to double + %ext2 = fpext float %y to double + %cmp = fcmp ogt double %ext1, %ext2 + ret i1 %cmp +; CHECK: @test1 +; CHECK-NEXT: fcmp ogt float %x, %y +} + +define i1 @test2(float %a) nounwind { + %ext = fpext float %a to double + %cmp = fcmp ogt double %ext, 1.000000e+00 + ret i1 %cmp +; CHECK: @test2 +; CHECK-NEXT: fcmp ogt float %a, 1.0 +} + +define i1 @test3(float %a) nounwind { + %ext = fpext float %a to double + %cmp = fcmp ogt double %ext, 0x3FF0000000000001 ; more precision than float. + ret i1 %cmp +; CHECK: @test3 +; CHECK-NEXT: fpext float %a to double +} + +define i1 @test4(float %a) nounwind { + %ext = fpext float %a to double + %cmp = fcmp ogt double %ext, 0x36A0000000000000 ; denormal in float. + ret i1 %cmp +; CHECK: @test4 +; CHECK-NEXT: fpext float %a to double +} + +define i1 @test5(float %a) nounwind { + %neg = fsub float -0.000000e+00, %a + %cmp = fcmp ogt float %neg, 1.000000e+00 + ret i1 %cmp +; CHECK: @test5 +; CHECK-NEXT: fcmp olt float %a, -1.0 +} + +define i1 @test6(float %x, float %y) nounwind { + %neg1 = fsub float -0.000000e+00, %x + %neg2 = fsub float -0.000000e+00, %y + %cmp = fcmp olt float %neg1, %neg2 + ret i1 %cmp +; CHECK: @test6 +; CHECK-NEXT: fcmp ogt float %x, %y +} + +define i1 @test7(float %x) nounwind readnone ssp noredzone { + %ext = fpext float %x to ppc_fp128 + %cmp = fcmp ogt ppc_fp128 %ext, 0xM00000000000000000000000000000000 + ret i1 %cmp +; Can't convert ppc_fp128 +; CHECK: @test7 +; CHECK-NEXT: fpext float %x to ppc_fp128 +} diff --git a/test/Transforms/InstCombine/fdiv.ll b/test/Transforms/InstCombine/fdiv.ll new file mode 100644 index 0000000000000..a2cce016e1887 --- /dev/null +++ b/test/Transforms/InstCombine/fdiv.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define float @test1(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x3810000000000000 + ret float %div + +; CHECK: @test1 +; CHECK-NEXT: fmul float %x, 0x47D0000000000000 +} + +define float @test2(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x47E0000000000000 + ret float %div + +; CHECK: @test2 +; CHECK-NEXT: fdiv float %x, 0x47E0000000000000 +} + +define float @test3(float %x) nounwind readnone ssp { + %div = fdiv float %x, 0x36A0000000000000 + ret float %div + +; CHECK: @test3 +; CHECK-NEXT: fdiv float %x, 0x36A0000000000000 +} diff --git a/test/Transforms/InstCombine/fold-bin-operand.ll b/test/Transforms/InstCombine/fold-bin-operand.ll index d0d072ac6bb53..a8bad0df5960f 100644 --- a/test/Transforms/InstCombine/fold-bin-operand.ll +++ b/test/Transforms/InstCombine/fold-bin-operand.ll @@ -1,14 +1,17 @@ -; RUN: opt < %s -instcombine -S | not grep icmp +; RUN: opt < %s -instcombine -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" define i1 @f(i1 %x) { +; CHECK: @f +; CHECK: ret i1 false %b = and i1 %x, icmp eq (i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 2 to i8*)) ret i1 %b } -; FIXME: This doesn't fold at the moment! -; define i32 @f(i32 %x) { -; %b = add i32 %x, zext (i1 icmp eq (i8* inttoptr (i32 1000000 to i8*), i8* inttoptr (i32 2000000 to i8*)) to i32) -; ret i32 %b -;} +define i32 @g(i32 %x) { +; CHECK: @g +; CHECK: ret i32 %x + %b = add i32 %x, zext (i1 icmp eq (i8* inttoptr (i32 1000000 to i8*), i8* inttoptr (i32 2000000 to i8*)) to i32) + ret i32 %b +} diff --git a/test/Transforms/InstCombine/gep-addrspace.ll b/test/Transforms/InstCombine/gep-addrspace.ll new file mode 100644 index 0000000000000..dfe12dbfaf7f4 --- /dev/null +++ b/test/Transforms/InstCombine/gep-addrspace.ll @@ -0,0 +1,19 @@ +; RUN: opt < %s -instcombine -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-pc-win32" + +%myStruct = type { float, [3 x float], [4 x float], i32 } + +; make sure that we are not crashing when creating an illegal type +define void @func(%myStruct addrspace(1)* nocapture %p) nounwind { +ST: + %A = getelementptr inbounds %myStruct addrspace(1)* %p, i64 0 + %B = bitcast %myStruct addrspace(1)* %A to %myStruct* + %C = getelementptr inbounds %myStruct* %B, i32 0, i32 1 + %D = getelementptr inbounds [3 x float]* %C, i32 0, i32 2 + %E = load float* %D, align 4 + %F = fsub float %E, undef + ret void +} + diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 3150883e7d710..099540ac74532 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -377,3 +377,136 @@ define i1 @test38(i32 %x, i32 %y, i32 %z) { %c = icmp ugt i32 %lhs, %rhs ret i1 %c } + +; PR9343 #1 +; CHECK: @test39 +; CHECK: %B = icmp eq i32 %X, 0 +define i1 @test39(i32 %X, i32 %Y) { + %A = ashr exact i32 %X, %Y + %B = icmp eq i32 %A, 0 + ret i1 %B +} + +; CHECK: @test40 +; CHECK: %B = icmp ne i32 %X, 0 +define i1 @test40(i32 %X, i32 %Y) { + %A = lshr exact i32 %X, %Y + %B = icmp ne i32 %A, 0 + ret i1 %B +} + +; PR9343 #3 +; CHECK: @test41 +; CHECK: ret i1 true +define i1 @test41(i32 %X, i32 %Y) { + %A = urem i32 %X, %Y + %B = icmp ugt i32 %Y, %A + ret i1 %B +} + +; CHECK: @test42 +; CHECK: %B = icmp sgt i32 %Y, -1 +define i1 @test42(i32 %X, i32 %Y) { + %A = srem i32 %X, %Y + %B = icmp slt i32 %A, %Y + ret i1 %B +} + +; CHECK: @test43 +; CHECK: %B = icmp slt i32 %Y, 0 +define i1 @test43(i32 %X, i32 %Y) { + %A = srem i32 %X, %Y + %B = icmp slt i32 %Y, %A + ret i1 %B +} + +; CHECK: @test44 +; CHECK: %B = icmp sgt i32 %Y, -1 +define i1 @test44(i32 %X, i32 %Y) { + %A = srem i32 %X, %Y + %B = icmp slt i32 %A, %Y + ret i1 %B +} + +; CHECK: @test45 +; CHECK: %B = icmp slt i32 %Y, 0 +define i1 @test45(i32 %X, i32 %Y) { + %A = srem i32 %X, %Y + %B = icmp slt i32 %Y, %A + ret i1 %B +} + +; PR9343 #4 +; CHECK: @test46 +; CHECK: %C = icmp ult i32 %X, %Y +define i1 @test46(i32 %X, i32 %Y, i32 %Z) { + %A = ashr exact i32 %X, %Z + %B = ashr exact i32 %Y, %Z + %C = icmp ult i32 %A, %B + ret i1 %C +} + +; PR9343 #5 +; CHECK: @test47 +; CHECK: %C = icmp ugt i32 %X, %Y +define i1 @test47(i32 %X, i32 %Y, i32 %Z) { + %A = ashr exact i32 %X, %Z + %B = ashr exact i32 %Y, %Z + %C = icmp ugt i32 %A, %B + ret i1 %C +} + +; PR9343 #8 +; CHECK: @test48 +; CHECK: %C = icmp eq i32 %X, %Y +define i1 @test48(i32 %X, i32 %Y, i32 %Z) { + %A = sdiv exact i32 %X, %Z + %B = sdiv exact i32 %Y, %Z + %C = icmp eq i32 %A, %B + ret i1 %C +} + +; PR8469 +; CHECK: @test49 +; CHECK: ret <2 x i1> <i1 true, i1 true> +define <2 x i1> @test49(<2 x i32> %tmp3) { +entry: + %tmp11 = and <2 x i32> %tmp3, <i32 3, i32 3> + %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4> + ret <2 x i1> %cmp +} + +; PR9343 #7 +; CHECK: @test50 +; CHECK: ret i1 true +define i1 @test50(i16 %X, i32 %Y) { + %A = zext i16 %X to i32 + %B = srem i32 %A, %Y + %C = icmp sgt i32 %B, -1 + ret i1 %C +} + +; CHECK: @test51 +; CHECK: ret i1 %C +define i1 @test51(i32 %X, i32 %Y) { + %A = and i32 %X, 2147483648 + %B = srem i32 %A, %Y + %C = icmp sgt i32 %B, -1 + ret i1 %C +} + +; CHECK: @test52 +; CHECK-NEXT: and i32 %x1, 16711935 +; CHECK-NEXT: icmp eq i32 {{.*}}, 4980863 +; CHECK-NEXT: ret i1 +define i1 @test52(i32 %x1) nounwind { + %conv = and i32 %x1, 255 + %cmp = icmp eq i32 %conv, 127 + %tmp2 = lshr i32 %x1, 16 + %tmp3 = trunc i32 %tmp2 to i8 + %cmp15 = icmp eq i8 %tmp3, 76 + + %A = and i1 %cmp, %cmp15 + ret i1 %A +} + diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 50e7f1f7c92d3..332cd46098ce8 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -112,6 +112,33 @@ define i8 @umultest2(i8 %A, i1* %overflowPtr) { ; CHECK-NEXT: ret i8 %A } +%ov.result.32 = type { i32, i1 } +declare %ov.result.32 @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone + +define i32 @umultest3(i32 %n) nounwind { + %shr = lshr i32 %n, 2 + %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %shr, i32 3) + %ov = extractvalue %ov.result.32 %mul, 1 + %res = extractvalue %ov.result.32 %mul, 0 + %ret = select i1 %ov, i32 -1, i32 %res + ret i32 %ret +; CHECK: @umultest3 +; CHECK-NEXT: shr +; CHECK-NEXT: mul nuw +; CHECK-NEXT: ret +} + +define i32 @umultest4(i32 %n) nounwind { + %shr = lshr i32 %n, 1 + %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %shr, i32 4) + %ov = extractvalue %ov.result.32 %mul, 1 + %res = extractvalue %ov.result.32 %mul, 0 + %ret = select i1 %ov, i32 -1, i32 %res + ret i32 %ret +; CHECK: @umultest4 +; CHECK: umul.with.overflow +} + define void @powi(double %V, double *%P) { entry: %A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind diff --git a/test/Transforms/InstCombine/merge-icmp.ll b/test/Transforms/InstCombine/merge-icmp.ll new file mode 100644 index 0000000000000..00020b157e0fe --- /dev/null +++ b/test/Transforms/InstCombine/merge-icmp.ll @@ -0,0 +1,29 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +define i1 @test1(i16* %x) { + %load = load i16* %x, align 4 + %trunc = trunc i16 %load to i8 + %cmp1 = icmp eq i8 %trunc, 127 + %and = and i16 %load, -256 + %cmp2 = icmp eq i16 %and, 17664 + %or = and i1 %cmp1, %cmp2 + ret i1 %or +; CHECK: @test1 +; CHECK-NEXT: load i16 +; CHECK-NEXT: icmp eq i16 %load, 17791 +; CHECK-NEXT: ret i1 +} + +define i1 @test2(i16* %x) { + %load = load i16* %x, align 4 + %and = and i16 %load, -256 + %cmp1 = icmp eq i16 %and, 32512 + %trunc = trunc i16 %load to i8 + %cmp2 = icmp eq i8 %trunc, 69 + %or = and i1 %cmp1, %cmp2 + ret i1 %or +; CHECK: @test2 +; CHECK-NEXT: load i16 +; CHECK-NEXT: icmp eq i16 %load, 32581 +; CHECK-NEXT: ret i1 +} diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll index f82f9faab2d56..94a57321862f9 100644 --- a/test/Transforms/InstCombine/or.ll +++ b/test/Transforms/InstCombine/or.ll @@ -390,3 +390,22 @@ define i1 @test36(i32 %x) { ; CHECK-NEXT: ret i1 } +define i32 @test37(i32* %xp, i32 %y) { +; CHECK: @test37 +; CHECK: select i1 %tobool, i32 -1, i32 %x + %tobool = icmp ne i32 %y, 0 + %sext = sext i1 %tobool to i32 + %x = load i32* %xp + %or = or i32 %sext, %x + ret i32 %or +} + +define i32 @test38(i32* %xp, i32 %y) { +; CHECK: @test38 +; CHECK: select i1 %tobool, i32 -1, i32 %x + %tobool = icmp ne i32 %y, 0 + %sext = sext i1 %tobool to i32 + %x = load i32* %xp + %or = or i32 %x, %sext + ret i32 %or +} diff --git a/test/Transforms/InstCombine/phi.ll b/test/Transforms/InstCombine/phi.ll index 62c6a63a7e581..cd865ae81bafe 100644 --- a/test/Transforms/InstCombine/phi.ll +++ b/test/Transforms/InstCombine/phi.ll @@ -197,25 +197,25 @@ declare i1 @test11a() define i1 @test11() { entry: %a = alloca i32 - %i = ptrtoint i32* %a to i32 + %i = ptrtoint i32* %a to i64 %b = call i1 @test11a() br i1 %b, label %one, label %two one: - %x = phi i32 [%i, %entry], [%y, %two] + %x = phi i64 [%i, %entry], [%y, %two] %c = call i1 @test11a() br i1 %c, label %two, label %end two: - %y = phi i32 [%i, %entry], [%x, %one] + %y = phi i64 [%i, %entry], [%x, %one] %d = call i1 @test11a() br i1 %d, label %one, label %end end: - %f = phi i32 [ %x, %one], [%y, %two] + %f = phi i64 [ %x, %one], [%y, %two] ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter ; even though %f must equal %i at this point - %g = inttoptr i32 %f to i32* + %g = inttoptr i64 %f to i32* store i32 10, i32* %g %z = call i1 @test11a() ret i1 %z @@ -544,3 +544,79 @@ BB2: ; CHECK-NEXT: %C = add nuw i32 %A, 1 ; CHECK-NEXT: ret i32 %C } + +; Same as test11, but used to be missed due to a bug. +declare i1 @test25a() + +define i1 @test25() { +entry: + %a = alloca i32 + %i = ptrtoint i32* %a to i64 + %b = call i1 @test25a() + br i1 %b, label %one, label %two + +one: + %x = phi i64 [%y, %two], [%i, %entry] + %c = call i1 @test25a() + br i1 %c, label %two, label %end + +two: + %y = phi i64 [%x, %one], [%i, %entry] + %d = call i1 @test25a() + br i1 %d, label %one, label %end + +end: + %f = phi i64 [ %x, %one], [%y, %two] + ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter + ; even though %f must equal %i at this point + %g = inttoptr i64 %f to i32* + store i32 10, i32* %g + %z = call i1 @test25a() + ret i1 %z +; CHECK: @test25 +; CHECK-NOT: phi i32 +; CHECK: ret i1 %z +} + +declare i1 @test26a() + +define i1 @test26(i32 %n) { +entry: + %a = alloca i32 + %i = ptrtoint i32* %a to i64 + %b = call i1 @test26a() + br label %one + +one: + %x = phi i64 [%y, %two], [%w, %three], [%i, %entry] + %c = call i1 @test26a() + switch i32 %n, label %end [ + i32 2, label %two + i32 3, label %three + ] + +two: + %y = phi i64 [%x, %one], [%w, %three] + %d = call i1 @test26a() + switch i32 %n, label %end [ + i32 10, label %one + i32 30, label %three + ] + +three: + %w = phi i64 [%y, %two], [%x, %one] + %e = call i1 @test26a() + br i1 %e, label %one, label %two + +end: + %f = phi i64 [ %x, %one], [%y, %two] + ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter + ; even though %f must equal %i at this point + %g = inttoptr i64 %f to i32* + store i32 10, i32* %g + %z = call i1 @test26a() + ret i1 %z +; CHECK: @test26 +; CHECK-NOT: phi i32 +; CHECK: ret i1 %z +} diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index ba9d99c97dd51..39259078b877d 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -714,3 +714,38 @@ define i32 @test52(i32 %n, i32 %m) nounwind { ret i32 %storemerge } +; PR9454 +define i32 @test53(i32 %x) nounwind { + %and = and i32 %x, 2 + %cmp = icmp eq i32 %and, %x + %sel = select i1 %cmp, i32 2, i32 1 + ret i32 %sel +; CHECK: @test53 +; CHECK: select i1 %cmp +; CHECK: ret +} + +define i32 @test54(i32 %X, i32 %Y) { + %A = ashr exact i32 %X, %Y + %B = icmp eq i32 %A, 0 + %C = select i1 %B, i32 %A, i32 1 + ret i32 %C +; CHECK: @test54 +; CHECK-NOT: ashr +; CHECK-NOT: select +; CHECK: icmp ne i32 %X, 0 +; CHECK: zext +; CHECK: ret +} + +define i1 @test55(i1 %X, i32 %Y, i32 %Z) { + %A = ashr exact i32 %Y, %Z + %B = select i1 %X, i32 %Y, i32 %A + %C = icmp eq i32 %B, 0 + ret i1 %C +; CHECK: @test55 +; CHECK-NOT: ashr +; CHECK-NOT: select +; CHECK: icmp eq +; CHECK: ret i1 +} diff --git a/test/Transforms/InstCombine/sext.ll b/test/Transforms/InstCombine/sext.ll index 60669b7a109f4..f49a2efb39d8f 100644 --- a/test/Transforms/InstCombine/sext.ll +++ b/test/Transforms/InstCombine/sext.ll @@ -126,3 +126,61 @@ define void @test11(<2 x i16> %srcA, <2 x i16> %srcB, <2 x i16>* %dst) { ; CHECK-NEXT: store <2 x i16> ; CHECK-NEXT: ret } + +define i64 @test12(i32 %x) nounwind { + %shr = lshr i32 %x, 1 + %sub = sub nsw i32 0, %shr + %conv = sext i32 %sub to i64 + ret i64 %conv +; CHECK: @test12 +; CHECK: sext +; CHECK: ret +} + +define i32 @test13(i32 %x) nounwind { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test13 +; CHECK-NEXT: %and = lshr i32 %x, 3 +; CHECK-NEXT: %1 = and i32 %and, 1 +; CHECK-NEXT: %sext = add i32 %1, -1 +; CHECK-NEXT: ret i32 %sext +} + +define i32 @test14(i16 %x) nounwind { + %and = and i16 %x, 16 + %cmp = icmp ne i16 %and, 16 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test14 +; CHECK-NEXT: %and = lshr i16 %x, 4 +; CHECK-NEXT: %1 = and i16 %and, 1 +; CHECK-NEXT: %sext = add i16 %1, -1 +; CHECK-NEXT: %ext = sext i16 %sext to i32 +; CHECK-NEXT: ret i32 %ext +} + +define i32 @test15(i32 %x) nounwind { + %and = and i32 %x, 16 + %cmp = icmp ne i32 %and, 0 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test15 +; CHECK-NEXT: %1 = shl i32 %x, 27 +; CHECK-NEXT: %sext = ashr i32 %1, 31 +; CHECK-NEXT: ret i32 %sext +} + +define i32 @test16(i16 %x) nounwind { + %and = and i16 %x, 8 + %cmp = icmp eq i16 %and, 8 + %ext = sext i1 %cmp to i32 + ret i32 %ext +; CHECK: @test16 +; CHECK-NEXT: %1 = shl i16 %x, 12 +; CHECK-NEXT: %sext = ashr i16 %1, 15 +; CHECK-NEXT: %ext = sext i16 %sext to i32 +; CHECK-NEXT: ret i32 %ext +} diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index 7fab1d2cab54b..bded68ac47558 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -485,3 +485,24 @@ entry: ; CHECK: ret i8 %tmp551 ret i8 %tmp55 } + +; PR9809 +define i32 @test40(i32 %a, i32 %b) nounwind { + %shl1 = shl i32 1, %b + %shl2 = shl i32 %shl1, 2 + %div = udiv i32 %a, %shl2 + ret i32 %div +; CHECK: @test40 +; CHECK-NEXT: add i32 %b, 2 +; CHECK-NEXT: lshr i32 %a +; CHECK-NEXT: ret i32 +} + +define i32 @test41(i32 %a, i32 %b) nounwind { + %1 = shl i32 1, %b + %2 = shl i32 %1, 3 + ret i32 %2 +; CHECK: @test41 +; CHECK-NEXT: shl i32 8, %b +; CHECK-NEXT: ret i32 +} diff --git a/test/Transforms/InstCombine/sign-test-and-or.ll b/test/Transforms/InstCombine/sign-test-and-or.ll new file mode 100644 index 0000000000000..47f5f3051e468 --- /dev/null +++ b/test/Transforms/InstCombine/sign-test-and-or.ll @@ -0,0 +1,79 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +declare void @foo() + +define void @test1(i32 %a, i32 %b) nounwind { + %1 = icmp slt i32 %a, 0 + %2 = icmp slt i32 %b, 0 + %or.cond = or i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test1 +; CHECK-NEXT: %1 = or i32 %a, %b +; CHECK-NEXT: %2 = icmp slt i32 %1, 0 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} + +define void @test2(i32 %a, i32 %b) nounwind { + %1 = icmp sgt i32 %a, -1 + %2 = icmp sgt i32 %b, -1 + %or.cond = or i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test2 +; CHECK-NEXT: %1 = and i32 %a, %b +; CHECK-NEXT: %2 = icmp sgt i32 %1, -1 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} + +define void @test3(i32 %a, i32 %b) nounwind { + %1 = icmp slt i32 %a, 0 + %2 = icmp slt i32 %b, 0 + %or.cond = and i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test3 +; CHECK-NEXT: %1 = and i32 %a, %b +; CHECK-NEXT: %2 = icmp slt i32 %1, 0 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} + +define void @test4(i32 %a, i32 %b) nounwind { + %1 = icmp sgt i32 %a, -1 + %2 = icmp sgt i32 %b, -1 + %or.cond = and i1 %1, %2 + br i1 %or.cond, label %if.then, label %if.end + +; CHECK: @test4 +; CHECK-NEXT: %1 = or i32 %a, %b +; CHECK-NEXT: %2 = icmp sgt i32 %1, -1 +; CHECK-NEXT: br + +if.then: + tail call void @foo() nounwind + ret void + +if.end: + ret void +} diff --git a/test/Transforms/InstCombine/strcpy_chk-64.ll b/test/Transforms/InstCombine/strcpy_chk-64.ll new file mode 100644 index 0000000000000..036fcbe6de1d7 --- /dev/null +++ b/test/Transforms/InstCombine/strcpy_chk-64.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -instcombine -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" + +define void @func(i8* %i) nounwind ssp { +; CHECK: @func +; CHECK: @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32) +entry: + %s = alloca [32 x i8], align 16 + %arraydecay = getelementptr inbounds [32 x i8]* %s, i32 0, i32 0 + %call = call i8* @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32) + call void @func2(i8* %arraydecay) + ret void +} + +declare i8* @__strcpy_chk(i8*, i8*, i64) nounwind + +declare void @func2(i8*) diff --git a/test/Transforms/InstCombine/udivrem-change-width.ll b/test/Transforms/InstCombine/udivrem-change-width.ll index 9983944df8d72..b388a3b0634ec 100644 --- a/test/Transforms/InstCombine/udivrem-change-width.ll +++ b/test/Transforms/InstCombine/udivrem-change-width.ll @@ -1,14 +1,16 @@ -; RUN: opt < %s -instcombine -S | not grep zext -; PR4548 +; RUN: opt < %s -instcombine -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" +; PR4548 define i8 @udiv_i8(i8 %a, i8 %b) nounwind { %conv = zext i8 %a to i32 %conv2 = zext i8 %b to i32 %div = udiv i32 %conv, %conv2 %conv3 = trunc i32 %div to i8 ret i8 %conv3 +; CHECK: @udiv_i8 +; CHECK: udiv i8 %a, %b } define i8 @urem_i8(i8 %a, i8 %b) nounwind { @@ -17,5 +19,44 @@ define i8 @urem_i8(i8 %a, i8 %b) nounwind { %div = urem i32 %conv, %conv2 %conv3 = trunc i32 %div to i8 ret i8 %conv3 +; CHECK: @urem_i8 +; CHECK: urem i8 %a, %b } +define i32 @udiv_i32(i8 %a, i8 %b) nounwind { + %conv = zext i8 %a to i32 + %conv2 = zext i8 %b to i32 + %div = udiv i32 %conv, %conv2 + ret i32 %div +; CHECK: @udiv_i32 +; CHECK: udiv i8 %a, %b +; CHECK: zext +} + +define i32 @urem_i32(i8 %a, i8 %b) nounwind { + %conv = zext i8 %a to i32 + %conv2 = zext i8 %b to i32 + %div = urem i32 %conv, %conv2 + ret i32 %div +; CHECK: @urem_i32 +; CHECK: urem i8 %a, %b +; CHECK: zext +} + +define i32 @udiv_i32_c(i8 %a) nounwind { + %conv = zext i8 %a to i32 + %div = udiv i32 %conv, 10 + ret i32 %div +; CHECK: @udiv_i32_c +; CHECK: udiv i8 %a, 10 +; CHECK: zext +} + +define i32 @urem_i32_c(i8 %a) nounwind { + %conv = zext i8 %a to i32 + %div = urem i32 %conv, 10 + ret i32 %div +; CHECK: @urem_i32_c +; CHECK: urem i8 %a, 10 +; CHECK: zext +} diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll index 250e44ce340f7..d2c564f567b44 100644 --- a/test/Transforms/InstSimplify/compare.ll +++ b/test/Transforms/InstSimplify/compare.ll @@ -137,22 +137,38 @@ define i1 @shl(i32 %x) { ; CHECK: ret i1 false } -define i1 @lshr(i32 %x) { -; CHECK: @lshr +define i1 @lshr1(i32 %x) { +; CHECK: @lshr1 %s = lshr i32 -1, %x %c = icmp eq i32 %s, 0 ret i1 %c ; CHECK: ret i1 false } -define i1 @ashr(i32 %x) { -; CHECK: @ashr +define i1 @lshr2(i32 %x) { +; CHECK: @lshr2 + %s = lshr i32 %x, 30 + %c = icmp ugt i32 %s, 8 + ret i1 %c +; CHECK: ret i1 false +} + +define i1 @ashr1(i32 %x) { +; CHECK: @ashr1 %s = ashr i32 -1, %x %c = icmp eq i32 %s, 0 ret i1 %c ; CHECK: ret i1 false } +define i1 @ashr2(i32 %x) { +; CHECK: @ashr2 + %s = ashr i32 %x, 30 + %c = icmp slt i32 %s, -5 + ret i1 %c +; CHECK: ret i1 false +} + define i1 @select1(i1 %cond) { ; CHECK: @select1 %s = select i1 %cond, i32 1, i32 0 @@ -187,3 +203,134 @@ define i1 @select4(i1 %cond) { ret i1 %c ; CHECK: ret i1 %cond } + +define i1 @urem1(i32 %X, i32 %Y) { +; CHECK: @urem1 + %A = urem i32 %X, %Y + %B = icmp ult i32 %A, %Y + ret i1 %B +; CHECK: ret i1 true +} + +define i1 @urem2(i32 %X, i32 %Y) { +; CHECK: @urem2 + %A = urem i32 %X, %Y + %B = icmp eq i32 %A, %Y + ret i1 %B +; CHECK: ret i1 false +} + +define i1 @urem3(i32 %X) { +; CHECK: @urem3 + %A = urem i32 %X, 10 + %B = icmp ult i32 %A, 15 + ret i1 %B +; CHECK: ret i1 true +} + +define i1 @urem4(i32 %X) { +; CHECK: @urem4 + %A = urem i32 %X, 15 + %B = icmp ult i32 %A, 10 + ret i1 %B +; CHECK: ret i1 %B +} + +define i1 @urem5(i16 %X, i32 %Y) { +; CHECK: @urem5 + %A = zext i16 %X to i32 + %B = urem i32 %A, %Y + %C = icmp slt i32 %B, %Y + ret i1 %C +; CHECK: ret i1 true +} + +define i1 @urem6(i32 %X, i32 %Y) { +; CHECK: @urem6 + %A = urem i32 %X, %Y + %B = icmp ugt i32 %Y, %A + ret i1 %B +; CHECK: ret i1 true +} + +define i1 @srem1(i32 %X) { +; CHECK: @srem1 + %A = srem i32 %X, -5 + %B = icmp sgt i32 %A, 5 + ret i1 %B +; CHECK: ret i1 false +} + +; PR9343 #15 +; CHECK: @srem2 +; CHECK: ret i1 false +define i1 @srem2(i16 %X, i32 %Y) { + %A = zext i16 %X to i32 + %B = add nsw i32 %A, 1 + %C = srem i32 %B, %Y + %D = icmp slt i32 %C, 0 + ret i1 %D +} + +; CHECK: @srem3 +; CHECK-NEXT: ret i1 false +define i1 @srem3(i16 %X, i32 %Y) { + %A = zext i16 %X to i32 + %B = or i32 2147483648, %A + %C = sub nsw i32 1, %B + %D = srem i32 %C, %Y + %E = icmp slt i32 %D, 0 + ret i1 %E +} + +; CHECK: @srem4 +; CHECK-NEXT: ret i1 false +define i1 @srem4(i16 %X, i32 %Y) { + %A = zext i16 %X to i32 + %B = or i32 2147483648, %A + %C = sub nsw i32 %A, %B + %D = srem i32 %C, %Y + %E = icmp slt i32 %D, 0 + ret i1 %E +} + +define i1 @udiv1(i32 %X) { +; CHECK: @udiv1 + %A = udiv i32 %X, 1000000 + %B = icmp ult i32 %A, 5000 + ret i1 %B +; CHECK: ret i1 true +} + +define i1 @udiv2(i32 %X, i32 %Y, i32 %Z) { +; CHECK: @udiv2 + %A = udiv exact i32 10, %Z + %B = udiv exact i32 20, %Z + %C = icmp ult i32 %A, %B + ret i1 %C +; CHECK: ret i1 true +} + +define i1 @sdiv1(i32 %X) { +; CHECK: @sdiv1 + %A = sdiv i32 %X, 1000000 + %B = icmp slt i32 %A, 3000 + ret i1 %B +; CHECK: ret i1 true +} + +define i1 @or1(i32 %X) { +; CHECK: @or1 + %A = or i32 %X, 62 + %B = icmp ult i32 %A, 50 + ret i1 %B +; CHECK: ret i1 false +} + +define i1 @and1(i32 %X) { +; CHECK: @and1 + %A = and i32 %X, 62 + %B = icmp ugt i32 %A, 70 + ret i1 %B +; CHECK: ret i1 false +} diff --git a/test/Transforms/InstSimplify/rem.ll b/test/Transforms/InstSimplify/rem.ll new file mode 100644 index 0000000000000..4c8f87cf5e920 --- /dev/null +++ b/test/Transforms/InstSimplify/rem.ll @@ -0,0 +1,17 @@ +; RUN: opt < %s -instsimplify -S | FileCheck %s + +define i32 @select1(i32 %x, i1 %b) { +; CHECK: @select1 + %rhs = select i1 %b, i32 %x, i32 1 + %rem = srem i32 %x, %rhs + ret i32 %rem +; CHECK: ret i32 0 +} + +define i32 @select2(i32 %x, i1 %b) { +; CHECK: @select2 + %rhs = select i1 %b, i32 %x, i32 1 + %rem = urem i32 %x, %rhs + ret i32 %rem +; CHECK: ret i32 0 +} diff --git a/test/Transforms/Internalize/available_externally.ll b/test/Transforms/Internalize/available_externally.ll new file mode 100644 index 0000000000000..a2cf23fb39092 --- /dev/null +++ b/test/Transforms/Internalize/available_externally.ll @@ -0,0 +1,16 @@ +; RUN: opt < %s -internalize -internalize-public-api-list foo -S | FileCheck %s + +; CHECK: define void @foo +define void @foo() { + ret void +} + +; CHECK: define internal void @zed +define void @zed() { + ret void +} + +; CHECK: define available_externally void @bar +define available_externally void @bar() { + ret void +} diff --git a/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll b/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll new file mode 100644 index 0000000000000..76dd2d12bdecf --- /dev/null +++ b/test/Transforms/JumpThreading/2011-04-02-SimplifyDeadBlock.ll @@ -0,0 +1,32 @@ +; RUN: opt < %s -jump-threading +; PR9446 +; Just check that it doesn't crash + +define void @int327() nounwind { +entry: + unreachable + +for.cond: ; preds = %for.cond4 + %tobool3 = icmp eq i8 undef, 0 + br i1 %tobool3, label %for.cond23, label %for.cond4 + +for.cond4: ; preds = %for.cond + br label %for.cond + +for.cond23: ; preds = %for.body28, %for.cond23, %for.cond + %conv321 = phi i32 [ %conv32, %for.body28 ], [ 0, %for.cond ], [ %conv321, %for.cond23 ] + %l_266.0 = phi i32 [ %phitmp, %for.body28 ], [ 0, %for.cond ], [ 0, %for.cond23 ] + %cmp26 = icmp eq i32 %l_266.0, 0 + br i1 %cmp26, label %for.body28, label %for.cond23 + +for.body28: ; preds = %for.cond23 + %and = and i32 %conv321, 1 + %conv32 = zext i8 undef to i32 + %add = add nsw i32 %l_266.0, 1 + %phitmp = and i32 %add, 255 + br label %for.cond23 + +if.end43: ; No predecessors! + ret void +} + diff --git a/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll b/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll new file mode 100644 index 0000000000000..46aaa00380e33 --- /dev/null +++ b/test/Transforms/JumpThreading/2011-04-14-InfLoop.ll @@ -0,0 +1,31 @@ +; RUN: opt -jump-threading < %s +; <rdar://problem/9284786> + +%0 = type <{ i64, i16, i64, i8, i8 }> + +@g_338 = external global %0, align 8 + +define void @func_1() nounwind ssp { +entry: + ret void + +for.cond1177: + %inc1187 = add nsw i32 0, 1 + %cmp1179 = icmp slt i32 %inc1187, 5 + br i1 %cmp1179, label %for.cond1177, label %land.rhs1320 + +land.rhs1320: + %tmp1324 = volatile load i64* getelementptr inbounds (%0* @g_338, i64 0, i32 2), align 1, !tbaa !0 + br label %if.end.i + +if.end.i: + %tobool.pr.i = phi i1 [ false, %if.end.i ], [ false, %land.rhs1320 ] + br i1 %tobool.pr.i, label %return, label %if.end.i + +return: + ret void +} + +!0 = metadata !{metadata !"long long", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} diff --git a/test/Transforms/JumpThreading/pr9331.ll b/test/Transforms/JumpThreading/pr9331.ll new file mode 100644 index 0000000000000..4c06d526ca189 --- /dev/null +++ b/test/Transforms/JumpThreading/pr9331.ll @@ -0,0 +1,50 @@ +; RUN: opt -jump-threading -S < %s + +define void @func(i8 zeroext %p_44) nounwind { +entry: + br i1 false, label %for.cond2, label %if.end50 + +for.cond2: ; preds = %for.inc46, %lor.end, %entry + %p_44.addr.1 = phi i8 [ %p_44.addr.1, %lor.end ], [ %p_44, %entry ], [ %p_44.addr.1, %for.inc46 ] + br i1 undef, label %for.inc46, label %for.body5 + +for.body5: ; preds = %for.cond2 + br i1 undef, label %lbl_465, label %if.then9 + +if.then9: ; preds = %for.body5 + br label %return + +lbl_465: ; preds = %lbl_465, %for.body5 + %tobool19 = icmp eq i8 undef, 0 + br i1 %tobool19, label %if.end21, label %lbl_465 + +if.end21: ; preds = %lbl_465 + %conv23 = zext i8 %p_44.addr.1 to i64 + %xor = xor i64 %conv23, 1 + %tobool.i = icmp eq i64 %conv23, 0 + br i1 %tobool.i, label %cond.false.i, label %safe_mod_func_uint64_t_u_u.exit + +cond.false.i: ; preds = %if.end21 + %div.i = udiv i64 %xor, %conv23 + br label %safe_mod_func_uint64_t_u_u.exit + +safe_mod_func_uint64_t_u_u.exit: ; preds = %cond.false.i, %if.end21 + %cond.i = phi i64 [ %div.i, %cond.false.i ], [ %conv23, %if.end21 ] + %tobool28 = icmp eq i64 %cond.i, 0 + br i1 %tobool28, label %lor.rhs, label %lor.end + +lor.rhs: ; preds = %safe_mod_func_uint64_t_u_u.exit + br label %lor.end + +lor.end: ; preds = %lor.rhs, %safe_mod_func_uint64_t_u_u.exit + br label %for.cond2 + +for.inc46: ; preds = %for.cond2 + br label %for.cond2 + +if.end50: ; preds = %entry + br label %return + +return: ; preds = %if.end50, %if.then9 + ret void +} diff --git a/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll b/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll index 7a80f8052b0dd..153458579b89a 100644 --- a/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll +++ b/test/Transforms/LCSSA/2006-06-03-IncorrectIDFPhis.ll @@ -1,7 +1,5 @@ ; RUN: opt < %s -loop-simplify -lcssa -S | \ ; RUN: grep {%%SJE.0.0.lcssa = phi .struct.SetJmpMapEntry} -; RUN: opt < %s -loop-simplify -lcssa -S | \ -; RUN: grep {%%SJE.0.0.lcssa1 = phi .struct.SetJmpMapEntry} %struct.SetJmpMapEntry = type { i8*, i32, %struct.SetJmpMapEntry* } diff --git a/test/Transforms/LCSSA/unused-phis.ll b/test/Transforms/LCSSA/unused-phis.ll new file mode 100644 index 0000000000000..aa2ab963411d8 --- /dev/null +++ b/test/Transforms/LCSSA/unused-phis.ll @@ -0,0 +1,38 @@ +; RUN: opt < %s -lcssa -S | FileCheck %s +; CHECK: exit1: +; CHECK: .lcssa = +; CHECK: exit2: +; CHECK: .lcssa2 = +; CHECK: exit3: +; CHECK-NOT: .lcssa1 = + +; Test to ensure that when there are multiple exit blocks, PHI nodes are +; only inserted by LCSSA when there is a use dominated by a given exit +; block. + +declare void @printf(i32 %i) + +define i32 @unused_phis() nounwind { +entry: + br label %loop + +loop: + %i = phi i32 [0, %entry], [1, %then2] + br i1 undef, label %exit1, label %then1 + +then1: + br i1 undef, label %exit2, label %then2 + +then2: + br i1 undef, label %exit3, label %loop + +exit1: + call void @printf(i32 %i) + ret i32 %i + +exit2: + ret i32 %i + +exit3: + ret i32 0 +} diff --git a/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll b/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll index 59f1dcbe2d7b1..e3d0d02edd9df 100644 --- a/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll +++ b/test/Transforms/LICM/2007-10-01-PromoteSafeValue.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -licm -S | grep promoted +; RUN: opt < %s -licm -S | FileCheck %s ; Promote value if at least one use is safe @@ -15,6 +15,8 @@ cond.true: ; preds = %loop.head store i32 40, i32* %p br label %loop.head +; CHECK: exit: +; CHECK: store i32 20, i32* %p exit: ; preds = %loop.head ret i32 0 } diff --git a/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll b/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll new file mode 100644 index 0000000000000..5774f587f1c3d --- /dev/null +++ b/test/Transforms/LICM/2011-04-06-HoistMissedASTUpdate.ll @@ -0,0 +1,32 @@ +; RUN: opt < %s -basicaa -licm -S | FileCheck %s +; PR9630 + +@g_39 = external global i16, align 2 + +declare i32* @func_84(i32** nocapture) nounwind readonly + +declare i32** @func_108(i32*** nocapture) nounwind readonly + +define void @func() nounwind { +entry: + br label %for.body4.lr.ph + +for.body4.lr.ph: + br label %for.body4 + +; CHECK: for.body4: +; CHECK: volatile load i16* @g_39 + +for.body4: + %l_612.11 = phi i32* [ undef, %for.body4.lr.ph ], [ %call19, %for.body4 ] + %tmp7 = volatile load i16* @g_39, align 2 + %call = call i32** @func_108(i32*** undef) + %call19 = call i32* @func_84(i32** %call) + br i1 false, label %for.body4, label %for.cond.loopexit + +for.cond.loopexit: + br i1 false, label %for.body4.lr.ph, label %for.end26 + +for.end26: + ret void +} diff --git a/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll b/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll new file mode 100644 index 0000000000000..86c2679b076a8 --- /dev/null +++ b/test/Transforms/LICM/2011-04-06-PromoteResultOfPromotion.ll @@ -0,0 +1,37 @@ +; RUN: opt < %s -tbaa -licm -S | FileCheck %s +; PR9634 + +@g_58 = common global i32 0, align 4 +@g_116 = common global i32* null, align 8 + +define void @f() nounwind { + +; CHECK: entry: +; CHECK: alloca [9 x i16] +; CHECK: load i32* @g_58 +; CHECK: br label %for.body + +entry: + %l_87.i = alloca [9 x i16], align 16 + br label %for.body + +for.body: ; preds = %entry, %for.inc + %inc12 = phi i32 [ 0, %entry ], [ %inc, %for.body ] + store i32* @g_58, i32** @g_116, align 8, !tbaa !0 + %tmp2 = load i32** @g_116, align 8, !tbaa !0 + %tmp3 = load i32* %tmp2, !tbaa !4 + %or = or i32 %tmp3, 10 + store i32 %or, i32* %tmp2, !tbaa !4 + %inc = add nsw i32 %inc12, 1 + %cmp = icmp slt i32 %inc, 4 + br i1 %cmp, label %for.body, label %for.end + +for.end: ; preds = %for.inc + ret void +} + +!0 = metadata !{metadata !"any pointer", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} +!3 = metadata !{metadata !"short", metadata !1} +!4 = metadata !{metadata !"int", metadata !1} diff --git a/test/Transforms/LICM/2011-04-09-RAUW-AST.ll b/test/Transforms/LICM/2011-04-09-RAUW-AST.ll new file mode 100644 index 0000000000000..4285bd19e5f1d --- /dev/null +++ b/test/Transforms/LICM/2011-04-09-RAUW-AST.ll @@ -0,0 +1,49 @@ +; RUN: opt < %s -loop-rotate -licm -S | FileCheck %s +; PR9604 + +@g_3 = global i32 0, align 4 +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00" + +define i32 @main() nounwind { +entry: + %tmp = load i32* @g_3, align 4 + %tobool = icmp eq i32 %tmp, 0 + br i1 %tobool, label %for.cond, label %if.then + +if.then: ; preds = %entry + br label %for.cond + +for.cond: ; preds = %for.inc10, %if.then, %entry + %g.0 = phi i32* [ %g.0, %for.inc10 ], [ @g_3, %entry ], [ null, %if.then ] + %x.0 = phi i32 [ %inc12, %for.inc10 ], [ 0, %entry ], [ 0, %if.then ] + %cmp = icmp slt i32 %x.0, 5 + br i1 %cmp, label %for.cond4, label %for.end13 + +for.cond4: ; preds = %for.body7, %for.cond + %y.0 = phi i32 [ %inc, %for.body7 ], [ 0, %for.cond ] + %cmp6 = icmp slt i32 %y.0, 5 + br i1 %cmp6, label %for.body7, label %for.inc10 + +; CHECK: for.body7: +; CHECK-NEXT: phi +; CHECK-NEXT: store i32 0 +; CHECK-NEXT: store i32 1 + +for.body7: ; preds = %for.cond4 + store i32 0, i32* @g_3, align 4 + store i32 1, i32* %g.0, align 4 + %inc = add nsw i32 %y.0, 1 + br label %for.cond4 + +for.inc10: ; preds = %for.cond4 + %inc12 = add nsw i32 %x.0, 1 + br label %for.cond + +for.end13: ; preds = %for.cond + %tmp14 = load i32* @g_3, align 4 + %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i32 %tmp14) nounwind + ret i32 0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind + diff --git a/test/Transforms/LICM/debug-value.ll b/test/Transforms/LICM/debug-value.ll new file mode 100644 index 0000000000000..889d4e2e3af9b --- /dev/null +++ b/test/Transforms/LICM/debug-value.ll @@ -0,0 +1,62 @@ +; RUN: opt -licm -basicaa < %s -S | FileCheck %s + +define void @dgefa() nounwind ssp { +entry: + br label %for.body + +for.body: ; preds = %for.cond.backedge, %entry + br i1 undef, label %if.then, label %for.cond.backedge, !dbg !11 + +for.cond.backedge: ; preds = %for.body61, %for.body61.us, %for.body + br i1 undef, label %for.end104, label %for.body, !dbg !15 + +if.then: ; preds = %for.body + br i1 undef, label %if.then27, label %if.end.if.end.split_crit_edge.critedge, !dbg !16 + +if.then27: ; preds = %if.then +; CHECK: tail call void @llvm.dbg.value + tail call void @llvm.dbg.value(metadata !18, i64 0, metadata !19), !dbg !21 + br label %for.body61.us + +if.end.if.end.split_crit_edge.critedge: ; preds = %if.then + br label %for.body61 + +for.body61.us: ; preds = %for.body61.us, %if.then27 + br i1 undef, label %for.cond.backedge, label %for.body61.us, !dbg !23 + +for.body61: ; preds = %for.body61, %if.end.if.end.split_crit_edge.critedge + br i1 undef, label %for.cond.backedge, label %for.body61, !dbg !23 + +for.end104: ; preds = %for.cond.backedge + ret void, !dbg !24 +} + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.sp = !{!0, !6, !9, !10} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"idamax", metadata !"idamax", metadata !"", metadata !1, i32 112, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, null} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/Benchmarks/CoyoteBench/lpbench.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 127169)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 589870, i32 0, metadata !1, metadata !"dscal", metadata !"dscal", metadata !"", metadata !1, i32 206, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, null} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{null} +!9 = metadata !{i32 589870, i32 0, metadata !1, metadata !"daxpy", metadata !"daxpy", metadata !"", metadata !1, i32 230, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, null} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 589870, i32 0, metadata !1, metadata !"dgefa", metadata !"dgefa", metadata !"", metadata !1, i32 267, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, null} ; [ DW_TAG_subprogram ] +!11 = metadata !{i32 281, i32 9, metadata !12, null} +!12 = metadata !{i32 589835, metadata !13, i32 272, i32 5, metadata !1, i32 32} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 589835, metadata !14, i32 271, i32 5, metadata !1, i32 31} ; [ DW_TAG_lexical_block ] +!14 = metadata !{i32 589835, metadata !10, i32 267, i32 1, metadata !1, i32 30} ; [ DW_TAG_lexical_block ] +!15 = metadata !{i32 271, i32 5, metadata !14, null} +!16 = metadata !{i32 284, i32 10, metadata !17, null} +!17 = metadata !{i32 589835, metadata !12, i32 282, i32 9, metadata !1, i32 33} ; [ DW_TAG_lexical_block ] +!18 = metadata !{double undef} +!19 = metadata !{i32 590080, metadata !14, metadata !"temp", metadata !1, i32 268, metadata !20, i32 0} ; [ DW_TAG_auto_variable ] +!20 = metadata !{i32 589860, metadata !2, metadata !"double", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!21 = metadata !{i32 286, i32 14, metadata !22, null} +!22 = metadata !{i32 589835, metadata !17, i32 285, i32 13, metadata !1, i32 34} ; [ DW_TAG_lexical_block ] +!23 = metadata !{i32 296, i32 13, metadata !17, null} +!24 = metadata !{i32 313, i32 1, metadata !14, null} diff --git a/test/Transforms/LoopIdiom/debug-line.ll b/test/Transforms/LoopIdiom/debug-line.ll new file mode 100644 index 0000000000000..d31662d57e981 --- /dev/null +++ b/test/Transforms/LoopIdiom/debug-line.ll @@ -0,0 +1,49 @@ +; RUN: opt -loop-idiom < %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.0.0" + + +define void @foo(double* nocapture %a) nounwind ssp { +entry: + tail call void @llvm.dbg.value(metadata !{double* %a}, i64 0, metadata !5), !dbg !8 + tail call void @llvm.dbg.value(metadata !9, i64 0, metadata !10), !dbg !14 + br label %for.body + +for.body: ; preds = %entry, %for.body + %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ] + %arrayidx = getelementptr double* %a, i64 %indvar +; CHECK: call void @llvm.memset{{.+}} !dbg + store double 0.000000e+00, double* %arrayidx, align 8, !dbg !15 + %indvar.next = add i64 %indvar, 1 + %exitcond = icmp ne i64 %indvar.next, 1000 + br i1 %exitcond, label %for.body, label %for.end, !dbg !14 + +for.end: ; preds = %for.body + tail call void @llvm.dbg.value(metadata !{null}, i64 0, metadata !10), !dbg !16 + ret void, !dbg !17 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (double*)* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"li.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"li.c", metadata !"/private/tmp", metadata !"clang version 2.9 (trunk 127165:127174)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 590081, metadata !0, metadata !"a", metadata !1, i32 16777218, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!6 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 64, i64 64, i64 0, i32 0, metadata !7} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 589860, metadata !2, metadata !"double", null, i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] +!8 = metadata !{i32 2, i32 18, metadata !0, null} +!9 = metadata !{i32 0} +!10 = metadata !{i32 590080, metadata !11, metadata !"i", metadata !1, i32 3, metadata !13, i32 0} ; [ DW_TAG_auto_variable ] +!11 = metadata !{i32 589835, metadata !12, i32 3, i32 3, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!12 = metadata !{i32 589835, metadata !0, i32 2, i32 21, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!14 = metadata !{i32 3, i32 3, metadata !12, null} +!15 = metadata !{i32 4, i32 5, metadata !11, null} +!16 = metadata !{i32 3, i32 29, metadata !11, null} +!17 = metadata !{i32 5, i32 1, metadata !12, null} diff --git a/test/Transforms/LoopRotate/crash.ll b/test/Transforms/LoopRotate/crash.ll index 9dc9862d150ab..16a6868f8ff14 100644 --- a/test/Transforms/LoopRotate/crash.ll +++ b/test/Transforms/LoopRotate/crash.ll @@ -137,3 +137,19 @@ bb17: ; preds = %bb15 } + + +; PR9523 - Non-canonical loop. +define void @test7(i8* %P) nounwind { +entry: + indirectbr i8* %P, [label %"3", label %"5"] + +"3": ; preds = %"4", %entry + br i1 undef, label %"5", label %"4" + +"4": ; preds = %"3" + br label %"3" + +"5": ; preds = %"3", %entry + ret void +} diff --git a/test/Transforms/LoopSimplify/merge-exits.ll b/test/Transforms/LoopSimplify/merge-exits.ll index 93a224744ca39..e5e471766b9a2 100644 --- a/test/Transforms/LoopSimplify/merge-exits.ll +++ b/test/Transforms/LoopSimplify/merge-exits.ll @@ -7,7 +7,7 @@ ; that indvars can promote the induction variable to i64 ; without needing casts. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target 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-n:32:64" define float @t(float* %pTmp1, float* %peakWeight, i32 %bandEdgeIndex) nounwind { entry: diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll index 4094e9c7e4d9f..986a55a3f6c4e 100644 --- a/test/Transforms/LoopStrengthReduce/invariant_value_first.ll +++ b/test/Transforms/LoopStrengthReduce/invariant_value_first.ll @@ -1,7 +1,8 @@ ; Check that the index of 'P[outer]' is pulled out of the loop. -; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \ +; RUN: opt < %s -loop-reduce -S | \ ; RUN: not grep {getelementptr.*%outer.*%INDVAR} +target datalayout = "e-p:32:32:32-n:8:16:32" declare i1 @pred() declare i32 @foo() diff --git a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll index e2aed78c32e3c..1d43961c356e1 100644 --- a/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll +++ b/test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll @@ -1,7 +1,8 @@ ; Check that the index of 'P[outer]' is pulled out of the loop. -; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \ +; RUN: opt < %s -loop-reduce -S | \ ; RUN: not grep {getelementptr.*%outer.*%INDVAR} +target datalayout = "e-p:32:32:32-n:32" declare i1 @pred() define void @test([10000 x i32]* %P, i32 %outer) { diff --git a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll index 410d88f672b54..00bd068d0b8f0 100644 --- a/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll +++ b/test/Transforms/LoopStrengthReduce/ops_after_indvar.ll @@ -1,7 +1,9 @@ ; Check that this test makes INDVAR and related stuff dead, because P[indvar] ; gets reduced, making INDVAR dead. -; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | not grep INDVAR +; RUN: opt < %s -loop-reduce -S | not grep INDVAR + +target datalayout = "e-p:32:32:32-n:32" declare i1 @pred() diff --git a/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll b/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll index 0a9fab0d5ea8d..7547d83629299 100644 --- a/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll +++ b/test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll @@ -9,7 +9,7 @@ ; mul uint %i, 3 -target datalayout = "e-p:32:32" +target datalayout = "e-p:32:32-n:32" target triple = "i686-apple-darwin8" @flags2 = external global [8193 x i8], align 32 ; <[8193 x i8]*> [#uses=1] diff --git a/test/Transforms/PhaseOrdering/basic.ll b/test/Transforms/PhaseOrdering/basic.ll new file mode 100644 index 0000000000000..c66e150aa7940 --- /dev/null +++ b/test/Transforms/PhaseOrdering/basic.ll @@ -0,0 +1,117 @@ +; RUN: opt -O3 -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-macosx10.6.7" + +declare i8* @malloc(i64) +declare void @free(i8*) + + +; PR2338 +define void @test1() nounwind ssp { + %retval = alloca i32, align 4 + %i = alloca i8*, align 8 + %call = call i8* @malloc(i64 1) + store i8* %call, i8** %i, align 8 + %tmp = load i8** %i, align 8 + store i8 1, i8* %tmp + %tmp1 = load i8** %i, align 8 + call void @free(i8* %tmp1) + ret void + +; CHECK: @test1 +; CHECK-NEXT: ret void +} + + +; PR6627 - This whole nasty sequence should be flattened down to a single +; 32-bit comparison. +define void @test2(i8* %arrayidx) nounwind ssp { +entry: + %xx = bitcast i8* %arrayidx to i32* + %x1 = load i32* %xx, align 4 + %tmp = trunc i32 %x1 to i8 + %conv = zext i8 %tmp to i32 + %cmp = icmp eq i32 %conv, 127 + br i1 %cmp, label %land.lhs.true, label %if.end + +land.lhs.true: ; preds = %entry + %arrayidx4 = getelementptr inbounds i8* %arrayidx, i64 1 + %tmp5 = load i8* %arrayidx4, align 1 + %conv6 = zext i8 %tmp5 to i32 + %cmp7 = icmp eq i32 %conv6, 69 + br i1 %cmp7, label %land.lhs.true9, label %if.end + +land.lhs.true9: ; preds = %land.lhs.true + %arrayidx12 = getelementptr inbounds i8* %arrayidx, i64 2 + %tmp13 = load i8* %arrayidx12, align 1 + %conv14 = zext i8 %tmp13 to i32 + %cmp15 = icmp eq i32 %conv14, 76 + br i1 %cmp15, label %land.lhs.true17, label %if.end + +land.lhs.true17: ; preds = %land.lhs.true9 + %arrayidx20 = getelementptr inbounds i8* %arrayidx, i64 3 + %tmp21 = load i8* %arrayidx20, align 1 + %conv22 = zext i8 %tmp21 to i32 + %cmp23 = icmp eq i32 %conv22, 70 + br i1 %cmp23, label %if.then, label %if.end + +if.then: ; preds = %land.lhs.true17 + %call25 = call i32 (...)* @doo() + br label %if.end + +if.end: + ret void + +; CHECK: @test2 +; CHECK: %x1 = load i32* %xx, align 4 +; CHECK-NEXT: icmp eq i32 %x1, 1179403647 +; CHECK-NEXT: br i1 {{.*}}, label %if.then, label %if.end +} + +declare i32 @doo(...) + +; PR6627 - This should all be flattened down to one compare. This is the same +; as test2, except that the initial load is done as an i8 instead of i32, thus +; requiring widening. +define void @test2a(i8* %arrayidx) nounwind ssp { +entry: + %x1 = load i8* %arrayidx, align 4 + %conv = zext i8 %x1 to i32 + %cmp = icmp eq i32 %conv, 127 + br i1 %cmp, label %land.lhs.true, label %if.end + +land.lhs.true: ; preds = %entry + %arrayidx4 = getelementptr inbounds i8* %arrayidx, i64 1 + %tmp5 = load i8* %arrayidx4, align 1 + %conv6 = zext i8 %tmp5 to i32 + %cmp7 = icmp eq i32 %conv6, 69 + br i1 %cmp7, label %land.lhs.true9, label %if.end + +land.lhs.true9: ; preds = %land.lhs.true + %arrayidx12 = getelementptr inbounds i8* %arrayidx, i64 2 + %tmp13 = load i8* %arrayidx12, align 1 + %conv14 = zext i8 %tmp13 to i32 + %cmp15 = icmp eq i32 %conv14, 76 + br i1 %cmp15, label %land.lhs.true17, label %if.end + +land.lhs.true17: ; preds = %land.lhs.true9 + %arrayidx20 = getelementptr inbounds i8* %arrayidx, i64 3 + %tmp21 = load i8* %arrayidx20, align 1 + %conv22 = zext i8 %tmp21 to i32 + %cmp23 = icmp eq i32 %conv22, 70 + br i1 %cmp23, label %if.then, label %if.end + +if.then: ; preds = %land.lhs.true17 + %call25 = call i32 (...)* @doo() + br label %if.end + +if.end: + ret void + +; CHECK: @test2a +; CHECK: %x1 = load i32* {{.*}}, align 4 +; CHECK-NEXT: icmp eq i32 %x1, 1179403647 +; CHECK-NEXT: br i1 {{.*}}, label %if.then, label %if.end +} + diff --git a/test/Transforms/Reassociate/crash.ll b/test/Transforms/Reassociate/crash.ll index 6f21b66ed0053..7a819422eab85 100644 --- a/test/Transforms/Reassociate/crash.ll +++ b/test/Transforms/Reassociate/crash.ll @@ -42,3 +42,28 @@ define i32 @test3(i32 %Arg, i32 %x1, i32 %x2, i32 %x3) { %E = add i32 %D, %C ret i32 %E } + + +; rdar://9096268 +define void @x66303361ae3f602889d1b7d0f86e5455(i8* %arg) nounwind { +_: + br label %_33 + +_33: ; preds = %_33, %_ + %tmp348 = load i8* %arg, align 1 + %tmp349 = lshr i8 %tmp348, 7 + %tmp350 = or i8 %tmp349, 42 + %tmp351 = add i8 %tmp350, -42 + %tmp352 = zext i8 %tmp351 to i32 + %tmp358 = add i32 %tmp352, -501049439 + %tmp359 = mul i32 %tmp358, %tmp358 + %tmp360 = mul i32 %tmp352, %tmp352 + %tmp361 = sub i32 %tmp359, %tmp360 + %tmp362 = mul i32 %tmp361, -920056735 + %tmp363 = add i32 %tmp362, 501049439 + %tmp364 = add i32 %tmp362, -2000262972 + %tmp365 = sub i32 %tmp363, %tmp364 + %tmp366 = sub i32 -501049439, %tmp362 + %tmp367 = add i32 %tmp365, %tmp366 + br label %_33 +} diff --git a/test/Transforms/Reassociate/secondary.ll b/test/Transforms/Reassociate/secondary.ll new file mode 100644 index 0000000000000..a52000ada5378 --- /dev/null +++ b/test/Transforms/Reassociate/secondary.ll @@ -0,0 +1,24 @@ +; RUN: opt -S -reassociate < %s | FileCheck %s +; rdar://9167457 + +; Reassociate shouldn't break this testcase involving a secondary +; reassociation. + +; CHECK: define +; CHECK-NOT: undef +; CHECK: %factor = mul i32 %tmp3, -2 +; CHECK-NOT: undef +; CHECK: } + +define void @x0f2f640ab6718391b59ce96d9fdeda54(i32 %arg, i32 %arg1, i32 %arg2, i32* %.out) nounwind { +_: + %tmp = sub i32 %arg, %arg1 + %tmp3 = mul i32 %tmp, -1268345047 + %tmp4 = add i32 %tmp3, 2014710503 + %tmp5 = add i32 %tmp3, -1048397418 + %tmp6 = sub i32 %tmp4, %tmp5 + %tmp7 = sub i32 -2014710503, %tmp3 + %tmp8 = add i32 %tmp6, %tmp7 + store i32 %tmp8, i32* %.out + ret void +} diff --git a/test/Transforms/SCCP/apint-basictest.ll b/test/Transforms/SCCP/apint-basictest.ll index c03bfef74301d..f6ef1ab3f23b9 100644 --- a/test/Transforms/SCCP/apint-basictest.ll +++ b/test/Transforms/SCCP/apint-basictest.ll @@ -1,4 +1,4 @@ -; This is a basic sanity check for constant propogation. The add instruction +; This is a basic sanity check for constant propagation. The add instruction ; should be eliminated. ; RUN: opt < %s -sccp -S | not grep add diff --git a/test/Transforms/SCCP/apint-basictest2.ll b/test/Transforms/SCCP/apint-basictest2.ll index 173482786f201..ad8b4a460cc01 100644 --- a/test/Transforms/SCCP/apint-basictest2.ll +++ b/test/Transforms/SCCP/apint-basictest2.ll @@ -1,4 +1,4 @@ -; This is a basic sanity check for constant propogation. The add instruction +; This is a basic sanity check for constant propagation. The add instruction ; and phi instruction should be eliminated. ; RUN: opt < %s -sccp -S | not grep phi diff --git a/test/Transforms/SCCP/apint-basictest3.ll b/test/Transforms/SCCP/apint-basictest3.ll index 47671bf46b31a..b8fcca6fda932 100644 --- a/test/Transforms/SCCP/apint-basictest3.ll +++ b/test/Transforms/SCCP/apint-basictest3.ll @@ -1,4 +1,4 @@ -; This is a basic sanity check for constant propogation. It tests the basic +; This is a basic sanity check for constant propagation. It tests the basic ; arithmatic operations. diff --git a/test/Transforms/SCCP/apint-basictest4.ll b/test/Transforms/SCCP/apint-basictest4.ll index 41036ea002d2e..862426020e4f2 100644 --- a/test/Transforms/SCCP/apint-basictest4.ll +++ b/test/Transforms/SCCP/apint-basictest4.ll @@ -1,4 +1,4 @@ -; This is a basic sanity check for constant propogation. It tests the basic +; This is a basic sanity check for constant propagation. It tests the basic ; logic operations. diff --git a/test/Transforms/SRETPromotion/2008-03-11-attributes.ll b/test/Transforms/SRETPromotion/2008-03-11-attributes.ll deleted file mode 100644 index 55abec55ed037..0000000000000 --- a/test/Transforms/SRETPromotion/2008-03-11-attributes.ll +++ /dev/null @@ -1,7 +0,0 @@ -; RUN: opt < %s -sretpromotion -disable-output - %struct.ObjPoint = type { double, double, double, double, double, double } - -define void @RotatePoint(%struct.ObjPoint* sret %agg.result, %struct.ObjPoint* byval %a, double %rx, double %ry, double %rz) nounwind { -entry: - unreachable -} diff --git a/test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll b/test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll deleted file mode 100644 index 1168b0b2e9d6f..0000000000000 --- a/test/Transforms/SRETPromotion/2008-06-04-function-pointer-passing.ll +++ /dev/null @@ -1,24 +0,0 @@ -; This test lures sretpromotion into promoting the sret argument of foo, even -; when the function is used as an argument to bar. It used to not check for -; this, assuming that all users of foo were direct calls, resulting in an -; assertion failure later on. - -; We're mainly testing for opt not to crash, but we'll check to see if the sret -; attribute is still there for good measure. -; RUN: opt < %s -sretpromotion -S | grep sret - -%struct.S = type <{ i32, i32 }> - -define i32 @main() { -entry: - %tmp = alloca %struct.S ; <%struct.S*> [#uses=1] - call void @bar( %struct.S* sret %tmp, void (%struct.S*, ...)* @foo ) - ret i32 undef -} - -declare void @bar(%struct.S* sret , void (%struct.S*, ...)*) - -define internal void @foo(%struct.S* sret %agg.result, ...) { -entry: - ret void -} diff --git a/test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll b/test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll deleted file mode 100644 index 26c6a6e5077b5..0000000000000 --- a/test/Transforms/SRETPromotion/2008-06-05-non-call-use.ll +++ /dev/null @@ -1,20 +0,0 @@ -; This test shows an sret function that is used as an operand to a bitcast. -; StructRetPromotion used to assume that a function was only used by call or -; invoke instructions, making this code cause an assertion failure. - -; We're mainly testing for opt not to crash, but we'll check to see if the sret -; attribute is still there for good measure. -; RUN: opt < %s -sretpromotion -S | grep sret - -%struct.S = type <{ i32, i32 }> - -define i32 @main() { -entry: - %bar = bitcast void (%struct.S*)* @foo to i32 ()* - ret i32 undef -} - -define internal void @foo(%struct.S* sret) { -entry: - ret void -} diff --git a/test/Transforms/SRETPromotion/basictest.ll b/test/Transforms/SRETPromotion/basictest.ll deleted file mode 100644 index ff047dc41ebae..0000000000000 --- a/test/Transforms/SRETPromotion/basictest.ll +++ /dev/null @@ -1,33 +0,0 @@ -; RUN: opt < %s -sretpromotion -S > %t -; RUN: cat %t | grep sret | count 1 - -; This function is promotable -define internal void @promotable({i32, i32}* sret %s) { - %A = getelementptr {i32, i32}* %s, i32 0, i32 0 - store i32 0, i32* %A - %B = getelementptr {i32, i32}* %s, i32 0, i32 0 - store i32 1, i32* %B - ret void -} - -; This function is not promotable (due to it's use below) -define internal void @notpromotable({i32, i32}* sret %s) { - %A = getelementptr {i32, i32}* %s, i32 0, i32 0 - store i32 0, i32* %A - %B = getelementptr {i32, i32}* %s, i32 0, i32 0 - store i32 1, i32* %B - ret void -} - -define void @caller({i32, i32}* %t) { - %s = alloca {i32, i32} - call void @promotable({i32, i32}* %s) - %A = getelementptr {i32, i32}* %s, i32 0, i32 0 - %a = load i32* %A - %B = getelementptr {i32, i32}* %s, i32 0, i32 0 - %b = load i32* %B - ; This passes in something that's not an alloca, which makes the argument not - ; promotable - call void @notpromotable({i32, i32}* %t) - ret void -} diff --git a/test/Transforms/SRETPromotion/dg.exp b/test/Transforms/SRETPromotion/dg.exp deleted file mode 100644 index f2005891a59a8..0000000000000 --- a/test/Transforms/SRETPromotion/dg.exp +++ /dev/null @@ -1,3 +0,0 @@ -load_lib llvm.exp - -RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] diff --git a/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll b/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll index d799bd77e4581..8bc4ff0b3ffc7 100644 --- a/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll +++ b/test/Transforms/ScalarRepl/2008-01-29-PromoteBug.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -scalarrepl -instcombine -S | grep {ret i8 17} ; rdar://5707076 -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 datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" target triple = "i386-apple-darwin9.1.0" %struct.T = type <{ i8, [3 x i8] }> diff --git a/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll b/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll index 87a08b7eaaf21..ce70a1b13b812 100644 --- a/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll +++ b/test/Transforms/ScalarRepl/2008-06-05-loadstore-agg.ll @@ -13,7 +13,7 @@ define i32 @foo() { %res2 = insertvalue { i32, i32 } %res1, i32 2, 1 ; <{ i32, i32 }> [#uses=1] ; And store it store { i32, i32 } %res2, { i32, i32 }* %target - ; Actually use %target, so it doesn't get removed alltogether + ; Actually use %target, so it doesn't get removed altogether %ptr = getelementptr { i32, i32 }* %target, i32 0, i32 0 %val = load i32* %ptr ret i32 %val @@ -26,7 +26,7 @@ define i32 @bar() { %res2 = insertvalue [ 2 x i32 ] %res1, i32 2, 1 ; <{ i32, i32 }> [#uses=1] ; And store it store [ 2 x i32 ] %res2, [ 2 x i32 ]* %target - ; Actually use %target, so it doesn't get removed alltogether + ; Actually use %target, so it doesn't get removed altogether %ptr = getelementptr [ 2 x i32 ]* %target, i32 0, i32 0 %val = load i32* %ptr ret i32 %val diff --git a/test/Transforms/ScalarRepl/dg.exp b/test/Transforms/ScalarRepl/dg.exp index f2005891a59a8..39954d8a498de 100644 --- a/test/Transforms/ScalarRepl/dg.exp +++ b/test/Transforms/ScalarRepl/dg.exp @@ -1,3 +1,3 @@ load_lib llvm.exp -RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]] diff --git a/test/Transforms/ScalarRepl/inline-vector.ll b/test/Transforms/ScalarRepl/inline-vector.ll new file mode 100644 index 0000000000000..2f51cc7cf59c0 --- /dev/null +++ b/test/Transforms/ScalarRepl/inline-vector.ll @@ -0,0 +1,53 @@ +; RUN: opt < %s -scalarrepl -S | FileCheck %s +; RUN: opt < %s -scalarrepl-ssa -S | FileCheck %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10.0.0" + +%struct.Vector4 = type { float, float, float, float } +@f.vector = internal constant %struct.Vector4 { float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 }, align 16 + +; CHECK: define void @f +; CHECK-NOT: alloca +; CHECK: phi <4 x float> + +define void @f() nounwind ssp { +entry: + %i = alloca i32, align 4 + %vector = alloca %struct.Vector4, align 16 + %agg.tmp = alloca %struct.Vector4, align 16 + %tmp = bitcast %struct.Vector4* %vector to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp, i8* bitcast (%struct.Vector4* @f.vector to i8*), i32 16, i32 16, i1 false) + br label %for.cond + +for.cond: ; preds = %for.body, %entry + %storemerge = phi i32 [ 0, %entry ], [ %inc, %for.body ] + store i32 %storemerge, i32* %i, align 4 + %cmp = icmp slt i32 %storemerge, 1000000 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %tmp2 = bitcast %struct.Vector4* %agg.tmp to i8* + %tmp3 = bitcast %struct.Vector4* %vector to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %tmp2, i8* %tmp3, i32 16, i32 16, i1 false) + %0 = bitcast %struct.Vector4* %agg.tmp to [2 x i64]* + %1 = load [2 x i64]* %0, align 16 + %tmp2.i = extractvalue [2 x i64] %1, 0 + %tmp3.i = zext i64 %tmp2.i to i128 + %tmp10.i = bitcast i128 %tmp3.i to <4 x float> + %sub.i.i = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %tmp10.i + %2 = bitcast %struct.Vector4* %vector to <4 x float>* + store <4 x float> %sub.i.i, <4 x float>* %2, align 16 + %tmp4 = load i32* %i, align 4 + %inc = add nsw i32 %tmp4, 1 + br label %for.cond + +for.end: ; preds = %for.cond + %x = getelementptr inbounds %struct.Vector4* %vector, i32 0, i32 0 + %tmp5 = load float* %x, align 16 + %conv = fpext float %tmp5 to double + %call = call i32 (...)* @printf(double %conv) nounwind + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind +declare i32 @printf(...) diff --git a/test/Transforms/ScalarRepl/only-memcpy-uses.ll b/test/Transforms/ScalarRepl/only-memcpy-uses.ll new file mode 100644 index 0000000000000..cfb88bd80d60e --- /dev/null +++ b/test/Transforms/ScalarRepl/only-memcpy-uses.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -scalarrepl -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" + +%struct.S = type { [12 x i32] } + +; CHECK: @bar4 +define void @bar4(%struct.S* byval %s) nounwind ssp { +entry: +; CHECK: alloca +; CHECK-NOT: load +; CHECK: memcpy + %t = alloca %struct.S, align 4 + %agg.tmp = alloca %struct.S, align 4 + %tmp = bitcast %struct.S* %t to i8* + %tmp1 = bitcast %struct.S* %s to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 48, i32 4, i1 false) + %tmp2 = bitcast %struct.S* %agg.tmp to i8* + %tmp3 = bitcast %struct.S* %t to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %tmp3, i64 48, i32 4, i1 false) + %call = call i32 (...)* @bazz(%struct.S* byval %agg.tmp) + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind + +declare i32 @bazz(...) diff --git a/test/Transforms/ScalarRepl/union-pointer.ll b/test/Transforms/ScalarRepl/union-pointer.ll index fe702fa217723..ea4ec14e5621b 100644 --- a/test/Transforms/ScalarRepl/union-pointer.ll +++ b/test/Transforms/ScalarRepl/union-pointer.ll @@ -3,7 +3,7 @@ ; RUN: not grep alloca ; RUN: opt < %s -scalarrepl -S | grep {ret i8} -target datalayout = "e-p:32:32" +target datalayout = "e-p:32:32-n8:16:32" target triple = "i686-apple-darwin8.7.2" %struct.Val = type { i32*, i32 } diff --git a/test/Transforms/ScalarRepl/vector_promote.ll b/test/Transforms/ScalarRepl/vector_promote.ll index 37cb49f539d60..c51ef109c0b28 100644 --- a/test/Transforms/ScalarRepl/vector_promote.ll +++ b/test/Transforms/ScalarRepl/vector_promote.ll @@ -94,7 +94,172 @@ define i64 @test6(<2 x float> %X) { %tmp = load i64* %P ret i64 %tmp ; CHECK: @test6 -; CHECK: bitcast <2 x float> %X to <1 x i64> +; CHECK: bitcast <2 x float> %X to i64 ; CHECK: ret i64 } +define float @test7(<4 x float> %x) { + %a = alloca <4 x float> + store <4 x float> %x, <4 x float>* %a + %p = bitcast <4 x float>* %a to <2 x float>* + %b = load <2 x float>* %p + %q = getelementptr <4 x float>* %a, i32 0, i32 2 + %c = load float* %q + ret float %c +; CHECK: @test7 +; CHECK-NOT: alloca +; CHECK: bitcast <4 x float> %x to <2 x double> +; CHECK-NEXT: extractelement <2 x double> +; CHECK-NEXT: bitcast double %tmp4 to <2 x float> +; CHECK-NEXT: extractelement <4 x float> +} + +define void @test8(<4 x float> %x, <2 x float> %y) { + %a = alloca <4 x float> + store <4 x float> %x, <4 x float>* %a + %p = bitcast <4 x float>* %a to <2 x float>* + store <2 x float> %y, <2 x float>* %p + ret void +; CHECK: @test8 +; CHECK-NOT: alloca +; CHECK: bitcast <4 x float> %x to <2 x double> +; CHECK-NEXT: bitcast <2 x float> %y to double +; CHECK-NEXT: insertelement <2 x double> +; CHECK-NEXT: bitcast <2 x double> %tmp2 to <4 x float> +} + +define i256 @test9(<4 x i256> %x) { + %a = alloca <4 x i256> + store <4 x i256> %x, <4 x i256>* %a + %p = bitcast <4 x i256>* %a to <2 x i256>* + %b = load <2 x i256>* %p + %q = getelementptr <4 x i256>* %a, i32 0, i32 2 + %c = load i256* %q + ret i256 %c +; CHECK: @test9 +; CHECK-NOT: alloca +; CHECK: bitcast <4 x i256> %x to <2 x i512> +; CHECK-NEXT: extractelement <2 x i512> +; CHECK-NEXT: bitcast i512 %tmp4 to <2 x i256> +; CHECK-NEXT: extractelement <4 x i256> +} + +define void @test10(<4 x i256> %x, <2 x i256> %y) { + %a = alloca <4 x i256> + store <4 x i256> %x, <4 x i256>* %a + %p = bitcast <4 x i256>* %a to <2 x i256>* + store <2 x i256> %y, <2 x i256>* %p + ret void +; CHECK: @test10 +; CHECK-NOT: alloca +; CHECK: bitcast <4 x i256> %x to <2 x i512> +; CHECK-NEXT: bitcast <2 x i256> %y to i512 +; CHECK-NEXT: insertelement <2 x i512> +; CHECK-NEXT: bitcast <2 x i512> %tmp2 to <4 x i256> +} + +%union.v = type { <2 x i64> } + +define void @test11(<2 x i64> %x) { + %a = alloca %union.v + %p = getelementptr inbounds %union.v* %a, i32 0, i32 0 + store <2 x i64> %x, <2 x i64>* %p, align 16 + %q = getelementptr inbounds %union.v* %a, i32 0, i32 0 + %r = bitcast <2 x i64>* %q to <4 x float>* + %b = load <4 x float>* %r, align 16 + ret void +; CHECK: @test11 +; CHECK-NOT: alloca +} + +define void @test12() { +entry: + %a = alloca <64 x i8>, align 64 + store <64 x i8> undef, <64 x i8>* %a, align 64 + %p = bitcast <64 x i8>* %a to <16 x i8>* + %0 = load <16 x i8>* %p, align 64 + store <16 x i8> undef, <16 x i8>* %p, align 64 + %q = bitcast <16 x i8>* %p to <64 x i8>* + %1 = load <64 x i8>* %q, align 64 + ret void +; CHECK: @test12 +; CHECK-NOT: alloca +; CHECK: extractelement <4 x i128> +; CHECK: insertelement <4 x i128> +} + +define float @test13(<4 x float> %x, <2 x i32> %y) { + %a = alloca <4 x float> + store <4 x float> %x, <4 x float>* %a + %p = bitcast <4 x float>* %a to <2 x float>* + %b = load <2 x float>* %p + %q = getelementptr <4 x float>* %a, i32 0, i32 2 + %c = load float* %q + %r = bitcast <4 x float>* %a to <2 x i32>* + store <2 x i32> %y, <2 x i32>* %r + ret float %c +; CHECK: @test13 +; CHECK-NOT: alloca +; CHECK: bitcast <4 x float> %x to i128 +} + +define <3 x float> @test14(<3 x float> %x) { +entry: + %x.addr = alloca <3 x float>, align 16 + %r = alloca <3 x i32>, align 16 + %extractVec = shufflevector <3 x float> %x, <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef> + %storetmp = bitcast <3 x float>* %x.addr to <4 x float>* + store <4 x float> %extractVec, <4 x float>* %storetmp, align 16 + %tmp = load <3 x float>* %x.addr, align 16 + %cmp = fcmp une <3 x float> %tmp, zeroinitializer + %sext = sext <3 x i1> %cmp to <3 x i32> + %and = and <3 x i32> <i32 1065353216, i32 1065353216, i32 1065353216>, %sext + %extractVec1 = shufflevector <3 x i32> %and, <3 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef> + %storetmp2 = bitcast <3 x i32>* %r to <4 x i32>* + store <4 x i32> %extractVec1, <4 x i32>* %storetmp2, align 16 + %tmp3 = load <3 x i32>* %r, align 16 + %0 = bitcast <3 x i32> %tmp3 to <3 x float> + %tmp4 = load <3 x float>* %x.addr, align 16 + ret <3 x float> %tmp4 +; CHECK: @test14 +; CHECK-NOT: alloca +; CHECK: shufflevector <4 x i32> %extractVec1, <4 x i32> undef, <3 x i32> <i32 0, i32 1, i32 2> +} + +define void @test15(<3 x i64>* sret %agg.result, <3 x i64> %x, <3 x i64> %min) { +entry: + %x.addr = alloca <3 x i64>, align 32 + %min.addr = alloca <3 x i64>, align 32 + %extractVec = shufflevector <3 x i64> %x, <3 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef> + %storetmp = bitcast <3 x i64>* %x.addr to <4 x i64>* + store <4 x i64> %extractVec, <4 x i64>* %storetmp, align 32 + %extractVec1 = shufflevector <3 x i64> %min, <3 x i64> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 undef> + %storetmp2 = bitcast <3 x i64>* %min.addr to <4 x i64>* + store <4 x i64> %extractVec1, <4 x i64>* %storetmp2, align 32 + %tmp = load <3 x i64>* %x.addr + %tmp5 = extractelement <3 x i64> %tmp, i32 0 + %tmp11 = insertelement <3 x i64> %tmp, i64 %tmp5, i32 0 + store <3 x i64> %tmp11, <3 x i64>* %x.addr + %tmp30 = load <3 x i64>* %x.addr, align 32 + store <3 x i64> %tmp30, <3 x i64>* %agg.result + ret void +; CHECK: @test15 +; CHECK-NOT: alloca +; CHECK: shufflevector <4 x i64> %tmpV2, <4 x i64> undef, <3 x i32> <i32 0, i32 1, i32 2> +} + +define <4 x float> @test16(<4 x float> %x, i64 %y0, i64 %y1) { +entry: + %tmp8 = bitcast <4 x float> undef to <2 x double> + %tmp9 = bitcast i64 %y0 to double + %tmp10 = insertelement <2 x double> %tmp8, double %tmp9, i32 0 + %tmp11 = bitcast <2 x double> %tmp10 to <4 x float> + %tmp3 = bitcast <4 x float> %tmp11 to <2 x double> + %tmp4 = bitcast i64 %y1 to double + %tmp5 = insertelement <2 x double> %tmp3, double %tmp4, i32 1 + %tmp6 = bitcast <2 x double> %tmp5 to <4 x float> + ret <4 x float> %tmp6 +; CHECK: @test16 +; CHECK-NOT: alloca +; CHECK: bitcast <4 x float> %tmp11 to <2 x double> +} diff --git a/test/Transforms/SimplifyCFG/2006-08-03-Crash.ll b/test/Transforms/SimplifyCFG/2006-08-03-Crash.ll index 2c84c937ae39d..70fbddfe33b49 100644 --- a/test/Transforms/SimplifyCFG/2006-08-03-Crash.ll +++ b/test/Transforms/SimplifyCFG/2006-08-03-Crash.ll @@ -1,7 +1,5 @@ -; RUN: opt < %s -gvn -simplifycfg \ -; RUN: -disable-output +; RUN: opt < %s -gvn -simplifycfg -disable-output ; PR867 -; END. target datalayout = "E-p:32:32" target triple = "powerpc-apple-darwin8" diff --git a/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll b/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll index 59e886b2ddbe5..56f43b64f74e6 100644 --- a/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll +++ b/test/Transforms/SimplifyCFG/2008-05-16-PHIBlockMerge.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -simplifycfg -S > %t ; RUN: not grep {^BB.tomerge} %t -; RUN grep {^BB.nomerge} %t | count 2 +; RUN: grep {^BB.nomerge} %t | count 2 ; ModuleID = '<stdin>' declare i1 @foo() diff --git a/test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll b/test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll new file mode 100644 index 0000000000000..329774e22429c --- /dev/null +++ b/test/Transforms/SimplifyCFG/2011-03-08-UnreachableUse.ll @@ -0,0 +1,31 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s +; PR9420 + +; Note that the crash in PR9420 test is sensitive to the ordering of +; the transformations done by SimplifyCFG, so this test is likely to rot +; quickly. + +define noalias i8* @func_29() nounwind { +; CHECK: entry: +; CHECK-NEXT: unreachable +entry: + br label %for.cond + +for.cond: ; preds = %for.inc38, %entry + %p_34.addr.0 = phi i16 [ 1, %entry ], [ %conv40, %for.inc38 ] + br label %for.cond1 + +for.cond1: ; preds = %for.inc29, %for.cond + %p_32.addr.0 = phi i1 [ true, %for.cond ], [ true, %for.inc29 ] + br i1 %p_32.addr.0, label %for.body8, label %for.inc38 + +for.body8: ; preds = %for.cond1 + unreachable + +for.inc29: ; preds = %for.cond17 + br label %for.cond1 + +for.inc38: ; preds = %for.end32 + %conv40 = add i16 %p_34.addr.0, 1 + br label %for.cond +} diff --git a/test/Transforms/SimplifyCFG/PhiBlockMerge.ll b/test/Transforms/SimplifyCFG/PhiBlockMerge.ll index c28d0bac37592..36b52f52d490e 100644 --- a/test/Transforms/SimplifyCFG/PhiBlockMerge.ll +++ b/test/Transforms/SimplifyCFG/PhiBlockMerge.ll @@ -6,6 +6,7 @@ define i32 @test(i1 %a, i1 %b) { ; CHECK: br i1 %a br i1 %a, label %M, label %O +; CHECK: O: O: ; preds = %0 ; CHECK: select i1 %b, i32 0, i32 1 ; CHECK-NOT: phi diff --git a/test/Transforms/SimplifyCFG/PhiEliminate2.ll b/test/Transforms/SimplifyCFG/PhiEliminate2.ll index c0f6781293db5..0b3893d520dbb 100644 --- a/test/Transforms/SimplifyCFG/PhiEliminate2.ll +++ b/test/Transforms/SimplifyCFG/PhiEliminate2.ll @@ -1,14 +1,17 @@ ; RUN: opt < %s -simplifycfg -S | not grep br -define i32 @test(i1 %C, i32 %V1, i32 %V2) { +define i32 @test(i1 %C, i32 %V1, i32 %V2, i16 %V3) { entry: - br i1 %C, label %then, label %Cont + br i1 %C, label %then, label %else then: ; preds = %entry - %V3 = or i32 %V2, %V1 ; <i32> [#uses=1] + %V4 = or i32 %V2, %V1 ; <i32> [#uses=1] br label %Cont -Cont: ; preds = %then, %entry - %V4 = phi i32 [ %V1, %entry ], [ %V3, %then ] ; <i32> [#uses=0] - call i32 @test( i1 false, i32 0, i32 0 ) ; <i32>:0 [#uses=0] +else: ; preds = %entry + %V5 = sext i16 %V3 to i32 ; <i32> [#uses=1] + br label %Cont +Cont: ; preds = %then, %else + %V6 = phi i32 [ %V5, %else ], [ %V4, %then ] ; <i32> [#uses=0] + call i32 @test( i1 false, i32 0, i32 0, i16 0 ) ; <i32>:0 [#uses=0] ret i32 %V1 } diff --git a/test/Transforms/SimplifyCFG/PhiEliminate3.ll b/test/Transforms/SimplifyCFG/PhiEliminate3.ll new file mode 100644 index 0000000000000..3566b874c0b7d --- /dev/null +++ b/test/Transforms/SimplifyCFG/PhiEliminate3.ll @@ -0,0 +1,34 @@ +; Test merging of blocks containing complex expressions, +; with various folding thresholds +; +; RUN: opt < %s -simplifycfg -S -phi-node-folding-threshold=1 | grep N: +; RUN: opt < %s -simplifycfg -S -phi-node-folding-threshold=2 | not grep N: +; RUN: opt < %s -simplifycfg -S -phi-node-folding-threshold=2 | grep M: +; RUN: opt < %s -simplifycfg -S -phi-node-folding-threshold=7 | not grep M: +; + +define i32 @test(i1 %a, i1 %b, i32 %i, i32 %j, i32 %k) { +entry: + br i1 %a, label %M, label %O +O: + br i1 %b, label %P, label %Q +P: + %iaj = add i32 %i, %j + %iajak = add i32 %iaj, %k + br label %N +Q: + %ixj = xor i32 %i, %j + %ixjxk = xor i32 %ixj, %k + br label %N +N: + ; This phi should be foldable if threshold >= 2 + %Wp = phi i32 [ %iajak, %P ], [ %ixjxk, %Q ] + %Wp2 = add i32 %Wp, %Wp + br label %M +M: + ; This phi should be foldable if threshold >= 7 + %W = phi i32 [ %Wp2, %N ], [ 2, %entry ] + %R = add i32 %W, 1 + ret i32 %R +} + diff --git a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll index 7133d9875cafb..4a692f3622ec8 100644 --- a/test/Transforms/SimplifyCFG/UnreachableEliminate.ll +++ b/test/Transforms/SimplifyCFG/UnreachableEliminate.ll @@ -1,33 +1,73 @@ -; RUN: opt < %s -simplifycfg -S | not grep unreachable +; RUN: opt < %s -simplifycfg -S | FileCheck %s define void @test1(i1 %C, i1* %BP) { +; CHECK: @test1 +; CHECK: entry: +; CHECK-NEXT: ret void +entry: br i1 %C, label %T, label %F -T: ; preds = %0 +T: store i1 %C, i1* %BP unreachable -F: ; preds = %0 +F: ret void } define void @test2() { +; CHECK: @test2 +; CHECK: entry: +; CHECK-NEXT: call void @test2() +; CHECK-NEXT: ret void +entry: invoke void @test2( ) to label %N unwind label %U -U: ; preds = %0 +U: unreachable -N: ; preds = %0 +N: ret void } define i32 @test3(i32 %v) { +; CHECK: @test3 +; CHECK: entry: +; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2 +; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1 +; CHECK-NEXT: ret +entry: switch i32 %v, label %default [ i32 1, label %U i32 2, label %T ] -default: ; preds = %0 +default: ret i32 1 -U: ; preds = %0 +U: unreachable -T: ; preds = %0 +T: ret i32 2 } +; PR9450 +define i32 @test4(i32 %v) { +; CHECK: entry: +; CHECK-NEXT: switch i32 %v, label %T [ +; CHECK-NEXT: i32 3, label %V +; CHECK-NEXT: i32 2, label %U +; CHECK-NEXT: ] + +entry: + br label %SWITCH +V: + ret i32 7 +SWITCH: + switch i32 %v, label %default [ + i32 1, label %T + i32 2, label %U + i32 3, label %V + ] +default: + unreachable +U: + ret i32 1 +T: + ret i32 2 +} diff --git a/test/Transforms/SimplifyCFG/branch-fold-dbg.ll b/test/Transforms/SimplifyCFG/branch-fold-dbg.ll new file mode 100644 index 0000000000000..0897c95a67784 --- /dev/null +++ b/test/Transforms/SimplifyCFG/branch-fold-dbg.ll @@ -0,0 +1,58 @@ +; RUN: opt -simplifycfg -S %s | FileCheck %s + +%0 = type { i32*, i32* } + +@0 = external hidden constant [5 x %0], align 4 + +define void @foo(i32) nounwind ssp { +Entry: + %1 = icmp slt i32 %0, 0, !dbg !5 + br i1 %1, label %BB5, label %BB1, !dbg !5 + +BB1: ; preds = %Entry + %2 = icmp sgt i32 %0, 4, !dbg !5 + br i1 %2, label %BB5, label %BB2, !dbg !5 + +BB2: ; preds = %BB1 + %3 = shl i32 1, %0, !dbg !5 + %4 = and i32 %3, 31, !dbg !5 + %5 = icmp eq i32 %4, 0, !dbg !5 + br i1 %5, label %BB5, label %BB3, !dbg !5 + +;CHECK: icmp eq +;CHECK-NEXT: getelementptr +;CHECK-NEXT: icmp eq + +BB3: ; preds = %BB2 + %6 = getelementptr inbounds [5 x %0]* @0, i32 0, i32 %0, !dbg !6 + call void @llvm.dbg.value(metadata !{%0* %6}, i64 0, metadata !7), !dbg !12 + %7 = icmp eq %0* %6, null, !dbg !13 + br i1 %7, label %BB5, label %BB4, !dbg !13 + +BB4: ; preds = %BB3 + %8 = icmp slt i32 %0, 0, !dbg !5 + ret void, !dbg !14 + +BB5: ; preds = %BB3, %BB2, %BB1, %Entry + ret void, !dbg !14 +} + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 231, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void (i32)* @foo, null} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"a.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"a.i", metadata !"/private/tmp", metadata !"clang (trunk 129006)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 131, i32 2, metadata !0, null} +!6 = metadata !{i32 134, i32 2, metadata !0, null} +!7 = metadata !{i32 590080, metadata !8, metadata !"bar", metadata !1, i32 232, metadata !9, i32 0} ; [ DW_TAG_auto_variable ] +!8 = metadata !{i32 589835, metadata !0, i32 231, i32 1, metadata !1, i32 3} ; [ DW_TAG_lexical_block ] +!9 = metadata !{i32 589839, metadata !2, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !10} ; [ DW_TAG_pointer_type ] +!10 = metadata !{i32 589862, metadata !2, metadata !"", null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata !11} ; [ DW_TAG_const_type ] +!11 = metadata !{i32 589860, metadata !2, metadata !"unsigned int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!12 = metadata !{i32 232, i32 40, metadata !8, null} +!13 = metadata !{i32 234, i32 2, metadata !8, null} +!14 = metadata !{i32 274, i32 1, metadata !8, null} diff --git a/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll b/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll new file mode 100644 index 0000000000000..03053f037d0a9 --- /dev/null +++ b/test/Transforms/SimplifyCFG/hoist-dbgvalue.ll @@ -0,0 +1,53 @@ +; RUN: opt -simplifycfg -S < %s | FileCheck %s + +define i32 @foo(i32 %i) nounwind ssp { + call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !6), !dbg !7 + call void @llvm.dbg.value(metadata !8, i64 0, metadata !9), !dbg !11 + %1 = icmp ne i32 %i, 0, !dbg !12 +;CHECK: call i32 (...)* @bar() +;CHECK-NEXT: llvm.dbg.value + br i1 %1, label %2, label %4, !dbg !12 + +; <label>:2 ; preds = %0 + %3 = call i32 (...)* @bar(), !dbg !13 + call void @llvm.dbg.value(metadata !{i32 %3}, i64 0, metadata !9), !dbg !13 + br label %6, !dbg !15 + +; <label>:4 ; preds = %0 + %5 = call i32 (...)* @bar(), !dbg !16 + call void @llvm.dbg.value(metadata !{i32 %5}, i64 0, metadata !9), !dbg !16 + br label %6, !dbg !18 + +; <label>:6 ; preds = %4, %2 + %k.0 = phi i32 [ %3, %2 ], [ %5, %4 ] + ret i32 %k.0, !dbg !19 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +declare i32 @bar(...) + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 (i32)* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"b.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"b.c", metadata !"/private/tmp", metadata !"clang", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 590081, metadata !0, metadata !"i", metadata !1, i32 16777218, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!7 = metadata !{i32 2, i32 13, metadata !0, null} +!8 = metadata !{i32 0} +!9 = metadata !{i32 590080, metadata !10, metadata !"k", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!10 = metadata !{i32 589835, metadata !0, i32 2, i32 16, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!11 = metadata !{i32 3, i32 12, metadata !10, null} +!12 = metadata !{i32 4, i32 3, metadata !10, null} +!13 = metadata !{i32 5, i32 5, metadata !14, null} +!14 = metadata !{i32 589835, metadata !10, i32 4, i32 10, metadata !1, i32 1} ; [ DW_TAG_lexical_block ] +!15 = metadata !{i32 6, i32 3, metadata !14, null} +!16 = metadata !{i32 7, i32 5, metadata !17, null} +!17 = metadata !{i32 589835, metadata !10, i32 6, i32 10, metadata !1, i32 2} ; [ DW_TAG_lexical_block ] +!18 = metadata !{i32 8, i32 3, metadata !17, null} +!19 = metadata !{i32 9, i32 3, metadata !10, null} diff --git a/test/Transforms/SimplifyCFG/switch-on-const-select.ll b/test/Transforms/SimplifyCFG/switch-on-const-select.ll new file mode 100644 index 0000000000000..5494a651d47da --- /dev/null +++ b/test/Transforms/SimplifyCFG/switch-on-const-select.ll @@ -0,0 +1,138 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +; Test basic folding to a conditional branch. +define i32 @foo(i64 %x, i64 %y) nounwind { +; CHECK: @foo +entry: + %eq = icmp eq i64 %x, %y + br i1 %eq, label %b, label %switch +switch: + %lt = icmp slt i64 %x, %y +; CHECK: br i1 %lt, label %a, label %b + %qux = select i1 %lt, i32 0, i32 2 + switch i32 %qux, label %bees [ + i32 0, label %a + i32 1, label %b + i32 2, label %b + ] +a: + tail call void @bees.a() nounwind + ret i32 1 +; CHECK: b: +; CHECK-NEXT: %retval = phi i32 [ 0, %switch ], [ 2, %entry ] +b: + %retval = phi i32 [0, %switch], [0, %switch], [2, %entry] + tail call void @bees.b() nounwind + ret i32 %retval +; CHECK-NOT: bees: +bees: + tail call void @llvm.trap() nounwind + unreachable +} + +; Test basic folding to an unconditional branch. +define i32 @bar(i64 %x, i64 %y) nounwind { +; CHECK: @bar +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call void @bees.a() nounwind +; CHECK-NEXT: ret i32 0 + %lt = icmp slt i64 %x, %y + %qux = select i1 %lt, i32 0, i32 2 + switch i32 %qux, label %bees [ + i32 0, label %a + i32 1, label %b + i32 2, label %a + ] +a: + %retval = phi i32 [0, %entry], [0, %entry], [1, %b] + tail call void @bees.a() nounwind + ret i32 0 +b: + tail call void @bees.b() nounwind + br label %a +bees: + tail call void @llvm.trap() nounwind + unreachable +} + +; Test the edge case where both values from the select are the default case. +define void @bazz(i64 %x, i64 %y) nounwind { +; CHECK: @bazz +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call void @bees.b() nounwind +; CHECK-NEXT: ret void + %lt = icmp slt i64 %x, %y + %qux = select i1 %lt, i32 10, i32 12 + switch i32 %qux, label %b [ + i32 0, label %a + i32 1, label %bees + i32 2, label %bees + ] +a: + tail call void @bees.a() nounwind + ret void +b: + tail call void @bees.b() nounwind + ret void +bees: + tail call void @llvm.trap() + unreachable +} + +; Test the edge case where both values from the select are equal. +define void @quux(i64 %x, i64 %y) nounwind { +; CHECK: @quux +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call void @bees.a() nounwind +; CHECK-NEXT: ret void + %lt = icmp slt i64 %x, %y + %qux = select i1 %lt, i32 0, i32 0 + switch i32 %qux, label %b [ + i32 0, label %a + i32 1, label %bees + i32 2, label %bees + ] +a: + tail call void @bees.a() nounwind + ret void +b: + tail call void @bees.b() nounwind + ret void +bees: + tail call void @llvm.trap() + unreachable +} + +; A final test, for phi node munging. +define i32 @xyzzy(i64 %x, i64 %y) { +; CHECK: @xyzzy +entry: + %eq = icmp eq i64 %x, %y + br i1 %eq, label %r, label %cont +cont: +; CHECK: %lt = icmp slt i64 %x, %y + %lt = icmp slt i64 %x, %y +; CHECK-NEXT: br i1 %lt, label %a, label %r + %qux = select i1 %lt, i32 0, i32 2 + switch i32 %qux, label %bees [ + i32 0, label %a + i32 1, label %r + i32 2, label %r + ] +r: + %val = phi i32 [0, %entry], [1, %cont], [1, %cont] + ret i32 %val +a: + ret i32 -1 +; CHECK-NOT: bees: +bees: + tail call void @llvm.trap() + unreachable +} + +declare void @llvm.trap() nounwind noreturn +declare void @bees.a() nounwind +declare void @bees.b() nounwind diff --git a/test/Transforms/SimplifyCFG/trap-debugloc.ll b/test/Transforms/SimplifyCFG/trap-debugloc.ll new file mode 100644 index 0000000000000..24540e5217b95 --- /dev/null +++ b/test/Transforms/SimplifyCFG/trap-debugloc.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -simplifycfg < %s | FileCheck %s +; Radar 9342286 +; Assign DebugLoc to trap instruction. +define void @foo() nounwind ssp { +; CHECK: call void @llvm.trap(), !dbg + store i32 42, i32* null, !dbg !5 + ret void, !dbg !7 +} + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, void ()* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"foo.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"foo.c", metadata !"/private/tmp", metadata !"Apple clang version 3.0 (tags/Apple/clang-206.1) (based on LLVM 3.0svn)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 4, i32 2, metadata !6, null} +!6 = metadata !{i32 589835, metadata !0, i32 3, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!7 = metadata !{i32 5, i32 1, metadata !6, null} diff --git a/test/Transforms/SimplifyLibCalls/debug-line.ll b/test/Transforms/SimplifyLibCalls/debug-line.ll new file mode 100644 index 0000000000000..b668e4b9d3428 --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/debug-line.ll @@ -0,0 +1,24 @@ +; RUN: opt -simplify-libcalls -S < %s | FileCheck %s + + +@.str = private constant [3 x i8] c"%c\00" + +define void @foo() nounwind ssp { +;CHECK: call i32 @putchar{{.+}} !dbg + %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32 97), !dbg !5 + ret void, !dbg !7 +} + +declare i32 @printf(i8*, ...) + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 4, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, void ()* @foo} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"m.c", metadata !"/private/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"m.c", metadata !"/private/tmp", metadata !"clang", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 5, i32 2, metadata !6, null} +!6 = metadata !{i32 589835, metadata !0, i32 4, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!7 = metadata !{i32 6, i32 1, metadata !6, null} + diff --git a/test/Transforms/SimplifyLibCalls/half-powr.ll b/test/Transforms/SimplifyLibCalls/half-powr.ll deleted file mode 100644 index 5d317fe864c67..0000000000000 --- a/test/Transforms/SimplifyLibCalls/half-powr.ll +++ /dev/null @@ -1,46 +0,0 @@ -; RUN: opt -simplify-libcalls-halfpowr %s -S | FileCheck %s - -define float @__half_powrf4(float %f, float %g) nounwind readnone { -entry: - %0 = fcmp olt float %f, 2.000000e+00 ; <i1> [#uses=1] - br i1 %0, label %bb, label %bb1 - -bb: ; preds = %entry - %1 = fdiv float %f, 3.000000e+00 ; <float> [#uses=1] - br label %bb1 - -bb1: ; preds = %bb, %entry - %f_addr.0 = phi float [ %1, %bb ], [ %f, %entry ] ; <float> [#uses=1] - %2 = fmul float %f_addr.0, %g ; <float> [#uses=1] -; CHECK: fmul float %f_addr -; CHECK: fmul float %f_addr -; CHECK: fmul float %f_addr -; CHECK: fmul float %f_addr - - ret float %2 -} - -define void @foo(float* %p) nounwind { -entry: - %0 = load float* %p, align 4 ; <float> [#uses=1] - %1 = getelementptr float* %p, i32 1 ; <float*> [#uses=1] - %2 = load float* %1, align 4 ; <float> [#uses=1] - %3 = getelementptr float* %p, i32 2 ; <float*> [#uses=1] - %4 = load float* %3, align 4 ; <float> [#uses=1] - %5 = getelementptr float* %p, i32 3 ; <float*> [#uses=1] - %6 = load float* %5, align 4 ; <float> [#uses=1] - %7 = getelementptr float* %p, i32 4 ; <float*> [#uses=1] - %8 = load float* %7, align 4 ; <float> [#uses=1] - %9 = getelementptr float* %p, i32 5 ; <float*> [#uses=1] - %10 = load float* %9, align 4 ; <float> [#uses=1] - %11 = tail call float @__half_powrf4(float %0, float %6) nounwind ; <float> [#uses=1] - %12 = tail call float @__half_powrf4(float %2, float %8) nounwind ; <float> [#uses=1] - %13 = tail call float @__half_powrf4(float %4, float %10) nounwind ; <float> [#uses=1] - %14 = getelementptr float* %p, i32 6 ; <float*> [#uses=1] - store float %11, float* %14, align 4 - %15 = getelementptr float* %p, i32 7 ; <float*> [#uses=1] - store float %12, float* %15, align 4 - %16 = getelementptr float* %p, i32 8 ; <float*> [#uses=1] - store float %13, float* %16, align 4 - ret void -} diff --git a/test/Transforms/SimplifyLibCalls/iprintf.ll b/test/Transforms/SimplifyLibCalls/iprintf.ll new file mode 100644 index 0000000000000..7f036fe3ab8bb --- /dev/null +++ b/test/Transforms/SimplifyLibCalls/iprintf.ll @@ -0,0 +1,71 @@ +; RUN: opt < %s -simplify-libcalls -S -o %t +; RUN: FileCheck < %t %s +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32" +target triple = "xcore-xmos-elf" + +@.str = internal constant [4 x i8] c"%f\0A\00" ; <[4 x i8]*> [#uses=1] +@.str1 = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + +; Verify printf with no floating point arguments is transformed to iprintf +define i32 @f0(i32 %x) nounwind { +entry: +; CHECK: define i32 @f0 +; CHECK: @iprintf +; CHECK: } + %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) ; <i32> [#uses=0] + ret i32 %0 +} + +; Verify we don't turn this into an iprintf call +define void @f1(double %x) nounwind { +entry: +; CHECK: define void @f1 +; CHECK: @printf +; CHECK: } + %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) nounwind ; <i32> [#uses=0] + ret void +} + +; Verify sprintf with no floating point arguments is transformed to siprintf +define i32 @f2(i8* %p, i32 %x) nounwind { +entry: +; CHECK: define i32 @f2 +; CHECK: @siprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @sprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) + ret i32 %0 +} + +; Verify we don't turn this into an siprintf call +define i32 @f3(i8* %p, double %x) nounwind { +entry: +; CHECK: define i32 @f3 +; CHECK: @sprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @sprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) + ret i32 %0 +} + +; Verify fprintf with no floating point arguments is transformed to fiprintf +define i32 @f4(i8* %p, i32 %x) nounwind { +entry: +; CHECK: define i32 @f4 +; CHECK: @fiprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @fprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str1, i32 0, i32 0), i32 %x) + ret i32 %0 +} + +; Verify we don't turn this into an fiprintf call +define i32 @f5(i8* %p, double %x) nounwind { +entry: +; CHECK: define i32 @f5 +; CHECK: @fprintf +; CHECK: } + %0 = tail call i32 (i8*, i8*, ...)* @fprintf(i8 *%p, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), double %x) + ret i32 %0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind +declare i32 @sprintf(i8* nocapture, i8* nocapture, ...) nounwind +declare i32 @fprintf(i8* nocapture, i8* nocapture, ...) nounwind |