diff options
Diffstat (limited to 'test/Transforms/GVN')
| -rw-r--r-- | test/Transforms/GVN/2009-03-10-PREOnVoid.ll | 56 | ||||
| -rw-r--r-- | test/Transforms/GVN/calloc-load-removal.ll | 25 | ||||
| -rw-r--r-- | test/Transforms/GVN/invariant-load.ll | 31 | ||||
| -rw-r--r-- | test/Transforms/GVN/load-pre-nonlocal.ll | 87 | ||||
| -rw-r--r-- | test/Transforms/GVN/rle.ll | 13 | ||||
| -rw-r--r-- | test/Transforms/GVN/unreachable_block_infinite_loop.ll | 2 |
6 files changed, 199 insertions, 15 deletions
diff --git a/test/Transforms/GVN/2009-03-10-PREOnVoid.ll b/test/Transforms/GVN/2009-03-10-PREOnVoid.ll index 89d6a5f982b8..fd31fce59a84 100644 --- a/test/Transforms/GVN/2009-03-10-PREOnVoid.ll +++ b/test/Transforms/GVN/2009-03-10-PREOnVoid.ll @@ -53,30 +53,58 @@ bb11: ; preds = %bb7, %bb5 unreachable } -declare i32 @pthread_once(i32*, void ()*) +define i32 @pthread_once(i32*, void ()*) { + ret i32 0 +} -declare i8* @pthread_getspecific(i32) +define i8* @pthread_getspecific(i32) { + ret i8* null +} -declare i32 @pthread_setspecific(i32, i8*) +define i32 @pthread_setspecific(i32, i8*) { + ret i32 0 +} -declare i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*) +define i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*) { + ret i32 0 +} -declare i32 @pthread_cancel(i32) +define i32 @pthread_cancel(i32) { + ret i32 0 +} -declare i32 @pthread_mutex_lock(%struct.pthread_mutex_t*) +define i32 @pthread_mutex_lock(%struct.pthread_mutex_t*) { + ret i32 0 +} -declare i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*) +define i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*) { + ret i32 0 +} -declare i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*) +define i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*) { + ret i32 0 +} -declare i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*) +define i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*) { + ret i32 0 +} -declare i32 @pthread_key_create(i32*, void (i8*)*) +define i32 @pthread_key_create(i32*, void (i8*)*) { + ret i32 0 +} -declare i32 @pthread_key_delete(i32) +define i32 @pthread_key_delete(i32) { + ret i32 0 +} -declare i32 @pthread_mutexattr_init(%struct.__sched_param*) +define i32 @pthread_mutexattr_init(%struct.__sched_param*) { + ret i32 0 +} -declare i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32) +define i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32) { + ret i32 0 +} -declare i32 @pthread_mutexattr_destroy(%struct.__sched_param*) +define i32 @pthread_mutexattr_destroy(%struct.__sched_param*) { + ret i32 0 +} diff --git a/test/Transforms/GVN/calloc-load-removal.ll b/test/Transforms/GVN/calloc-load-removal.ll new file mode 100644 index 000000000000..2dde5b7b4146 --- /dev/null +++ b/test/Transforms/GVN/calloc-load-removal.ll @@ -0,0 +1,25 @@ +; RUN: opt -S -basicaa -gvn < %s | FileCheck %s +; RUN: opt -S -basicaa -gvn -disable-simplify-libcalls < %s | FileCheck %s -check-prefix=CHECK_NO_LIBCALLS +; Check that loads from calloc are recognized as being zero. + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" + +; Function Attrs: nounwind uwtable +define i32 @test1() { + %1 = tail call noalias i8* @calloc(i64 1, i64 4) + %2 = bitcast i8* %1 to i32* + ; This load is trivially constant zero + %3 = load i32* %2, align 4 + ret i32 %3 + +; CHECK-LABEL: @test1( +; CHECK-NOT: %3 = load i32* %2, align 4 +; CHECK: ret i32 0 + +; CHECK_NO_LIBCALLS-LABEL: @test1( +; CHECK_NO_LIBCALLS: load +; CHECK_NO_LIBCALLS: ret i32 % + +} + +declare noalias i8* @calloc(i64, i64) diff --git a/test/Transforms/GVN/invariant-load.ll b/test/Transforms/GVN/invariant-load.ll new file mode 100644 index 000000000000..80e2226b5fae --- /dev/null +++ b/test/Transforms/GVN/invariant-load.ll @@ -0,0 +1,31 @@ +; Test if the !invariant.load metadata is maintained by GVN. +; RUN: opt -basicaa -gvn -S < %s | FileCheck %s + +define i32 @test1(i32* nocapture %p, i8* nocapture %q) { +; CHECK-LABEL: test1 +; CHECK: %x = load i32* %p, align 4, !invariant.load !0 +; CHECK-NOT: %y = load +entry: + %x = load i32* %p, align 4, !invariant.load !0 + %conv = trunc i32 %x to i8 + store i8 %conv, i8* %q, align 1 + %y = load i32* %p, align 4, !invariant.load !0 + %add = add i32 %y, 1 + ret i32 %add +} + +define i32 @test2(i32* nocapture %p, i8* nocapture %q) { +; CHECK-LABEL: test2 +; CHECK-NOT: !invariant.load +; CHECK-NOT: %y = load +entry: + %x = load i32* %p, align 4 + %conv = trunc i32 %x to i8 + store i8 %conv, i8* %q, align 1 + %y = load i32* %p, align 4, !invariant.load !0 + %add = add i32 %y, 1 + ret i32 %add +} + +!0 = metadata !{ } + diff --git a/test/Transforms/GVN/load-pre-nonlocal.ll b/test/Transforms/GVN/load-pre-nonlocal.ll new file mode 100644 index 000000000000..7bac1b78e6a2 --- /dev/null +++ b/test/Transforms/GVN/load-pre-nonlocal.ll @@ -0,0 +1,87 @@ +; RUN: opt -S -o - -basicaa -domtree -gvn %s | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +%struct.S1 = type { i32, i32 } + +@a2 = common global i32* null, align 8 +@a = common global i32* null, align 8 +@s1 = common global %struct.S1 zeroinitializer, align 8 + +; Check that GVN doesn't determine %2 is partially redundant. + +; CHECK-LABEL: define i32 @volatile_load +; CHECK: for.body: +; CHECK: %2 = load i32* +; CHECK: %3 = load volatile i32* +; CHECK: for.cond.for.end_crit_edge: + +define i32 @volatile_load(i32 %n) { +entry: + %cmp6 = icmp sgt i32 %n, 0 + br i1 %cmp6, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: + %0 = load i32** @a2, align 8, !tbaa !1 + %1 = load i32** @a, align 8, !tbaa !1 + br label %for.body + +for.body: + %indvars.iv = phi i64 [ 0, %for.body.lr.ph ], [ %indvars.iv.next, %for.body ] + %s.09 = phi i32 [ 0, %for.body.lr.ph ], [ %add, %for.body ] + %p.08 = phi i32* [ %0, %for.body.lr.ph ], [ %incdec.ptr, %for.body ] + %2 = load i32* %p.08, align 4, !tbaa !5 + %arrayidx = getelementptr inbounds i32* %1, i64 %indvars.iv + store i32 %2, i32* %arrayidx, align 4, !tbaa !5 + %3 = load volatile i32* %p.08, align 4, !tbaa !5 + %add = add nsw i32 %3, %s.09 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %incdec.ptr = getelementptr inbounds i32* %p.08, i64 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp ne i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.body, label %for.cond.for.end_crit_edge + +for.cond.for.end_crit_edge: + %add.lcssa = phi i32 [ %add, %for.body ] + br label %for.end + +for.end: + %s.0.lcssa = phi i32 [ %add.lcssa, %for.cond.for.end_crit_edge ], [ 0, %entry ] + ret i32 %s.0.lcssa +} + +; %1 is partially redundant if %0 can be widened to a 64-bit load. + +; CHECK-LABEL: define i32 @overaligned_load +; CHECK: if.end: +; CHECK-NOT: %1 = load i32* + +define i32 @overaligned_load(i32 %a, i32* nocapture %b) { +entry: + %cmp = icmp sgt i32 %a, 0 + br i1 %cmp, label %if.then, label %if.else + +if.then: + %0 = load i32* getelementptr inbounds (%struct.S1* @s1, i64 0, i32 0), align 8, !tbaa !5 + br label %if.end + +if.else: + %arrayidx = getelementptr inbounds i32* %b, i64 2 + store i32 10, i32* %arrayidx, align 4, !tbaa !5 + br label %if.end + +if.end: + %i.0 = phi i32 [ %0, %if.then ], [ 0, %if.else ] + %p.0 = phi i32* [ getelementptr inbounds (%struct.S1* @s1, i64 0, i32 0), %if.then ], [ %b, %if.else ] + %add.ptr = getelementptr inbounds i32* %p.0, i64 1 + %1 = load i32* %add.ptr, align 4, !tbaa !5 + %add1 = add nsw i32 %1, %i.0 + ret i32 %add1 +} + +!1 = metadata !{metadata !2, metadata !2, i64 0} +!2 = metadata !{metadata !"any pointer", metadata !3, i64 0} +!3 = metadata !{metadata !"omnipotent char", metadata !4, i64 0} +!4 = metadata !{metadata !"Simple C/C++ TBAA"} +!5 = metadata !{metadata !6, metadata !6, i64 0} +!6 = metadata !{metadata !"int", metadata !3, i64 0} diff --git a/test/Transforms/GVN/rle.ll b/test/Transforms/GVN/rle.ll index 8d289b06997c..6aac93e75a78 100644 --- a/test/Transforms/GVN/rle.ll +++ b/test/Transforms/GVN/rle.ll @@ -318,6 +318,19 @@ define i8 @coerce_offset0(i32 %V, i32* %P) { ; CHECK: ret i8 } +define i8 @coerce_offset0_addrspacecast(i32 %V, i32* %P) { + store i32 %V, i32* %P + + %P2 = addrspacecast i32* %P to i8 addrspace(1)* + %P3 = getelementptr i8 addrspace(1)* %P2, i32 2 + + %A = load i8 addrspace(1)* %P3 + ret i8 %A +; CHECK-LABEL: @coerce_offset0_addrspacecast( +; CHECK-NOT: load +; CHECK: ret i8 +} + ;; non-local i32/float -> i8 load forwarding. define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) { %P2 = bitcast i32* %P to float* diff --git a/test/Transforms/GVN/unreachable_block_infinite_loop.ll b/test/Transforms/GVN/unreachable_block_infinite_loop.ll index fe335ced5c37..fca5a28b38dd 100644 --- a/test/Transforms/GVN/unreachable_block_infinite_loop.ll +++ b/test/Transforms/GVN/unreachable_block_infinite_loop.ll @@ -1,4 +1,4 @@ -; RUN: opt -memdep -gvn -disable-output +; RUN: opt -memdep -gvn -disable-output < %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0" |
