From: Sam Clegg Date: Fri, 19 Apr 2019 22:43:32 +0000 (+0000) Subject: [WebAssembly] FastISel: Don't fallback to SelectionDAG after BuildMI in selectCall X-Git-Tag: llvmorg-9.0.0-rc1~7460 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a27252794e0785af0eff7367ac9d57d91dffe944;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index 170574867378..2d9aae7a698c 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -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); diff --git a/llvm/test/CodeGen/WebAssembly/call-pic.ll b/llvm/test/CodeGen/WebAssembly/call-pic.ll index b50f96d6d723..b319ea4924f3 100644 --- a/llvm/test/CodeGen/WebAssembly/call-pic.ll +++ b/llvm/test/CodeGen/WebAssembly/call-pic.ll @@ -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{{$}}