[WebAssembly] FastISel: Don't fallback to SelectionDAG after BuildMI in selectCall
authorSam Clegg <sbc@chromium.org>
Fri, 19 Apr 2019 22:43:32 +0000 (22:43 +0000)
committerSam Clegg <sbc@chromium.org>
Fri, 19 Apr 2019 22:43:32 +0000 (22:43 +0000)
My understanding is that once BuildMI has been called we can't fallback
to SelectionDAG.

This change moves the fallback for when getRegForValue() fails for
that target of an indirect call.  This was failing in -fPIC mode when
the callee is GlobalValue.

Add a test case that tickles this.

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

llvm-svn: 358793

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

index 1705748673788caff15b9f3e80093af08d0b0252..2d9aae7a698c90f4e3976c904d671b6cd45f4a09 100644 (file)
@@ -851,6 +851,13 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
     Args.push_back(Reg);
   }
 
+  unsigned CalleeReg = 0;
+  if (!IsDirect) {
+    CalleeReg = getRegForValue(Call->getCalledValue());
+    if (!CalleeReg)
+      return false;
+  }
+
   auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
 
   if (!IsVoid)
@@ -858,12 +865,8 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
 
   if (IsDirect)
     MIB.addGlobalAddress(Func);
-  else {
-    unsigned Reg = getRegForValue(Call->getCalledValue());
-    if (Reg == 0)
-      return false;
-    MIB.addReg(Reg);
-  }
+  else
+    MIB.addReg(CalleeReg);
 
   for (unsigned ArgReg : Args)
     MIB.addReg(ArgReg);
index b50f96d6d7239d75c9d70612b8bb7af2b1334540..b319ea4924f308a11901f9dfac2ba5bac7e75b02 100644 (file)
@@ -8,6 +8,11 @@ declare i32 @bar()
 declare hidden i32 @hidden_function()
 
 @indirect_func = global i32 ()* @foo
+@alias_func = hidden alias i32 (), i32 ()* @local_function
+
+define i32 @local_function() {
+  ret i32 1
+}
 
 define void @call_indirect_func() {
 ; CHECK-LABEL: call_indirect_func:
@@ -31,6 +36,16 @@ define void @call_direct() {
   ret void
 }
 
+define void @call_alias_func() {
+; CHECK-LABEL: call_alias_func:
+; CHECK: .functype call_alias_func () -> ()
+; CHECK-NEXT: i32.call $push0=, alias_func
+; CHECK-NEXT: drop $pop0{{$}}
+; CHECK-NEXT: return{{$}}
+  %call = call i32 @alias_func()
+  ret void
+}
+
 define i8* @get_function_address() {
 ; CHECK-LABEL: get_function_address:
 ; CHECK:       global.get $push[[L0:[0-9]+]]=, bar@GOT{{$}}