| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- ; 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, 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, 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, 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, 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*, 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, 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*, 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*, 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 }
|