[PATCH] D95410: [WebAssembly] Fix Fast ISEL not lowering 64-bit function pointers

Wouter van Oortmerssen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 25 16:51:13 PST 2021


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

https://reviews.llvm.org/D95410

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


Index: llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll
@@ -0,0 +1,21 @@
+; RUN: llc < %s -fast-isel --mtriple=wasm64 -asm-verbose=false -wasm-keep-registers | FileCheck %s
+
+target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128"
+target triple = "wasm64"
+
+; Ensure fast isel also lowers function pointers to 32-bit.
+
+; CHECK:       i64.load $push[[L0:[0-9]+]]=, 8($pop{{[0-9]+}})
+; CHECK-NEXT:  i32.wrap_i64 $push[[L1:[0-9]+]]=, $pop[[L0]]
+; CHECK-NEXT:  call_indirect $push[[L2:[0-9]+]]=, $pop[[L1]]
+; CHECK-NEXT:  local.set {{[0-9]+}}, $pop[[L2]]
+
+define hidden i32 @b(i32 (...)* %f) {
+entry:
+  %f.addr = alloca i32 (...)*, align 8
+  store i32 (...)* %f, i32 (...)** %f.addr, align 8
+  %0 = load i32 (...)*, i32 (...)** %f.addr, align 8
+  %callee.knr.cast = bitcast i32 (...)* %0 to i32 ()*
+  %call = call i32 %callee.knr.cast()
+  ret i32 %call
+}
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -454,6 +454,7 @@
   // See if we must truncate the function pointer.
   // CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
   // as 64-bit for uniformity with other pointer types.
+  // See also: WebAssemblyFastISel::selectCall
   if (IsIndirect && MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()) {
     Register Reg32 =
         MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
Index: llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -889,6 +889,19 @@
     // it as NO_STRIP so as to ensure that the indirect function table makes it
     // to linked output.
     Sym->setNoStrip();
+
+    // See if we must truncate the function pointer.
+    // CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
+    // as 64-bit for uniformity with other pointer types.
+    // See also: WebAssemblyISelLowering.cpp: LowerCallResults
+    if (Subtarget->hasAddr64()) {
+      auto Wrap = BuildMI(*FuncInfo.MBB, std::prev(FuncInfo.InsertPt), DbgLoc,
+                          TII.get(WebAssembly::I32_WRAP_I64));
+      unsigned Reg32 = createResultReg(&WebAssembly::I32RegClass);
+      Wrap.addReg(Reg32, RegState::Define);
+      Wrap.addReg(CalleeReg);
+      CalleeReg = Reg32;
+    }
   }
 
   for (unsigned ArgReg : Args)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95410.319168.patch
Type: text/x-patch
Size: 2749 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210126/751a7246/attachment.bin>


More information about the llvm-commits mailing list