From d73b41ae220128db3f585f27e39633426675e304 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 11 Jan 2016 23:38:05 +0000 Subject: [PATCH] [WebAssembly] Define WebAssembly-specific relocation codes. Currently WebAssembly has two kinds of relocations; data addresses and function addresses. This adds ELF relocations for them, as well as an MC symbol kind to indicate which type of relocation is needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257416 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 2 +- include/llvm/MC/MCExpr.h | 3 ++ include/llvm/Support/ELF.h | 5 ++++ .../llvm/Support/ELFRelocs/WebAssembly.def | 8 ++++++ lib/MC/MCExpr.cpp | 1 + .../WebAssemblyELFObjectWriter.cpp | 19 +++++++++++-- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 9 ++++++ .../WebAssembly/WebAssemblyISelLowering.cpp | 14 ++++++++-- .../WebAssembly/WebAssemblyMCInstLower.cpp | 28 +++++++++++++------ .../WebAssembly/WebAssemblyMCInstLower.h | 3 +- test/CodeGen/WebAssembly/call.ll | 20 ++++++------- test/CodeGen/WebAssembly/f32.ll | 2 +- test/CodeGen/WebAssembly/f64.ll | 2 +- test/CodeGen/WebAssembly/frem.ll | 4 +-- test/CodeGen/WebAssembly/global.ll | 2 +- test/CodeGen/WebAssembly/returned.ll | 8 +++--- test/CodeGen/WebAssembly/signext-zeroext.ll | 4 +-- test/CodeGen/WebAssembly/switch.ll | 24 ++++++++-------- test/CodeGen/WebAssembly/unreachable.ll | 2 +- test/CodeGen/WebAssembly/unused-argument.ll | 2 +- test/CodeGen/WebAssembly/varargs.ll | 2 +- 21 files changed, 112 insertions(+), 52 deletions(-) create mode 100644 include/llvm/Support/ELFRelocs/WebAssembly.def diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index f5e778b2f26..cf29fc9ef88 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -259,7 +259,7 @@ public: void EmitAlignment(unsigned NumBits, const GlobalObject *GO = nullptr) const; /// Lower the specified LLVM Constant to an MCExpr. - const MCExpr *lowerConstant(const Constant *CV); + virtual const MCExpr *lowerConstant(const Constant *CV); /// \brief Print a general LLVM constant to the .s file. void EmitGlobalConstant(const DataLayout &DL, const Constant *CV); diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 1d6bdef0af2..f6ccdc09555 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -290,6 +290,9 @@ public: VK_Hexagon_LD_PLT, VK_Hexagon_IE, VK_Hexagon_IE_GOT, + + VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr + VK_TPREL, VK_DTPREL }; diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 97708a7cdd6..33975688c24 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -594,6 +594,11 @@ enum { #include "ELFRelocs/Sparc.def" }; +// ELF Relocation types for WebAssembly +enum { +#include "ELFRelocs/WebAssembly.def" +}; + #undef ELF_RELOC // Section header. diff --git a/include/llvm/Support/ELFRelocs/WebAssembly.def b/include/llvm/Support/ELFRelocs/WebAssembly.def new file mode 100644 index 00000000000..9a34349efb9 --- /dev/null +++ b/include/llvm/Support/ELFRelocs/WebAssembly.def @@ -0,0 +1,8 @@ + +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +ELF_RELOC(R_WEBASSEMBLY_NONE, 0) +ELF_RELOC(R_WEBASSEMBLY_DATA, 1) +ELF_RELOC(R_WEBASSEMBLY_FUNCTION, 2) diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 0f26b38c29d..748644bd9c8 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -300,6 +300,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_Hexagon_LD_PLT: return "LDPLT"; case VK_Hexagon_IE: return "IE"; case VK_Hexagon_IE_GOT: return "IEGOT"; + case VK_WebAssembly_FUNCTION: return "FUNCTION"; case VK_TPREL: return "tprel"; case VK_DTPREL: return "dtprel"; } diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyELFObjectWriter.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyELFObjectWriter.cpp index c47a3d9094e..f9012d8fb77 100644 --- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyELFObjectWriter.cpp +++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyELFObjectWriter.cpp @@ -41,8 +41,23 @@ WebAssemblyELFObjectWriter::WebAssemblyELFObjectWriter(bool Is64Bit, unsigned WebAssemblyELFObjectWriter::GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - // FIXME: Do we need our own relocs? - return Fixup.getKind(); + // WebAssembly functions are not allocated in the address space. To resolve a + // pointer to a function, we must use a special relocation type. + if (const MCSymbolRefExpr *SyExp = + dyn_cast(Fixup.getValue())) + if (SyExp->getKind() == MCSymbolRefExpr::VK_WebAssembly_FUNCTION) + return ELF::R_WEBASSEMBLY_FUNCTION; + + switch (Fixup.getKind()) { + case FK_Data_4: + assert(!is64Bit() && "4-byte relocations only supported on wasm32"); + return ELF::R_WEBASSEMBLY_DATA; + case FK_Data_8: + assert(is64Bit() && "8-byte relocations only supported on wasm64"); + return ELF::R_WEBASSEMBLY_DATA; + default: + llvm_unreachable("unimplemented fixup kind"); + } } MCObjectWriter *llvm::createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS, diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 6c1ef40b0cc..8d84901b3a2 100644 --- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -70,6 +70,7 @@ private: void EmitConstantPool() override; void EmitFunctionBodyStart() override; void EmitInstruction(const MachineInstr *MI) override; + const MCExpr *lowerConstant(const Constant *CV) override; bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS) override; @@ -221,6 +222,14 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) { } } +const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) { + if (const GlobalValue *GV = dyn_cast(CV)) + if (GV->getValueType()->isFunctionTy()) + return MCSymbolRefExpr::create( + getSymbol(GV), MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext); + return AsmPrinter::lowerConstant(CV); +} + bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 7a89f788c1a..e9933b09298 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -573,7 +573,8 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op, SDLoc DL(Op); const auto *GA = cast(Op); EVT VT = Op.getValueType(); - assert(GA->getTargetFlags() == 0 && "WebAssembly doesn't set target flags"); + assert(GA->getTargetFlags() == 0 && + "Unexpected target flags on generic GlobalAddressSDNode"); if (GA->getAddressSpace() != 0) fail(DL, DAG, "WebAssembly only expects the 0 address space"); return DAG.getNode( @@ -587,9 +588,16 @@ WebAssemblyTargetLowering::LowerExternalSymbol(SDValue Op, SDLoc DL(Op); const auto *ES = cast(Op); EVT VT = Op.getValueType(); - assert(ES->getTargetFlags() == 0 && "WebAssembly doesn't set target flags"); + assert(ES->getTargetFlags() == 0 && + "Unexpected target flags on generic ExternalSymbolSDNode"); + // Set the TargetFlags to 0x1 which indicates that this is a "function" + // symbol rather than a data symbol. We do this unconditionally even though + // we don't know anything about the symbol other than its name, because all + // external symbols used in target-independent SelectionDAG code are for + // functions. return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT, - DAG.getTargetExternalSymbol(ES->getSymbol(), VT)); + DAG.getTargetExternalSymbol(ES->getSymbol(), VT, + /*TargetFlags=*/0x1)); } SDValue WebAssemblyTargetLowering::LowerJumpTable(SDValue Op, diff --git a/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index a953f824700..eaba53e46ed 100644 --- a/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -36,15 +36,17 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol( return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); } -MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO, - MCSymbol *Sym) const { - assert(MO.getTargetFlags() == 0 && "WebAssembly does not use target flags"); +MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym, + int64_t Offset, + bool IsFunc) const { + MCSymbolRefExpr::VariantKind VK = + IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION + : MCSymbolRefExpr::VK_None; + const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx); - const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx); - - int64_t Offset = MO.getOffset(); if (Offset != 0) { - assert(!MO.isJTI() && "Unexpected offset with jump table index"); + if (IsFunc) + report_fatal_error("Function addresses with offsets not supported"); Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx); } @@ -94,10 +96,18 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI, MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); break; case MachineOperand::MO_GlobalAddress: - MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); + assert(MO.getTargetFlags() == 0 && + "WebAssembly does not use target flags on GlobalAddresses"); + MCOp = LowerSymbolOperand(GetGlobalAddressSymbol(MO), MO.getOffset(), + MO.getGlobal()->getValueType()->isFunctionTy()); break; case MachineOperand::MO_ExternalSymbol: - MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); + // The target flag indicates whether this is a symbol for a + // variable or a function. + assert((MO.getTargetFlags() & -2) == 0 && + "WebAssembly uses only one target flag bit on ExternalSymbols"); + MCOp = LowerSymbolOperand(GetExternalSymbolSymbol(MO), /*Offset=*/0, + MO.getTargetFlags() & 1); break; } diff --git a/lib/Target/WebAssembly/WebAssemblyMCInstLower.h b/lib/Target/WebAssembly/WebAssemblyMCInstLower.h index 6d704704f57..ab4ba1c28d5 100644 --- a/lib/Target/WebAssembly/WebAssemblyMCInstLower.h +++ b/lib/Target/WebAssembly/WebAssemblyMCInstLower.h @@ -31,9 +31,10 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyMCInstLower { MCContext &Ctx; AsmPrinter &Printer; - MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const; MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const; + MCOperand LowerSymbolOperand(MCSymbol *Sym, int64_t Offset, + bool IsFunc) const; public: WebAssemblyMCInstLower(MCContext &ctx, AsmPrinter &printer) diff --git a/test/CodeGen/WebAssembly/call.ll b/test/CodeGen/WebAssembly/call.ll index 6ef443e91d1..6d5542c89d3 100644 --- a/test/CodeGen/WebAssembly/call.ll +++ b/test/CodeGen/WebAssembly/call.ll @@ -15,7 +15,7 @@ declare void @void_nullary() ; CHECK-LABEL: call_i32_nullary: ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_nullary{{$}} +; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_nullary@FUNCTION{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i32 @call_i32_nullary() { %r = call i32 @i32_nullary() @@ -24,7 +24,7 @@ define i32 @call_i32_nullary() { ; CHECK-LABEL: call_i64_nullary: ; CHECK-NEXT: .result i64{{$}} -; CHECK-NEXT: {{^}} i64.call $push[[NUM:[0-9]+]]=, i64_nullary{{$}} +; CHECK-NEXT: {{^}} i64.call $push[[NUM:[0-9]+]]=, i64_nullary@FUNCTION{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i64 @call_i64_nullary() { %r = call i64 @i64_nullary() @@ -33,7 +33,7 @@ define i64 @call_i64_nullary() { ; CHECK-LABEL: call_float_nullary: ; CHECK-NEXT: .result f32{{$}} -; CHECK-NEXT: {{^}} f32.call $push[[NUM:[0-9]+]]=, float_nullary{{$}} +; CHECK-NEXT: {{^}} f32.call $push[[NUM:[0-9]+]]=, float_nullary@FUNCTION{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define float @call_float_nullary() { %r = call float @float_nullary() @@ -42,7 +42,7 @@ define float @call_float_nullary() { ; CHECK-LABEL: call_double_nullary: ; CHECK-NEXT: .result f64{{$}} -; CHECK-NEXT: {{^}} f64.call $push[[NUM:[0-9]+]]=, double_nullary{{$}} +; CHECK-NEXT: {{^}} f64.call $push[[NUM:[0-9]+]]=, double_nullary@FUNCTION{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define double @call_double_nullary() { %r = call double @double_nullary() @@ -50,7 +50,7 @@ define double @call_double_nullary() { } ; CHECK-LABEL: call_void_nullary: -; CHECK-NEXT: {{^}} call void_nullary{{$}} +; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} define void @call_void_nullary() { call void @void_nullary() @@ -60,7 +60,7 @@ define void @call_void_nullary() { ; CHECK-LABEL: call_i32_unary: ; CHECK-NEXT: .param i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_unary, $0{{$}} +; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_unary@FUNCTION, $0{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i32 @call_i32_unary(i32 %a) { %r = call i32 @i32_unary(i32 %a) @@ -70,7 +70,7 @@ define i32 @call_i32_unary(i32 %a) { ; CHECK-LABEL: call_i32_binary: ; CHECK-NEXT: .param i32, i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_binary, $0, $1{{$}} +; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_binary@FUNCTION, $0, $1{{$}} ; CHECK-NEXT: return $pop[[NUM]]{{$}} define i32 @call_i32_binary(i32 %a, i32 %b) { %r = call i32 @i32_binary(i32 %a, i32 %b) @@ -97,7 +97,7 @@ define i32 @call_indirect_i32(i32 ()* %callee) { } ; CHECK-LABEL: tail_call_void_nullary: -; CHECK-NEXT: {{^}} call void_nullary{{$}} +; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} define void @tail_call_void_nullary() { tail call void @void_nullary() @@ -105,7 +105,7 @@ define void @tail_call_void_nullary() { } ; CHECK-LABEL: fastcc_tail_call_void_nullary: -; CHECK-NEXT: {{^}} call void_nullary{{$}} +; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} define void @fastcc_tail_call_void_nullary() { tail call fastcc void @void_nullary() @@ -113,7 +113,7 @@ define void @fastcc_tail_call_void_nullary() { } ; CHECK-LABEL: coldcc_tail_call_void_nullary: -; CHECK-NEXT: {{^}} call void_nullary +; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} define void @coldcc_tail_call_void_nullary() { tail call coldcc void @void_nullary() diff --git a/test/CodeGen/WebAssembly/f32.ll b/test/CodeGen/WebAssembly/f32.ll index 25d057e8958..c32a7c3dc7d 100644 --- a/test/CodeGen/WebAssembly/f32.ll +++ b/test/CodeGen/WebAssembly/f32.ll @@ -146,7 +146,7 @@ define float @fmax32(float %x) { } ; CHECK-LABEL: fma32: -; CHECK: {{^}} f32.call $push0=, fmaf, $0, $1, $2{{$}} +; CHECK: {{^}} f32.call $push0=, fmaf@FUNCTION, $0, $1, $2{{$}} ; CHECK-NEXT: return $pop0{{$}} define float @fma32(float %a, float %b, float %c) { %d = call float @llvm.fma.f32(float %a, float %b, float %c) diff --git a/test/CodeGen/WebAssembly/f64.ll b/test/CodeGen/WebAssembly/f64.ll index d9c16eedf51..92284999cbf 100644 --- a/test/CodeGen/WebAssembly/f64.ll +++ b/test/CodeGen/WebAssembly/f64.ll @@ -146,7 +146,7 @@ define double @fmax64(double %x) { } ; CHECK-LABEL: fma64: -; CHECK: {{^}} f64.call $push0=, fma, $0, $1, $2{{$}} +; CHECK: {{^}} f64.call $push0=, fma@FUNCTION, $0, $1, $2{{$}} ; CHECK-NEXT: return $pop0{{$}} define double @fma64(double %a, double %b, double %c) { %d = call double @llvm.fma.f64(double %a, double %b, double %c) diff --git a/test/CodeGen/WebAssembly/frem.ll b/test/CodeGen/WebAssembly/frem.ll index 1d7ac959e5b..b8c80fbe699 100644 --- a/test/CodeGen/WebAssembly/frem.ll +++ b/test/CodeGen/WebAssembly/frem.ll @@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown" ; CHECK-LABEL: frem32: ; CHECK-NEXT: .param f32, f32{{$}} ; CHECK-NEXT: .result f32{{$}} -; CHECK-NEXT: {{^}} f32.call $push0=, fmodf, $0, $1{{$}} +; CHECK-NEXT: {{^}} f32.call $push0=, fmodf@FUNCTION, $0, $1{{$}} ; CHECK-NEXT: return $pop0{{$}} define float @frem32(float %x, float %y) { %a = frem float %x, %y @@ -18,7 +18,7 @@ define float @frem32(float %x, float %y) { ; CHECK-LABEL: frem64: ; CHECK-NEXT: .param f64, f64{{$}} ; CHECK-NEXT: .result f64{{$}} -; CHECK-NEXT: {{^}} f64.call $push0=, fmod, $0, $1{{$}} +; CHECK-NEXT: {{^}} f64.call $push0=, fmod@FUNCTION, $0, $1{{$}} ; CHECK-NEXT: return $pop0{{$}} define double @frem64(double %x, double %y) { %a = frem double %x, %y diff --git a/test/CodeGen/WebAssembly/global.ll b/test/CodeGen/WebAssembly/global.ll index f2bb8e7deac..85fe5c89656 100644 --- a/test/CodeGen/WebAssembly/global.ll +++ b/test/CodeGen/WebAssembly/global.ll @@ -21,7 +21,7 @@ define i32 @foo() { ; CHECK-LABEL: call_memcpy: ; CHECK-NEXT: .param i32, i32, i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: call memcpy, $0, $1, $2{{$}} +; CHECK-NEXT: call memcpy@FUNCTION, $0, $1, $2{{$}} ; CHECK-NEXT: return $0{{$}} declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) { diff --git a/test/CodeGen/WebAssembly/returned.ll b/test/CodeGen/WebAssembly/returned.ll index cfb96285c54..9c892bb3ece 100644 --- a/test/CodeGen/WebAssembly/returned.ll +++ b/test/CodeGen/WebAssembly/returned.ll @@ -8,8 +8,8 @@ target triple = "wasm32-unknown-unknown" ; CHECK-LABEL: _Z3foov: ; CHECK-NEXT: .result i32{{$}} ; CHECK-NEXT: i32.const $push0=, 1{{$}} -; CHECK-NEXT: {{^}} i32.call $push1=, _Znwm, $pop0{{$}} -; CHECK-NEXT: {{^}} i32.call $push2=, _ZN5AppleC1Ev, $pop1{{$}} +; CHECK-NEXT: {{^}} i32.call $push1=, _Znwm@FUNCTION, $pop0{{$}} +; CHECK-NEXT: {{^}} i32.call $push2=, _ZN5AppleC1Ev@FUNCTION, $pop1{{$}} ; CHECK-NEXT: return $pop2{{$}} %class.Apple = type { i8 } declare noalias i8* @_Znwm(i32) @@ -25,7 +25,7 @@ entry: ; CHECK-LABEL: _Z3barPvS_l: ; CHECK-NEXT: .param i32, i32, i32{{$}} ; CHECK-NEXT: .result i32{{$}} -; CHECK-NEXT: {{^}} i32.call $push0=, memcpy, $0, $1, $2{{$}} +; CHECK-NEXT: {{^}} i32.call $push0=, memcpy@FUNCTION, $0, $1, $2{{$}} ; CHECK-NEXT: return $pop0{{$}} declare i8* @memcpy(i8* returned, i8*, i32) define i8* @_Z3barPvS_l(i8* %p, i8* %s, i32 %n) { @@ -38,7 +38,7 @@ entry: ; CHECK-LABEL: test_constant_arg: ; CHECK-NEXT: i32.const $push0=, global{{$}} -; CHECK-NEXT: {{^}} i32.call $discard=, returns_arg, $pop0{{$}} +; CHECK-NEXT: {{^}} i32.call $discard=, returns_arg@FUNCTION, $pop0{{$}} ; CHECK-NEXT: return{{$}} @global = external global i32 @addr = global i32* @global diff --git a/test/CodeGen/WebAssembly/signext-zeroext.ll b/test/CodeGen/WebAssembly/signext-zeroext.ll index 48490c30dc3..f6f56363c1a 100644 --- a/test/CodeGen/WebAssembly/signext-zeroext.ll +++ b/test/CodeGen/WebAssembly/signext-zeroext.ll @@ -32,7 +32,7 @@ define zeroext i8 @s2z_func(i8 signext %t) { ; CHECK-NEXT: .result i32{{$}} ; CHECK-NEXT: i32.const $push[[NUM0:[0-9]+]]=, 255{{$}} ; CHECK-NEXT: i32.and $push[[NUM1:[0-9]+]]=, $0, $pop[[NUM0]]{{$}} -; CHECK-NEXT: call $push[[NUM2:[0-9]+]]=, z2s_func, $pop[[NUM1]]{{$}} +; CHECK-NEXT: call $push[[NUM2:[0-9]+]]=, z2s_func@FUNCTION, $pop[[NUM1]]{{$}} ; CHECK-NEXT: return $pop[[NUM2]]{{$}} define i32 @z2s_call(i32 %t) { %s = trunc i32 %t to i8 @@ -48,7 +48,7 @@ define i32 @z2s_call(i32 %t) { ; CHECK-NEXT: i32.const $[[NUM0:[0-9]+]]=, 24{{$}} ; CHECK-NEXT: i32.shl $push[[NUM1:[0-9]+]]=, $0, $[[NUM0]]{{$}} ; CHECK-NEXT: i32.shr_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]], $[[NUM0]]{{$}} -; CHECK-NEXT: call $push[[NUM3:[0-9]]]=, s2z_func, $pop[[NUM2]]{{$}} +; CHECK-NEXT: call $push[[NUM3:[0-9]]]=, s2z_func@FUNCTION, $pop[[NUM2]]{{$}} ; CHECK-NEXT: i32.shl $push[[NUM4:[0-9]+]]=, $pop[[NUM3]], $[[NUM0]]{{$}} ; CHECK-NEXT: i32.shr_s $push[[NUM5:[0-9]+]]=, $pop[[NUM4]], $[[NUM0]]{{$}} ; CHECK-NEXT: return $pop[[NUM5]]{{$}} diff --git a/test/CodeGen/WebAssembly/switch.ll b/test/CodeGen/WebAssembly/switch.ll index 04c9fb20f50..ef35ba11a0d 100644 --- a/test/CodeGen/WebAssembly/switch.ll +++ b/test/CodeGen/WebAssembly/switch.ll @@ -23,17 +23,17 @@ declare void @foo5() ; CHECK: block .LBB0_2{{$}} ; CHECK: tableswitch {{[^,]*}}, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_2, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_3, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_4, .LBB0_5, .LBB0_6, .LBB0_7{{$}} ; CHECK: .LBB0_2: -; CHECK: call foo0 +; CHECK: call foo0@FUNCTION{{$}} ; CHECK: .LBB0_3: -; CHECK: call foo1 +; CHECK: call foo1@FUNCTION{{$}} ; CHECK: .LBB0_4: -; CHECK: call foo2 +; CHECK: call foo2@FUNCTION{{$}} ; CHECK: .LBB0_5: -; CHECK: call foo3 +; CHECK: call foo3@FUNCTION{{$}} ; CHECK: .LBB0_6: -; CHECK: call foo4 +; CHECK: call foo4@FUNCTION{{$}} ; CHECK: .LBB0_7: -; CHECK: call foo5 +; CHECK: call foo5@FUNCTION{{$}} ; CHECK: .LBB0_8: ; CHECK: return{{$}} define void @bar32(i32 %n) { @@ -103,17 +103,17 @@ sw.epilog: ; preds = %entry, %sw.bb.5, %s ; CHECK: block .LBB1_2{{$}} ; CHECK: tableswitch {{[^,]*}}, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_2, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_3, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_4, .LBB1_5, .LBB1_6, .LBB1_7{{$}} ; CHECK: .LBB1_2: -; CHECK: call foo0 +; CHECK: call foo0@FUNCTION{{$}} ; CHECK: .LBB1_3: -; CHECK: call foo1 +; CHECK: call foo1@FUNCTION{{$}} ; CHECK: .LBB1_4: -; CHECK: call foo2 +; CHECK: call foo2@FUNCTION{{$}} ; CHECK: .LBB1_5: -; CHECK: call foo3 +; CHECK: call foo3@FUNCTION{{$}} ; CHECK: .LBB1_6: -; CHECK: call foo4 +; CHECK: call foo4@FUNCTION{{$}} ; CHECK: .LBB1_7: -; CHECK: call foo5 +; CHECK: call foo5@FUNCTION{{$}} ; CHECK: .LBB1_8: ; CHECK: return{{$}} define void @bar64(i64 %n) { diff --git a/test/CodeGen/WebAssembly/unreachable.ll b/test/CodeGen/WebAssembly/unreachable.ll index 2b031128350..7b23bf3cecf 100644 --- a/test/CodeGen/WebAssembly/unreachable.ll +++ b/test/CodeGen/WebAssembly/unreachable.ll @@ -12,7 +12,7 @@ declare void @llvm.debugtrap() declare void @abort() ; CHECK-LABEL: f1: -; CHECK: call abort +; CHECK: call abort@FUNCTION{{$}} ; CHECK: unreachable define i32 @f1() { call void @abort() diff --git a/test/CodeGen/WebAssembly/unused-argument.ll b/test/CodeGen/WebAssembly/unused-argument.ll index 285168cfe6d..00dea769ee8 100644 --- a/test/CodeGen/WebAssembly/unused-argument.ll +++ b/test/CodeGen/WebAssembly/unused-argument.ll @@ -22,7 +22,7 @@ define i32 @unused_second(i32 %x, i32 %y) { } ; CHECK-LABEL: call_something: -; CHECK-NEXT: {{^}} i32.call $discard=, return_something{{$}} +; CHECK-NEXT: {{^}} i32.call $discard=, return_something@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} declare i32 @return_something() define void @call_something() { diff --git a/test/CodeGen/WebAssembly/varargs.ll b/test/CodeGen/WebAssembly/varargs.ll index 95919225c79..c12264625c3 100644 --- a/test/CodeGen/WebAssembly/varargs.ll +++ b/test/CodeGen/WebAssembly/varargs.ll @@ -103,7 +103,7 @@ entry: declare void @callee(...) ; CHECK-LABEL: caller_none: -; CHECK-NEXT: call callee{{$}} +; CHECK-NEXT: call callee@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} define void @caller_none() { call void (...) @callee() -- 2.34.1