[llvm] r352445 - [WebAssembly] Handle more types of uses in WebAssemblyAddMissingPrototypes

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 28 16:30:47 PST 2019


Author: sbc
Date: Mon Jan 28 16:30:46 2019
New Revision: 352445

URL: http://llvm.org/viewvc/llvm-project?rev=352445&view=rev
Log:
[WebAssembly] Handle more types of uses in WebAssemblyAddMissingPrototypes

Previously we were only handling bitcast operations, however
prototypeless functions can also appear in other places such as
comparisons and as function params.

Switch to using replaceAllUsesWith() to replace the prototype-less
function uses.  This new approach results in some redundant bitcasting
but is much simpler and handles all cases.

Differential Revision: https://reviews.llvm.org/D56938

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp
    llvm/trunk/test/CodeGen/WebAssembly/add-prototypes.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp?rev=352445&r1=352444&r2=352445&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAddMissingPrototypes.cpp Mon Jan 28 16:30:46 2019
@@ -95,9 +95,10 @@ bool WebAssemblyAddMissingPrototypes::ru
           if (!NewType) {
             // Create a new function with the correct type
             NewType = DestType;
-            NewF = Function::Create(NewType, F.getLinkage(), F.getName());
+            NewF = Function::Create(NewType, F.getLinkage(), F.getName() + ".fixed_sig");
             NewF->setAttributes(F.getAttributes());
             NewF->removeFnAttr("no-prototype");
+            Replacements.emplace_back(&F, NewF);
           } else {
             if (NewType != DestType) {
               report_fatal_error("Prototypeless function used with "
@@ -115,45 +116,17 @@ bool WebAssemblyAddMissingPrototypes::ru
                         F.getName() + "\n");
       continue;
     }
-
-    SmallVector<Instruction *, 4> DeadInsts;
-
-    for (Use &US : F.uses()) {
-      User *U = US.getUser();
-      if (auto *BC = dyn_cast<BitCastOperator>(U)) {
-        if (auto *Inst = dyn_cast<BitCastInst>(U)) {
-          // Replace with a new bitcast
-          IRBuilder<> Builder(Inst);
-          Value *NewCast = Builder.CreatePointerCast(NewF, BC->getDestTy());
-          Inst->replaceAllUsesWith(NewCast);
-          DeadInsts.push_back(Inst);
-        } else if (auto *Const = dyn_cast<ConstantExpr>(U)) {
-          Constant *NewConst =
-              ConstantExpr::getPointerCast(NewF, BC->getDestTy());
-          Const->replaceAllUsesWith(NewConst);
-        } else {
-          dbgs() << *U->getType() << "\n";
-#ifndef NDEBUG
-          U->dump();
-#endif
-          report_fatal_error("unexpected use of prototypeless function: " +
-                             F.getName() + "\n");
-        }
-      }
-    }
-
-    for (auto I : DeadInsts)
-      I->eraseFromParent();
-    Replacements.emplace_back(&F, NewF);
   }
 
-
-  // Finally replace the old function declarations with the new ones
   for (auto &Pair : Replacements) {
-    Function *Old = Pair.first;
-    Function *New = Pair.second;
-    Old->eraseFromParent();
-    M.getFunctionList().push_back(New);
+    Function *OldF = Pair.first;
+    Function *NewF = Pair.second;
+    std::string Name = OldF->getName();
+    M.getFunctionList().push_back(NewF);
+    OldF->replaceAllUsesWith(
+      ConstantExpr::getPointerBitCastOrAddrSpaceCast(NewF, OldF->getType()));
+    OldF->eraseFromParent();
+    NewF->setName(Name);
   }
 
   return !Replacements.empty();

Modified: llvm/trunk/test/CodeGen/WebAssembly/add-prototypes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/add-prototypes.ll?rev=352445&r1=352444&r2=352445&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/add-prototypes.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/add-prototypes.ll Mon Jan 28 16:30:46 2019
@@ -17,7 +17,8 @@ define void @call_foo(i32 %a) {
 }
 
 ; CHECK-LABEL: @call_foo_ptr
-; CHECK: %call = call i64 @foo(i32 43)
+; CHECK: %1 = bitcast i64 (...)* bitcast (i64 (i32)* @foo to i64 (...)*) to i64 (i32)*
+; CHECK-NEXT: %call = call i64 %1(i32 43)
 define i64 @call_foo_ptr(i32 %a) {
   %1 = bitcast i64 (...)* @foo to i64 (i32)*
   %call = call i64 (i32) %1(i32 43)
@@ -25,7 +26,8 @@ define i64 @call_foo_ptr(i32 %a) {
 }
 
 ; CHECK-LABEL: @to_intptr_inst
-; CHECK: ret i8* bitcast (i64 (i32)* @foo to i8*)
+; CHECK: %1 = bitcast i64 (...)* bitcast (i64 (i32)* @foo to i64 (...)*) to i8*
+; CHECK-NEXT: ret i8* %1
 define i8* @to_intptr_inst() {
   %1 = bitcast i64 (...)* @foo to i8*
   ret i8* %1
@@ -37,8 +39,27 @@ define i8* @to_intptr_constexpr() {
   ret i8* bitcast (i64 (...)* @foo to i8*)
 }
 
-; CHECK: declare i64 @foo(i32)
-declare i64 @foo(...) #1
+; CHECK-LABEL: @null_compare
+; CHECK: br i1 icmp eq (i64 (...)* bitcast (i64 (i32)* @foo to i64 (...)*), i64 (...)* null), label %if.then, label %if.end
+define i8 @null_compare() {
+  br i1 icmp eq (i64 (...)* @foo, i64 (...)* null), label %if.then, label %if.end
+if.then:
+  ret i8 0
+if.end:
+  ret i8 1
+}
+
+; CHECK-LABEL: @as_paramater
+; CHECK: call void @func_param(i64 (...)* bitcast (i64 (i32)* @foo to i64 (...)*))
+define void @as_paramater() {
+  call void @func_param(i64 (...)* @foo)
+  ret void
+}
+
+declare void @func_param(i64 (...)*)
+
+; CHECK: declare extern_weak i64 @foo(i32)
+declare extern_weak i64 @foo(...) #1
 
 ; CHECK-NOT: attributes {{.*}} = { {{.*}}"no-prototype"{{.*}} }
 attributes #1 = { "no-prototype" }




More information about the llvm-commits mailing list