[PATCH] D110901: [SimplifyCFG] Prevent SimplifyCFG from sinking indirect calls.

Joseph Huber via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 30 20:31:38 PDT 2021


jhuber6 created this revision.
jhuber6 added reviewers: jdoerfert, lebedev.ri.
jhuber6 added a project: LLVM.
Herald added a subscriber: hiraditya.
jhuber6 requested review of this revision.
Herald added a subscriber: llvm-commits.

This patch prevents the CFG simplification pass from sinking indirect
calls. Currently, the indirect calls will be combined into a single
indirect call after the arguments have been selected. This prevents the
indirect calls from being replaced with direct ones once the callee is
known through other optimizations.

      

An example of this is shown in https://godbolt.org/z/jTcfYnvYx where the
indirect calls cannot be replaced with direct calls once they are
inlined and the calls are known. This is generally more costly than
calling the function directly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110901

Files:
  llvm/lib/Transforms/Utils/SimplifyCFG.cpp
  llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll


Index: llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
===================================================================
--- llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
+++ llvm/test/Transforms/SimplifyCFG/X86/sink-common-code.ll
@@ -1406,9 +1406,14 @@
 
 define void @indirect_caller(i1 %c, i32 %v, void (i32)* %foo, void (i32)* %bar) {
 ; CHECK-LABEL: @indirect_caller(
-; CHECK-NEXT:  end:
-; CHECK-NEXT:    [[FOO_BAR:%.*]] = select i1 [[C:%.*]], void (i32)* [[FOO:%.*]], void (i32)* [[BAR:%.*]]
-; CHECK-NEXT:    tail call void [[FOO_BAR]](i32 [[V:%.*]])
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[CALL_FOO:%.*]], label [[CALL_BAR:%.*]]
+; CHECK:       call_foo:
+; CHECK-NEXT:    tail call void [[FOO:%.*]](i32 [[V:%.*]])
+; CHECK-NEXT:    br label [[END:%.*]]
+; CHECK:       call_bar:
+; CHECK-NEXT:    tail call void [[BAR:%.*]](i32 [[V]])
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
 ; CHECK-NEXT:    ret void
 ;
   br i1 %c, label %call_foo, label %call_bar
Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
===================================================================
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Analysis/MemorySSAUpdater.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/AbstractCallSite.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CFG.h"
@@ -2057,7 +2058,13 @@
   // actually sink before encountering instruction that is unprofitable to sink?
   auto ProfitableToSinkInstruction = [&](LockstepReverseIterator &LRI) {
     unsigned NumPHIdValues = 0;
-    for (auto *I : *LRI)
+    for (auto *I : *LRI) {
+      // Sinking indirect calls prevents us from replacing the indirect call
+      // with a direct call once the callee is known.
+      if (auto *CB = dyn_cast<CallBase>(I))
+        if (AbstractCallSite ACS = &CB->getCalledOperandUse())
+          if (ACS.isIndirectCall())
+            return false;
       for (auto *V : PHIOperands[I]) {
         if (InstructionsToSink.count(V) == 0)
           ++NumPHIdValues;
@@ -2065,6 +2072,7 @@
         // said instruction, due to the very same profitability check.
         // See @creating_too_many_phis in sink-common-code.ll.
       }
+    }
     LLVM_DEBUG(dbgs() << "SINK: #phid values: " << NumPHIdValues << "\n");
     unsigned NumPHIInsts = NumPHIdValues / UnconditionalPreds.size();
     if ((NumPHIdValues % UnconditionalPreds.size()) != 0)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110901.376416.patch
Type: text/x-patch
Size: 2564 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211001/7d09f0dd/attachment.bin>


More information about the llvm-commits mailing list