[PATCH] D108060: [WebAssembly] Always use call_indirect when calling interposable functions

Sam Clegg via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 13 16:05:15 PDT 2021


sbc100 created this revision.
Herald added subscribers: wingo, ecnelises, sunfish, hiraditya, jgravelle-google, dschuff.
sbc100 requested review of this revision.
Herald added subscribers: llvm-commits, aheejin.
Herald added a project: LLVM.

Without this calls to DSO-local but weakly defined symbols will be
direct calls even though at runtime another DLL could define that
symbol.

Fixes: https://github.com/emscripten-core/emscripten/issues/13773


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D108060

Files:
  llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/test/CodeGen/WebAssembly/call-pic.ll


Index: llvm/test/CodeGen/WebAssembly/call-pic.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/call-pic.ll
+++ llvm/test/CodeGen/WebAssembly/call-pic.ll
@@ -9,7 +9,7 @@
 @indirect_func = hidden global i32 ()* @foo
 @alias_func = hidden alias i32 (), i32 ()* @local_function
 
-define i32 @local_function() {
+define hidden i32 @local_function() {
   ret i32 1
 }
 
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1077,13 +1077,18 @@
   }
 
   if (Callee->getOpcode() == ISD::GlobalAddress) {
-    // If the callee is a GlobalAddress node (quite common, every direct call
-    // is) turn it into a TargetGlobalAddress node so that LowerGlobalAddress
-    // doesn't at MO_GOT which is not needed for direct calls.
     GlobalAddressSDNode* GA = cast<GlobalAddressSDNode>(Callee);
-    Callee = DAG.getTargetGlobalAddress(GA->getGlobal(), DL,
-                                        getPointerTy(DAG.getDataLayout()),
-                                        GA->getOffset());
+    // llvm::dbgs() << "LowerCall: " << GA->getGlobal()->getName() << "\n";
+    if (!isPositionIndependent() || !GA->getGlobal()->isInterposable()) {
+      // llvm::dbgs() << "is decl\n";
+      // If the callee is a GlobalAddress node (quite common, every direct call
+      // is) turn it into a TargetGlobalAddress node so that LowerGlobalAddress
+      // doesn't add MO_GOT which is not needed for direct calls (to
+      // non-interposable functions);
+      Callee = DAG.getTargetGlobalAddress(GA->getGlobal(), DL,
+                                          getPointerTy(DAG.getDataLayout()),
+                                          GA->getOffset());
+    }
     Callee = DAG.getNode(WebAssemblyISD::Wrapper, DL,
                          getPointerTy(DAG.getDataLayout()), Callee);
   }
@@ -1577,7 +1582,10 @@
   unsigned OperandFlags = 0;
   if (isPositionIndependent()) {
     const GlobalValue *GV = GA->getGlobal();
-    if (getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV)) {
+    // llvm::dbgs() << "LowerGlobalAddress: " << GV->getName() << "\n";
+    if (getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV) &&
+        !GV->isInterposable()) {
+      // llvm::dbgs() << "DSO local\n";
       MachineFunction &MF = DAG.getMachineFunction();
       MVT PtrVT = getPointerTy(MF.getDataLayout());
       const char *BaseName;
@@ -1600,6 +1608,7 @@
 
       return DAG.getNode(ISD::ADD, DL, VT, BaseAddr, SymAddr);
     } else {
+      // llvm::dbgs() << "not DSO local\n";
       OperandFlags = WebAssemblyII::MO_GOT;
     }
   }
Index: llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -767,6 +767,8 @@
     return false;
 
   bool IsDirect = Func != nullptr;
+  if (TLI.isPositionIndependent() && Func && Func->isInterposable())
+    IsDirect = false;
   if (!IsDirect && isa<ConstantExpr>(Call->getCalledOperand()))
     return false;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108060.366367.patch
Type: text/x-patch
Size: 3307 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210813/1928683f/attachment.bin>


More information about the llvm-commits mailing list