mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[Local] Treat calls that may not return as being alive.
With the addition of the `willreturn` attribute, functions that may not return (e.g. due to an infinite loop) are well defined, if they are not marked as `willreturn`. This patch updates `wouldInstructionBeTriviallyDead` to not consider calls that may not return as dead. This patch still provides an escape hatch for intrinsics, which are still assumed as willreturn unconditionally. It will be removed once all intrinsics definitions have been reviewed and updated. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D94106
This commit is contained in:
parent
dbeacbd88e
commit
283961f4c8
@ -1756,6 +1756,10 @@ public:
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
|
||||
}
|
||||
|
||||
/// Returns true if this function is guaranteed to return.
|
||||
bool willReturn() const { return hasFnAttr(Attribute::WillReturn); }
|
||||
|
||||
void setOnlyReadsMemory() {
|
||||
addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
|
||||
}
|
||||
|
@ -420,6 +420,14 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto *CB = dyn_cast<CallBase>(I)) {
|
||||
// Treat calls that may not return as alive.
|
||||
// TODO: Remove the intrinsic escape hatch once all intrinsics set
|
||||
// willreturn properly.
|
||||
if (!CB->willReturn() && !isa<IntrinsicInst>(I))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!I->mayHaveSideEffects())
|
||||
return true;
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
; they're carrying unknown operand bundles since the presence of
|
||||
; unknown operand bundles implies arbitrary memory effects.
|
||||
|
||||
declare void @readonly_function() readonly nounwind
|
||||
declare void @readnone_function() readnone nounwind
|
||||
declare void @readonly_function() readonly nounwind willreturn
|
||||
declare void @readnone_function() readnone nounwind willreturn
|
||||
|
||||
define i32 @test0(i32* %x) {
|
||||
; CHECK-LABEL: @test0(
|
||||
|
@ -17,16 +17,32 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
@a = internal global %struct.Foo { i32 1, i64 2 }, align 8
|
||||
|
||||
define void @run() {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@run
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR0:#.*]] {
|
||||
; NOT_CGSCC_NPM-NEXT: entry:
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; IS________OPM-LABEL: define {{[^@]+}}@run
|
||||
; IS________OPM-SAME: () [[ATTR0:#.*]] {
|
||||
; IS________OPM-NEXT: entry:
|
||||
; IS________OPM-NEXT: [[TMP0:%.*]] = call i64 @CaptureAStruct(%struct.Foo* nocapture nofree noundef nonnull readonly align 8 dereferenceable(16) @a) [[ATTR0]]
|
||||
; IS________OPM-NEXT: unreachable
|
||||
;
|
||||
; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@run
|
||||
; IS__TUNIT_NPM-SAME: () [[ATTR0:#.*]] {
|
||||
; IS__TUNIT_NPM-NEXT: entry:
|
||||
; IS__TUNIT_NPM-NEXT: [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
|
||||
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
|
||||
; IS__TUNIT_NPM-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
|
||||
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
|
||||
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = call i64 @CaptureAStruct(i32 [[TMP0]], i64 [[TMP1]]) [[ATTR0]]
|
||||
; IS__TUNIT_NPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readonly willreturn
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@run
|
||||
; IS__CGSCC____-SAME: () [[ATTR0:#.*]] {
|
||||
; IS__CGSCC____-NEXT: entry:
|
||||
; IS__CGSCC____-NEXT: [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
|
||||
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
|
||||
; IS__CGSCC____-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
|
||||
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
|
||||
; IS__CGSCC____-NEXT: unreachable
|
||||
;
|
||||
entry:
|
||||
@ -86,6 +102,37 @@ define internal i64 @CaptureAStruct(%struct.Foo* byval(%struct.Foo) %a) {
|
||||
; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
|
||||
; IS__CGSCC_OPM-NEXT: br label [[LOOP]]
|
||||
;
|
||||
; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; IS________OPM-LABEL: define {{[^@]+}}@CaptureAStruct
|
||||
; IS________OPM-SAME: (%struct.Foo* noalias nofree noundef nonnull byval(%struct.Foo) align 8 dereferenceable(16) [[A:%.*]]) [[ATTR0]] {
|
||||
; IS________OPM-NEXT: entry:
|
||||
; IS________OPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
||||
; IS________OPM-NEXT: br label [[LOOP:%.*]]
|
||||
; IS________OPM: loop:
|
||||
; IS________OPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
|
||||
; IS________OPM-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ [[A]], [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
|
||||
; IS________OPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
||||
; IS________OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
|
||||
; IS________OPM-NEXT: br label [[LOOP]]
|
||||
;
|
||||
; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@CaptureAStruct
|
||||
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR0]] {
|
||||
; IS__TUNIT_NPM-NEXT: entry:
|
||||
; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
|
||||
; IS__TUNIT_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo* [[A_PRIV]] to i32*
|
||||
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]], align 4
|
||||
; IS__TUNIT_NPM-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1
|
||||
; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]], align 8
|
||||
; IS__TUNIT_NPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
||||
; IS__TUNIT_NPM-NEXT: br label [[LOOP:%.*]]
|
||||
; IS__TUNIT_NPM: loop:
|
||||
; IS__TUNIT_NPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
|
||||
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]], [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ]
|
||||
; IS__TUNIT_NPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
||||
; IS__TUNIT_NPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i64 0
|
||||
; IS__TUNIT_NPM-NEXT: br label [[LOOP]]
|
||||
;
|
||||
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct
|
||||
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR2:#.*]] {
|
||||
|
@ -102,30 +102,34 @@ define i32* @test5_2() {
|
||||
; TEST 6
|
||||
; SCC
|
||||
define i32* @test6_1() #0 {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
; NOT_CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
|
||||
; NOT_CGSCC_OPM-SAME: () [[ATTR1:#.*]] {
|
||||
; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_2() [[ATTR11:#.*]]
|
||||
; NOT_CGSCC_OPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
|
||||
; IS__CGSCC_NPM-NEXT: unreachable
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
|
||||
; IS__CGSCC_OPM-SAME: () [[ATTR1:#.*]] {
|
||||
; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_2() [[ATTR12:#.*]]
|
||||
; IS__CGSCC_OPM-NEXT: unreachable
|
||||
;
|
||||
%ret = tail call i32* @test6_2()
|
||||
ret i32* %ret
|
||||
}
|
||||
|
||||
define i32* @test6_2() #0 {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR1]] {
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
; NOT_CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
|
||||
; NOT_CGSCC_OPM-SAME: () [[ATTR1]] {
|
||||
; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_1() [[ATTR11]]
|
||||
; NOT_CGSCC_OPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR1]] {
|
||||
; IS__CGSCC_NPM-NEXT: unreachable
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
|
||||
; IS__CGSCC_OPM-SAME: () [[ATTR1]] {
|
||||
; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_1() [[ATTR12]]
|
||||
; IS__CGSCC_OPM-NEXT: unreachable
|
||||
;
|
||||
%ret = tail call i32* @test6_1()
|
||||
ret i32* %ret
|
||||
@ -967,7 +971,7 @@ define i32 @musttail_caller_1(i32* %p) {
|
||||
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
|
||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
|
||||
; IS__CGSCC_OPM: mt:
|
||||
; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR12:#.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR13:#.*]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i32 [[V]]
|
||||
; IS__CGSCC_OPM: exit:
|
||||
; IS__CGSCC_OPM-NEXT: ret i32 0
|
||||
@ -978,7 +982,7 @@ define i32 @musttail_caller_1(i32* %p) {
|
||||
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
|
||||
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
|
||||
; IS__CGSCC_NPM: mt:
|
||||
; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR11:#.*]]
|
||||
; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) [[ATTR12:#.*]]
|
||||
; IS__CGSCC_NPM-NEXT: ret i32 [[V]]
|
||||
; IS__CGSCC_NPM: exit:
|
||||
; IS__CGSCC_NPM-NEXT: ret i32 0
|
||||
|
@ -849,6 +849,8 @@ define void @ptr_uses(i8* %ptr, i8* %wptr) {
|
||||
; CHECK: Function Attrs: nounwind
|
||||
; CHECK-LABEL: define {{[^@]+}}@ptr_uses
|
||||
; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) [[ATTR13:#.*]] {
|
||||
; CHECK-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]]) [[ATTR4]]
|
||||
; CHECK-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]]) [[ATTR4]]
|
||||
; CHECK-NEXT: store i8 0, i8* [[WPTR]], align 1
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
|
@ -728,7 +728,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r
|
||||
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3
|
||||
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) [[ATTR8]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) [[ATTR6]]
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) [[ATTR8]]
|
||||
; CHECK-NEXT: ret i32* [[CALL]]
|
||||
;
|
||||
entry:
|
||||
|
@ -149,11 +149,13 @@ define i8* @test4_helper() {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
|
||||
; NOT_CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4()
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
|
||||
; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4()
|
||||
; IS__CGSCC_NPM-NEXT: unreachable
|
||||
;
|
||||
%ret = call i8* @test4()
|
||||
@ -164,11 +166,13 @@ define i8* @test4() {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR2]] {
|
||||
; NOT_CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4_helper()
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR2]] {
|
||||
; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = call i8* @test4_helper()
|
||||
; IS__CGSCC_NPM-NEXT: unreachable
|
||||
;
|
||||
%ret = call i8* @test4_helper()
|
||||
|
@ -34,29 +34,21 @@ define i32 @self_rec() {
|
||||
}
|
||||
|
||||
define i32 @indirect_rec() {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
|
||||
; IS__CGSCC_NPM-NEXT: unreachable
|
||||
; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@indirect_rec
|
||||
; CHECK-SAME: () [[ATTR2:#.*]] {
|
||||
; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec2() [[ATTR2]]
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
%a = call i32 @indirect_rec2()
|
||||
ret i32 %a
|
||||
}
|
||||
define i32 @indirect_rec2() {
|
||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2
|
||||
; NOT_CGSCC_NPM-SAME: () [[ATTR2]] {
|
||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR1]] {
|
||||
; IS__CGSCC_NPM-NEXT: unreachable
|
||||
; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@indirect_rec2
|
||||
; CHECK-SAME: () [[ATTR2]] {
|
||||
; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec() [[ATTR2]]
|
||||
; CHECK-NEXT: unreachable
|
||||
;
|
||||
%a = call i32 @indirect_rec()
|
||||
ret i32 %a
|
||||
@ -65,7 +57,7 @@ define i32 @indirect_rec2() {
|
||||
define i32 @extern() {
|
||||
; CHECK: Function Attrs: nosync readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@extern
|
||||
; CHECK-SAME: () [[ATTR2:#.*]] {
|
||||
; CHECK-SAME: () [[ATTR3:#.*]] {
|
||||
; CHECK-NEXT: [[A:%.*]] = call i32 @k()
|
||||
; CHECK-NEXT: ret i32 [[A]]
|
||||
;
|
||||
@ -78,17 +70,11 @@ define i32 @extern() {
|
||||
declare i32 @k() readnone
|
||||
|
||||
define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
|
||||
; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
|
||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@intrinsic
|
||||
; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR5:#.*]] {
|
||||
; NOT_CGSCC_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR10:#.*]]
|
||||
; NOT_CGSCC_NPM-NEXT: ret void
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@intrinsic
|
||||
; IS__CGSCC_NPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR4:#.*]] {
|
||||
; IS__CGSCC_NPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR7:#.*]]
|
||||
; IS__CGSCC_NPM-NEXT: ret void
|
||||
; CHECK: Function Attrs: argmemonly nofree nosync nounwind willreturn
|
||||
; CHECK-LABEL: define {{[^@]+}}@intrinsic
|
||||
; CHECK-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR5:#.*]] {
|
||||
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR10:#.*]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false)
|
||||
ret void
|
||||
@ -107,7 +93,7 @@ define internal i32 @called_by_norecurse() {
|
||||
;
|
||||
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse
|
||||
; IS__CGSCC____-SAME: () [[ATTR5:#.*]] {
|
||||
; IS__CGSCC____-SAME: () [[ATTR6:#.*]] {
|
||||
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @k()
|
||||
; IS__CGSCC____-NEXT: ret i32 undef
|
||||
;
|
||||
@ -123,7 +109,7 @@ define void @m() norecurse {
|
||||
;
|
||||
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@m
|
||||
; IS__CGSCC____-SAME: () [[ATTR5]] {
|
||||
; IS__CGSCC____-SAME: () [[ATTR6]] {
|
||||
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
|
||||
; IS__CGSCC____-NEXT: ret void
|
||||
;
|
||||
@ -134,7 +120,7 @@ define void @m() norecurse {
|
||||
define internal i32 @called_by_norecurse_indirectly() {
|
||||
; CHECK: Function Attrs: nosync readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly
|
||||
; CHECK-SAME: () [[ATTR2]] {
|
||||
; CHECK-SAME: () [[ATTR3]] {
|
||||
; CHECK-NEXT: [[A:%.*]] = call i32 @k()
|
||||
; CHECK-NEXT: ret i32 [[A]]
|
||||
;
|
||||
@ -150,7 +136,7 @@ define internal i32 @o() {
|
||||
;
|
||||
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@o
|
||||
; IS__CGSCC____-SAME: () [[ATTR5]] {
|
||||
; IS__CGSCC____-SAME: () [[ATTR6]] {
|
||||
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
|
||||
; IS__CGSCC____-NEXT: ret i32 [[A]]
|
||||
;
|
||||
@ -166,7 +152,7 @@ define i32 @p() norecurse {
|
||||
;
|
||||
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@p
|
||||
; IS__CGSCC____-SAME: () [[ATTR5]] {
|
||||
; IS__CGSCC____-SAME: () [[ATTR6]] {
|
||||
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @o()
|
||||
; IS__CGSCC____-NEXT: ret i32 [[A]]
|
||||
;
|
||||
@ -175,48 +161,20 @@ define i32 @p() norecurse {
|
||||
}
|
||||
|
||||
define void @f(i32 %x) {
|
||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@f
|
||||
; IS__TUNIT____-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
|
||||
; IS__TUNIT____-NEXT: entry:
|
||||
; IS__TUNIT____-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
||||
; IS__TUNIT____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
||||
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
||||
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||
; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; IS__TUNIT____: if.then:
|
||||
; IS__TUNIT____-NEXT: call void @g() [[ATTR8:#.*]]
|
||||
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
||||
; IS__TUNIT____: if.end:
|
||||
; IS__TUNIT____-NEXT: ret void
|
||||
;
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
|
||||
; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
|
||||
; IS__CGSCC_OPM-NEXT: entry:
|
||||
; IS__CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
||||
; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
||||
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
||||
; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||
; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; IS__CGSCC_OPM: if.then:
|
||||
; IS__CGSCC_OPM-NEXT: br label [[IF_END]]
|
||||
; IS__CGSCC_OPM: if.end:
|
||||
; IS__CGSCC_OPM-NEXT: ret void
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
|
||||
; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) [[ATTR0:#.*]] {
|
||||
; IS__CGSCC_NPM-NEXT: entry:
|
||||
; IS__CGSCC_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
||||
; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
||||
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
||||
; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||
; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; IS__CGSCC_NPM: if.then:
|
||||
; IS__CGSCC_NPM-NEXT: br label [[IF_END]]
|
||||
; IS__CGSCC_NPM: if.end:
|
||||
; IS__CGSCC_NPM-NEXT: ret void
|
||||
; CHECK: Function Attrs: nofree nosync nounwind readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@f
|
||||
; CHECK-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
; CHECK-NEXT: call void @g() [[ATTR8:#.*]]
|
||||
; CHECK-NEXT: br label [[IF_END]]
|
||||
; CHECK: if.end:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%x.addr = alloca i32, align 4
|
||||
@ -234,24 +192,12 @@ if.end:
|
||||
}
|
||||
|
||||
define void @g() norecurse {
|
||||
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone
|
||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@g
|
||||
; IS__TUNIT____-SAME: () [[ATTR8]] {
|
||||
; IS__TUNIT____-NEXT: entry:
|
||||
; IS__TUNIT____-NEXT: ret void
|
||||
;
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g
|
||||
; IS__CGSCC_OPM-SAME: () [[ATTR8:#.*]] {
|
||||
; IS__CGSCC_OPM-NEXT: entry:
|
||||
; IS__CGSCC_OPM-NEXT: call void @f(i32 noundef 0) [[ATTR7]]
|
||||
; IS__CGSCC_OPM-NEXT: ret void
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g
|
||||
; IS__CGSCC_NPM-SAME: () [[ATTR0]] {
|
||||
; IS__CGSCC_NPM-NEXT: entry:
|
||||
; IS__CGSCC_NPM-NEXT: ret void
|
||||
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@g
|
||||
; CHECK-SAME: () [[ATTR8]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @f(i32 noundef 0) [[ATTR7]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
call void @f(i32 0)
|
||||
@ -279,7 +225,7 @@ define i32 @eval_func1(i32 (i32)* , i32) local_unnamed_addr {
|
||||
define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_valid{
|
||||
; CHECK: Function Attrs: null_pointer_is_valid
|
||||
; CHECK-LABEL: define {{[^@]+}}@eval_func2
|
||||
; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr [[ATTR6:#.*]] {
|
||||
; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr [[ATTR9:#.*]] {
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
|
||||
; CHECK-NEXT: ret i32 [[TMP3]]
|
||||
;
|
||||
|
@ -600,7 +600,7 @@ define void @f1(i32){
|
||||
;
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
|
||||
; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) {
|
||||
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1(), [[RNG3:!range !.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1() [[ATTR4:#.*]], [[RNG3:!range !.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
|
||||
; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
|
||||
; IS__CGSCC_OPM: 4:
|
||||
@ -698,7 +698,7 @@ define dso_local i32 @test4-g1(i32 %u) {
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g1
|
||||
; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2:#.*]] {
|
||||
; IS__CGSCC_OPM-NEXT: entry:
|
||||
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) [[ATTR4:#.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]]) [[ATTR5:#.*]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]]
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
@ -790,7 +790,7 @@ define dso_local i32 @test4-g2(i32 %u) {
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g2
|
||||
; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2]] {
|
||||
; IS__CGSCC_OPM-NEXT: entry:
|
||||
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i32 [[CALL]]
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
@ -1154,10 +1154,10 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dp
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fcmp_caller
|
||||
; IS__CGSCC_OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]]) [[ATTR2]] {
|
||||
; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
|
||||
; IS__CGSCC_OPM-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
|
||||
@ -1329,8 +1329,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2
|
||||
; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) [[ATTR2]] {
|
||||
; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR4]], [[RNG5:!range !.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR4]], [[RNG5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) [[ATTR5]], [[RNG5:!range !.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) [[ATTR5]], [[RNG5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
|
||||
; IS__CGSCC_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
|
||||
; IS__CGSCC_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
|
||||
@ -1488,10 +1488,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
|
||||
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
|
||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||
; IS__CGSCC_OPM: t:
|
||||
; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) [[ATTR4]], [[RNG4:!range !.*]]
|
||||
; IS__CGSCC_OPM-NEXT: [[RET1:%.*]] = call i32 @func(i1 noundef [[C]]) [[ATTR5]], [[RNG4:!range !.*]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i32 [[RET1]]
|
||||
; IS__CGSCC_OPM: f:
|
||||
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR4]], [[RNG4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 noundef false) [[ATTR5]], [[RNG4]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]]
|
||||
;
|
||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
@ -1575,10 +1575,10 @@ define i1 @check_divided_range(i32 %arg) {
|
||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_divided_range
|
||||
; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) [[ATTR2]] {
|
||||
; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[CSRET1:%.*]] = call i32 @less_than_65536(i32 noundef 0) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[CSRET2:%.*]] = call i32 @less_than_65536(i32 [[ARG]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET1]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32 [[CSRET2]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i1 [[RET]]
|
||||
;
|
||||
@ -1930,7 +1930,7 @@ define i1 @context(i8* %p) {
|
||||
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp slt i8 0, [[L]]
|
||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||
; IS__CGSCC_OPM: t:
|
||||
; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR4]]
|
||||
; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR5]]
|
||||
; IS__CGSCC_OPM-NEXT: ret i1 [[R]]
|
||||
; IS__CGSCC_OPM: f:
|
||||
; IS__CGSCC_OPM-NEXT: ret i1 false
|
||||
|
@ -204,7 +204,7 @@ define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
|
||||
; CHECK: Function Attrs: argmemonly nounwind readonly
|
||||
; CHECK-LABEL: define {{[^@]+}}@test11_2
|
||||
; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) [[ATTR6:#.*]] {
|
||||
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) [[ATTR2]]
|
||||
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]]) [[ATTR9:#.*]]
|
||||
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
||||
;
|
||||
%res = call <4 x i32> @test11_1(<4 x i32*> %ptrs)
|
||||
@ -323,7 +323,7 @@ define void @byval_not_readonly_2(i8* byval(i8) %written) readonly {
|
||||
define void @byval_not_readnone_1(i8* byval(i8) %written) readnone {
|
||||
; CHECK: Function Attrs: readnone
|
||||
; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1
|
||||
; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) [[ATTR9:#.*]] {
|
||||
; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1) [[WRITTEN:%.*]]) [[ATTR8:#.*]] {
|
||||
; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
@ -395,7 +395,9 @@ declare void @val_use(i8 %ptr) readonly nounwind
|
||||
define void @ptr_uses(i8* %ptr) {
|
||||
; CHECK: Function Attrs: nounwind readonly
|
||||
; CHECK-LABEL: define {{[^@]+}}@ptr_uses
|
||||
; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) [[ATTR10:#.*]] {
|
||||
; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) [[ATTR9:#.*]] {
|
||||
; CHECK-NEXT: [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8* readonly [[PTR]])
|
||||
; CHECK-NEXT: [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8* readonly [[CALL_PTR]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)
|
||||
|
@ -392,6 +392,6 @@ entry:
|
||||
ret i16 %cast
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #0 = { nounwind readnone willreturn }
|
||||
attributes #1 = { nounwind }
|
||||
|
||||
|
@ -21,7 +21,7 @@ entry:
|
||||
|
||||
if.end:
|
||||
%gep = getelementptr i8, i8* %d, i32 42
|
||||
%call = call i64 @foo(i8* %gep) nounwind readonly
|
||||
%call = call i64 @foo(i8* %gep) nounwind readonly willreturn
|
||||
%cmp2 = icmp ne i64 %call, 0
|
||||
call void @llvm.assume(i1 %cmp2)
|
||||
br label %exit
|
||||
@ -31,5 +31,5 @@ exit:
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
declare i64 @foo(i8*) nounwind readonly
|
||||
declare i64 @foo(i8*) nounwind readonly willreturn
|
||||
declare void @llvm.assume(i1 noundef) nounwind willreturn
|
||||
|
@ -77,4 +77,4 @@ declare i1 @llvm.coro.end(i8*, i1)
|
||||
|
||||
declare noalias i8* @malloc(i32)
|
||||
declare void @print(i32)
|
||||
declare void @free(i8*)
|
||||
declare void @free(i8*) willreturn
|
||||
|
@ -79,4 +79,4 @@ declare i1 @llvm.coro.end(i8*, i1)
|
||||
|
||||
declare noalias i8* @malloc(i32)
|
||||
declare void @print(i32)
|
||||
declare void @free(i8*)
|
||||
declare void @free(i8*) willreturn
|
||||
|
@ -415,7 +415,7 @@ lpad:
|
||||
}
|
||||
|
||||
declare i8* @malloc(i32)
|
||||
declare void @free(i8*)
|
||||
declare void @free(i8*) willreturn
|
||||
declare void @print(i32)
|
||||
declare void @foo()
|
||||
|
||||
|
@ -234,8 +234,8 @@ define i32 addrspace(1)* @test13_addrspacecast() {
|
||||
}
|
||||
|
||||
|
||||
declare noalias i8* @malloc(i32)
|
||||
declare noalias i8* @calloc(i32, i32)
|
||||
declare noalias i8* @malloc(i32) willreturn
|
||||
declare noalias i8* @calloc(i32, i32) willreturn
|
||||
|
||||
define void @test14(i32* %Q) {
|
||||
; CHECK-LABEL: @test14(
|
||||
|
@ -1,8 +1,8 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -basic-aa -dse -enable-dse-memoryssa=false -S | FileCheck %s
|
||||
|
||||
declare i8* @_Znwj(i32) local_unnamed_addr
|
||||
declare void @foo() readnone
|
||||
declare i8* @_Znwj(i32) willreturn
|
||||
declare void @foo() readnone willreturn
|
||||
|
||||
define void @test1(i8** %ptr) {
|
||||
; CHECK-LABEL: @test1(
|
||||
|
@ -267,8 +267,8 @@ define i32 addrspace(1)* @test13_addrspacecast() {
|
||||
ret i32 addrspace(1)* %P
|
||||
}
|
||||
|
||||
declare noalias i8* @malloc(i32)
|
||||
declare noalias i8* @calloc(i32, i32)
|
||||
declare noalias i8* @malloc(i32) willreturn
|
||||
declare noalias i8* @calloc(i32, i32) willreturn
|
||||
declare noalias i8* @aligned_alloc(i32, i32)
|
||||
declare void @free(i8*)
|
||||
|
||||
|
@ -31,6 +31,10 @@ entry:
|
||||
define void @caller_may_not_return() ssp {
|
||||
; CHECK-LABEL: @caller_may_not_return(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]]
|
||||
; CHECK: while.body.i:
|
||||
; CHECK-NEXT: br label [[WHILE_BODY_I]]
|
||||
; CHECK: readnone_may_not_return.exit:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -41,13 +45,13 @@ entry:
|
||||
|
||||
; @caller_willreturn is marked as willreturn, so all called functions also must
|
||||
; return. All calls are dead.
|
||||
define void @caller_willreturn() ssp willreturn {
|
||||
define void @caller_willreturn() ssp {
|
||||
; CHECK-LABEL: @caller_willreturn(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
call void @readnone_may_not_return()
|
||||
call void @readnone_may_not_return() willreturn
|
||||
call void @readnone_willreturn()
|
||||
ret void
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
declare double @acos(double)
|
||||
declare double @acos(double) willreturn
|
||||
|
||||
; Check that functions without any function attributes are simplified.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: opt < %s -instcombine -S | not grep call
|
||||
; rdar://6880732
|
||||
declare double @t1(i32) readonly
|
||||
declare double @t1(i32) readonly willreturn
|
||||
|
||||
define void @t2() nounwind {
|
||||
call double @t1(i32 42) ;; dead call even though callee is not nothrow.
|
||||
|
@ -2,13 +2,13 @@
|
||||
; RUN: opt -S -early-cse -earlycse-debug-hash < %s | FileCheck %s
|
||||
|
||||
declare float @nearbyintf(float) #0
|
||||
declare float @llvm.nearbyint.f32(float) #0
|
||||
declare float @llvm.nearbyint.f32(float)
|
||||
declare double @nearbyint(double) #0
|
||||
declare double @llvm.nearbyint.f64(double) #0
|
||||
declare double @llvm.nearbyint.f64(double)
|
||||
declare float @rintf(float) #0
|
||||
declare float @llvm.rint.f32(float) #0
|
||||
declare float @llvm.rint.f32(float)
|
||||
declare double @rint(double) #0
|
||||
declare double @llvm.rint.f64(double) #0
|
||||
declare double @llvm.rint.f64(double)
|
||||
|
||||
define float @constant_fold_rint_f32_01() #0 {
|
||||
; CHECK-LABEL: @constant_fold_rint_f32_01(
|
||||
@ -106,4 +106,4 @@ define double @constant_fold_rint_f64_06() #0 {
|
||||
ret double %x
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind readnone }
|
||||
attributes #0 = { nounwind readnone willreturn }
|
||||
|
@ -9,9 +9,9 @@
|
||||
|
||||
define internal void @func_1(i64* nocapture readnone %0) #0 {
|
||||
; CHECK-LABEL: @func_1(
|
||||
; CHECK-NEXT: unreachable
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
unreachable
|
||||
ret void
|
||||
}
|
||||
|
||||
define i16 @main(i16 %0, i16** nocapture readnone %1) #1 {
|
||||
@ -24,5 +24,5 @@ bb1:
|
||||
unreachable
|
||||
}
|
||||
|
||||
attributes #0 = { noinline norecurse nounwind readnone }
|
||||
attributes #0 = { noinline norecurse nounwind readnone willreturn }
|
||||
attributes #1 = { norecurse nounwind readnone }
|
||||
|
@ -25,6 +25,6 @@ define i1 @gep3() {
|
||||
; CHECK-NEXT: ret i1 false
|
||||
}
|
||||
|
||||
declare i8* @func1(i8* returned) nounwind readnone
|
||||
declare %gept* @func2(%gept* returned) nounwind readnone
|
||||
declare i8* @func1(i8* returned) nounwind readnone willreturn
|
||||
declare %gept* @func2(%gept* returned) nounwind readnone willreturn
|
||||
|
||||
|
@ -285,7 +285,7 @@ define void @test8() {
|
||||
ret void
|
||||
}
|
||||
|
||||
declare noalias i8* @malloc(i32)
|
||||
declare noalias i8* @malloc(i32) willreturn
|
||||
|
||||
; rdar://11341081
|
||||
%struct.big = type { [50 x i32] }
|
||||
@ -384,5 +384,6 @@ declare void @f2(%struct.big*)
|
||||
; CHECK: attributes [[ATTR0]] = { nounwind }
|
||||
; CHECK: attributes #1 = { argmemonly nofree nosync nounwind willreturn }
|
||||
; CHECK: attributes #2 = { nounwind ssp }
|
||||
; CHECK: attributes #3 = { nounwind ssp uwtable }
|
||||
; CHECK: attributes #4 = { argmemonly nofree nosync nounwind willreturn writeonly }
|
||||
; CHECK: attributes #3 = { willreturn }
|
||||
; CHECK: attributes #4 = { nounwind ssp uwtable }
|
||||
; CHECK: attributes #5 = { argmemonly nofree nosync nounwind willreturn writeonly }
|
||||
|
@ -14,4 +14,4 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
attributes #1 = { noinline nounwind readnone }
|
||||
attributes #1 = { noinline nounwind readnone willreturn }
|
||||
|
@ -25,9 +25,9 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
|
||||
;
|
||||
; We delete all but the first of the parallel regions in this test.
|
||||
define void @delete_parallel_0() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0()
|
||||
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0:@.*]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -40,9 +40,9 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined.willreturn(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #0
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR0:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @unknown() #0
|
||||
; CHECK-NEXT: call void @unknown() [[ATTR0]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -52,9 +52,9 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined.willreturn.0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) willreturn {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #1
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR1:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @readonly() #4
|
||||
; CHECK-NEXT: call void @readonly() [[ATTR4:#.*]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -64,9 +64,9 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined.willreturn.1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #2
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR2:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @readnone() #0
|
||||
; CHECK-NEXT: call void @readnone() [[ATTR0]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -76,7 +76,7 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined.willreturn.2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #3
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR3:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
@ -97,11 +97,11 @@ entry:
|
||||
;
|
||||
; We delete only the last parallel regions in this test because the others might not return.
|
||||
define void @delete_parallel_1() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1()
|
||||
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -114,7 +114,7 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined.(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]])
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @unknown()
|
||||
; CHECK-NEXT: ret void
|
||||
@ -126,9 +126,9 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #4
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR4]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @readonly() #4
|
||||
; CHECK-NEXT: call void @readonly() [[ATTR4]]
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -138,7 +138,7 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined..1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #5
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR5:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: call void @readnone()
|
||||
; CHECK-NEXT: ret void
|
||||
@ -150,7 +150,7 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined..2(i32* noalias %.global_tid., i32* noalias %.bound_tid.) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #3
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) [[ATTR3]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
@ -184,16 +184,16 @@ entry:
|
||||
; FIXME: We do not realize that `a` is dead and all accesses to it can be removed
|
||||
; making the parallel regions readonly and deletable.
|
||||
define void @delete_parallel_2() {
|
||||
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2()
|
||||
; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) #0
|
||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 dereferenceable(4) [[TMP]]) [[ATTR0]]
|
||||
; CHECK-NEXT: store i32 0, i32* [[A]], align 4
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8 dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)* noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8* noundef nonnull [[TMP1]])
|
||||
; CHECK-NEXT: ret void
|
||||
@ -214,9 +214,9 @@ entry:
|
||||
|
||||
define internal void @.omp_outlined..3(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) #6
|
||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) [[ATTR6:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() #4
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @omp_get_thread_num() [[ATTR12:#.*]]
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||
; CHECK: if.then:
|
||||
@ -244,17 +244,17 @@ if.end: ; preds = %if.then, %entry
|
||||
|
||||
define internal void @.omp_outlined..4(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
|
||||
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]])
|
||||
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull @0, i32 [[TMP]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
||||
; CHECK: omp_if.then:
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4
|
||||
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
||||
; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4
|
||||
; CHECK-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull @0, i32 [[TMP]])
|
||||
; CHECK-NEXT: call void @__kmpc_end_master(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
|
||||
; CHECK-NEXT: br label [[OMP_IF_END]]
|
||||
; CHECK: omp_if.end:
|
||||
; CHECK-NEXT: ret void
|
||||
@ -286,21 +286,21 @@ declare void @__kmpc_end_master(%struct.ident_t*, i32)
|
||||
|
||||
define internal void @.omp_outlined..5(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
|
||||
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]])
|
||||
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @0)
|
||||
; CHECK-NEXT: [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull [[GLOB0]]) [[ATTR12]]
|
||||
; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull @0, i32 [[TMP]])
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
||||
; CHECK-NEXT: br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label [[OMP_IF_THEN:%.*]]
|
||||
; CHECK: omp_if.then:
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[A]], align 4
|
||||
; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP3]], 1
|
||||
; CHECK-NEXT: store i32 [[INC]], i32* [[A]], align 4
|
||||
; CHECK-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull @0, i32 [[TMP]])
|
||||
; CHECK-NEXT: call void @__kmpc_end_single(%struct.ident_t* noundef nonnull [[GLOB0]], i32 [[TMP]])
|
||||
; CHECK-NEXT: br label [[OMP_IF_END]]
|
||||
; CHECK: omp_if.end:
|
||||
; CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull @1, i32 [[OMP_GLOBAL_THREAD_NUM]])
|
||||
; CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* noundef nonnull [[GLOB1:@.*]], i32 [[OMP_GLOBAL_THREAD_NUM]])
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
@ -324,18 +324,18 @@ omp_if.end: ; preds = %entry, %omp_if.then
|
||||
|
||||
define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) %a) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
|
||||
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]])
|
||||
; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A:%.*]]) {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[A1:%.*]] = alloca i32, align 4
|
||||
; CHECK-NEXT: [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*], align 8
|
||||
; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A1]] to i8*
|
||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) #0
|
||||
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noundef nonnull align 4 [[TMP]]) [[ATTR0]]
|
||||
; CHECK-NEXT: store i32 1, i32* [[A1]], align 4
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i32**
|
||||
; CHECK-NEXT: store i32* [[A1]], i32** [[TMP1]], align 8
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
|
||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast [1 x i8*]* [[DOTOMP_REDUCTION_RED_LIST]] to i8*
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull @2, i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = call i32 @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull [[GLOB2:@.*]], i32 [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
|
||||
; CHECK-NEXT: switch i32 [[TMP4]], label [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
|
||||
; CHECK-NEXT: i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
|
||||
; CHECK-NEXT: i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
|
||||
@ -345,7 +345,7 @@ define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32* noalias
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[A1]], align 4
|
||||
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
|
||||
; CHECK-NEXT: store i32 [[ADD]], i32* [[A]], align 4
|
||||
; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull @2, i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
|
||||
; CHECK-NEXT: call void @__kmpc_end_reduce_nowait(%struct.ident_t* noundef nonnull [[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
|
||||
; CHECK-NEXT: br label [[DOTOMP_REDUCTION_DEFAULT]]
|
||||
; CHECK: .omp.reduction.case2:
|
||||
; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[A1]], align 4
|
||||
@ -393,7 +393,7 @@ entry:
|
||||
|
||||
define internal void @.omp.reduction.reduction_func(i8* %arg, i8* %arg1) {
|
||||
; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
|
||||
; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) #{{[0-9]+}}
|
||||
; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[ARG1:%.*]]) [[ATTR9:#.*]] {
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32**
|
||||
; CHECK-NEXT: [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8
|
||||
|
@ -20,7 +20,7 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @bar() noinline nounwind readnone {
|
||||
define internal void @bar() noinline nounwind readnone willreturn {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user