diff options
author | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
commit | 7b3392326c40c3c20697816acae597ba7b3144eb (patch) | |
tree | 2cbcf22585e99f8a87d12d5ff94f392c0d266819 /test/Transforms/InstCombine | |
parent | 1176aa52646fe641a4243a246aa7f960c708a274 (diff) | |
download | FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.zip FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.tar.gz |
Vendor import of llvm release_30 branch r142614:
http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614
Diffstat (limited to 'test/Transforms/InstCombine')
32 files changed, 665 insertions, 38 deletions
diff --git a/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll b/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll index cfe5df6..56493e2 100644 --- a/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll +++ b/test/Transforms/InstCombine/2003-10-29-CallSiteResolve.ll @@ -10,6 +10,9 @@ invoke_cont: ; preds = %0 ret float* %tmp.11 X: ; preds = %0 + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret float* null } +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll b/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll index bec0b9e..6df30c7 100644 --- a/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll +++ b/test/Transforms/InstCombine/2004-01-13-InstCombineInvokePHI.ll @@ -23,6 +23,9 @@ cont: ; preds = %call, %entry ret i32 %V N: ; preds = %call + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret i32 0 } +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll b/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll index 9bb9408..aacea9d 100644 --- a/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll +++ b/test/Transforms/InstCombine/2008-01-14-VarArgTrampoline.ll @@ -3,7 +3,8 @@ %struct.FRAME.nest = type { i32, i32 (...)* } %struct.__builtin_trampoline = type { [10 x i8] } -declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind +declare void @llvm.init.trampoline(i8*, i8*, i8*) nounwind +declare i8* @llvm.adjust.trampoline(i8*) nounwind declare i32 @f(%struct.FRAME.nest* nest , ...) @@ -15,7 +16,8 @@ entry: %tmp3 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 0 ; <i32*> [#uses=1] store i32 %n, i32* %tmp3, align 8 %FRAME.06 = bitcast %struct.FRAME.nest* %FRAME.0 to i8* ; <i8*> [#uses=1] - %tramp = call i8* @llvm.init.trampoline( i8* %TRAMP.216.sub, i8* bitcast (i32 (%struct.FRAME.nest*, ...)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1] + call void @llvm.init.trampoline( i8* %TRAMP.216.sub, i8* bitcast (i32 (%struct.FRAME.nest*, ...)* @f to i8*), i8* %FRAME.06 ) ; <i8*> [#uses=1] + %tramp = call i8* @llvm.adjust.trampoline( i8* %TRAMP.216.sub) %tmp7 = getelementptr %struct.FRAME.nest* %FRAME.0, i32 0, i32 1 ; <i32 (...)**> [#uses=1] %tmp89 = bitcast i8* %tramp to i32 (...)* ; <i32 (...)*> [#uses=2] store i32 (...)* %tmp89, i32 (...)** %tmp7, align 8 diff --git a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll index 626564da..6847f5e 100644 --- a/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll +++ b/test/Transforms/InstCombine/2008-04-28-VolatileStore.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep {volatile store} +; RUN: opt < %s -instcombine -S | grep {store volatile} define void @test() { %votf = alloca <4 x float> ; <<4 x float>*> [#uses=1] diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll index f2cc725..a24f307 100644 --- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll +++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadDontMerge.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep {volatile load} | count 2 +; RUN: opt < %s -instcombine -S | grep {load volatile} | count 2 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i386-apple-darwin8" @g_1 = internal global i32 0 ; <i32*> [#uses=3] diff --git a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll index 176162d..5fb11ff 100644 --- a/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll +++ b/test/Transforms/InstCombine/2008-04-29-VolatileLoadMerge.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep {volatile load} | count 2 +; RUN: opt < %s -instcombine -S | grep {load volatile} | count 2 ; PR2262 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i386-apple-darwin8" diff --git a/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll b/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll index d56a1a0..f6eb248 100644 --- a/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll +++ b/test/Transforms/InstCombine/2008-05-09-SinkOfInvoke.ll @@ -29,5 +29,9 @@ invcont37: ; preds = %invcont31 ret void lpad: ; preds = %invcont31, %invcont, %entry + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup unreachable } + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll index ccfb118..8104408 100644 --- a/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll +++ b/test/Transforms/InstCombine/2008-07-08-VolatileLoadMerge.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep {volatile load} | count 2 +; RUN: opt < %s -instcombine -S | grep {load volatile} | count 2 ; PR2496 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" target triple = "i386-apple-darwin8" diff --git a/test/Transforms/InstCombine/2011-09-03-Trampoline.ll b/test/Transforms/InstCombine/2011-09-03-Trampoline.ll new file mode 100644 index 0000000..5456e03 --- /dev/null +++ b/test/Transforms/InstCombine/2011-09-03-Trampoline.ll @@ -0,0 +1,87 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +declare void @llvm.init.trampoline(i8*, i8*, i8*) +declare i8* @llvm.adjust.trampoline(i8*) +declare i32 @f(i8 * nest, i32) + +; Most common case +define i32 @test0(i32 %n) { + %alloca = alloca [10 x i8], align 16 + %gep = getelementptr [10 x i8]* %alloca, i32 0, i32 0 + call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*), + i8* null) + %tramp = call i8* @llvm.adjust.trampoline(i8* %gep) + %function = bitcast i8* %tramp to i32(i32)* + %ret = call i32 %function(i32 %n) + ret i32 %ret + +; CHECK: define i32 @test0(i32 %n) { +; CHECK: %ret = call i32 @f(i8* nest null, i32 %n) +} + +define i32 @test1(i32 %n, i8* %trampmem) { + call void @llvm.init.trampoline(i8* %trampmem, + i8* bitcast (i32 (i8*, i32)* @f to i8*), + i8* null) + %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem) + %function = bitcast i8* %tramp to i32(i32)* + %ret = call i32 %function(i32 %n) + ret i32 %ret +; CHECK: define i32 @test1(i32 %n, i8* %trampmem) { +; CHECK: %ret = call i32 @f(i8* nest null, i32 %n) +} + +define i32 @test2(i32 %n, i8* %trampmem) { + %tramp = call i8* @llvm.adjust.trampoline(i8* %trampmem) + %functiona = bitcast i8* %tramp to i32(i32)* + %ret = call i32 %functiona(i32 %n) + ret i32 %ret +; CHECK: define i32 @test2(i32 %n, i8* %trampmem) { +; CHECK: %ret = call i32 %functiona(i32 %n) +} + +define i32 @test3(i32 %n, i8* %trampmem) { + call void @llvm.init.trampoline(i8* %trampmem, + i8* bitcast (i32 (i8*, i32)* @f to i8*), + i8* null) + +; CHECK: define i32 @test3(i32 %n, i8* %trampmem) { +; CHECK: %ret0 = call i32 @f(i8* nest null, i32 %n) + %tramp0 = call i8* @llvm.adjust.trampoline(i8* %trampmem) + %function0 = bitcast i8* %tramp0 to i32(i32)* + %ret0 = call i32 %function0(i32 %n) + + ;; Not optimized since previous call could be writing. + %tramp1 = call i8* @llvm.adjust.trampoline(i8* %trampmem) + %function1 = bitcast i8* %tramp1 to i32(i32)* + %ret1 = call i32 %function1(i32 %n) +; CHECK: %ret1 = call i32 %function1(i32 %n) + + ret i32 %ret1 +} + +define i32 @test4(i32 %n) { + %alloca = alloca [10 x i8], align 16 + %gep = getelementptr [10 x i8]* %alloca, i32 0, i32 0 + call void @llvm.init.trampoline(i8* %gep, i8* bitcast (i32 (i8*, i32)* @f to i8*), + i8* null) + + %tramp0 = call i8* @llvm.adjust.trampoline(i8* %gep) + %function0 = bitcast i8* %tramp0 to i32(i32)* + %ret0 = call i32 %function0(i32 %n) + + %tramp1 = call i8* @llvm.adjust.trampoline(i8* %gep) + %function1 = bitcast i8* %tramp0 to i32(i32)* + %ret1 = call i32 %function1(i32 %n) + + %tramp2 = call i8* @llvm.adjust.trampoline(i8* %gep) + %function2 = bitcast i8* %tramp2 to i32(i32)* + %ret2 = call i32 %function2(i32 %n) + + ret i32 %ret2 + +; CHECK: define i32 @test4(i32 %n) { +; CHECK: %ret0 = call i32 @f(i8* nest null, i32 %n) +; CHECK: %ret1 = call i32 @f(i8* nest null, i32 %n) +; CHECK: %ret2 = call i32 @f(i8* nest null, i32 %n) +} diff --git a/test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll b/test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll new file mode 100644 index 0000000..22061b2 --- /dev/null +++ b/test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll @@ -0,0 +1,20 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s +; rdar://problem/10063307 +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32" +target triple = "thumbv7-apple-ios5.0.0" + +%0 = type { [2 x i32] } +%struct.CGPoint = type { float, float } + +define void @t(%struct.CGPoint* %a) nounwind { + %Point = alloca %struct.CGPoint, align 4 + %1 = bitcast %struct.CGPoint* %a to i64* + %2 = bitcast %struct.CGPoint* %Point to i64* + %3 = load i64* %1, align 4 + store i64 %3, i64* %2, align 4 + call void @foo(i64* %2) nounwind + ret void +; CHECK: %Point = alloca i64, align 4 +} + +declare void @foo(i64*) diff --git a/test/Transforms/InstCombine/LandingPadClauses.ll b/test/Transforms/InstCombine/LandingPadClauses.ll new file mode 100644 index 0000000..055bdcc --- /dev/null +++ b/test/Transforms/InstCombine/LandingPadClauses.ll @@ -0,0 +1,181 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +@T1 = external constant i32 +@T2 = external constant i32 +@T3 = external constant i32 + +declare i32 @generic_personality(i32, i64, i8*, i8*) +declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*) + +declare void @bar() + +define void @foo_generic() { +; CHECK: @foo_generic + invoke void @bar() + to label %cont.a unwind label %lpad.a +cont.a: + invoke void @bar() + to label %cont.b unwind label %lpad.b +cont.b: + invoke void @bar() + to label %cont.c unwind label %lpad.c +cont.c: + invoke void @bar() + to label %cont.d unwind label %lpad.d +cont.d: + invoke void @bar() + to label %cont.e unwind label %lpad.e +cont.e: + invoke void @bar() + to label %cont.f unwind label %lpad.f +cont.f: + invoke void @bar() + to label %cont.g unwind label %lpad.g +cont.g: + invoke void @bar() + to label %cont.h unwind label %lpad.h +cont.h: + invoke void @bar() + to label %cont.i unwind label %lpad.i +cont.i: + ret void + +lpad.a: + %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + catch i32* @T1 + catch i32* @T2 + catch i32* @T1 + catch i32* @T2 + unreachable +; CHECK: %a = landingpad +; CHECK-NEXT: @T1 +; CHECK-NEXT: @T2 +; CHECK-NEXT: unreachable + +lpad.b: + %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + filter [0 x i32*] zeroinitializer + catch i32* @T1 + unreachable +; CHECK: %b = landingpad +; CHECK-NEXT: filter +; CHECK-NEXT: unreachable + +lpad.c: + %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + catch i32* @T1 + filter [1 x i32*] [i32* @T1] + catch i32* @T2 + unreachable +; CHECK: %c = landingpad +; CHECK-NEXT: @T1 +; CHECK-NEXT: filter [0 x i32*] +; CHECK-NEXT: unreachable + +lpad.d: + %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + filter [3 x i32*] zeroinitializer + unreachable +; CHECK: %d = landingpad +; CHECK-NEXT: filter [1 x i32*] zeroinitializer +; CHECK-NEXT: unreachable + +lpad.e: + %e = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + catch i32* @T1 + filter [3 x i32*] [i32* @T1, i32* @T2, i32* @T2] + unreachable +; CHECK: %e = landingpad +; CHECK-NEXT: @T1 +; CHECK-NEXT: filter [1 x i32*] [i32* @T2] +; CHECK-NEXT: unreachable + +lpad.f: + %f = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + filter [2 x i32*] [i32* @T2, i32* @T1] + filter [1 x i32*] [i32* @T1] + unreachable +; CHECK: %f = landingpad +; CHECK-NEXT: filter [1 x i32*] [i32* @T1] +; CHECK-NEXT: unreachable + +lpad.g: + %g = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + filter [1 x i32*] [i32* @T1] + catch i32* @T3 + filter [2 x i32*] [i32* @T2, i32* @T1] + unreachable +; CHECK: %g = landingpad +; CHECK-NEXT: filter [1 x i32*] [i32* @T1] +; CHECK-NEXT: catch i32* @T3 +; CHECK-NEXT: unreachable + +lpad.h: + %h = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + filter [2 x i32*] [i32* @T1, i32* null] + filter [1 x i32*] zeroinitializer + unreachable +; CHECK: %h = landingpad +; CHECK-NEXT: filter [1 x i32*] zeroinitializer +; CHECK-NEXT: unreachable + +lpad.i: + %i = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality + cleanup + filter [0 x i32*] zeroinitializer + unreachable +; CHECK: %i = landingpad +; CHECK-NEXT: filter +; CHECK-NEXT: unreachable +} + +define void @foo_cxx() { +; CHECK: @foo_cxx + invoke void @bar() + to label %cont.a unwind label %lpad.a +cont.a: + invoke void @bar() + to label %cont.b unwind label %lpad.b +cont.b: + invoke void @bar() + to label %cont.c unwind label %lpad.c +cont.c: + invoke void @bar() + to label %cont.d unwind label %lpad.d +cont.d: + ret void + +lpad.a: + %a = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 + catch i32* null + catch i32* @T1 + unreachable +; CHECK: %a = landingpad +; CHECK-NEXT: null +; CHECK-NEXT: unreachable + +lpad.b: + %b = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 + filter [1 x i32*] zeroinitializer + unreachable +; CHECK: %b = landingpad +; CHECK-NEXT: cleanup +; CHECK-NEXT: unreachable + +lpad.c: + %c = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 + filter [2 x i32*] [i32* @T1, i32* null] + unreachable +; CHECK: %c = landingpad +; CHECK-NEXT: cleanup +; CHECK-NEXT: unreachable + +lpad.d: + %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 + cleanup + catch i32* null + unreachable +; CHECK: %d = landingpad +; CHECK-NEXT: null +; CHECK-NEXT: unreachable +} diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll index a888152..531aedb 100644 --- a/test/Transforms/InstCombine/and2.ll +++ b/test/Transforms/InstCombine/and2.ll @@ -35,3 +35,10 @@ define i1 @test4(i32 %X) { ; CHECK: @test4 ; CHECK-NEXT: ret i1 false } + +; Make sure we don't go into an infinite loop with this test +define <4 x i32> @test5(<4 x i32> %A) { + %1 = xor <4 x i32> %A, <i32 1, i32 2, i32 3, i32 4> + %2 = and <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %1 + ret <4 x i32> %2 +} diff --git a/test/Transforms/InstCombine/atomic.ll b/test/Transforms/InstCombine/atomic.ll new file mode 100644 index 0000000..097cf5e --- /dev/null +++ b/test/Transforms/InstCombine/atomic.ll @@ -0,0 +1,24 @@ +; RUN: opt -S < %s -instcombine | 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.7.0" + +; Check transforms involving atomic operations + +define i32* @test1(i8** %p) { +; CHECK: define i32* @test1 +; CHECK: load atomic i8** %p monotonic, align 8 + %c = bitcast i8** %p to i32** + %r = load atomic i32** %c monotonic, align 8 + ret i32* %r +} + +define i32 @test2(i32* %p) { +; CHECK: define i32 @test2 +; CHECK: %x = load atomic i32* %p seq_cst, align 4 +; CHECK: shl i32 %x, 1 + %x = load atomic i32* %p seq_cst, align 4 + %y = load i32* %p, align 4 + %z = add i32 %x, %y + ret i32 %z +} diff --git a/test/Transforms/InstCombine/bitcast.ll b/test/Transforms/InstCombine/bitcast.ll index 0718b8a..8f6ae7d 100644 --- a/test/Transforms/InstCombine/bitcast.ll +++ b/test/Transforms/InstCombine/bitcast.ll @@ -1,5 +1,8 @@ ; 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" + ; Bitcasts between vectors and scalars are valid. ; PR4487 define i32 @test1(i64 %a) { @@ -103,3 +106,34 @@ define <2 x float> @test6(float %A){ ; CHECK-NEXT: insertelement <2 x float> <float 4.200000e+01, float undef>, float %A, i32 1 ; CHECK: ret } + +define i64 @ISPC0(i64 %in) { + %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1> to i64), i64 -1) + ret i64 %out +; CHECK: @ISPC0 +; CHECK: ret i64 0 +} + + +define i64 @Vec2(i64 %in) { + %out = and i64 %in, xor (i64 bitcast (<4 x i16> <i16 0, i16 0, i16 0, i16 0> to i64), i64 0) + ret i64 %out +; CHECK: @Vec2 +; CHECK: ret i64 0 +} + +define i64 @All11(i64 %in) { + %out = and i64 %in, xor (i64 bitcast (<2 x float> bitcast (i64 -1 to <2 x float>) to i64), i64 -1) + ret i64 %out +; CHECK: @All11 +; CHECK: ret i64 0 +} + + +define i32 @All111(i32 %in) { + %out = and i32 %in, xor (i32 bitcast (<1 x float> bitcast (i32 -1 to <1 x float>) to i32), i32 -1) + ret i32 %out +; CHECK: @All111 +; CHECK: ret i32 0 +} + diff --git a/test/Transforms/InstCombine/call.ll b/test/Transforms/InstCombine/call.ll index d084873..96ec420 100644 --- a/test/Transforms/InstCombine/call.ll +++ b/test/Transforms/InstCombine/call.ll @@ -9,8 +9,8 @@ declare void @test1a(i8*) define void @test1(i32* %A) { call void bitcast (void (i8*)* @test1a to void (i32*)*)( i32* %A ) ret void -; CHECK: %tmp = bitcast i32* %A to i8* -; CHECK: call void @test1a(i8* %tmp) +; CHECK: %1 = bitcast i32* %A to i8* +; CHECK: call void @test1a(i8* %1) ; CHECK: ret void } @@ -24,8 +24,8 @@ define void @test2a(i8 %A) { define i32 @test2(i32 %A) { call void bitcast (void (i8)* @test2a to void (i32)*)( i32 %A ) ret i32 %A -; CHECK: %tmp = trunc i32 %A to i8 -; CHECK: call void @test2a(i8 %tmp) +; CHECK: %1 = trunc i32 %A to i8 +; CHECK: call void @test2a(i8 %1) ; CHECK: ret i32 %A } @@ -38,8 +38,8 @@ define void @test3(i8 %A, i8 %B) { call void bitcast (void (i8, ...)* @test3a to void (i8, i8)*)( i8 %A, i8 %B ) ret void -; CHECK: %tmp = zext i8 %B to i32 -; CHECK: call void (i8, ...)* @test3a(i8 %A, i32 %tmp) +; CHECK: %1 = zext i8 %B to i32 +; CHECK: call void (i8, ...)* @test3a(i8 %A, i32 %1) ; CHECK: ret void } @@ -54,8 +54,8 @@ define i32 @test4() { %X = call i32 bitcast (i8 ()* @test4a to i32 ()*)( ) ; <i32> [#uses=1] ret i32 %X ; CHECK: %X = call i8 @test4a() -; CHECK: %tmp = zext i8 %X to i32 -; CHECK: ret i32 %tmp +; CHECK: %1 = zext i8 %X to i32 +; CHECK: ret i32 %1 } @@ -107,9 +107,13 @@ invoke.cont: ; preds = %entry unreachable try.handler: ; preds = %entry + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret i8* null } +declare i32 @__gxx_personality_v0(...) + ; Don't turn this into "unreachable": the callee and caller don't agree in ; calling conv, but the implementation of test8a may actually end up using the ; right calling conv. diff --git a/test/Transforms/InstCombine/canonicalize_branch.ll b/test/Transforms/InstCombine/canonicalize_branch.ll index 24090ab..869546d 100644 --- a/test/Transforms/InstCombine/canonicalize_branch.ll +++ b/test/Transforms/InstCombine/canonicalize_branch.ll @@ -1,8 +1,23 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s +; Test an already canonical branch to make sure we don't flip those. +define i32 @test0(i32 %X, i32 %Y) { + %C = icmp eq i32 %X, %Y + br i1 %C, label %T, label %F, !prof !0 + +; CHECK: @test0 +; CHECK: %C = icmp eq i32 %X, %Y +; CHECK: br i1 %C, label %T, label %F + +T: + ret i32 12 +F: + ret i32 123 +} + define i32 @test1(i32 %X, i32 %Y) { %C = icmp ne i32 %X, %Y - br i1 %C, label %T, label %F + br i1 %C, label %T, label %F, !prof !1 ; CHECK: @test1 ; CHECK: %C = icmp eq i32 %X, %Y @@ -16,7 +31,7 @@ F: define i32 @test2(i32 %X, i32 %Y) { %C = icmp ule i32 %X, %Y - br i1 %C, label %T, label %F + br i1 %C, label %T, label %F, !prof !2 ; CHECK: @test2 ; CHECK: %C = icmp ugt i32 %X, %Y @@ -30,7 +45,7 @@ F: define i32 @test3(i32 %X, i32 %Y) { %C = icmp uge i32 %X, %Y - br i1 %C, label %T, label %F + br i1 %C, label %T, label %F, !prof !3 ; CHECK: @test3 ; CHECK: %C = icmp ult i32 %X, %Y @@ -42,3 +57,13 @@ F: ret i32 123 } +!0 = metadata !{metadata !"branch_weights", i32 1, i32 2} +!1 = metadata !{metadata !"branch_weights", i32 3, i32 4} +!2 = metadata !{metadata !"branch_weights", i32 5, i32 6} +!3 = metadata !{metadata !"branch_weights", i32 7, i32 8} +; Base case shouldn't change. +; CHECK: !0 = {{.*}} i32 1, i32 2} +; Ensure that the branch metadata is reversed to match the reversals above. +; CHECK: !1 = {{.*}} i32 4, i32 3} +; CHECK: !2 = {{.*}} i32 6, i32 5} +; CHECK: !3 = {{.*}} i32 8, i32 7} diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index f85636f..19d5a0a 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -630,3 +630,50 @@ entry: ; CHECK: uitofp } +define <4 x float> @test64(<4 x float> %c) nounwind { + %t0 = bitcast <4 x float> %c to <4 x i32> + %t1 = bitcast <4 x i32> %t0 to <4 x float> + ret <4 x float> %t1 +; CHECK: @test64 +; CHECK-NEXT: ret <4 x float> %c +} + +define <4 x float> @test65(<4 x float> %c) nounwind { + %t0 = bitcast <4 x float> %c to <2 x double> + %t1 = bitcast <2 x double> %t0 to <4 x float> + ret <4 x float> %t1 +; CHECK: @test65 +; CHECK-NEXT: ret <4 x float> %c +} + +define <2 x float> @test66(<2 x float> %c) nounwind { + %t0 = bitcast <2 x float> %c to double + %t1 = bitcast double %t0 to <2 x float> + ret <2 x float> %t1 +; CHECK: @test66 +; CHECK-NEXT: ret <2 x float> %c +} + +define float @test2c() { + ret float extractelement (<2 x float> bitcast (double bitcast (<2 x float> <float -1.000000e+00, float -1.000000e+00> to double) to <2 x float>), i32 0) +; CHECK: @test2c +; CHECK-NOT: extractelement +} + +define i64 @test_mmx(<2 x i32> %c) nounwind { + %A = bitcast <2 x i32> %c to x86_mmx + %B = bitcast x86_mmx %A to <2 x i32> + %C = bitcast <2 x i32> %B to i64 + ret i64 %C +; CHECK: @test_mmx +; CHECK-NOT: x86_mmx +} + +define i64 @test_mmx_const(<2 x i32> %c) nounwind { + %A = bitcast <2 x i32> zeroinitializer to x86_mmx + %B = bitcast x86_mmx %A to <2 x i32> + %C = bitcast <2 x i32> %B to i64 + ret i64 %C +; CHECK: @test_mmx_const +; CHECK-NOT: x86_mmx +} diff --git a/test/Transforms/InstCombine/crash.ll b/test/Transforms/InstCombine/crash.ll index e17774d..1a657f5 100644 --- a/test/Transforms/InstCombine/crash.ll +++ b/test/Transforms/InstCombine/crash.ll @@ -135,6 +135,8 @@ define void @test5() { store i1 true, i1* undef %1 = invoke i32 @test5a() to label %exit unwind label %exit exit: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret void } @@ -219,6 +221,8 @@ invoke.cont: ; preds = %entry unreachable try.handler: ; preds = %entry + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + catch i8* null ret i8* %self } diff --git a/test/Transforms/InstCombine/deadcode.ll b/test/Transforms/InstCombine/deadcode.ll index 52af0ef..7c7f1ab 100644 --- a/test/Transforms/InstCombine/deadcode.ll +++ b/test/Transforms/InstCombine/deadcode.ll @@ -1,5 +1,5 @@ ; RUN: opt < %s -instcombine -S | grep {ret i32 %A} -; RUN: opt < %s -die -S | not grep call.*llvm.stacksave +; RUN: opt < %s -die -S | not grep call.*llvm define i32 @test(i32 %A) { %X = or i1 false, false @@ -22,3 +22,12 @@ define i32* @test2(i32 %width) { declare i8* @llvm.stacksave() +declare void @llvm.lifetime.start(i64, i8*) +declare void @llvm.lifetime.end(i64, i8*) + +define void @test3() { + call void @llvm.lifetime.start(i64 -1, i8* undef) + call void @llvm.lifetime.end(i64 -1, i8* undef) + ret void +} + diff --git a/test/Transforms/InstCombine/devirt.ll b/test/Transforms/InstCombine/devirt.ll new file mode 100644 index 0000000..6189dc2 --- /dev/null +++ b/test/Transforms/InstCombine/devirt.ll @@ -0,0 +1,39 @@ +; RUN: opt -instcombine -S -o - %s | FileCheck %s + +; CHECK-NOT: getelementptr +; CHECK-NOT: ptrtoint +; CHECK: bitcast i8* +%struct.S = type { i32 (...)** } + +@_ZL1p = internal constant { i64, i64 } { i64 1, i64 0 }, align 8 + +define void @_Z1g1S(%struct.S* %s) nounwind { +entry: + %tmp = load { i64, i64 }* @_ZL1p, align 8 + %memptr.adj = extractvalue { i64, i64 } %tmp, 1 + %0 = bitcast %struct.S* %s to i8* + %1 = getelementptr inbounds i8* %0, i64 %memptr.adj + %this.adjusted = bitcast i8* %1 to %struct.S* + %memptr.ptr = extractvalue { i64, i64 } %tmp, 0 + %2 = and i64 %memptr.ptr, 1 + %memptr.isvirtual = icmp ne i64 %2, 0 + br i1 %memptr.isvirtual, label %memptr.virtual, label %memptr.nonvirtual + +memptr.virtual: ; preds = %entry + %3 = bitcast %struct.S* %this.adjusted to i8** + %memptr.vtable = load i8** %3 + %4 = sub i64 %memptr.ptr, 1 + %5 = getelementptr i8* %memptr.vtable, i64 %4 + %6 = bitcast i8* %5 to void (%struct.S*)** + %memptr.virtualfn = load void (%struct.S*)** %6 + br label %memptr.end + +memptr.nonvirtual: ; preds = %entry + %memptr.nonvirtualfn = inttoptr i64 %memptr.ptr to void (%struct.S*)* + br label %memptr.end + +memptr.end: ; preds = %memptr.nonvirtual, %memptr.virtual + %7 = phi void (%struct.S*)* [ %memptr.virtualfn, %memptr.virtual ], [ %memptr.nonvirtualfn, %memptr.nonvirtual ] + call void %7(%struct.S* %this.adjusted) + ret void +} diff --git a/test/Transforms/InstCombine/extractvalue.ll b/test/Transforms/InstCombine/extractvalue.ll index 64edc18..cf36b8f 100644 --- a/test/Transforms/InstCombine/extractvalue.ll +++ b/test/Transforms/InstCombine/extractvalue.ll @@ -96,7 +96,7 @@ define i32 @nogep-multiuse({i32, i32}* %pair) { } ; CHECK: define i32 @nogep-volatile -; CHECK-NEXT: volatile load {{.*}} %pair +; CHECK-NEXT: load volatile {{.*}} %pair ; CHECK-NEXT: extractvalue ; CHECK-NEXT: ret define i32 @nogep-volatile({i32, i32}* %pair) { diff --git a/test/Transforms/InstCombine/fcmp.ll b/test/Transforms/InstCombine/fcmp.ll index 2eb4f05..d08cbf5 100644 --- a/test/Transforms/InstCombine/fcmp.ll +++ b/test/Transforms/InstCombine/fcmp.ll @@ -58,3 +58,14 @@ define i1 @test7(float %x) nounwind readnone ssp noredzone { ; CHECK: @test7 ; CHECK-NEXT: fpext float %x to ppc_fp128 } + +define float @test8(float %x) nounwind readnone optsize ssp { + %conv = fpext float %x to double + %cmp = fcmp olt double %conv, 0.000000e+00 + %conv1 = zext i1 %cmp to i32 + %conv2 = sitofp i32 %conv1 to float + ret float %conv2 +; Float comparison to zero shouldn't cast to double. +; CHECK: @test8 +; CHECK-NEXT: fcmp olt float %x, 0.000000e+00 +} diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index 26c0e47..1c120ec 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -472,3 +472,23 @@ entry: ; CHECK: @pr10322_f1 ; CHECK: %tmp2 = getelementptr inbounds %pr10322_t* %arrayidx8, i64 0, i32 0 } + +; Test that we combine the last two geps in this sequence, before we +; would wait for gep1 and gep2 to be combined and never combine 2 and 3. +%three_gep_t = type {i32} +%three_gep_t2 = type {%three_gep_t} + +define void @three_gep_f(%three_gep_t2* %x) { + %gep1 = getelementptr %three_gep_t2* %x, i64 2 + call void @three_gep_h(%three_gep_t2* %gep1) + %gep2 = getelementptr %three_gep_t2* %gep1, i64 0, i32 0 + %gep3 = getelementptr %three_gep_t* %gep2, i64 0, i32 0 + call void @three_gep_g(i32* %gep3) + +; CHECK: @three_gep_f +; CHECK: %gep3 = getelementptr %three_gep_t2* %gep1, i64 0, i32 0, i32 0 + ret void +} + +declare void @three_gep_g(i32*) +declare void @three_gep_h(%three_gep_t2*) diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 0d84ae4..f033e51 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -152,9 +152,9 @@ entry: ret void ; CHECK: @powi ; CHECK: %A = fdiv double 1.0{{.*}}, %V -; CHECK: volatile store double %A, -; CHECK: volatile store double 1.0 -; CHECK: volatile store double %V +; CHECK: store volatile double %A, +; CHECK: store volatile double 1.0 +; CHECK: store volatile double %V } define i32 @cttz(i32 %a) { @@ -194,11 +194,11 @@ entry: ; CHECK: @cmp.simplify ; CHECK-NEXT: entry: ; CHECK-NEXT: %lz.cmp = icmp eq i32 %a, 0 -; CHECK-NEXT: volatile store i1 %lz.cmp, i1* %c +; CHECK-NEXT: store volatile i1 %lz.cmp, i1* %c ; CHECK-NEXT: %tz.cmp = icmp ne i32 %a, 0 -; CHECK-NEXT: volatile store i1 %tz.cmp, i1* %c +; CHECK-NEXT: store volatile i1 %tz.cmp, i1* %c ; CHECK-NEXT: %pop.cmp = icmp eq i32 %b, 0 -; CHECK-NEXT: volatile store i1 %pop.cmp, i1* %c +; CHECK-NEXT: store volatile i1 %pop.cmp, i1* %c } diff --git a/test/Transforms/InstCombine/malloc-free-delete.ll b/test/Transforms/InstCombine/malloc-free-delete.ll index 8455300..eae973d 100644 --- a/test/Transforms/InstCombine/malloc-free-delete.ll +++ b/test/Transforms/InstCombine/malloc-free-delete.ll @@ -12,7 +12,7 @@ define i32 @main(i32 %argc, i8** %argv) { ; CHECK: ret i32 0 } -declare i8* @malloc(i32) +declare noalias i8* @malloc(i32) declare void @free(i8*) define i1 @foo() { @@ -23,3 +23,26 @@ define i1 @foo() { call void @free(i8* %m) ret i1 %z } + +declare void @llvm.lifetime.start(i64, i8*) +declare void @llvm.lifetime.end(i64, i8*) + +define void @test3() { +; CHECK: @test3 +; CHECK-NEXT: ret void + %a = call noalias i8* @malloc(i32 10) + call void @llvm.lifetime.start(i64 10, i8* %a) + call void @llvm.lifetime.end(i64 10, i8* %a) + ret void +} + +;; This used to crash. +define void @test4() { +; CHECK: @test4 +; CHECK-NEXT: ret void + %A = call i8* @malloc(i32 16000) + %B = bitcast i8* %A to double* + %C = bitcast double* %B to i8* + call void @free(i8* %C) + ret void +} diff --git a/test/Transforms/InstCombine/nsw.ll b/test/Transforms/InstCombine/nsw.ll index 681bdc2..0140c2f 100644 --- a/test/Transforms/InstCombine/nsw.ll +++ b/test/Transforms/InstCombine/nsw.ll @@ -37,3 +37,47 @@ define i64 @shl1(i64 %X, i64* %P) nounwind { %B = shl i64 %A, 8 ret i64 %B } + +; CHECK: @preserve1 +; CHECK: add nsw i32 %x, 5 +define i32 @preserve1(i32 %x) nounwind { + %add = add nsw i32 %x, 2 + %add3 = add nsw i32 %add, 3 + ret i32 %add3 +} + +; CHECK: @nopreserve1 +; CHECK: add i8 %x, -126 +define i8 @nopreserve1(i8 %x) nounwind { + %add = add nsw i8 %x, 127 + %add3 = add nsw i8 %add, 3 + ret i8 %add3 +} + +; CHECK: @nopreserve2 +; CHECK: add i8 %x, 3 +define i8 @nopreserve2(i8 %x) nounwind { + %add = add i8 %x, 1 + %add3 = add nsw i8 %add, 2 + ret i8 %add3 +} + +; CHECK: @nopreserve3 +; CHECK: add i8 %A, %B +; CHECK: add i8 +define i8 @nopreserve3(i8 %A, i8 %B) nounwind { + %x = add i8 %A, 10 + %y = add i8 %B, 10 + %add = add nsw i8 %x, %y + ret i8 %add +} + +; CHECK: @nopreserve4 +; CHECK: add i8 %A, %B +; CHECK: add i8 +define i8 @nopreserve4(i8 %A, i8 %B) nounwind { + %x = add nsw i8 %A, 10 + %y = add nsw i8 %B, 10 + %add = add nsw i8 %x, %y + ret i8 %add +} diff --git a/test/Transforms/InstCombine/ptr-int-cast.ll b/test/Transforms/InstCombine/ptr-int-cast.ll index ad11e43..9524d44 100644 --- a/test/Transforms/InstCombine/ptr-int-cast.ll +++ b/test/Transforms/InstCombine/ptr-int-cast.ll @@ -5,22 +5,22 @@ define i1 @test1(i32 *%x) nounwind { entry: ; CHECK: test1 ; CHECK: ptrtoint i32* %x to i64 - %tmp = ptrtoint i32* %x to i1 - ret i1 %tmp + %0 = ptrtoint i32* %x to i1 + ret i1 %0 } define i32* @test2(i128 %x) nounwind { entry: ; CHECK: test2 -; CHECK: inttoptr i64 %tmp1 to i32* - %tmp = inttoptr i128 %x to i32* - ret i32* %tmp +; CHECK: inttoptr i64 %0 to i32* + %0 = inttoptr i128 %x to i32* + ret i32* %0 } ; PR3574 ; CHECK: f0 -; CHECK: %tmp = zext i32 %a0 to i64 -; CHECK: ret i64 %tmp +; CHECK: %1 = zext i32 %a0 to i64 +; CHECK: ret i64 %1 define i64 @f0(i32 %a0) nounwind { %t0 = inttoptr i32 %a0 to i8* %t1 = ptrtoint i8* %t0 to i64 diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index 4ca9bd2..4661561 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -799,3 +799,13 @@ define i1 @test60(i32 %x, i1* %y) nounwind { ; CHECK: @test60 ; CHECK: select } + +@glbl = constant i32 10 +define i32 @test61(i32* %ptr) { + %A = load i32* %ptr + %B = icmp eq i32* %ptr, @glbl + %C = select i1 %B, i32 %A, i32 10 + ret i32 %C +; CHECK: @test61 +; CHECK: ret i32 10 +} diff --git a/test/Transforms/InstCombine/shift.ll b/test/Transforms/InstCombine/shift.ll index d9ac9cb..132d51a 100644 --- a/test/Transforms/InstCombine/shift.ll +++ b/test/Transforms/InstCombine/shift.ll @@ -525,5 +525,20 @@ define i32 @test43(i32 %a, i32 %b) nounwind { ; CHECK-NEXT: ret } - - +define i32 @test44(i32 %a) nounwind { + %y = shl nuw i32 %a, 1 + %z = shl i32 %y, 4 + ret i32 %z +; CHECK: @test44 +; CHECK-NEXT: %y = shl i32 %a, 5 +; CHECK-NEXT: ret i32 %y +} + +define i32 @test45(i32 %a) nounwind { + %y = lshr exact i32 %a, 1 + %z = lshr i32 %y, 4 + ret i32 %z +; CHECK: @test45 +; CHECK-NEXT: %y = lshr i32 %a, 5 +; CHECK-NEXT: ret i32 %y +} diff --git a/test/Transforms/InstCombine/vec_demanded_elts.ll b/test/Transforms/InstCombine/vec_demanded_elts.ll index e0188fe..cc63371 100644 --- a/test/Transforms/InstCombine/vec_demanded_elts.ll +++ b/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -152,3 +152,14 @@ entry: ret <4 x i32> %0 } declare <4 x i32> @llvm.x86.sse41.pmovzxwd(<8 x i16>) nounwind readnone + +define <4 x float> @dead_shuffle_elt(<4 x float> %x, <2 x float> %y) nounwind { +entry: +; CHECK: define <4 x float> @dead_shuffle_elt +; CHECK: shufflevector <2 x float> %y, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef> + %shuffle.i = shufflevector <2 x float> %y, <2 x float> %y, <4 x i32> <i32 0, i32 1, i32 0, i32 1> + %shuffle9.i = shufflevector <4 x float> %x, <4 x float> %shuffle.i, <4 x i32> <i32 4, i32 5, i32 2, i32 3> + ret <4 x float> %shuffle9.i +} + + diff --git a/test/Transforms/InstCombine/vector-casts.ll b/test/Transforms/InstCombine/vector-casts.ll index e931dc7..7bbf53c 100644 --- a/test/Transforms/InstCombine/vector-casts.ll +++ b/test/Transforms/InstCombine/vector-casts.ll @@ -7,7 +7,7 @@ define <2 x i1> @test1(<2 x i64> %a) { ; CHECK: @test1 ; CHECK: and <2 x i64> %a, <i64 1, i64 1> -; CHECK: icmp ne <2 x i64> %tmp, zeroinitializer +; CHECK: icmp ne <2 x i64> %1, zeroinitializer } ; The ashr turns into an lshr. diff --git a/test/Transforms/InstCombine/volatile_store.ll b/test/Transforms/InstCombine/volatile_store.ll index 5316bd7..0518e5a 100644 --- a/test/Transforms/InstCombine/volatile_store.ll +++ b/test/Transforms/InstCombine/volatile_store.ll @@ -1,5 +1,5 @@ -; RUN: opt < %s -instcombine -S | grep {volatile store} -; RUN: opt < %s -instcombine -S | grep {volatile load} +; RUN: opt < %s -instcombine -S | grep {store volatile} +; RUN: opt < %s -instcombine -S | grep {load volatile} @x = weak global i32 0 ; <i32*> [#uses=2] |