diff options
Diffstat (limited to 'test/Transforms/InstCombine/assume.ll')
-rw-r--r-- | test/Transforms/InstCombine/assume.ll | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/test/Transforms/InstCombine/assume.ll b/test/Transforms/InstCombine/assume.ll new file mode 100644 index 0000000..7e45c04 --- /dev/null +++ b/test/Transforms/InstCombine/assume.ll @@ -0,0 +1,265 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define i32 @foo1(i32* %a) #0 { +entry: + %0 = load i32* %a, align 4 + +; Check that the alignment has been upgraded and that the assume has not +; been removed: +; CHECK-LABEL: @foo1 +; CHECK-DAG: load i32* %a, align 32 +; CHECK-DAG: call void @llvm.assume +; CHECK: ret i32 + + %ptrint = ptrtoint i32* %a to i64 + %maskedptr = and i64 %ptrint, 31 + %maskcond = icmp eq i64 %maskedptr, 0 + tail call void @llvm.assume(i1 %maskcond) + + ret i32 %0 +} + +; Function Attrs: nounwind uwtable +define i32 @foo2(i32* %a) #0 { +entry: +; Same check as in @foo1, but make sure it works if the assume is first too. +; CHECK-LABEL: @foo2 +; CHECK-DAG: load i32* %a, align 32 +; CHECK-DAG: call void @llvm.assume +; CHECK: ret i32 + + %ptrint = ptrtoint i32* %a to i64 + %maskedptr = and i64 %ptrint, 31 + %maskcond = icmp eq i64 %maskedptr, 0 + tail call void @llvm.assume(i1 %maskcond) + + %0 = load i32* %a, align 4 + ret i32 %0 +} + +; Function Attrs: nounwind +declare void @llvm.assume(i1) #1 + +define i32 @simple(i32 %a) #1 { +entry: + +; CHECK-LABEL: @simple +; CHECK: call void @llvm.assume +; CHECK: ret i32 4 + + %cmp = icmp eq i32 %a, 4 + tail call void @llvm.assume(i1 %cmp) + ret i32 %a +} + +; Function Attrs: nounwind uwtable +define i32 @can1(i1 %a, i1 %b, i1 %c) { +entry: + %and1 = and i1 %a, %b + %and = and i1 %and1, %c + tail call void @llvm.assume(i1 %and) + +; CHECK-LABEL: @can1 +; CHECK: call void @llvm.assume(i1 %a) +; CHECK: call void @llvm.assume(i1 %b) +; CHECK: call void @llvm.assume(i1 %c) +; CHECK: ret i32 + + ret i32 5 +} + +; Function Attrs: nounwind uwtable +define i32 @can2(i1 %a, i1 %b, i1 %c) { +entry: + %v = or i1 %a, %b + %w = xor i1 %v, 1 + tail call void @llvm.assume(i1 %w) + +; CHECK-LABEL: @can2 +; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true +; CHECK: call void @llvm.assume(i1 %[[V1]]) +; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true +; CHECK: call void @llvm.assume(i1 %[[V2]]) +; CHECK: ret i32 + + ret i32 5 +} + +define i32 @bar1(i32 %a) #0 { +entry: + %and1 = and i32 %a, 3 + +; CHECK-LABEL: @bar1 +; CHECK: call void @llvm.assume +; CHECK: ret i32 1 + + %and = and i32 %a, 7 + %cmp = icmp eq i32 %and, 1 + tail call void @llvm.assume(i1 %cmp) + + ret i32 %and1 +} + +; Function Attrs: nounwind uwtable +define i32 @bar2(i32 %a) #0 { +entry: +; CHECK-LABEL: @bar2 +; CHECK: call void @llvm.assume +; CHECK: ret i32 1 + + %and = and i32 %a, 7 + %cmp = icmp eq i32 %and, 1 + tail call void @llvm.assume(i1 %cmp) + + %and1 = and i32 %a, 3 + ret i32 %and1 +} + +; Function Attrs: nounwind uwtable +define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 { +entry: + %and1 = and i32 %a, 3 + +; Don't be fooled by other assumes around. +; CHECK-LABEL: @bar3 +; CHECK: call void @llvm.assume +; CHECK: ret i32 1 + + tail call void @llvm.assume(i1 %x) + + %and = and i32 %a, 7 + %cmp = icmp eq i32 %and, 1 + tail call void @llvm.assume(i1 %cmp) + + tail call void @llvm.assume(i1 %y) + + ret i32 %and1 +} + +; Function Attrs: nounwind uwtable +define i32 @bar4(i32 %a, i32 %b) { +entry: + %and1 = and i32 %b, 3 + +; CHECK-LABEL: @bar4 +; CHECK: call void @llvm.assume +; CHECK: call void @llvm.assume +; CHECK: ret i32 1 + + %and = and i32 %a, 7 + %cmp = icmp eq i32 %and, 1 + tail call void @llvm.assume(i1 %cmp) + + %cmp2 = icmp eq i32 %a, %b + tail call void @llvm.assume(i1 %cmp2) + + ret i32 %and1 +} + +define i32 @icmp1(i32 %a) #0 { +entry: + %cmp = icmp sgt i32 %a, 5 + tail call void @llvm.assume(i1 %cmp) + %conv = zext i1 %cmp to i32 + ret i32 %conv + +; CHECK-LABEL: @icmp1 +; CHECK: call void @llvm.assume +; CHECK: ret i32 1 + +} + +; Function Attrs: nounwind uwtable +define i32 @icmp2(i32 %a) #0 { +entry: + %cmp = icmp sgt i32 %a, 5 + tail call void @llvm.assume(i1 %cmp) + %0 = zext i1 %cmp to i32 + %lnot.ext = xor i32 %0, 1 + ret i32 %lnot.ext + +; CHECK-LABEL: @icmp2 +; CHECK: call void @llvm.assume +; CHECK: ret i32 0 +} + +declare void @escape(i32* %a) + +; Do we canonicalize a nonnull assumption on a load into +; metadata form? +define i1 @nonnull1(i32** %a) { +entry: + %load = load i32** %a + %cmp = icmp ne i32* %load, null + tail call void @llvm.assume(i1 %cmp) + tail call void @escape(i32* %load) + %rval = icmp eq i32* %load, null + ret i1 %rval + +; CHECK-LABEL: @nonnull1 +; CHECK: !nonnull +; CHECK-NOT: call void @llvm.assume +; CHECK: ret i1 false +} + +; Make sure the above canonicalization applies only +; to pointer types. Doing otherwise would be illegal. +define i1 @nonnull2(i32* %a) { +entry: + %load = load i32* %a + %cmp = icmp ne i32 %load, 0 + tail call void @llvm.assume(i1 %cmp) + %rval = icmp eq i32 %load, 0 + ret i1 %rval + +; CHECK-LABEL: @nonnull2 +; CHECK-NOT: !nonnull +; CHECK: call void @llvm.assume +} + +; Make sure the above canonicalization does not trigger +; if the assume is control dependent on something else +define i1 @nonnull3(i32** %a, i1 %control) { +entry: + %load = load i32** %a + %cmp = icmp ne i32* %load, null + br i1 %control, label %taken, label %not_taken +taken: + tail call void @llvm.assume(i1 %cmp) + %rval = icmp eq i32* %load, null + ret i1 %rval +not_taken: + ret i1 true + +; CHECK-LABEL: @nonnull3 +; CHECK-NOT: !nonnull +; CHECK: call void @llvm.assume +} + +; Make sure the above canonicalization does not trigger +; if the path from the load to the assume is potentially +; interrupted by an exception being thrown +define i1 @nonnull4(i32** %a) { +entry: + %load = load i32** %a + ;; This call may throw! + tail call void @escape(i32* %load) + %cmp = icmp ne i32* %load, null + tail call void @llvm.assume(i1 %cmp) + %rval = icmp eq i32* %load, null + ret i1 %rval + +; CHECK-LABEL: @nonnull4 +; CHECK-NOT: !nonnull +; CHECK: call void @llvm.assume +} + + + + +attributes #0 = { nounwind uwtable } +attributes #1 = { nounwind } + |