[llvm-branch-commits] [llvm] 418df4a - [WebAssembly] call_indirect issues table number relocs
Andy Wingo via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jan 19 00:39:48 PST 2021
Author: Andy Wingo
Date: 2021-01-19T09:32:45+01:00
New Revision: 418df4a6ab35d343cc0f2608c90a73dd9b8d0ab1
URL: https://github.com/llvm/llvm-project/commit/418df4a6ab35d343cc0f2608c90a73dd9b8d0ab1
DIFF: https://github.com/llvm/llvm-project/commit/418df4a6ab35d343cc0f2608c90a73dd9b8d0ab1.diff
LOG: [WebAssembly] call_indirect issues table number relocs
This patch changes to make call_indirect explicitly refer to the
corresponding function table, residualizing TABLE_NUMBER relocs against
it.
With this change, wasm-ld now sees all references to tables, and can
link multiple tables.
Differential Revision: https://reviews.llvm.org/D90948
Added:
llvm/test/MC/WebAssembly/call-indirect-relocs.s
Modified:
lld/test/wasm/call-indirect.ll
lld/test/wasm/compress-relocs.ll
lld/test/wasm/shared.ll
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/test/CodeGen/WebAssembly/function-pointer64.ll
llvm/test/CodeGen/WebAssembly/multivalue.ll
llvm/test/MC/WebAssembly/basic-assembly.s
llvm/test/MC/WebAssembly/reloc-code.ll
llvm/test/MC/WebAssembly/tail-call-encodings.s
llvm/test/MC/WebAssembly/type-index.s
llvm/test/MC/WebAssembly/weak-alias.s
Removed:
################################################################################
diff --git a/lld/test/wasm/call-indirect.ll b/lld/test/wasm/call-indirect.ll
index 4acc1edae4f2..d54647d67da1 100644
--- a/lld/test/wasm/call-indirect.ll
+++ b/lld/test/wasm/call-indirect.ll
@@ -122,16 +122,16 @@ define void @call_ptr(i64 (i64)* %arg) {
; CHECK-NEXT: Body: 42010B
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Locals:
-; CHECK-NEXT: Body: 28028088808000118080808000001A28028488808000118180808000001A0B
+; CHECK-NEXT: Body: 2802808880800011808080800080808080001A2802848880800011818080800080808080001A0B
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 41020B
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Locals:
-; CHECK-NEXT: Body: 410028028888808000118180808000001A0B
+; CHECK-NEXT: Body: 41002802888880800011818080800080808080001A0B
; CHECK-NEXT: - Index: 4
; CHECK-NEXT: Locals:
-; CHECK-NEXT: Body: 42012000118280808000001A0B
+; CHECK-NEXT: Body: 4201200011828080800080808080001A0B
; CHECK-NEXT: - Type: DATA
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 7
diff --git a/lld/test/wasm/compress-relocs.ll b/lld/test/wasm/compress-relocs.ll
index 6c3533a108a5..ccfc525d4b83 100644
--- a/lld/test/wasm/compress-relocs.ll
+++ b/lld/test/wasm/compress-relocs.ll
@@ -22,5 +22,5 @@ entry:
; ERROR: wasm-ld: error: --compress-relocations is incompatible with output debug information. Please pass --strip-debug or --strip-all
-; CHECK: Body: 28028088808000118080808000001A28028488808000118180808000001A0B
+; CHECK: Body: 2802808880800011808080800080808080001A2802848880800011818080800080808080001A0B
; COMPRESS: Body: 280280081100001A280284081101001A0B
diff --git a/lld/test/wasm/shared.ll b/lld/test/wasm/shared.ll
index 61337fcc6a3a..aca517ea7443 100644
--- a/lld/test/wasm/shared.ll
+++ b/lld/test/wasm/shared.ll
@@ -84,10 +84,6 @@ declare void @func_external()
; CHECK-NEXT: GlobalType: I32
; CHECK-NEXT: GlobalMutable: false
; CHECK-NEXT: - Module: env
-; CHECK-NEXT: Field: func_external
-; CHECK-NEXT: Kind: FUNCTION
-; CHECK-NEXT: SigIndex: 1
-; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __indirect_function_table
; CHECK-NEXT: Kind: TABLE
; CHECK-NEXT: Table:
@@ -95,6 +91,10 @@ declare void @func_external()
; CHECK-NEXT: ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x2
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: func_external
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: SigIndex: 1
; CHECK-NEXT: - Module: GOT.mem
; CHECK-NEXT: Field: indirect_func
; CHECK-NEXT: Kind: GLOBAL
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index b2d94dcadd81..70a5e503c5a1 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -405,13 +405,6 @@ void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
- // As a stopgap measure until call_indirect instructions start explicitly
- // referencing the indirect function table via TABLE_NUMBER relocs, ensure
- // that the indirect function table import makes it to the output if anything
- // in the compilation unit has caused it to be present.
- if (auto *Sym = Asm.getContext().lookupSymbol("__indirect_function_table"))
- Asm.registerSymbol(*Sym);
-
// Build a map of sections to the function that defines them, for use
// in recordRelocation.
for (const MCSymbol &S : Asm.symbols()) {
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 60ac3248b9e7..272cdfa6313c 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -472,6 +472,15 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
WebAssemblyOperand::IntOp{static_cast<int64_t>(BT)}));
}
+ void addFunctionTableOperand(OperandVector &Operands, StringRef TableName,
+ SMLoc StartLoc, SMLoc EndLoc) {
+ MCSymbolWasm *Sym = GetOrCreateFunctionTableSymbol(getContext(), TableName);
+ auto *Val = MCSymbolRefExpr::create(Sym, getContext());
+ Operands.push_back(std::make_unique<WebAssemblyOperand>(
+ WebAssemblyOperand::Symbol, StartLoc, EndLoc,
+ WebAssemblyOperand::SymOp{Val}));
+ }
+
bool ParseInstruction(ParseInstructionInfo & /*Info*/, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override {
// Note: Name does NOT point into the sourcecode, but to a local, so
@@ -508,6 +517,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
bool ExpectBlockType = false;
bool ExpectFuncType = false;
bool ExpectHeapType = false;
+ bool ExpectFunctionTable = false;
if (Name == "block") {
push(Block);
ExpectBlockType = true;
@@ -547,15 +557,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
return true;
} else if (Name == "call_indirect" || Name == "return_call_indirect") {
ExpectFuncType = true;
- // Ensure that the object file has a __indirect_function_table import, as
- // we call_indirect against it.
- auto &Ctx = getStreamer().getContext();
- MCSymbolWasm *Sym =
- GetOrCreateFunctionTableSymbol(Ctx, "__indirect_function_table");
- // Until call_indirect emits TABLE_NUMBER relocs against this symbol, mark
- // it as NO_STRIP so as to ensure that the indirect function table makes
- // it to linked output.
- Sym->setNoStrip();
+ ExpectFunctionTable = true;
} else if (Name == "ref.null") {
ExpectHeapType = true;
}
@@ -571,7 +573,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
return true;
// Got signature as block type, don't need more
ExpectBlockType = false;
- auto &Ctx = getStreamer().getContext();
+ auto &Ctx = getContext();
// The "true" here will cause this to be a nameless symbol.
MCSymbol *Sym = Ctx.createTempSymbol("typeindex", true);
auto *WasmSym = cast<MCSymbolWasm>(Sym);
@@ -583,6 +585,16 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
Operands.push_back(std::make_unique<WebAssemblyOperand>(
WebAssemblyOperand::Symbol, Loc.getLoc(), Loc.getEndLoc(),
WebAssemblyOperand::SymOp{Expr}));
+
+ // Allow additional operands after the signature, notably for
+ // call_indirect against a named table.
+ if (Lexer.isNot(AsmToken::EndOfStatement)) {
+ if (expect(AsmToken::Comma, ","))
+ return true;
+ if (Lexer.is(AsmToken::EndOfStatement)) {
+ return error("Unexpected trailing comma");
+ }
+ }
}
while (Lexer.isNot(AsmToken::EndOfStatement)) {
@@ -608,8 +620,11 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
WebAssemblyOperand::Integer, Id.getLoc(), Id.getEndLoc(),
WebAssemblyOperand::IntOp{static_cast<int64_t>(HeapType)}));
Parser.Lex();
+ } else if (ExpectFunctionTable) {
+ addFunctionTableOperand(Operands, Id.getString(), Id.getLoc(),
+ Id.getEndLoc());
+ Parser.Lex();
} else {
- // Assume this identifier is a label.
const MCExpr *Val;
SMLoc End;
if (Parser.parseExpression(Val, End))
@@ -674,6 +689,11 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
// Support blocks with no operands as default to void.
addBlockTypeOperand(Operands, NameLoc, WebAssembly::BlockType::Void);
}
+ if (ExpectFunctionTable && Operands.size() == 2) {
+ // If call_indirect doesn't specify a target table, supply one.
+ addFunctionTableOperand(Operands, "__indirect_function_table", NameLoc,
+ SMLoc::getFromPointer(Name.end()));
+ }
Parser.Lex();
return false;
}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index fb8b0c364f30..20937254e67b 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -68,7 +68,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
for (auto I = Start, E = MI->getNumOperands(); I < E; ++I) {
if (MI->getOpcode() == WebAssembly::CALL_INDIRECT &&
I - Start == NumVariadicDefs) {
- // Skip type and flags arguments when printing for tests
+ // Skip type and table arguments when printing for tests.
++I;
continue;
}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index 5b77b8495adf..1696ba3f6358 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -401,6 +401,16 @@ inline bool isCallIndirect(unsigned Opc) {
}
}
+inline bool isRetCallIndirect(unsigned Opc) {
+ switch (Opc) {
+ case WebAssembly::RET_CALL_INDIRECT:
+ case WebAssembly::RET_CALL_INDIRECT_S:
+ return true;
+ default:
+ return false;
+ }
+}
+
inline bool isBrTable(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::BR_TABLE_I32:
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 82b032267d55..9279e69e0ece 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -869,18 +869,11 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
if (IsDirect) {
MIB.addGlobalAddress(Func);
} else {
- // Add placeholders for the type index and immediate flags
+ // Placehoder for the type index.
MIB.addImm(0);
- MIB.addImm(0);
-
- // Ensure that the object file has a __indirect_function_table import, as we
- // call_indirect against it.
- MCSymbolWasm *Sym = WebAssembly::getOrCreateFunctionTableSymbol(
- MF->getMMI().getContext(), "__indirect_function_table");
- // Until call_indirect emits TABLE_NUMBER relocs against this symbol, mark
- // it as NO_STRIP so as to ensure that the indirect function table makes it
- // to linked output.
- Sym->setNoStrip();
+ // The table into which this call_indirect indexes.
+ MIB.addSym(WebAssembly::getOrCreateFunctionTableSymbol(
+ MF->getMMI().getContext(), "__indirect_function_table"));
}
for (unsigned ArgReg : Args)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index e348bba2b04c..59a0ba9ff592 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -475,19 +475,12 @@ static MachineBasicBlock *LowerCallResults(MachineInstr &CallResults,
for (auto Def : CallResults.defs())
MIB.add(Def);
- // Add placeholders for the type index and immediate flags
if (IsIndirect) {
+ // Placehoder for the type index.
MIB.addImm(0);
- MIB.addImm(0);
-
- // Ensure that the object file has a __indirect_function_table import, as we
- // call_indirect against it.
- MCSymbolWasm *Sym = WebAssembly::getOrCreateFunctionTableSymbol(
- MF.getContext(), "__indirect_function_table");
- // Until call_indirect emits TABLE_NUMBER relocs against this symbol, mark
- // it as NO_STRIP so as to ensure that the indirect function table makes it
- // to linked output.
- Sym->setNoStrip();
+ // The table into which this call_indirect indexes.
+ MIB.addSym(WebAssembly::getOrCreateFunctionTableSymbol(
+ MF.getContext(), "__indirect_function_table"));
}
for (auto Use : CallParams.uses())
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
index b997c1c16fcb..6a123f8f4030 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
@@ -48,6 +48,9 @@ defm RET_CALL_RESULTS :
I<(outs), (ins variable_ops), (outs), (ins), [],
"return_call_results", "return_call_results", -1>;
+// Note that instructions with variable_ops have custom printers in
+// WebAssemblyInstPrinter.cpp.
+
let variadicOpsAreDefs = 1 in
defm CALL :
I<(outs), (ins function32_op:$callee, variable_ops),
@@ -56,9 +59,12 @@ defm CALL :
let variadicOpsAreDefs = 1 in
defm CALL_INDIRECT :
- I<(outs), (ins TypeIndex:$type, i32imm:$flags, variable_ops),
- (outs), (ins TypeIndex:$type, i32imm:$flags), [],
- "call_indirect", "call_indirect\t$type", 0x11>;
+ I<(outs),
+ (ins TypeIndex:$type, table32_op:$table, variable_ops),
+ (outs),
+ (ins TypeIndex:$type, table32_op:$table),
+ [],
+ "call_indirect", "call_indirect\t$type, $table", 0x11>;
let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in
defm RET_CALL :
@@ -69,9 +75,9 @@ defm RET_CALL :
let isReturn = 1 in
defm RET_CALL_INDIRECT :
- I<(outs), (ins TypeIndex:$type, i32imm:$flags, variable_ops),
- (outs), (ins TypeIndex:$type, i32imm:$flags), [],
- "return_call_indirect\t", "return_call_indirect\t$type",
+ I<(outs), (ins TypeIndex:$type, table32_op:$table, variable_ops),
+ (outs), (ins TypeIndex:$type, table32_op:$table), [],
+ "return_call_indirect\t", "return_call_indirect\t$type, $table",
0x13>,
Requires<[HasTailCall]>;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index 86d59ef807ab..8923ecb20266 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -161,6 +161,8 @@ MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
report_fatal_error("Global indexes with offsets not supported");
if (WasmSym->isEvent())
report_fatal_error("Event indexes with offsets not supported");
+ if (WasmSym->isTable())
+ report_fatal_error("Table indexes with offsets not supported");
Expr = MCBinaryExpr::createAdd(
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
@@ -259,7 +261,7 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
// return_call_indirect instructions have the return type of the
// caller
- if (MI->getOpcode() == WebAssembly::RET_CALL_INDIRECT)
+ if (WebAssembly::isRetCallIndirect(MI->getOpcode()))
getFunctionReturns(MI, Returns);
MCOp = lowerTypeIndexOperand(std::move(Returns), std::move(Params));
diff --git a/llvm/test/CodeGen/WebAssembly/function-pointer64.ll b/llvm/test/CodeGen/WebAssembly/function-pointer64.ll
index 6b279cfb6ec0..699844a08726 100644
--- a/llvm/test/CodeGen/WebAssembly/function-pointer64.ll
+++ b/llvm/test/CodeGen/WebAssembly/function-pointer64.ll
@@ -34,14 +34,15 @@ entry:
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.wrap_i64
-; CHECK-NEXT: call_indirect (i32) -> ()
+; CHECK-NEXT: call_indirect (i32) -> (), __indirect_function_table
; CHECK: .functype test () -> ()
; CHECK-NEXT: i64.const bar
; CHECK-NEXT: call foo
-; Check we're emitting a 64-bit reloc for `i64.const bar` and the global.
+; Check we're emitting a 64-bit relocs for the call_indirect, the
+; `i64.const bar` reference in code, and the global.
; YAML: Memory:
; YAML-NEXT: Flags: [ IS_64 ]
@@ -50,7 +51,10 @@ entry:
; YAML: - Type: CODE
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
; YAML-NEXT: Index: 0
-; YAML-NEXT: Offset: 0x16
+; YAML-NEXT: Offset: 0x1A
+; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
+; YAML-NEXT: Index: 0
+; YAML-NEXT: Offset: 0x2D
; YAML: - Type: DATA
; YAML: - Type: R_WASM_TABLE_INDEX_I64
diff --git a/llvm/test/CodeGen/WebAssembly/multivalue.ll b/llvm/test/CodeGen/WebAssembly/multivalue.ll
index d5dfcacb6a2b..3de6c2581fbf 100644
--- a/llvm/test/CodeGen/WebAssembly/multivalue.ll
+++ b/llvm/test/CodeGen/WebAssembly/multivalue.ll
@@ -57,7 +57,7 @@ define %pair @pair_call_return() {
; CHECK-LABEL: pair_call_indirect:
; CHECK-NEXT: .functype pair_call_indirect (i32) -> (i32, i64)
; CHECK-NEXT: local.get 0{{$}}
-; CHECK-NEXT: call_indirect () -> (i32, i64){{$}}
+; CHECK-NEXT: call_indirect () -> (i32, i64), __indirect_function_table{{$}}
; CHECK-NEXT: end_function{{$}}
; REGS: call_indirect $push{{[0-9]+}}=, $push{{[0-9]+}}=, $0{{$}}
define %pair @pair_call_indirect(%pair()* %f) {
diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s
index 786100d91e5c..cbb70f13ed3b 100644
--- a/llvm/test/MC/WebAssembly/basic-assembly.s
+++ b/llvm/test/MC/WebAssembly/basic-assembly.s
@@ -153,7 +153,7 @@ empty_fref_table:
# CHECK-NEXT: i64.const 1234
# CHECK-NEXT: call something2
# CHECK-NEXT: i32.const 0
-# CHECK-NEXT: call_indirect (i32, f64) -> ()
+# CHECK-NEXT: call_indirect (i32, f64) -> (), __indirect_function_table
# CHECK-NEXT: i32.const 1
# CHECK-NEXT: i32.add
# CHECK-NEXT: local.tee 0
diff --git a/llvm/test/MC/WebAssembly/call-indirect-relocs.s b/llvm/test/MC/WebAssembly/call-indirect-relocs.s
new file mode 100644
index 000000000000..12a1cb017c5d
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/call-indirect-relocs.s
@@ -0,0 +1,83 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown < %s | FileCheck %s
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj < %s | obj2yaml | FileCheck -check-prefix=BIN %s
+
+test0:
+ .functype test0 () -> ()
+ i32.const 42
+ f64.const 2.5
+ i32.const 0
+ call_indirect (i32, f64) -> (), empty_fref_table
+ end_function
+
+.tabletype empty_fref_table, funcref
+empty_fref_table:
+
+
+# CHECK: .text
+# CHECK-LABEL: test0:
+# CHECK-NEXT: .functype test0 () -> ()
+# CHECK-NEXT: i32.const 42
+# CHECK-NEXT: f64.const 0x1.4p1
+# CHECK-NEXT: i32.const 0
+# CHECK-NEXT: call_indirect (i32, f64) -> (), empty_fref_table
+# CHECK-NEXT: end_function
+
+# CHECK: .tabletype empty_fref_table, funcref
+# CHECK: empty_fref_table:
+
+# BIN: --- !WASM
+# BIN-NEXT: FileHeader:
+# BIN-NEXT: Version: 0x1
+# BIN-NEXT: Sections:
+# BIN-NEXT: - Type: TYPE
+# BIN-NEXT: Signatures:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: ParamTypes: []
+# BIN-NEXT: ReturnTypes: []
+# BIN-NEXT: - Index: 1
+# BIN-NEXT: ParamTypes:
+# BIN-NEXT: - I32
+# BIN-NEXT: - F64
+# BIN-NEXT: ReturnTypes: []
+# BIN-NEXT: - Type: IMPORT
+# BIN-NEXT: Imports:
+# BIN-NEXT: - Module: env
+# BIN-NEXT: Field: __linear_memory
+# BIN-NEXT: Kind: MEMORY
+# BIN-NEXT: Memory:
+# BIN-NEXT: Initial: 0x0
+# BIN-NEXT: - Type: FUNCTION
+# BIN-NEXT: FunctionTypes: [ 0 ]
+# BIN-NEXT: - Type: TABLE
+# BIN-NEXT: Tables:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: ElemType: FUNCREF
+# BIN-NEXT: Limits:
+# BIN-NEXT: Initial: 0x0
+# BIN-NEXT: - Type: CODE
+# BIN-NEXT: Relocations:
+# BIN-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
+# BIN-NEXT: Index: 1
+# BIN-NEXT: Offset: 0x11
+# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
+# BIN-NEXT: Index: 1
+# BIN-NEXT: Offset: 0x16
+# BIN-NEXT: Functions:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: Locals: []
+# BIN-NEXT: Body: 412A440000000000000440410011818080800080808080000B
+# BIN-NEXT: - Type: CUSTOM
+# BIN-NEXT: Name: linking
+# BIN-NEXT: Version: 2
+# BIN-NEXT: SymbolTable:
+# BIN-NEXT: - Index: 0
+# BIN-NEXT: Kind: FUNCTION
+# BIN-NEXT: Name: test0
+# BIN-NEXT: Flags: [ BINDING_LOCAL ]
+# BIN-NEXT: Function: 0
+# BIN-NEXT: - Index: 1
+# BIN-NEXT: Kind: TABLE
+# BIN-NEXT: Name: empty_fref_table
+# BIN-NEXT: Flags: [ BINDING_LOCAL ]
+# BIN-NEXT: Table: 0
+# BIN-NEXT: ...
diff --git a/llvm/test/MC/WebAssembly/reloc-code.ll b/llvm/test/MC/WebAssembly/reloc-code.ll
index 0aafeabec5ca..08784c6fdf91 100644
--- a/llvm/test/MC/WebAssembly/reloc-code.ll
+++ b/llvm/test/MC/WebAssembly/reloc-code.ll
@@ -43,18 +43,28 @@ entry:
; CHECK-NEXT: Index: 0x1
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
+; CHECK-NEXT: Type: R_WASM_TABLE_NUMBER_LEB (20)
+; CHECK-NEXT: Offset: 0x1F
+; CHECK-NEXT: Symbol: __indirect_function_table
+; CHECK-NEXT: }
+; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WASM_TYPE_INDEX_LEB (6)
-; CHECK-NEXT: Offset: 0x24
+; CHECK-NEXT: Offset: 0x28
; CHECK-NEXT: Index: 0x0
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
-; CHECK-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
+; CHECK-NEXT: Type: R_WASM_TABLE_NUMBER_LEB (20)
; CHECK-NEXT: Offset: 0x2D
+; CHECK-NEXT: Symbol: __indirect_function_table
+; CHECK-NEXT: }
+; CHECK-NEXT: Relocation {
+; CHECK-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
+; CHECK-NEXT: Offset: 0x35
; CHECK-NEXT: Symbol: c
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WASM_FUNCTION_INDEX_LEB (0)
-; CHECK-NEXT: Offset: 0x34
+; CHECK-NEXT: Offset: 0x3C
; CHECK-NEXT: Symbol: d
; CHECK-NEXT: }
; CHECK-NEXT: }
diff --git a/llvm/test/MC/WebAssembly/tail-call-encodings.s b/llvm/test/MC/WebAssembly/tail-call-encodings.s
index 405e6337f5fa..814793f5c370 100644
--- a/llvm/test/MC/WebAssembly/tail-call-encodings.s
+++ b/llvm/test/MC/WebAssembly/tail-call-encodings.s
@@ -16,7 +16,7 @@ foo1:
foo2:
.functype foo2 () -> ()
- # CHECK: return_call_indirect (i32) -> (i32) # encoding: [0x13,
+ # CHECK: return_call_indirect (i32) -> (i32), __indirect_function_table # encoding: [0x13,
# CHECK-NEXT: fixup A - offset: 1, value: .Ltypeindex0 at TYPEINDEX, kind: fixup_uleb128_i32
return_call_indirect (i32) -> (i32)
diff --git a/llvm/test/MC/WebAssembly/type-index.s b/llvm/test/MC/WebAssembly/type-index.s
index dfaaad53506b..9ae0ef3f829a 100644
--- a/llvm/test/MC/WebAssembly/type-index.s
+++ b/llvm/test/MC/WebAssembly/type-index.s
@@ -53,10 +53,13 @@ test0:
# BIN-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
# BIN-NEXT: Index: 1
# BIN-NEXT: Offset: 0x4
+# BIN-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
+# BIN-NEXT: Index: 1
+# BIN-NEXT: Offset: 0x9
# BIN-NEXT: Functions:
# BIN-NEXT: - Index: 0
# BIN-NEXT: Locals: []
-# BIN-NEXT: Body: 118180808000000B
+# BIN-NEXT: Body: 11818080800080808080000B
# BIN-NEXT: - Type: CUSTOM
# BIN-NEXT: Name: linking
# BIN-NEXT: Version: 2
@@ -69,6 +72,6 @@ test0:
# BIN-NEXT: - Index: 1
# BIN-NEXT: Kind: TABLE
# BIN-NEXT: Name: __indirect_function_table
-# BIN-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
+# BIN-NEXT: Flags: [ UNDEFINED ]
# BIN-NEXT: Table: 0
# BIN-NEXT: ...
diff --git a/llvm/test/MC/WebAssembly/weak-alias.s b/llvm/test/MC/WebAssembly/weak-alias.s
index 139a681eeea0..22a32fa211ed 100644
--- a/llvm/test/MC/WebAssembly/weak-alias.s
+++ b/llvm/test/MC/WebAssembly/weak-alias.s
@@ -78,7 +78,7 @@ alias_address:
# CHECK: - Type: TYPE
# CHECK-NEXT: Signatures:
# CHECK-NEXT: - Index: 0
-# CHECK-NEXT: ParamTypes:
+# CHECK-NEXT: ParamTypes: []
# CHECK-NEXT: ReturnTypes:
# CHECK-NEXT: - I32
# CHECK-NEXT: - Type: IMPORT
@@ -120,28 +120,34 @@ alias_address:
# CHECK-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
# CHECK-NEXT: Index: 0
# CHECK-NEXT: Offset: 0x24
+# CHECK-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
+# CHECK-NEXT: Index: 6
+# CHECK-NEXT: Offset: 0x29
# CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB
-# CHECK-NEXT: Index: 7
-# CHECK-NEXT: Offset: 0x31
+# CHECK-NEXT: Index: 8
+# CHECK-NEXT: Offset: 0x35
# CHECK-NEXT: - Type: R_WASM_TYPE_INDEX_LEB
# CHECK-NEXT: Index: 0
-# CHECK-NEXT: Offset: 0x37
+# CHECK-NEXT: Offset: 0x3B
+# CHECK-NEXT: - Type: R_WASM_TABLE_NUMBER_LEB
+# CHECK-NEXT: Index: 6
+# CHECK-NEXT: Offset: 0x40
# CHECK-NEXT: Functions:
# CHECK-NEXT: - Index: 0
-# CHECK-NEXT: Locals:
+# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 41000B
# CHECK-NEXT: - Index: 1
-# CHECK-NEXT: Locals:
+# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 1080808080000B
# CHECK-NEXT: - Index: 2
-# CHECK-NEXT: Locals:
+# CHECK-NEXT: Locals: []
# CHECK-NEXT: Body: 1080808080000B
# CHECK-NEXT: - Index: 3
-# CHECK-NEXT: Locals:
-# CHECK-NEXT: Body: 410028028880808000118080808000000B
+# CHECK-NEXT: Locals: []
+# CHECK-NEXT: Body: 41002802888080800011808080800080808080000B
# CHECK-NEXT: - Index: 4
-# CHECK-NEXT: Locals:
-# CHECK-NEXT: Body: 410028029080808000118080808000000B
+# CHECK-NEXT: Locals: []
+# CHECK-NEXT: Body: 41002802908080800011808080800080808080000B
# CHECK-NEXT: - Type: DATA
# CHECK-NEXT: Relocations:
# CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
@@ -205,46 +211,46 @@ alias_address:
# CHECK-NEXT: Segment: 1
# CHECK-NEXT: Size: 4
# CHECK-NEXT: - Index: 6
+# CHECK-NEXT: Kind: TABLE
+# CHECK-NEXT: Name: __indirect_function_table
+# CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
+# CHECK-NEXT: Table: 0
+# CHECK-NEXT: - Index: 7
# CHECK-NEXT: Kind: FUNCTION
# CHECK-NEXT: Name: call_alias_ptr
# CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
# CHECK-NEXT: Function: 4
-# CHECK-NEXT: - Index: 7
+# CHECK-NEXT: - Index: 8
# CHECK-NEXT: Kind: DATA
# CHECK-NEXT: Name: alias_address
# CHECK-NEXT: Flags: [ ]
# CHECK-NEXT: Segment: 2
# CHECK-NEXT: Size: 4
-# CHECK-NEXT: - Index: 8
+# CHECK-NEXT: - Index: 9
# CHECK-NEXT: Kind: DATA
# CHECK-NEXT: Name: bar
# CHECK-NEXT: Flags: [ ]
# CHECK-NEXT: Segment: 0
# CHECK-NEXT: Size: 4
-# CHECK-NEXT: - Index: 9
+# CHECK-NEXT: - Index: 10
# CHECK-NEXT: Kind: DATA
# CHECK-NEXT: Name: bar_alias
# CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, NO_STRIP ]
# CHECK-NEXT: Segment: 0
# CHECK-NEXT: Size: 4
-# CHECK-NEXT: - Index: 10
-# CHECK-NEXT: Kind: TABLE
-# CHECK-NEXT: Name: __indirect_function_table
-# CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ]
-# CHECK-NEXT: Table: 0
# CHECK-NEXT: SegmentInfo:
# CHECK-NEXT: - Index: 0
# CHECK-NEXT: Name: .data.bar
# CHECK-NEXT: Alignment: 3
-# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Flags: [ ]
# CHECK-NEXT: - Index: 1
# CHECK-NEXT: Name: .data.direct_address
# CHECK-NEXT: Alignment: 3
-# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Flags: [ ]
# CHECK-NEXT: - Index: 2
# CHECK-NEXT: Name: .data.alias_address
# CHECK-NEXT: Alignment: 3
-# CHECK-NEXT: Flags: [ ]
+# CHECK-NEXT: Flags: [ ]
# CHECK-NEXT: ...
# CHECK-SYMS: SYMBOL TABLE:
More information about the llvm-branch-commits
mailing list