From: Derek Schuff Date: Mon, 16 Nov 2015 21:12:41 +0000 (+0000) Subject: [WebAssembly] Fix function return type printing X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=1a4e019fc0dec593268af08eeede197f10fcd727 [WebAssembly] Fix function return type printing Summary: Previously return type information for a function was derived from return dag nodes. But this didn't work for dags with != return node. So instead compute it directly from the LLVM function as is done for imports. Differential Revision: http://reviews.llvm.org/D14593 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253251 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 0ab8888015e..0516e7a3bd8 100644 --- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -146,14 +146,38 @@ void WebAssemblyAsmPrinter::EmitJumpTableInfo() { // Nothing to do; jump tables are incorporated into the instruction stream. } +static void ComputeLegalValueVTs(const Function &F, + const TargetMachine &TM, + Type *Ty, + SmallVectorImpl &ValueVTs) { + const DataLayout& DL(F.getParent()->getDataLayout()); + const WebAssemblyTargetLowering &TLI = + *TM.getSubtarget(F).getTargetLowering(); + SmallVector VTs; + ComputeValueVTs(TLI, DL, Ty, VTs); + + for (EVT VT : VTs) { + unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT); + MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT); + for (unsigned i = 0; i != NumRegs; ++i) + ValueVTs.push_back(RegisterVT); + } +} + void WebAssemblyAsmPrinter::EmitFunctionBodyStart() { SmallString<128> Str; raw_svector_ostream OS(Str); for (MVT VT : MFI->getParams()) OS << "\t" ".param " << toString(VT) << '\n'; - for (MVT VT : MFI->getResults()) - OS << "\t" ".result " << toString(VT) << '\n'; + + SmallVector ResultVTs; + const Function &F(*MF->getFunction()); + ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs); + // If the return type needs to be legalized it will get converted into + // passing a pointer. + if (ResultVTs.size() == 1) + OS << "\t" ".result " << toString(ResultVTs.front()) << '\n'; bool FirstVReg = true; for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) { @@ -210,20 +234,7 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) { } } -static void ComputeLegalValueVTs(LLVMContext &Context, - const WebAssemblyTargetLowering &TLI, - const DataLayout &DL, Type *Ty, - SmallVectorImpl &ValueVTs) { - SmallVector VTs; - ComputeValueVTs(TLI, DL, Ty, VTs); - for (EVT VT : VTs) { - unsigned NumRegs = TLI.getNumRegisters(Context, VT); - MVT RegisterVT = TLI.getRegisterType(Context, VT); - for (unsigned i = 0; i != NumRegs; ++i) - ValueVTs.push_back(RegisterVT); - } -} void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { const DataLayout &DL = M.getDataLayout(); @@ -248,8 +259,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { // passing a pointer. bool SawParam = false; SmallVector ResultVTs; - ComputeLegalValueVTs(M.getContext(), TLI, DL, F.getReturnType(), - ResultVTs); + ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs); if (ResultVTs.size() > 1) { ResultVTs.clear(); OS << " (param " << toString(TLI.getPointerTy(DL)); @@ -258,20 +268,20 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) { for (const Argument &A : F.args()) { SmallVector ParamVTs; - ComputeLegalValueVTs(M.getContext(), TLI, DL, A.getType(), ParamVTs); - for (EVT VT : ParamVTs) { + ComputeLegalValueVTs(F, TM, A.getType(), ParamVTs); + for (MVT VT : ParamVTs) { if (!SawParam) { OS << " (param"; SawParam = true; } - OS << ' ' << toString(VT.getSimpleVT()); + OS << ' ' << toString(VT); } } if (SawParam) OS << ')'; - for (EVT VT : ResultVTs) - OS << " (result " << toString(VT.getSimpleVT()) << ')'; + for (MVT VT : ResultVTs) + OS << " (result " << toString(VT) << ')'; OS << '\n'; } diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 47eea934b8c..bae4f526723 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -326,8 +326,6 @@ SDValue WebAssemblyTargetLowering::LowerReturn( const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, SDLoc DL, SelectionDAG &DAG) const { - MachineFunction &MF = DAG.getMachineFunction(); - assert(Outs.size() <= 1 && "WebAssembly can only return up to one value"); if (CallConv != CallingConv::C) fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions"); @@ -352,7 +350,6 @@ SDValue WebAssemblyTargetLowering::LowerReturn( fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results"); if (!Out.IsFixed) fail(DL, DAG, "WebAssembly doesn't support non-fixed results yet"); - MF.getInfo()->addResult(Out.VT); } return Chain; diff --git a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 6e8b1dcb7a5..9c23412b3cc 100644 --- a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -28,7 +28,6 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo { MachineFunction &MF; std::vector Params; - std::vector Results; /// A mapping from CodeGen vreg index to WebAssembly register number. std::vector WARegs; @@ -48,9 +47,6 @@ public: void addParam(MVT VT) { Params.push_back(VT); } const std::vector &getParams() const { return Params; } - void addResult(MVT VT) { Results.push_back(VT); } - const std::vector &getResults() const { return Results; } - static const unsigned UnusedReg = -1u; void stackifyVReg(unsigned VReg) { diff --git a/test/CodeGen/WebAssembly/func.ll b/test/CodeGen/WebAssembly/func.ll index 17d20760e8c..97fd9913641 100644 --- a/test/CodeGen/WebAssembly/func.ll +++ b/test/CodeGen/WebAssembly/func.ll @@ -45,3 +45,24 @@ define i32 @f2(i32 %p1, float %p2) { define void @f3(i32 %p1, float %p2) { ret void } + +; CHECK-LABEL: f4: +; CHECK-NEXT: .param i32{{$}} +; CHECK-NEXT: .result i32{{$}} +; CHECK-NEXT: .local +define i32 @f4(i32 %x) { +entry: + %c = trunc i32 %x to i1 + br i1 %c, label %true, label %false +true: + ret i32 0 +false: + ret i32 1 +} + +; CHECK-LABEL: f5: +; CHECK-NEXT: .result f32{{$}} +; CHECK-NEXT: unreachable +define float @f5() { + unreachable +}