Skip to content

Commit 39d32b2

Browse files
authored
[WebAssembly] Use 64-bit table when targeting wasm64 (#92042)
See WebAssembly/memory64#51
1 parent 8f5a232 commit 39d32b2

File tree

10 files changed

+14
-80
lines changed

10 files changed

+14
-80
lines changed

lld/test/wasm/shared64.s

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ get_local_func_address:
154154
# CHECK-NEXT: Index: 0
155155
# CHECK-NEXT: ElemType: FUNCREF
156156
# CHECK-NEXT: Limits:
157+
# CHECK-NEXT: Flags: [ IS_64 ]
157158
# CHECK-NEXT: Minimum: 0x2
158159
# CHECK-NEXT: - Module: env
159160
# CHECK-NEXT: Field: __stack_pointer
@@ -170,11 +171,6 @@ get_local_func_address:
170171
# CHECK-NEXT: Kind: GLOBAL
171172
# CHECK-NEXT: GlobalType: I64
172173
# CHECK-NEXT: GlobalMutable: false
173-
# CHECK-NEXT: - Module: env
174-
# CHECK-NEXT: Field: __table_base32
175-
# CHECK-NEXT: Kind: GLOBAL
176-
# CHECK-NEXT: GlobalType: I32
177-
# CHECK-NEXT: GlobalMutable: false
178174
# CHECK-NEXT: - Module: GOT.mem
179175
# CHECK-NEXT: Field: indirect_func
180176
# CHECK-NEXT: Kind: GLOBAL
@@ -209,7 +205,7 @@ get_local_func_address:
209205
# CHECK-NEXT: Segments:
210206
# CHECK-NEXT: - Offset:
211207
# CHECK-NEXT: Opcode: GLOBAL_GET
212-
# CHECK-NEXT: Index: 3
208+
# CHECK-NEXT: Index: 2
213209
# CHECK-NEXT: Functions: [ 3, 2 ]
214210

215211
# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions
@@ -223,7 +219,7 @@ get_local_func_address:
223219
# DIS-NEXT: i64.const 4
224220
# DIS-NEXT: global.get 1
225221
# DIS-NEXT: i64.add
226-
# DIS-NEXT: global.get 5
222+
# DIS-NEXT: global.get 4
227223
# DIS-NEXT: i64.store 0:p2align=2
228224
# DIS-NEXT: i64.const 12
229225
# DIS-NEXT: global.get 1
@@ -242,12 +238,12 @@ get_local_func_address:
242238
# DIS-NEXT: i64.const 24
243239
# DIS-NEXT: global.get 1
244240
# DIS-NEXT: i64.add
245-
# DIS-NEXT: global.get 6
241+
# DIS-NEXT: global.get 5
246242
# DIS-NEXT: i64.store 0:p2align=2
247243
# DIS-NEXT: i64.const 32
248244
# DIS-NEXT: global.get 1
249245
# DIS-NEXT: i64.add
250-
# DIS-NEXT: global.get 7
246+
# DIS-NEXT: global.get 6
251247
# DIS-NEXT: i32.const 4
252248
# DIS-NEXT: i32.add
253249
# DIS-NEXT: i32.store 0

lld/wasm/Driver.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -870,13 +870,6 @@ static void createSyntheticSymbols() {
870870
WasmSym::tableBase = createUndefinedGlobal("__table_base", globalType);
871871
WasmSym::memoryBase->markLive();
872872
WasmSym::tableBase->markLive();
873-
if (is64) {
874-
WasmSym::tableBase32 =
875-
createUndefinedGlobal("__table_base32", &globalTypeI32);
876-
WasmSym::tableBase32->markLive();
877-
} else {
878-
WasmSym::tableBase32 = nullptr;
879-
}
880873
} else {
881874
// For non-PIC code
882875
WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true);
@@ -923,9 +916,6 @@ static void createOptionalSymbols() {
923916
WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end");
924917
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
925918
WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
926-
if (config->is64.value_or(false))
927-
WasmSym::definedTableBase32 =
928-
symtab->addOptionalDataSymbol("__table_base32");
929919
}
930920

931921
// For non-shared memory programs we still need to define __tls_base since we

lld/wasm/Symbols.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ GlobalSymbol *WasmSym::tlsSize;
9696
GlobalSymbol *WasmSym::tlsAlign;
9797
UndefinedGlobal *WasmSym::tableBase;
9898
DefinedData *WasmSym::definedTableBase;
99-
UndefinedGlobal *WasmSym::tableBase32;
100-
DefinedData *WasmSym::definedTableBase32;
10199
UndefinedGlobal *WasmSym::memoryBase;
102100
DefinedData *WasmSym::definedMemoryBase;
103101
TableSymbol *WasmSym::indirectFunctionTable;

lld/wasm/Symbols.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -603,11 +603,6 @@ struct WasmSym {
603603
// Used in PIC code for offset of indirect function table
604604
static UndefinedGlobal *tableBase;
605605
static DefinedData *definedTableBase;
606-
// 32-bit copy in wasm64 to work around init expr limitations.
607-
// These can potentially be removed again once we have
608-
// https://github.com/WebAssembly/extended-const
609-
static UndefinedGlobal *tableBase32;
610-
static DefinedData *definedTableBase32;
611606

612607
// __memory_base
613608
// Used in PIC code for offset of global data

lld/wasm/SyntheticSections.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,10 @@ void ElemSection::writeBody() {
584584
initExpr.Extended = false;
585585
if (ctx.isPic) {
586586
initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET;
587-
initExpr.Inst.Value.Global =
588-
(config->is64.value_or(false) ? WasmSym::tableBase32
589-
: WasmSym::tableBase)
590-
->getGlobalIndex();
587+
initExpr.Inst.Value.Global = WasmSym::tableBase->getGlobalIndex();
591588
} else {
592-
initExpr.Inst.Opcode = WASM_OPCODE_I32_CONST;
589+
bool is64 = config->is64.value_or(false);
590+
initExpr.Inst.Opcode = is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
593591
initExpr.Inst.Value.Int32 = config->tableBase;
594592
}
595593
writeInitExpr(os, initExpr);

lld/wasm/Writer.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,8 @@ static void finalizeIndirectFunctionTable() {
939939
limits.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
940940
limits.Maximum = limits.Minimum;
941941
}
942+
if (config->is64.value_or(false))
943+
limits.Flags |= WASM_LIMITS_FLAG_IS_64;
942944
WasmSym::indirectFunctionTable->setLimits(limits);
943945
}
944946

@@ -1691,12 +1693,8 @@ void Writer::createSyntheticSectionsPostLayout() {
16911693
void Writer::run() {
16921694
// For PIC code the table base is assigned dynamically by the loader.
16931695
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
1694-
if (!ctx.isPic) {
1695-
if (WasmSym::definedTableBase)
1696-
WasmSym::definedTableBase->setVA(config->tableBase);
1697-
if (WasmSym::definedTableBase32)
1698-
WasmSym::definedTableBase32->setVA(config->tableBase);
1699-
}
1696+
if (!ctx.isPic && WasmSym::definedTableBase)
1697+
WasmSym::definedTableBase->setVA(config->tableBase);
17001698

17011699
log("-- createOutputSegments");
17021700
createOutputSegments();

llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -885,18 +885,6 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
885885
Table->setNoStrip();
886886
MIB.addImm(0);
887887
}
888-
// See if we must truncate the function pointer.
889-
// CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
890-
// as 64-bit for uniformity with other pointer types.
891-
// See also: WebAssemblyISelLowering.cpp: LowerCallResults
892-
if (Subtarget->hasAddr64()) {
893-
auto Wrap = BuildMI(*FuncInfo.MBB, std::prev(FuncInfo.InsertPt), MIMD,
894-
TII.get(WebAssembly::I32_WRAP_I64));
895-
Register Reg32 = createResultReg(&WebAssembly::I32RegClass);
896-
Wrap.addReg(Reg32, RegState::Define);
897-
Wrap.addReg(CalleeReg);
898-
CalleeReg = Reg32;
899-
}
900888
}
901889

902890
for (unsigned ArgReg : Args)

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -576,20 +576,6 @@ LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB,
576576
const MCInstrDesc &MCID = TII.get(CallOp);
577577
MachineInstrBuilder MIB(MF, MF.CreateMachineInstr(MCID, DL));
578578

579-
// See if we must truncate the function pointer.
580-
// CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
581-
// as 64-bit for uniformity with other pointer types.
582-
// See also: WebAssemblyFastISel::selectCall
583-
if (IsIndirect && MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()) {
584-
Register Reg32 =
585-
MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
586-
auto &FnPtr = CallParams.getOperand(0);
587-
BuildMI(*BB, CallResults.getIterator(), DL,
588-
TII.get(WebAssembly::I32_WRAP_I64), Reg32)
589-
.addReg(FnPtr.getReg());
590-
FnPtr.setReg(Reg32);
591-
}
592-
593579
// Move the function pointer to the end of the arguments for indirect calls
594580
if (IsIndirect) {
595581
auto FnPtr = CallParams.getOperand(0);

llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll

Lines changed: 0 additions & 14 deletions
This file was deleted.

llvm/test/CodeGen/WebAssembly/function-pointer64.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ entry:
3434
; CHECK: .functype foo (i64) -> ()
3535
; CHECK-NEXT: i32.const 1
3636
; CHECK-NEXT: local.get 0
37-
; CHECK-NEXT: i32.wrap_i64
3837
; CHECK-NEXT: call_indirect (i32) -> ()
3938
; REF: call_indirect __indirect_function_table, (i32) -> ()
4039

@@ -53,10 +52,10 @@ entry:
5352
; YAML: - Type: CODE
5453
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
5554
; YAML-NEXT: Index: 0
56-
; YAML-NEXT: Offset: 0x16
55+
; YAML-NEXT: Offset: 0x15
5756
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
5857
; YAML-NEXT: Index: 0
59-
; YAML-NEXT: Offset: 0x29
58+
; YAML-NEXT: Offset: 0x28
6059

6160
; YAML: - Type: DATA
6261
; YAML: - Type: R_WASM_TABLE_INDEX_I64

0 commit comments

Comments
 (0)