llvm-project/llvm/test/Transforms/Attributor/value-simplify-assume.ll

1380 lines
54 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
declare void @llvm.assume(i1)
declare void @useI1p(i1*)
declare void @unknown()
define i1 @readI1p(i1* %p) {
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: read)
; 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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c_nr
; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4:[0-9]+]]
; TUNIT-NEXT: ret i1 true
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c_nr
; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR5:[0-9]+]]
; CGSCC-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 {
; TUNIT: Function Attrs: norecurse
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c_nr
; TUNIT-SAME: () #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC: Function Attrs: norecurse
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c_nr
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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 {
; TUNIT: Function Attrs: norecurse
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c_nr
; TUNIT-SAME: () #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L4]]
;
; CGSCC: Function Attrs: norecurse
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c_nr
; CGSCC-SAME: () #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1_nr
; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
; TUNIT-NEXT: ret i1 [[ARG]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1_nr
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]]
; CGSCC-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 {
; TUNIT: Function Attrs: norecurse
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3_nr
; TUNIT-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC: Function Attrs: norecurse
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3_nr
; CGSCC-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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 {
; TUNIT: Function Attrs: norecurse
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4_nr
; TUNIT-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC: Function Attrs: norecurse
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4_nr
; CGSCC-SAME: (i1 [[ARG:%.*]]) #[[ATTR2]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_1_nr
; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: ret i1 [[ARG]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_1_nr
; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_1b_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_1b_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_2_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_2_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_2b_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_2b_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_3_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5:[0-9]+]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_3_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_4_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_4_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_5_nr
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_5_nr
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]]
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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 {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_5c_nr
; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_5c_nr
; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]]
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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() {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c
; TUNIT-SAME: () #[[ATTR3]] {
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR4]]
; TUNIT-NEXT: ret i1 true
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c
; CGSCC-SAME: () #[[ATTR3]] {
; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR5]]
; CGSCC-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() {
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3c() {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3c() {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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() {
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4c() {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L4]]
;
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4c() {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1
; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
; TUNIT-NEXT: ret i1 [[ARG]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]]
; CGSCC-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) {
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_3
; TUNIT-SAME: (i1 [[ARG:%.*]]) {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_3
; CGSCC-SAME: (i1 [[ARG:%.*]]) {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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) {
; TUNIT-LABEL: define {{[^@]+}}@keep_assume_4
; TUNIT-SAME: (i1 [[ARG:%.*]]) {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4
; CGSCC-SAME: (i1 [[ARG:%.*]]) {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: call void @useI1p(i1* noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_1
; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: ret i1 [[ARG]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_1
; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_1b
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_1b
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_2
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: ret i1 [[L]]
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_2
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_2b
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: ret void
;
; CGSCC: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_2b
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_3
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_3
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4:[0-9]+]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_4
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR4]]
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_4
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR5]]
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_5
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; TUNIT-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_5
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 [[COND:%.*]]) #[[ATTR4]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 [[ARG]], i1* [[STACK]], align 1
; CGSCC-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]]
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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) {
; TUNIT: Function Attrs: nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; TUNIT-LABEL: define {{[^@]+}}@assume_5c
; TUNIT-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] {
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR4]]
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; TUNIT: t:
; TUNIT-NEXT: store i1 true, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M:%.*]]
; TUNIT: f:
; TUNIT-NEXT: store i1 false, i1* [[STACK]], align 1
; TUNIT-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR4]]
; TUNIT-NEXT: br label [[M]]
; TUNIT: m:
; TUNIT-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR4]]
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; TUNIT-NEXT: ret i1 [[R]]
;
; CGSCC: Function Attrs: nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@assume_5c
; CGSCC-SAME: (i1 [[COND:%.*]]) #[[ATTR4]] {
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L1:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR5]]
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
; CGSCC: t:
; CGSCC-NEXT: store i1 true, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L2:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M:%.*]]
; CGSCC: f:
; CGSCC-NEXT: store i1 false, i1* [[STACK]], align 1
; CGSCC-NEXT: [[L3:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR5]]
; CGSCC-NEXT: br label [[M]]
; CGSCC: m:
; CGSCC-NEXT: [[L4:%.*]] = load i1, i1* [[STACK]], align 1
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR5]]
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(i1* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR5]]
; CGSCC-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
}
;.
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; TUNIT: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; TUNIT: attributes #[[ATTR2]] = { norecurse }
; TUNIT: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; TUNIT: attributes #[[ATTR4]] = { willreturn }
; TUNIT: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn }
;.
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; CGSCC: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR2]] = { norecurse }
; CGSCC: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; CGSCC: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
; CGSCC: attributes #[[ATTR5]] = { willreturn }
;.