1391 lines
54 KiB
LLVM
1391 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-annotate-decl-cs -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
|
||
|
|
||
|
@Gstatic_int1 = internal global i32 zeroinitializer, align 4
|
||
|
@Gstatic_int2 = internal global i32 zeroinitializer, align 4
|
||
|
|
||
|
declare void @llvm.assume(i1)
|
||
|
declare void @useI1p(ptr)
|
||
|
declare void @unknown()
|
||
|
|
||
|
;.
|
||
|
; CHECK: @[[GSTATIC_INT1:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0, align 4
|
||
|
; CHECK: @[[GSTATIC_INT2:[a-zA-Z0-9_$"\\.-]+]] = internal global i32 0, align 4
|
||
|
;.
|
||
|
define i1 @readI1p(ptr %p) {
|
||
|
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
|
||
|
; CHECK-LABEL: define {{[^@]+}}@readI1p
|
||
|
; CHECK-SAME: (ptr nocapture nofree noundef nonnull readonly dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
|
||
|
; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[P]], align 1
|
||
|
; CHECK-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%l = load i1, ptr %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, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
|
||
|
; CHECK-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define i1 @drop_assume_1c_nr() norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c_nr
|
||
|
; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7:[0-9]+]]
|
||
|
; TUNIT-NEXT: ret i1 true
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c_nr
|
||
|
; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8:[0-9]+]]
|
||
|
; CGSCC-NEXT: ret i1 true
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l = load i1, ptr %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, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
|
||
|
; CHECK-NEXT: call void @unknown()
|
||
|
; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: ret i1 [[L2]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
call void @unknown()
|
||
|
%l2 = load i1, ptr %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, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr 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, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
call void @useI1p(ptr %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, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; TUNIT-NEXT: ret i1 true
|
||
|
;
|
||
|
; 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, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 true
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l4 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l4)
|
||
|
call void @useI1p(ptr 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]], ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
|
||
|
; CHECK-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define i1 @drop_assume_1_nr(i1 %arg) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1_nr
|
||
|
; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: ret i1 [[ARG]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1_nr
|
||
|
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4:[0-9]+]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: ret i1 [[ARG]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %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]], ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
|
||
|
; CHECK-NEXT: call void @unknown()
|
||
|
; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: ret i1 [[L2]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
call void @unknown()
|
||
|
%l2 = load i1, ptr %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]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr 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]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
call void @useI1p(ptr %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 returned [[ARG:%.*]]) #[[ATTR2]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; TUNIT-NEXT: ret i1 [[ARG]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: norecurse
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@keep_assume_4_nr
|
||
|
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR2]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[ARG]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
call void @useI1p(ptr nocapture %stack)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define i1 @assume_1_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_1_nr
|
||
|
; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
|
||
|
; 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: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_1_nr
|
||
|
; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
|
||
|
; 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, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define void @assume_1b_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CHECK-LABEL: define {{[^@]+}}@assume_1b_nr
|
||
|
; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4:[0-9]+]] {
|
||
|
; 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, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define i1 @assume_2_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_2_nr
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_2_nr
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define void @assume_2b_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CHECK-LABEL: define {{[^@]+}}@assume_2b_nr
|
||
|
; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; 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: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define i1 @assume_3_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_3_nr
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8:[0-9]+]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_3_nr
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9:[0-9]+]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i1 @assume_4_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_4_nr
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_4_nr
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i1 @assume_5_nr(i1 %arg, i1 %cond) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_5_nr
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9:[0-9]+]]
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_5_nr
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10:[0-9]+]]
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
%l2 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l2)
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
%l3 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l3)
|
||
|
br label %m
|
||
|
m:
|
||
|
%l4 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l4)
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i1 @assume_5c_nr(i1 %cond) norecurse {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_5c_nr
|
||
|
; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_5c_nr
|
||
|
; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
%l2 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l2)
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
%l3 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l3)
|
||
|
br label %m
|
||
|
m:
|
||
|
%l4 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l4)
|
||
|
%r = call i1 @readI1p(ptr %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, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
|
||
|
; CHECK-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define i1 @drop_assume_1c() {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1c
|
||
|
; TUNIT-SAME: () #[[ATTR3]] {
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: ret i1 true
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1c
|
||
|
; CGSCC-SAME: () #[[ATTR3]] {
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: ret i1 true
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l = load i1, ptr %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, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
|
||
|
; CHECK-NEXT: call void @unknown()
|
||
|
; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: ret i1 [[L2]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
call void @unknown()
|
||
|
%l2 = load i1, ptr %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, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr 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, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
call void @useI1p(ptr %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, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr 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, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[L4]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l4 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l4)
|
||
|
call void @useI1p(ptr 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]], ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L]])
|
||
|
; CHECK-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define i1 @drop_assume_1(i1 %arg) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@drop_assume_1
|
||
|
; TUNIT-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: ret i1 [[ARG]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@drop_assume_1
|
||
|
; CGSCC-SAME: (i1 returned [[ARG:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: ret i1 [[ARG]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %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]], ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CHECK-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[L1]])
|
||
|
; CHECK-NEXT: call void @unknown()
|
||
|
; CHECK-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: ret i1 [[L2]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
call void @useI1p(ptr %stack)
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
call void @unknown()
|
||
|
%l2 = load i1, ptr %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]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr 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]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
call void @useI1p(ptr %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]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: call void @useI1p(ptr 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]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: call void @useI1p(ptr noalias nocapture noundef nonnull dereferenceable(1) [[STACK]])
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
call void @useI1p(ptr nocapture %stack)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define i1 @assume_1(i1 %arg, i1 %cond) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_1
|
||
|
; TUNIT-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR7]]
|
||
|
; 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: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_1
|
||
|
; CGSCC-SAME: (i1 returned [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[ARG]]) #[[ATTR8]]
|
||
|
; 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, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define void @assume_1b(i1 %arg, i1 %cond) {
|
||
|
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CHECK-LABEL: define {{[^@]+}}@assume_1b
|
||
|
; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[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, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define i1 @assume_2(i1 %arg, i1 %cond) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_2
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_2
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: ret i1 [[L]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret i1 %l
|
||
|
}
|
||
|
|
||
|
define void @assume_2b(i1 %arg, i1 %cond) {
|
||
|
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CHECK-LABEL: define {{[^@]+}}@assume_2b
|
||
|
; CHECK-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; CHECK-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; 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: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define i1 @assume_3(i1 %arg, i1 %cond) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_3
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_3
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5:[0-9]+]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i1 @assume_4(i1 %arg, i1 %cond) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_4
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_4
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR9]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
br label %m
|
||
|
m:
|
||
|
%l = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l)
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i1 @assume_5(i1 %arg, i1 %cond) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_5
|
||
|
; TUNIT-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_5
|
||
|
; CGSCC-SAME: (i1 [[ARG:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR5]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 [[ARG]], ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 %arg, ptr %stack
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
%l2 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l2)
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
%l3 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l3)
|
||
|
br label %m
|
||
|
m:
|
||
|
%l4 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l4)
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i1 @assume_5c(i1 %cond) {
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_5c
|
||
|
; TUNIT-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR4]] {
|
||
|
; TUNIT-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; TUNIT: t:
|
||
|
; TUNIT-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M:%.*]]
|
||
|
; TUNIT: f:
|
||
|
; TUNIT-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: br label [[M]]
|
||
|
; TUNIT: m:
|
||
|
; TUNIT-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR9]]
|
||
|
; TUNIT-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR8]]
|
||
|
; TUNIT-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_5c
|
||
|
; CGSCC-SAME: (i1 noundef [[COND:%.*]]) #[[ATTR5]] {
|
||
|
; CGSCC-NEXT: [[STACK:%.*]] = alloca i1, align 1
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L1:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L1]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]]
|
||
|
; CGSCC: t:
|
||
|
; CGSCC-NEXT: store i1 true, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L2:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L2]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M:%.*]]
|
||
|
; CGSCC: f:
|
||
|
; CGSCC-NEXT: store i1 false, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: [[L3:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L3]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: br label [[M]]
|
||
|
; CGSCC: m:
|
||
|
; CGSCC-NEXT: [[L4:%.*]] = load i1, ptr [[STACK]], align 1
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[L4]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: [[R:%.*]] = call i1 @readI1p(ptr noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[STACK]]) #[[ATTR10]]
|
||
|
; CGSCC-NEXT: ret i1 [[R]]
|
||
|
;
|
||
|
%stack = alloca i1
|
||
|
store i1 true, ptr %stack
|
||
|
%l1 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l1)
|
||
|
br i1 %cond, label %t, label %f
|
||
|
t:
|
||
|
store i1 true, ptr %stack
|
||
|
%l2 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l2)
|
||
|
br label %m
|
||
|
f:
|
||
|
store i1 false, ptr %stack
|
||
|
%l3 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l3)
|
||
|
br label %m
|
||
|
m:
|
||
|
%l4 = load i1, ptr %stack
|
||
|
call void @llvm.assume(i1 %l4)
|
||
|
%r = call i1 @readI1p(ptr %stack)
|
||
|
ret i1 %r
|
||
|
}
|
||
|
|
||
|
define i32 @assume_read_global_good() {
|
||
|
;
|
||
|
;
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_good
|
||
|
; TUNIT-SAME: () #[[ATTR5:[0-9]+]] {
|
||
|
; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 4
|
||
|
; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 4
|
||
|
; TUNIT-NEXT: store i32 17, ptr @Gstatic_int1, align 4
|
||
|
; TUNIT-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 4
|
||
|
; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]
|
||
|
; TUNIT-NEXT: ret i32 [[ADD]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_good
|
||
|
; CGSCC-SAME: () #[[ATTR6:[0-9]+]] {
|
||
|
; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int1, align 4
|
||
|
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int1, align 4
|
||
|
; CGSCC-NEXT: store i32 17, ptr @Gstatic_int1, align 4
|
||
|
; CGSCC-NEXT: [[LGS3:%.*]] = load i32, ptr @Gstatic_int1, align 4
|
||
|
; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[LGS2]], [[LGS3]]
|
||
|
; CGSCC-NEXT: ret i32 [[ADD]]
|
||
|
;
|
||
|
%lgs1 = load i32, ptr @Gstatic_int1
|
||
|
%c = icmp eq i32 %lgs1, 42
|
||
|
call void @llvm.assume(i1 %c)
|
||
|
%lgs2 = load i32, ptr @Gstatic_int1
|
||
|
store i32 13, ptr @Gstatic_int1, align 4
|
||
|
store i32 17, ptr @Gstatic_int1, align 4
|
||
|
%lgs3 = load i32, ptr @Gstatic_int1
|
||
|
%add = add i32 %lgs2, %lgs3
|
||
|
ret i32 %add
|
||
|
}
|
||
|
|
||
|
; TODO: Technically we could still utilize the assumption if we employ AA.
|
||
|
define i32 @assume_read_global_bad(ptr %p) {
|
||
|
;
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_read_global_bad
|
||
|
; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR5]] {
|
||
|
; TUNIT-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int2, align 4
|
||
|
; TUNIT-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
|
||
|
; TUNIT-NEXT: store i32 13, ptr [[P]], align 4
|
||
|
; TUNIT-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR7]]
|
||
|
; TUNIT-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 4
|
||
|
; TUNIT-NEXT: store i32 17, ptr @Gstatic_int2, align 4
|
||
|
; TUNIT-NEXT: ret i32 [[LGS2]]
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_read_global_bad
|
||
|
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR6]] {
|
||
|
; CGSCC-NEXT: [[LGS1:%.*]] = load i32, ptr @Gstatic_int2, align 4
|
||
|
; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[LGS1]], 42
|
||
|
; CGSCC-NEXT: store i32 13, ptr [[P]], align 4
|
||
|
; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR8]]
|
||
|
; CGSCC-NEXT: [[LGS2:%.*]] = load i32, ptr @Gstatic_int2, align 4
|
||
|
; CGSCC-NEXT: store i32 17, ptr @Gstatic_int2, align 4
|
||
|
; CGSCC-NEXT: ret i32 [[LGS2]]
|
||
|
;
|
||
|
%lgs1 = load i32, ptr @Gstatic_int2
|
||
|
%c = icmp eq i32 %lgs1, 42
|
||
|
store i32 13, ptr %p, align 4
|
||
|
call void @llvm.assume(i1 %c)
|
||
|
%lgs2 = load i32, ptr @Gstatic_int2
|
||
|
store i32 17, ptr @Gstatic_int2, align 4
|
||
|
ret i32 %lgs2
|
||
|
}
|
||
|
|
||
|
define void @assume_write_globals() {
|
||
|
;
|
||
|
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
||
|
; TUNIT-LABEL: define {{[^@]+}}@assume_write_globals
|
||
|
; TUNIT-SAME: () #[[ATTR6:[0-9]+]] {
|
||
|
; TUNIT-NEXT: store i32 42, ptr @Gstatic_int1, align 4
|
||
|
; TUNIT-NEXT: store i32 42, ptr @Gstatic_int2, align 4
|
||
|
; TUNIT-NEXT: ret void
|
||
|
;
|
||
|
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
|
||
|
; CGSCC-LABEL: define {{[^@]+}}@assume_write_globals
|
||
|
; CGSCC-SAME: () #[[ATTR7:[0-9]+]] {
|
||
|
; CGSCC-NEXT: store i32 42, ptr @Gstatic_int1, align 4
|
||
|
; CGSCC-NEXT: store i32 42, ptr @Gstatic_int2, align 4
|
||
|
; CGSCC-NEXT: ret void
|
||
|
;
|
||
|
store i32 42, ptr @Gstatic_int1, align 4
|
||
|
store i32 42, ptr @Gstatic_int2, align 4
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
;.
|
||
|
; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
|
||
|
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
|
||
|
; TUNIT: attributes #[[ATTR2]] = { norecurse }
|
||
|
; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) }
|
||
|
; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
|
||
|
; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }
|
||
|
; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
|
||
|
; TUNIT: attributes #[[ATTR7]] = { nofree willreturn memory(write) }
|
||
|
; TUNIT: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn memory(read) }
|
||
|
; TUNIT: attributes #[[ATTR9]] = { nofree willreturn }
|
||
|
;.
|
||
|
; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
|
||
|
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
|
||
|
; CGSCC: attributes #[[ATTR2]] = { norecurse }
|
||
|
; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: write) }
|
||
|
; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
|
||
|
; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
|
||
|
; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn }
|
||
|
; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
|
||
|
; CGSCC: attributes #[[ATTR8]] = { nofree willreturn memory(write) }
|
||
|
; CGSCC: attributes #[[ATTR9]] = { nofree willreturn memory(read) }
|
||
|
; CGSCC: attributes #[[ATTR10]] = { nofree willreturn }
|
||
|
;.
|