diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2021-04-28 17:58:08 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2021-04-28 19:08:54 +0300 |
commit | 38dd222b4a5bc29eed5be90f85ca754a521b0cd2 (patch) | |
tree | 87bb0ff732560ab5f56c676d4bd67bf4286ebf31 | |
parent | 8978b1d3717ffa826a1ed8b36300faebf7629041 (diff) | |
download | llvm-38dd222b4a5bc29eed5be90f85ca754a521b0cd2.tar.gz |
[NFC][SimplifyCFG] Add common code sinking test with direct and indirect callees
This is the pattern ICP produces.
We shouldn't fold this back into an indirect call.
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll b/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll index 917d1ab89eea..84b7f75ab038 100644 --- a/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll +++ b/llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll @@ -1381,6 +1381,32 @@ if.end: ret i32 1 } +define void @direct_caller(i1 %c) { +; CHECK-LABEL: @direct_caller( +; CHECK-NEXT: br i1 [[C:%.*]], label [[CALL_FOO:%.*]], label [[CALL_BAR:%.*]] +; CHECK: call_foo: +; CHECK-NEXT: call void @direct_callee() +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: call_bar: +; CHECK-NEXT: call void @direct_callee2() +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void +; + br i1 %c, label %call_foo, label %call_bar + +call_foo: + call void @direct_callee() + br label %end + +call_bar: + call void @direct_callee2() + br label %end + +end: + ret void +} + define void @indirect_caller(i1 %c, i32 %v, void (i32)* %foo, void (i32)* %bar) { ; CHECK-LABEL: @indirect_caller( ; CHECK-NEXT: br i1 [[C:%.*]], label [[CALL_FOO:%.*]], label [[CALL_BAR:%.*]] @@ -1407,5 +1433,62 @@ end: ret void } +define void @maybe_indirect_caller(void ()* %fun) { +; CHECK-LABEL: @maybe_indirect_caller( +; CHECK-NEXT: [[C:%.*]] = icmp eq void ()* [[FUN:%.*]], @direct_callee +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]] +; CHECK: if.true.direct_targ: +; CHECK-NEXT: tail call void @direct_callee() +; CHECK-NEXT: br label [[IF_END_ICP:%.*]] +; CHECK: if.false.orig_indirect: +; CHECK-NEXT: tail call void [[FUN]]() +; CHECK-NEXT: br label [[IF_END_ICP]] +; CHECK: if.end.icp: +; CHECK-NEXT: ret void +; + %c = icmp eq void ()* %fun, @direct_callee + br i1 %c, label %if.true.direct_targ, label %if.false.orig_indirect + +if.true.direct_targ: + tail call void @direct_callee() + br label %if.end.icp + +if.false.orig_indirect: + tail call void %fun() + br label %if.end.icp + +if.end.icp: + ret void +} +define void @maybe_indirect_caller2(void ()* %fun) { +; CHECK-LABEL: @maybe_indirect_caller2( +; CHECK-NEXT: [[C:%.*]] = icmp eq void ()* [[FUN:%.*]], @direct_callee +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]] +; CHECK: if.false.orig_indirect: +; CHECK-NEXT: tail call void [[FUN]]() +; CHECK-NEXT: br label [[IF_END_ICP:%.*]] +; CHECK: if.true.direct_targ: +; CHECK-NEXT: tail call void @direct_callee() +; CHECK-NEXT: br label [[IF_END_ICP]] +; CHECK: if.end.icp: +; CHECK-NEXT: ret void +; + %c = icmp eq void ()* %fun, @direct_callee + br i1 %c, label %if.true.direct_targ, label %if.false.orig_indirect + +if.false.orig_indirect: + tail call void %fun() + br label %if.end.icp + +if.true.direct_targ: + tail call void @direct_callee() + br label %if.end.icp + +if.end.icp: + ret void +} +declare void @direct_callee() +declare void @direct_callee2() + declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) |