diff options
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/Bitcode/attributes.ll | 10 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/compare.ll | 34 | ||||
-rw-r--r-- | llvm/test/Transforms/LICM/hoist-deref-load.ll | 86 |
3 files changed, 130 insertions, 0 deletions
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index 49366de9836..2490e592072 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -229,6 +229,16 @@ define void @f38() unnamed_addr jumptable { unreachable } +define dereferenceable(2) i8* @f39(i8* dereferenceable(1) %a) { +; CHECK: define dereferenceable(2) i8* @f39(i8* dereferenceable(1) %a) { + ret i8* %a +} + +define dereferenceable(18446744073709551606) i8* @f40(i8* dereferenceable(18446744073709551615) %a) { +; CHECK: define dereferenceable(18446744073709551606) i8* @f40(i8* dereferenceable(18446744073709551615) %a) { + ret i8* %a +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll index 42084c9eeed..94872d35bb9 100644 --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -874,6 +874,21 @@ define i1 @nonnull_arg(i32* nonnull %i) { ; CHECK: ret i1 false } +define i1 @nonnull_deref_arg(i32* dereferenceable(4) %i) { + %cmp = icmp eq i32* %i, null + ret i1 %cmp +; CHECK-LABEL: @nonnull_deref_arg +; CHECK: ret i1 false +} + +define i1 @nonnull_deref_as_arg(i32 addrspace(1)* dereferenceable(4) %i) { + %cmp = icmp eq i32 addrspace(1)* %i, null + ret i1 %cmp +; CHECK-LABEL: @nonnull_deref_as_arg +; CHECK: icmp +; CHECK ret +} + declare nonnull i32* @returns_nonnull_helper() define i1 @returns_nonnull() { %call = call nonnull i32* @returns_nonnull_helper() @@ -883,6 +898,25 @@ define i1 @returns_nonnull() { ; CHECK: ret i1 false } +declare dereferenceable(4) i32* @returns_nonnull_deref_helper() +define i1 @returns_nonnull_deref() { + %call = call dereferenceable(4) i32* @returns_nonnull_deref_helper() + %cmp = icmp eq i32* %call, null + ret i1 %cmp +; CHECK-LABEL: @returns_nonnull_deref +; CHECK: ret i1 false +} + +declare dereferenceable(4) i32 addrspace(1)* @returns_nonnull_deref_as_helper() +define i1 @returns_nonnull_as_deref() { + %call = call dereferenceable(4) i32 addrspace(1)* @returns_nonnull_deref_as_helper() + %cmp = icmp eq i32 addrspace(1)* %call, null + ret i1 %cmp +; CHECK-LABEL: @returns_nonnull_as_deref +; CHECK: icmp +; CHECK: ret +} + ; If a bit is known to be zero for A and known to be one for B, ; then A and B cannot be equal. define i1 @icmp_eq_const(i32 %a) nounwind { diff --git a/llvm/test/Transforms/LICM/hoist-deref-load.ll b/llvm/test/Transforms/LICM/hoist-deref-load.ll new file mode 100644 index 00000000000..972d75fff35 --- /dev/null +++ b/llvm/test/Transforms/LICM/hoist-deref-load.ll @@ -0,0 +1,86 @@ +; RUN: opt -S -basicaa -licm < %s | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; This test represents the following function: +; void test1(int * __restrict__ a, int * __restrict__ b, int &c, int n) { +; for (int i = 0; i < n; ++i) +; if (a[i] > 0) +; a[i] = c*b[i]; +; } +; and we want to hoist the load of %c out of the loop. This can be done only +; because the dereferenceable attribute is on %c. + +; CHECK-LABEL: @test1 +; CHECK: load i32* %c, align 4 +; CHECK: for.body: + +define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull dereferenceable(4) %c, i32 %n) #0 { +entry: + %cmp11 = icmp sgt i32 %n, 0 + br i1 %cmp11, label %for.body, label %for.end + +for.body: ; preds = %entry, %for.inc + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %cmp1 = icmp sgt i32 %0, 0 + br i1 %cmp1, label %if.then, label %for.inc + +if.then: ; preds = %for.body + %1 = load i32* %c, align 4 + %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv + %2 = load i32* %arrayidx3, align 4 + %mul = mul nsw i32 %2, %1 + store i32 %mul, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body, %if.then + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.inc, %entry + ret void +} + +; This is the same as @test1, but without the dereferenceable attribute on %c. +; Without this attribute, we should not hoist the load of %c. + +; CHECK-LABEL: @test2 +; CHECK: if.then: +; CHECK: load i32* %c, align 4 + +define void @test2(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* nocapture readonly nonnull %c, i32 %n) #0 { +entry: + %cmp11 = icmp sgt i32 %n, 0 + br i1 %cmp11, label %for.body, label %for.end + +for.body: ; preds = %entry, %for.inc + %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ] + %arrayidx = getelementptr inbounds i32* %a, i64 %indvars.iv + %0 = load i32* %arrayidx, align 4 + %cmp1 = icmp sgt i32 %0, 0 + br i1 %cmp1, label %if.then, label %for.inc + +if.then: ; preds = %for.body + %1 = load i32* %c, align 4 + %arrayidx3 = getelementptr inbounds i32* %b, i64 %indvars.iv + %2 = load i32* %arrayidx3, align 4 + %mul = mul nsw i32 %2, %1 + store i32 %mul, i32* %arrayidx, align 4 + br label %for.inc + +for.inc: ; preds = %for.body, %if.then + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + %lftr.wideiv = trunc i64 %indvars.iv.next to i32 + %exitcond = icmp eq i32 %lftr.wideiv, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.inc, %entry + ret void +} + +attributes #0 = { nounwind uwtable } + |