[WebAssembly] FastISel: Don't fallback to SelectionDAG after BuildMI in selectCall

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
This commit is contained in:
Sam Clegg 2019-04-19 22:43:32 +00:00
parent d600e6fa85
commit a27252794e
2 changed files with 24 additions and 6 deletions

View 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);

View 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{{$}}