Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -124,6 +124,8 @@ case WebAssembly::STORE8_I32_S: case WebAssembly::STORE8_I64: case WebAssembly::STORE8_I64_S: + case WebAssembly::ATOMIC_STORE8_I32: + case WebAssembly::ATOMIC_STORE8_I64: return 0; case WebAssembly::LOAD16_S_I32: case WebAssembly::LOAD16_S_I32_S: @@ -141,6 +143,8 @@ case WebAssembly::STORE16_I32_S: case WebAssembly::STORE16_I64: case WebAssembly::STORE16_I64_S: + case WebAssembly::ATOMIC_STORE16_I32: + case WebAssembly::ATOMIC_STORE16_I64: return 1; case WebAssembly::LOAD_I32: case WebAssembly::LOAD_I32_S: @@ -160,6 +164,8 @@ case WebAssembly::ATOMIC_LOAD_I32_S: case WebAssembly::ATOMIC_LOAD32_U_I64: case WebAssembly::ATOMIC_LOAD32_U_I64_S: + case WebAssembly::ATOMIC_STORE_I32: + case WebAssembly::ATOMIC_STORE32_I64: return 2; case WebAssembly::LOAD_I64: case WebAssembly::LOAD_I64_S: @@ -171,6 +177,7 @@ case WebAssembly::STORE_F64_S: case WebAssembly::ATOMIC_LOAD_I64: case WebAssembly::ATOMIC_LOAD_I64_S: + case WebAssembly::ATOMIC_STORE_I64: return 3; default: llvm_unreachable("Only loads and stores have p2align values"); Index: lib/Target/WebAssembly/WebAssemblyInstrAtomics.td =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrAtomics.td +++ lib/Target/WebAssembly/WebAssemblyInstrAtomics.td @@ -196,8 +196,52 @@ // Atomic stores //===----------------------------------------------------------------------===// -// TODO: add atomic stores here... +let Defs = [ARGUMENTS] in { +def ATOMIC_STORE_I32 : WebAssemblyStore; +def ATOMIC_STORE_I64 : WebAssemblyStore; +} // Defs = [ARGUMENTS] + +// Select stores with no constant offset. +let Predicates = [HasAtomics] in { +def : StorePatNoOffset; +def : StorePatNoOffset; + +// Select stores with a constant offset. + +// Pattern with address + immediate offset +def : StorePatImmOff; +def : StorePatImmOff; +def : StorePatImmOff; +def : StorePatImmOff; + +def : StorePatGlobalAddr; +def : StorePatGlobalAddr; + +def : StorePatExternalSym; +def : StorePatExternalSym; +// Select stores with just a constant offset. +//def : StorePatOffsetOnly; +//def : StorePatOffsetOnly; + +def : StorePatGlobalAddrOffOnly; +def : StorePatGlobalAddrOffOnly; + +def : StorePatExternSymOffOnly; +def : StorePatExternSymOffOnly; + +} + +let Defs = [ARGUMENTS] in { + +// Truncating store. +def ATOMIC_STORE8_I32 : WebAssemblyStore; +def ATOMIC_STORE16_I32 : WebAssemblyStore; +def ATOMIC_STORE8_I64 : WebAssemblyStore; +def ATOMIC_STORE16_I64 : WebAssemblyStore; +def ATOMIC_STORE32_I64 : WebAssemblyStore; + +} // Defs = [ARGUMENTS] //===----------------------------------------------------------------------===// // Low-level exclusive operations //===----------------------------------------------------------------------===// Index: lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp +++ lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp @@ -118,6 +118,13 @@ case WebAssembly::STORE8_I64: case WebAssembly::STORE16_I64: case WebAssembly::STORE32_I64: + case WebAssembly::ATOMIC_STORE_I32: + case WebAssembly::ATOMIC_STORE8_I32: + case WebAssembly::ATOMIC_STORE16_I32: + case WebAssembly::ATOMIC_STORE_I64: + case WebAssembly::ATOMIC_STORE8_I64: + case WebAssembly::ATOMIC_STORE16_I64: + case WebAssembly::ATOMIC_STORE32_I64: RewriteP2Align(MI, WebAssembly::StoreP2AlignOperandNo); break; default: Index: test/CodeGen/WebAssembly/i32-load-store-alignment.ll =================================================================== --- test/CodeGen/WebAssembly/i32-load-store-alignment.ll +++ test/CodeGen/WebAssembly/i32-load-store-alignment.ll @@ -236,3 +236,21 @@ %v = load atomic i32, i32* %p seq_cst, align 8 ret i32 %v } + +; CHECK-LABEL: sti32_atomic_a4: +; CHECK-NEXT: .param i32, i32{{$}} +; CHECK-NEXT: i32.atomic.store 0($1), $0{{$}} +; CHECK-NEXT: return{{$}} +define void @sti32_atomic_a4(i32 *%p, i32 %v) { + store atomic i32 %v, i32* %p seq_cst, align 4 + ret void +} + +; CHECK-LABEL: sti32_atomic_a8: +; CHECK-NEXT: .param i32, i32{{$}} +; CHECK-NEXT: i32.atomic.store 0($1), $0{{$}} +; CHECK-NEXT: return{{$}} +define void @sti32_atomic_a8(i32 *%p, i32 %v) { + store atomic i32 %v, i32* %p seq_cst, align 8 + ret void +} Index: test/CodeGen/WebAssembly/offset-atomics.ll =================================================================== --- test/CodeGen/WebAssembly/offset-atomics.ll +++ test/CodeGen/WebAssembly/offset-atomics.ll @@ -305,3 +305,13 @@ %v = load atomic i8, i8* %p seq_cst, align 1 ret i8 %v } + +; Basic store. +; CHECK-LABEL: sti64: +; CHECK-NEXT: .param i32, i64{{$}} +; CHECK-NEXT: i64.atomic.store 0($0), $1{{$}} +; CHECK-NEXT: return{{$}} +define void @sti64(i64 *%p, i64 %v) { + store atomic i64 %v, i64* %p seq_cst, align 8 + ret void +}