[llvm] dd92b29 - [Attributor][NFC] Pre-commit new test case

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 5 16:21:39 PDT 2022


Author: Johannes Doerfert
Date: 2022-04-05T18:20:45-05:00
New Revision: dd92b29e757da8ba10d7af516e6cf22b9ea625f8

URL: https://github.com/llvm/llvm-project/commit/dd92b29e757da8ba10d7af516e6cf22b9ea625f8
DIFF: https://github.com/llvm/llvm-project/commit/dd92b29e757da8ba10d7af516e6cf22b9ea625f8.diff

LOG: [Attributor][NFC] Pre-commit new test case

Added: 
    llvm/test/Transforms/Attributor/value-simplify-assume.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/Attributor/value-simplify-assume.ll b/llvm/test/Transforms/Attributor/value-simplify-assume.ll
new file mode 100644
index 0000000000000..5d6a7fdd27e27
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/value-simplify-assume.ll
@@ -0,0 +1,989 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
+; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
+; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
+; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
+
+declare void @llvm.assume(i1)
+declare void @useI1p(i1*)
+declare void @unknown()
+
+define i1 @readI1p(i1* %p) {
+; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; CHECK-LABEL: define {{[^@]+}}@readI1p
+; CHECK-SAME: (i1* nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[P]], align 1
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %l = load i1, i1* %p
+  ret i1 %l
+}
+
+define i1 @keep_assume_1c_nr() norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c_nr
+; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @drop_assume_1c_nr() norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@drop_assume_1c_nr
+; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT:    ret i1 true
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @keep_assume_2c_nr() norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c_nr
+; CHECK-SAME: () #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L1:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L1]])
+; CHECK-NEXT:    call void @unknown()
+; CHECK-NEXT:    [[L2:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    ret i1 [[L2]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  call void @unknown()
+  %l2 = load i1, i1* %stack
+  ret i1 %l2
+}
+
+define i1 @keep_assume_3c_nr() norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_3c_nr
+; CHECK-SAME: () #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  call void @useI1p(i1* %stack)
+  ret i1 %l
+}
+define i1 @keep_assume_4c_nr() norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_4c_nr
+; CHECK-SAME: () #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L4:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L4]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l4 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l4)
+  call void @useI1p(i1* nocapture %stack)
+  ret i1 %l4
+}
+
+define i1 @keep_assume_1_nr(i1 %arg) norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_1_nr
+; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @drop_assume_1_nr(i1 %arg) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@drop_assume_1_nr
+; CHECK-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret i1 [[ARG]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @keep_assume_2_nr(i1 %arg) norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_2_nr
+; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L1:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L1]])
+; CHECK-NEXT:    call void @unknown()
+; CHECK-NEXT:    [[L2:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    ret i1 [[L2]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  call void @unknown()
+  %l2 = load i1, i1* %stack
+  ret i1 %l2
+}
+
+define i1 @keep_assume_3_nr(i1 %arg) norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_3_nr
+; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  call void @useI1p(i1* %stack)
+  ret i1 %l
+}
+
+define i1 @keep_assume_4_nr(i1 %arg) norecurse {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_4_nr
+; CHECK-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  call void @useI1p(i1* nocapture %stack)
+  ret i1 %l
+}
+
+define i1 @assume_1_nr(i1 %arg, i1 %cond) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_1_nr
+; CHECK-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    ret i1 [[ARG]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  ret i1 %l
+}
+
+define void @assume_1b_nr(i1 %arg, i1 %cond) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_1b_nr
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    ret void
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  ret void
+}
+
+define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_2_nr
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define void @assume_2b_nr(i1 %arg, i1 %cond) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_2b_nr
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    ret void
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret void
+}
+
+define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_3_nr
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5:[0-9]+]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_4_nr
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
+; IS________OPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; IS________OPM-LABEL: define {{[^@]+}}@assume_5_nr
+; IS________OPM-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; IS________OPM-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; IS________OPM-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; IS________OPM-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; IS________OPM:       t:
+; IS________OPM-NEXT:    store i1 true, i1* [[STACK]], align 1
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    br label [[M:%.*]]
+; IS________OPM:       f:
+; IS________OPM-NEXT:    store i1 false, i1* [[STACK]], align 1
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    br label [[M]]
+; IS________OPM:       m:
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; IS________OPM-NEXT:    ret i1 [[R]]
+;
+; IS________NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; IS________NPM-LABEL: define {{[^@]+}}@assume_5_nr
+; IS________NPM-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; IS________NPM-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; IS________NPM-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; IS________NPM-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; IS________NPM:       t:
+; IS________NPM-NEXT:    store i1 true, i1* [[STACK]], align 1
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________NPM-NEXT:    br label [[M:%.*]]
+; IS________NPM:       f:
+; IS________NPM-NEXT:    store i1 false, i1* [[STACK]], align 1
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR4]]
+; IS________NPM-NEXT:    br label [[M]]
+; IS________NPM:       m:
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________NPM-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; IS________NPM-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  %l2 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l2)
+  br label %m
+f:
+  store i1 false, i1* %stack
+  %l3 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l3)
+  br label %m
+m:
+  %l4 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l4)
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+define i1 @assume_5c_nr(i1 %cond) norecurse {
+; IS________OPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; IS________OPM-LABEL: define {{[^@]+}}@assume_5c_nr
+; IS________OPM-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] {
+; IS________OPM-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; IS________OPM-NEXT:    store i1 true, i1* [[STACK]], align 1
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; IS________OPM:       t:
+; IS________OPM-NEXT:    store i1 true, i1* [[STACK]], align 1
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    br label [[M:%.*]]
+; IS________OPM:       f:
+; IS________OPM-NEXT:    store i1 false, i1* [[STACK]], align 1
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    br label [[M]]
+; IS________OPM:       m:
+; IS________OPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________OPM-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; IS________OPM-NEXT:    ret i1 [[R]]
+;
+; IS________NPM: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; IS________NPM-LABEL: define {{[^@]+}}@assume_5c_nr
+; IS________NPM-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] {
+; IS________NPM-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; IS________NPM-NEXT:    store i1 true, i1* [[STACK]], align 1
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________NPM-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; IS________NPM:       t:
+; IS________NPM-NEXT:    store i1 true, i1* [[STACK]], align 1
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________NPM-NEXT:    br label [[M:%.*]]
+; IS________NPM:       f:
+; IS________NPM-NEXT:    store i1 false, i1* [[STACK]], align 1
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef false) #[[ATTR4]]
+; IS________NPM-NEXT:    br label [[M]]
+; IS________NPM:       m:
+; IS________NPM-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; IS________NPM-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; IS________NPM-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  %l2 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l2)
+  br label %m
+f:
+  store i1 false, i1* %stack
+  %l3 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l3)
+  br label %m
+m:
+  %l4 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l4)
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+
+define i1 @keep_assume_1c() {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_1c() {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @drop_assume_1c() {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@drop_assume_1c
+; CHECK-SAME: () #[[ATTR3]] {
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    ret i1 true
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @keep_assume_2c() {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_2c() {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L1:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L1]])
+; CHECK-NEXT:    call void @unknown()
+; CHECK-NEXT:    [[L2:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    ret i1 [[L2]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  call void @unknown()
+  %l2 = load i1, i1* %stack
+  ret i1 %l2
+}
+
+define i1 @keep_assume_3c() {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_3c() {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  call void @useI1p(i1* %stack)
+  ret i1 %l
+}
+define i1 @keep_assume_4c() {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_4c() {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L4:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L4]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l4 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l4)
+  call void @useI1p(i1* nocapture %stack)
+  ret i1 %l4
+}
+
+define i1 @keep_assume_1(i1 %arg) {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_1
+; CHECK-SAME: (i1 [[ARG:%.*]]) {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @drop_assume_1(i1 %arg) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@drop_assume_1
+; CHECK-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    ret i1 [[ARG]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define i1 @keep_assume_2(i1 %arg) {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_2
+; CHECK-SAME: (i1 [[ARG:%.*]]) {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    [[L1:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L1]])
+; CHECK-NEXT:    call void @unknown()
+; CHECK-NEXT:    [[L2:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    ret i1 [[L2]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  call void @useI1p(i1* %stack)
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  call void @unknown()
+  %l2 = load i1, i1* %stack
+  ret i1 %l2
+}
+
+define i1 @keep_assume_3(i1 %arg) {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_3
+; CHECK-SAME: (i1 [[ARG:%.*]]) {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  call void @useI1p(i1* %stack)
+  ret i1 %l
+}
+
+define i1 @keep_assume_4(i1 %arg) {
+; CHECK-LABEL: define {{[^@]+}}@keep_assume_4
+; CHECK-SAME: (i1 [[ARG:%.*]]) {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  call void @useI1p(i1* nocapture %stack)
+  ret i1 %l
+}
+
+define i1 @assume_1(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_1
+; CHECK-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    ret i1 [[ARG]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  ret i1 %l
+}
+
+define void @assume_1b(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_1b
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    ret void
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  ret void
+}
+
+define i1 @assume_2(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_2
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    [[L:%.*]] = load i1, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
+; CHECK-NEXT:    ret i1 [[L]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret i1 %l
+}
+
+define void @assume_2b(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_2b
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    ret void
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  ret void
+}
+
+define i1 @assume_3(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_3
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+define i1 @assume_4(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_4
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  br label %m
+f:
+  store i1 false, i1* %stack
+  br label %m
+m:
+  %l = load i1, i1* %stack
+  call void @llvm.assume(i1 %l)
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+define i1 @assume_5(i1 %arg, i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_5
+; CHECK-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 [[ARG]], i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 %arg, i1* %stack
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  %l2 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l2)
+  br label %m
+f:
+  store i1 false, i1* %stack
+  %l3 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l3)
+  br label %m
+m:
+  %l4 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l4)
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+define i1 @assume_5c(i1 %cond) {
+; CHECK: Function Attrs: inaccessiblememonly nofree norecurse nosync nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@assume_5c
+; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT:    [[STACK:%.*]] = alloca i1, align 1
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    store i1 true, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    br label [[M:%.*]]
+; CHECK:       f:
+; CHECK-NEXT:    store i1 false, i1* [[STACK]], align 1
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    br label [[M]]
+; CHECK:       m:
+; CHECK-NEXT:    call void @llvm.assume(i1 noundef true) #[[ATTR4]]
+; CHECK-NEXT:    [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %stack = alloca i1
+  store i1 true, i1* %stack
+  %l1 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l1)
+  br i1 %cond, label %t, label %f
+t:
+  store i1 true, i1* %stack
+  %l2 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l2)
+  br label %m
+f:
+  store i1 false, i1* %stack
+  %l3 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l3)
+  br label %m
+m:
+  %l4 = load i1, i1* %stack
+  call void @llvm.assume(i1 %l4)
+  %r = call i1 @readI1p(i1* %stack)
+  ret i1 %r
+}
+
+;.
+; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn }
+; IS__TUNIT____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
+; IS__TUNIT____: attributes #[[ATTR2]] = { norecurse }
+; IS__TUNIT____: attributes #[[ATTR3]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn }
+; IS__TUNIT____: attributes #[[ATTR4]] = { willreturn }
+; IS__TUNIT____: attributes #[[ATTR5]] = { nofree nosync nounwind readonly willreturn }
+;.
+; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { inaccessiblememonly nocallback nofree nosync nounwind willreturn }
+; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn }
+; IS__CGSCC____: attributes #[[ATTR2]] = { norecurse }
+; IS__CGSCC____: attributes #[[ATTR3]] = { inaccessiblememonly nofree norecurse nosync nounwind willreturn }
+; IS__CGSCC____: attributes #[[ATTR4]] = { willreturn }
+; IS__CGSCC____: attributes #[[ATTR5]] = { readonly willreturn }
+;.


        


More information about the llvm-commits mailing list