From 0d9b17d0efe065f23b7f1c1f8f2b2b32491abd45 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Thu, 28 Jan 2021 16:38:24 -0800 Subject: [PATCH] [WebAssembly] fixed wasm64 data segment init exp not 64-bit As defined in the spec: https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md Differential Revision: https://reviews.llvm.org/D95651 --- lld/test/wasm/data-layout.ll | 6 ++++-- lld/test/wasm/data-segments.ll | 15 +++++++++++---- lld/wasm/OutputSections.cpp | 6 ++++-- llvm/lib/MC/WasmObjectWriter.cpp | 4 ++-- llvm/test/MC/WebAssembly/data-section.s | 12 ++++++++++-- llvm/test/MC/WebAssembly/wasm64.s | 2 +- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/lld/test/wasm/data-layout.ll b/lld/test/wasm/data-layout.ll index 0709430aff82..0074517925e9 100644 --- a/lld/test/wasm/data-layout.ll +++ b/lld/test/wasm/data-layout.ll @@ -52,13 +52,15 @@ ; CHECK-NEXT: - SectionOffset: 7 ; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: -; CHECK-NEXT: Opcode: I32_CONST +; CHK32-NEXT: Opcode: I32_CONST +; CHK64-NEXT: Opcode: I64_CONST ; CHECK-NEXT: Value: 1024 ; CHECK-NEXT: Content: 68656C6C6F0A00 ; CHECK-NEXT: - SectionOffset: 20 ; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: -; CHECK-NEXT: Opcode: I32_CONST +; CHK32-NEXT: Opcode: I32_CONST +; CHK64-NEXT: Opcode: I64_CONST ; CHECK-NEXT: Value: 1040 diff --git a/lld/test/wasm/data-segments.ll b/lld/test/wasm/data-segments.ll index 8c4c4ca79672..1af6dccce457 100644 --- a/lld/test/wasm/data-segments.ll +++ b/lld/test/wasm/data-segments.ll @@ -1,5 +1,6 @@ ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.o -mattr=+atomics ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.bulk-mem.o -mattr=+bulk-memory +; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o %t.bulk-mem64.o -mattr=+bulk-memory ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem.o -mattr=+atomics,+bulk-memory ; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem64.o -mattr=+atomics,+bulk-memory ; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.atomics.bulk-mem.pic.o -relocation-model=pic -mattr=+atomics,+bulk-memory,+mutable-globals @@ -10,13 +11,17 @@ ; bulk memory, unshared memory => active segments ; RUN: wasm-ld -no-gc-sections --no-entry %t.bulk-mem.o -o %t.bulk-mem.wasm -; RUN: obj2yaml %t.bulk-mem.wasm | FileCheck %s --check-prefix ACTIVE +; RUN: obj2yaml %t.bulk-mem.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE32 + +; bulk memory, unshared memory, wasm64 => active segments +; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry %t.bulk-mem64.o -o %t.bulk-mem64.wasm +; RUN: obj2yaml %t.bulk-mem64.wasm | FileCheck %s --check-prefixes ACTIVE,ACTIVE64 ; atomics, bulk memory, shared memory => passive segments ; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.o -o %t.atomics.bulk-mem.wasm ; RUN: obj2yaml %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefixes PASSIVE,PASSIVE32 -; Also test with wasm64 +; atomics, bulk memory, shared memory, wasm64 => passive segments ; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem64.o -o %t.atomics.bulk-mem64.wasm ; RUN: obj2yaml %t.atomics.bulk-mem64.wasm | FileCheck %s --check-prefixes PASSIVE,PASSIVE64 @@ -48,13 +53,15 @@ ; ACTIVE-NEXT: - SectionOffset: 7 ; ACTIVE-NEXT: InitFlags: 0 ; ACTIVE-NEXT: Offset: -; ACTIVE-NEXT: Opcode: I32_CONST +; ACTIVE32-NEXT: Opcode: I32_CONST +; ACTIVE64-NEXT: Opcode: I64_CONST ; ACTIVE-NEXT: Value: 1024 ; ACTIVE-NEXT: Content: 636F6E7374616E74000000002B ; ACTIVE-NEXT: - SectionOffset: 26 ; ACTIVE-NEXT: InitFlags: 0 ; ACTIVE-NEXT: Offset: -; ACTIVE-NEXT: Opcode: I32_CONST +; ACTIVE32-NEXT: Opcode: I32_CONST +; ACTIVE64-NEXT: Opcode: I64_CONST ; ACTIVE-NEXT: Value: 1040 ; ACTIVE-NEXT: Content: 68656C6C6F00676F6F646279650000002A000000 ; ACTIVE-NEXT: - Type: CUSTOM diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp index 47ad1891efa0..daa877604c0b 100644 --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -161,10 +161,12 @@ void DataSection::finalizeContents() { if (config->isPic) { initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; initExpr.Value.Global = WasmSym::memoryBase->getGlobalIndex(); + } else if (config->is64.getValueOr(false)) { + initExpr.Opcode = WASM_OPCODE_I64_CONST; + initExpr.Value.Int64 = static_cast(segment->startVA); } else { - // FIXME(wvo): I64? initExpr.Opcode = WASM_OPCODE_I32_CONST; - initExpr.Value.Int32 = segment->startVA; + initExpr.Value.Int32 = static_cast(segment->startVA); } writeInitExpr(os, initExpr); } diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 930413e83438..dcfb9dd78b82 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -975,8 +975,8 @@ uint32_t WasmObjectWriter::writeDataSection(const MCAsmLayout &Layout) { if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) encodeULEB128(0, W->OS); // memory index if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) { - W->OS << char(Segment.Offset > INT32_MAX ? wasm::WASM_OPCODE_I64_CONST - : wasm::WASM_OPCODE_I32_CONST); + W->OS << char(is64Bit() ? wasm::WASM_OPCODE_I64_CONST + : wasm::WASM_OPCODE_I32_CONST); encodeSLEB128(Segment.Offset, W->OS); // offset W->OS << char(wasm::WASM_OPCODE_END); } diff --git a/llvm/test/MC/WebAssembly/data-section.s b/llvm/test/MC/WebAssembly/data-section.s index 36427603120d..71c62e5f0b16 100644 --- a/llvm/test/MC/WebAssembly/data-section.s +++ b/llvm/test/MC/WebAssembly/data-section.s @@ -1,6 +1,12 @@ # RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s # Check that it converts to .o without errors: -# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefix=BIN %s +# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefixes=BIN,BIN32 %s + +# Same again for wasm64 + +# RUN: llvm-mc -triple=wasm64-unknown-unknown -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s +# Check that it converts to .o without errors: +# RUN: llvm-mc -triple=wasm64-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefixes=BIN,BIN64 %s # Minimal test for data sections. @@ -44,6 +50,7 @@ test0: # BIN-NEXT: Field: __linear_memory # BIN-NEXT: Kind: MEMORY # BIN-NEXT: Memory: +# BIN64-NEXT: Flags: [ IS_64 ] # BIN-NEXT: Initial: 0x1 # BIN-NEXT: - Type: FUNCTION # BIN-NEXT: FunctionTypes: [ 0 ] @@ -63,7 +70,8 @@ test0: # BIN-NEXT: - SectionOffset: 6 # BIN-NEXT: InitFlags: 0 # BIN-NEXT: Offset: -# BIN-NEXT: Opcode: I32_CONST +# BIN32-NEXT: Opcode: I32_CONST +# BIN64-NEXT: Opcode: I64_CONST # BIN-NEXT: Value: 0 # BIN-NEXT: Content: '64' # BIN-NEXT: - Type: CUSTOM diff --git a/llvm/test/MC/WebAssembly/wasm64.s b/llvm/test/MC/WebAssembly/wasm64.s index a7eb510cb050..793f91f11af9 100644 --- a/llvm/test/MC/WebAssembly/wasm64.s +++ b/llvm/test/MC/WebAssembly/wasm64.s @@ -201,7 +201,7 @@ test: # BIN-NEXT: - SectionOffset: 6 # BIN-NEXT: InitFlags: 0 # BIN-NEXT: Offset: -# BIN-NEXT: Opcode: I32_CONST +# BIN-NEXT: Opcode: I64_CONST # BIN-NEXT: Value: 0 # BIN-NEXT: Content: 48656C6C6F2C20576F726C64212121000000000000000000 # BIN-NEXT: - Type: CUSTOM