diff --git a/lld/test/wasm/data-segment-merging.ll b/lld/test/wasm/data-segment-merging.ll --- a/lld/test/wasm/data-segment-merging.ll +++ b/lld/test/wasm/data-segment-merging.ll @@ -1,5 +1,3 @@ -target triple = "wasm32-unknown-unknown" - @a = hidden global [6 x i8] c"hello\00", align 1 @b = hidden global [8 x i8] c"goodbye\00", align 1 @c = hidden global [9 x i8] c"whatever\00", align 1 @@ -8,8 +6,9 @@ @e = private constant [9 x i8] c"constant\00", align 1 @f = private constant i8 43, align 4 -; RUN: llc -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.passive.o -; RUN: llc -filetype=obj %s -o %t.o +; RUN: llc --mtriple=wasm32-unknown-unknown -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.passive.o +; RUN: llc --mtriple=wasm64-unknown-unknown -mattr=+bulk-memory,+atomics -filetype=obj %s -o %t.passive64.o +; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o %t.o ; RUN: wasm-ld -no-gc-sections --no-entry -o %t.merged.wasm %t.o ; RUN: obj2yaml %t.merged.wasm | FileCheck %s --check-prefix=MERGE @@ -76,6 +75,8 @@ ; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 -o %t.merged.passive.wasm %t.passive.o ; RUN: obj2yaml %t.merged.passive.wasm | FileCheck %s --check-prefix=PASSIVE-MERGE +; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 -o %t.merged.passive64.wasm %t.passive64.o +; RUN: obj2yaml %t.merged.passive64.wasm | FileCheck %s --check-prefix=PASSIVE-MERGE ; PASSIVE-MERGE-LABEL: - Type: DATACOUNT ; PASSIVE-MERGE-NEXT: Count: 2 @@ -99,6 +100,8 @@ ; RUN: wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 -no-merge-data-segments -o %t.separate.passive.wasm %t.passive.o ; RUN: obj2yaml %t.separate.passive.wasm | FileCheck %s --check-prefix=PASSIVE-SEPARATE +; RUN: wasm-ld -mwasm64 -no-gc-sections --no-entry --shared-memory --max-memory=131072 -no-merge-data-segments -o %t.separate.passive64.wasm %t.passive64.o +; RUN: obj2yaml %t.separate.passive64.wasm | FileCheck %s --check-prefix=PASSIVE-SEPARATE ; PASSIVE-SEPARATE-LABEL: - Type: DATACOUNT ; PASSIVE-SEPARATE-NEXT: Count: 6 diff --git a/lld/test/wasm/data-segments.ll b/lld/test/wasm/data-segments.ll --- a/lld/test/wasm/data-segments.ll +++ b/lld/test/wasm/data-segments.ll @@ -1,6 +1,7 @@ -; RUN: llc -filetype=obj %s -o %t.atomics.o -mattr=+atomics -; RUN: llc -filetype=obj %s -o %t.bulk-mem.o -mattr=+bulk-memory -; RUN: llc -filetype=obj %s -o %t.atomics.bulk-mem.o -mattr=+atomics,+bulk-memory +; 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=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 ; atomics, shared memory => error ; RUN: not wasm-ld -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.o -o %t.atomics.wasm 2>&1 | FileCheck %s --check-prefix ERROR @@ -11,14 +12,16 @@ ; 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 +; RUN: obj2yaml %t.atomics.bulk-mem.wasm | FileCheck %s --check-prefixes PASSIVE,PASSIVE32 + +; Also test with wasm64 +; 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 ; Also test in combination with PIC/pie -; RUN: llc -filetype=obj -relocation-model=pic %s -o %t.atomics.bulk-mem.pic.o -mattr=+atomics,+bulk-memory,+mutable-globals +; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj -relocation-model=pic %s -o %t.atomics.bulk-mem.pic.o -mattr=+atomics,+bulk-memory,+mutable-globals ; RUN: wasm-ld --experimental-pic -pie -no-gc-sections --no-entry --shared-memory --max-memory=131072 %t.atomics.bulk-mem.pic.o -o %t.pic.wasm -target triple = "wasm32-unknown-unknown" - @a = hidden global [6 x i8] c"hello\00", align 1 @b = hidden global [8 x i8] c"goodbye\00", align 1 @c = hidden global [10000 x i8] zeroinitializer, align 1 @@ -65,7 +68,8 @@ ; PASSIVE-NEXT: Body: 0B ; PASSIVE-NEXT: - Index: 1 ; PASSIVE-NEXT: Locals: [] -; PASSIVE-NEXT: Body: 41B4D60041004101FE480200044041B4D6004101427FFE0102001A054180084100410DFC08000041900841004114FC08010041B4D6004102FE17020041B4D600417FFE0002001A0BFC0900FC09010B +; PASSIVE32-NEXT: Body: 41B4D60041004101FE480200044041B4D6004101427FFE0102001A054180084100410DFC08000041900841004114FC08010041B4D6004102FE17020041B4D600417FFE0002001A0BFC0900FC09010B +; PASSIVE64-NEXT: Body: 42B4D60041004101FE480200044042B4D6004101427FFE0102001A054280084100410DFC08000042900841004114FC08010042B4D6004102FE17020042B4D600417FFE0002001A0BFC0900FC09010B ; PASSIVE-NEXT: - Index: 2 ; PASSIVE-NEXT: Locals: [] diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -857,7 +857,7 @@ void Writer::createInitMemoryFunction() { LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); assert(WasmSym::initMemoryFlag); - uint32_t flagAddress = WasmSym::initMemoryFlag->getVirtualAddress(); + uint64_t flagAddress = WasmSym::initMemoryFlag->getVirtualAddress(); std::string bodyContent; { raw_string_ostream os(bodyContent); @@ -906,8 +906,10 @@ // ( ... drop data segments ... ) // ) + bool is64 = config->is64.getValueOr(false); + // Atomically check whether this is the main thread. - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, 0, "expected flag value"); writeI32Const(os, 1, "flag value"); writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); @@ -917,9 +919,10 @@ writeU8(os, WASM_TYPE_NORESULT, "blocktype"); // Did not increment 0, so wait for main thread to initialize memory - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, 1, "expected flag value"); writeI64Const(os, -1, "timeout"); + writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); writeUleb128(os, WASM_OPCODE_I32_ATOMIC_WAIT, "i32.atomic.wait"); writeMemArg(os, 2, 0); @@ -931,12 +934,7 @@ for (const OutputSegment *s : segments) { if (needsPassiveInitialization(s)) { // destination address - if (config->is64.getValueOr(false)) { - writeI64Const(os, s->startVA, "destination address"); - } else { - writeI32Const(os, static_cast(s->startVA), - "destination address"); - } + writePtrConst(os, s->startVA, is64, "destination address"); // source segment offset writeI32Const(os, 0, "segment offset"); // memory region size @@ -950,14 +948,14 @@ } // Set flag to 2 to mark end of initialization - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, 2, "flag value"); writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); writeUleb128(os, WASM_OPCODE_I32_ATOMIC_STORE, "i32.atomic.store"); writeMemArg(os, 2, 0); // Notify any waiters that memory initialization is complete - writeI32Const(os, flagAddress, "flag address"); + writePtrConst(os, flagAddress, is64, "flag address"); writeI32Const(os, -1, "number of waiters"); writeU8(os, WASM_OPCODE_ATOMICS_PREFIX, "atomics prefix"); writeUleb128(os, WASM_OPCODE_ATOMIC_NOTIFY, "atomic.notify"); diff --git a/lld/wasm/WriterUtils.h b/lld/wasm/WriterUtils.h --- a/lld/wasm/WriterUtils.h +++ b/lld/wasm/WriterUtils.h @@ -40,6 +40,9 @@ void writeI64Const(raw_ostream &os, int64_t number, const Twine &msg); +void writePtrConst(raw_ostream &os, int64_t number, bool is64, + const Twine &msg); + void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset); void writeInitExpr(raw_ostream &os, const llvm::wasm::WasmInitExpr &initExpr); diff --git a/lld/wasm/WriterUtils.cpp b/lld/wasm/WriterUtils.cpp --- a/lld/wasm/WriterUtils.cpp +++ b/lld/wasm/WriterUtils.cpp @@ -136,6 +136,14 @@ writeSleb128(os, number, msg); } +void writePtrConst(raw_ostream &os, int64_t number, bool is64, + const Twine &msg) { + if (is64) + writeI64Const(os, number, msg); + else + writeI32Const(os, static_cast(number), msg); +} + void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset) { writeUleb128(os, alignment, "alignment"); writeUleb128(os, offset, "offset");