[llvm] 275c6af - [WebAssembly] Fix Fast ISEL not lowering 64-bit function pointers
Wouter van Oortmerssen via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 28 10:10:47 PST 2021
Author: Wouter van Oortmerssen
Date: 2021-01-28T10:05:29-08:00
New Revision: 275c6af7d7f1ed63a03d05b4484413e447133269
URL: https://github.com/llvm/llvm-project/commit/275c6af7d7f1ed63a03d05b4484413e447133269
DIFF: https://github.com/llvm/llvm-project/commit/275c6af7d7f1ed63a03d05b4484413e447133269.diff
LOG: [WebAssembly] Fix Fast ISEL not lowering 64-bit function pointers
Differential Revision: https://reviews.llvm.org/D95410
Added:
llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 82b032267d55..509f2be8de59 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -881,6 +881,19 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
// 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)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index e348bba2b04c..5eee013f9ac8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -455,6 +455,7 @@ static MachineBasicBlock *LowerCallResults(MachineInstr &CallResults,
// 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);
diff --git a/llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll b/llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll
new file mode 100644
index 000000000000..f82b05fc1085
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll
@@ -0,0 +1,15 @@
+; 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: local.get $push[[L0:[0-9]+]]=, 0
+; CHECK-NEXT: i32.wrap_i64 $push[[L1:[0-9]+]]=, $pop[[L0]]
+; CHECK-NEXT: call_indirect $pop[[L1]]
+
+define hidden void @f(void ()* %g) {
+ call void %g()
+ ret void
+}
More information about the llvm-commits
mailing list