diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -41,9 +41,9 @@ TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling") // Atomic wait and notify. -TARGET_BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n", "atomics") -TARGET_BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n", "atomics") -TARGET_BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n", "atomics") +TARGET_BUILTIN(__builtin_wasm_memory_atomic_wait32, "ii*iLLi", "n", "atomics") +TARGET_BUILTIN(__builtin_wasm_memory_atomic_wait64, "iLLi*LLiLLi", "n", "atomics") +TARGET_BUILTIN(__builtin_wasm_memory_atomic_notify, "Uii*Ui", "n", "atomics") // Trapping fp-to-int conversions BUILTIN(__builtin_wasm_trunc_s_i32_f32, "if", "nc") diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16425,24 +16425,24 @@ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow_in_catch); return Builder.CreateCall(Callee); } - case WebAssembly::BI__builtin_wasm_atomic_wait_i32: { + case WebAssembly::BI__builtin_wasm_memory_atomic_wait32: { Value *Addr = EmitScalarExpr(E->getArg(0)); Value *Expected = EmitScalarExpr(E->getArg(1)); Value *Timeout = EmitScalarExpr(E->getArg(2)); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i32); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_wait32); return Builder.CreateCall(Callee, {Addr, Expected, Timeout}); } - case WebAssembly::BI__builtin_wasm_atomic_wait_i64: { + case WebAssembly::BI__builtin_wasm_memory_atomic_wait64: { Value *Addr = EmitScalarExpr(E->getArg(0)); Value *Expected = EmitScalarExpr(E->getArg(1)); Value *Timeout = EmitScalarExpr(E->getArg(2)); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_wait_i64); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_wait64); return Builder.CreateCall(Callee, {Addr, Expected, Timeout}); } - case WebAssembly::BI__builtin_wasm_atomic_notify: { + case WebAssembly::BI__builtin_wasm_memory_atomic_notify: { Value *Addr = EmitScalarExpr(E->getArg(0)); Value *Count = EmitScalarExpr(E->getArg(1)); - Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_atomic_notify); + Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_memory_atomic_notify); return Builder.CreateCall(Callee, {Addr, Count}); } case WebAssembly::BI__builtin_wasm_trunc_s_i32_f32: diff --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c --- a/clang/test/CodeGen/builtins-wasm.c +++ b/clang/test/CodeGen/builtins-wasm.c @@ -55,22 +55,22 @@ // WEBASSEMBLY64: call void @llvm.wasm.rethrow.in.catch() } -int atomic_wait_i32(int *addr, int expected, long long timeout) { - return __builtin_wasm_atomic_wait_i32(addr, expected, timeout); - // WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) - // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) +int memory_atomic_wait32(int *addr, int expected, long long timeout) { + return __builtin_wasm_memory_atomic_wait32(addr, expected, timeout); + // WEBASSEMBLY32: call i32 @llvm.wasm.memory.atomic.wait32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) + // WEBASSEMBLY64: call i32 @llvm.wasm.memory.atomic.wait32(i32* %{{.*}}, i32 %{{.*}}, i64 %{{.*}}) } -int atomic_wait_i64(long long *addr, long long expected, long long timeout) { - return __builtin_wasm_atomic_wait_i64(addr, expected, timeout); - // WEBASSEMBLY32: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) - // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.wait.i64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) +int memory_atomic_wait64(long long *addr, long long expected, long long timeout) { + return __builtin_wasm_memory_atomic_wait64(addr, expected, timeout); + // WEBASSEMBLY32: call i32 @llvm.wasm.memory.atomic.wait64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) + // WEBASSEMBLY64: call i32 @llvm.wasm.memory.atomic.wait64(i64* %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) } -unsigned int atomic_notify(int *addr, unsigned int count) { - return __builtin_wasm_atomic_notify(addr, count); - // WEBASSEMBLY32: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}}) - // WEBASSEMBLY64: call i32 @llvm.wasm.atomic.notify(i32* %{{.*}}, i32 %{{.*}}) +unsigned int memory_atomic_notify(int *addr, unsigned int count) { + return __builtin_wasm_memory_atomic_notify(addr, count); + // WEBASSEMBLY32: call i32 @llvm.wasm.memory.atomic.notify(i32* %{{.*}}, i32 %{{.*}}) + // WEBASSEMBLY64: call i32 @llvm.wasm.memory.atomic.notify(i32* %{{.*}}, i32 %{{.*}}) } int trunc_s_i32_f32(float f) { diff --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td --- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td @@ -79,22 +79,23 @@ //===----------------------------------------------------------------------===// // wait / notify -def int_wasm_atomic_wait_i32 : +def int_wasm_memory_atomic_wait32 : Intrinsic<[llvm_i32_ty], [LLVMPointerType, llvm_i32_ty, llvm_i64_ty], - [IntrInaccessibleMemOrArgMemOnly, ReadOnly>, NoCapture>, - IntrHasSideEffects], - "", [SDNPMemOperand]>; -def int_wasm_atomic_wait_i64 : + [IntrInaccessibleMemOrArgMemOnly, ReadOnly>, + NoCapture>, IntrHasSideEffects], + "", [SDNPMemOperand]>; +def int_wasm_memory_atomic_wait64 : Intrinsic<[llvm_i32_ty], [LLVMPointerType, llvm_i64_ty, llvm_i64_ty], - [IntrInaccessibleMemOrArgMemOnly, ReadOnly>, NoCapture>, - IntrHasSideEffects], - "", [SDNPMemOperand]>; -def int_wasm_atomic_notify: + [IntrInaccessibleMemOrArgMemOnly, ReadOnly>, + NoCapture>, IntrHasSideEffects], + "", [SDNPMemOperand]>; +def int_wasm_memory_atomic_notify: Intrinsic<[llvm_i32_ty], [LLVMPointerType, llvm_i32_ty], - [IntrInaccessibleMemOnly, NoCapture>, IntrHasSideEffects], "", - [SDNPMemOperand]>; + [IntrInaccessibleMemOnly, NoCapture>, + IntrHasSideEffects], + "", [SDNPMemOperand]>; //===----------------------------------------------------------------------===// // SIMD intrinsics diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -249,8 +249,8 @@ WASM_LOAD_STORE(ATOMIC_RMW32_U_XCHG_I64) WASM_LOAD_STORE(ATOMIC_RMW_CMPXCHG_I32) WASM_LOAD_STORE(ATOMIC_RMW32_U_CMPXCHG_I64) - WASM_LOAD_STORE(ATOMIC_NOTIFY) - WASM_LOAD_STORE(ATOMIC_WAIT_I32) + WASM_LOAD_STORE(MEMORY_ATOMIC_NOTIFY) + WASM_LOAD_STORE(MEMORY_ATOMIC_WAIT32) WASM_LOAD_STORE(LOAD_SPLAT_v32x4) WASM_LOAD_STORE(LOAD_ZERO_v4i32) WASM_LOAD_STORE(LOAD_LANE_v4i32) @@ -269,7 +269,7 @@ WASM_LOAD_STORE(ATOMIC_RMW_XOR_I64) WASM_LOAD_STORE(ATOMIC_RMW_XCHG_I64) WASM_LOAD_STORE(ATOMIC_RMW_CMPXCHG_I64) - WASM_LOAD_STORE(ATOMIC_WAIT_I64) + WASM_LOAD_STORE(MEMORY_ATOMIC_WAIT64) WASM_LOAD_STORE(LOAD_SPLAT_v64x2) WASM_LOAD_STORE(LOAD_EXTEND_S_v8i16) WASM_LOAD_STORE(LOAD_EXTEND_U_v8i16) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -646,7 +646,7 @@ MachineFunction &MF, unsigned Intrinsic) const { switch (Intrinsic) { - case Intrinsic::wasm_atomic_notify: + case Intrinsic::wasm_memory_atomic_notify: Info.opc = ISD::INTRINSIC_W_CHAIN; Info.memVT = MVT::i32; Info.ptrVal = I.getArgOperand(0); @@ -660,7 +660,7 @@ // consistent. The same applies for wasm_atomic_wait intrinsics too. Info.flags = MachineMemOperand::MOVolatile | MachineMemOperand::MOLoad; return true; - case Intrinsic::wasm_atomic_wait_i32: + case Intrinsic::wasm_memory_atomic_wait32: Info.opc = ISD::INTRINSIC_W_CHAIN; Info.memVT = MVT::i32; Info.ptrVal = I.getArgOperand(0); @@ -668,7 +668,7 @@ Info.align = Align(4); Info.flags = MachineMemOperand::MOVolatile | MachineMemOperand::MOLoad; return true; - case Intrinsic::wasm_atomic_wait_i64: + case Intrinsic::wasm_memory_atomic_wait64: Info.opc = ISD::INTRINSIC_W_CHAIN; Info.memVT = MVT::i64; Info.ptrVal = I.getArgOperand(0); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td @@ -33,96 +33,98 @@ //===----------------------------------------------------------------------===// let hasSideEffects = 1 in { -defm ATOMIC_NOTIFY_A32 : +defm MEMORY_ATOMIC_NOTIFY_A32 : ATOMIC_I<(outs I32:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, I32:$count), (outs), (ins P2Align:$p2align, offset32_op:$off), [], - "atomic.notify \t$dst, ${off}(${addr})${p2align}, $count", - "atomic.notify \t${off}${p2align}", 0x00, "false">; -defm ATOMIC_NOTIFY_A64 : + "memory.atomic.notify \t$dst, ${off}(${addr})${p2align}, $count", + "memory.atomic.notify \t${off}${p2align}", 0x00, "false">; +defm MEMORY_ATOMIC_NOTIFY_A64 : ATOMIC_I<(outs I32:$dst), (ins P2Align:$p2align, offset64_op:$off, I64:$addr, I32:$count), (outs), (ins P2Align:$p2align, offset64_op:$off), [], - "atomic.notify \t$dst, ${off}(${addr})${p2align}, $count", - "atomic.notify \t${off}${p2align}", 0x00, "true">; + "memory.atomic.notify \t$dst, ${off}(${addr})${p2align}, $count", + "memory.atomic.notify \t${off}${p2align}", 0x00, "true">; let mayLoad = 1 in { -defm ATOMIC_WAIT_I32_A32 : +defm MEMORY_ATOMIC_WAIT32_A32 : ATOMIC_I<(outs I32:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, I32:$exp, I64:$timeout), (outs), (ins P2Align:$p2align, offset32_op:$off), [], - "i32.atomic.wait \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", - "i32.atomic.wait \t${off}${p2align}", 0x01, "false">; -defm ATOMIC_WAIT_I32_A64 : + "memory.atomic.wait32 \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", + "memory.atomic.wait32 \t${off}${p2align}", 0x01, "false">; +defm MEMORY_ATOMIC_WAIT32_A64 : ATOMIC_I<(outs I32:$dst), (ins P2Align:$p2align, offset64_op:$off, I64:$addr, I32:$exp, I64:$timeout), (outs), (ins P2Align:$p2align, offset64_op:$off), [], - "i32.atomic.wait \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", - "i32.atomic.wait \t${off}${p2align}", 0x01, "true">; -defm ATOMIC_WAIT_I64_A32 : + "memory.atomic.wait32 \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", + "memory.atomic.wait32 \t${off}${p2align}", 0x01, "true">; +defm MEMORY_ATOMIC_WAIT64_A32 : ATOMIC_I<(outs I32:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, I64:$exp, I64:$timeout), (outs), (ins P2Align:$p2align, offset32_op:$off), [], - "i64.atomic.wait \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", - "i64.atomic.wait \t${off}${p2align}", 0x02, "false">; -defm ATOMIC_WAIT_I64_A64 : + "memory.atomic.wait64 \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", + "memory.atomic.wait64 \t${off}${p2align}", 0x02, "false">; +defm MEMORY_ATOMIC_WAIT64_A64 : ATOMIC_I<(outs I32:$dst), (ins P2Align:$p2align, offset64_op:$off, I64:$addr, I64:$exp, I64:$timeout), (outs), (ins P2Align:$p2align, offset64_op:$off), [], - "i64.atomic.wait \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", - "i64.atomic.wait \t${off}${p2align}", 0x02, "true">; + "memory.atomic.wait64 \t$dst, ${off}(${addr})${p2align}, $exp, $timeout", + "memory.atomic.wait64 \t${off}${p2align}", 0x02, "true">; } // mayLoad = 1 } // hasSideEffects = 1 let Predicates = [HasAtomics] in { // Select notifys with no constant offset. def NotifyPatNoOffset_A32 : - Pat<(i32 (int_wasm_atomic_notify I32:$addr, I32:$count)), - (ATOMIC_NOTIFY_A32 0, 0, I32:$addr, I32:$count)>, + Pat<(i32 (int_wasm_memory_atomic_notify I32:$addr, I32:$count)), + (MEMORY_ATOMIC_NOTIFY_A32 0, 0, I32:$addr, I32:$count)>, Requires<[HasAddr32]>; def NotifyPatNoOffset_A64 : - Pat<(i32 (int_wasm_atomic_notify I64:$addr, I32:$count)), - (ATOMIC_NOTIFY_A64 0, 0, I64:$addr, I32:$count)>, + Pat<(i32 (int_wasm_memory_atomic_notify I64:$addr, I32:$count)), + (MEMORY_ATOMIC_NOTIFY_A64 0, 0, I64:$addr, I32:$count)>, Requires<[HasAddr64]>; // Select notifys with a constant offset. // Pattern with address + immediate offset multiclass NotifyPatImmOff { - def : Pat<(i32 (int_wasm_atomic_notify (operand I32:$addr, imm:$off), + def : Pat<(i32 (int_wasm_memory_atomic_notify (operand I32:$addr, imm:$off), I32:$count)), (!cast(inst#_A32) 0, imm:$off, I32:$addr, I32:$count)>, Requires<[HasAddr32]>; - def : Pat<(i32 (int_wasm_atomic_notify (operand I64:$addr, imm:$off), + def : Pat<(i32 (int_wasm_memory_atomic_notify (operand I64:$addr, imm:$off), I32:$count)), (!cast(inst#_A64) 0, imm:$off, I64:$addr, I32:$count)>, Requires<[HasAddr64]>; } -defm : NotifyPatImmOff; -defm : NotifyPatImmOff; +defm : NotifyPatImmOff; +defm : NotifyPatImmOff; // Select notifys with just a constant offset. def NotifyPatOffsetOnly_A32 : - Pat<(i32 (int_wasm_atomic_notify imm:$off, I32:$count)), - (ATOMIC_NOTIFY_A32 0, imm:$off, (CONST_I32 0), I32:$count)>, + Pat<(i32 (int_wasm_memory_atomic_notify imm:$off, I32:$count)), + (MEMORY_ATOMIC_NOTIFY_A32 0, imm:$off, (CONST_I32 0), I32:$count)>, Requires<[HasAddr32]>; def NotifyPatOffsetOnly_A64 : - Pat<(i32 (int_wasm_atomic_notify imm:$off, I32:$count)), - (ATOMIC_NOTIFY_A64 0, imm:$off, (CONST_I64 0), I32:$count)>, + Pat<(i32 (int_wasm_memory_atomic_notify imm:$off, I32:$count)), + (MEMORY_ATOMIC_NOTIFY_A64 0, imm:$off, (CONST_I64 0), I32:$count)>, Requires<[HasAddr64]>; def NotifyPatGlobalAddrOffOnly_A32 : - Pat<(i32 (int_wasm_atomic_notify (WebAssemblywrapper tglobaladdr:$off), - I32:$count)), - (ATOMIC_NOTIFY_A32 0, tglobaladdr:$off, (CONST_I32 0), I32:$count)>, + Pat<(i32 (int_wasm_memory_atomic_notify (WebAssemblywrapper tglobaladdr:$off), + I32:$count)), + (MEMORY_ATOMIC_NOTIFY_A32 0, tglobaladdr:$off, (CONST_I32 0), I32:$count) + >, Requires<[HasAddr32]>; def NotifyPatGlobalAddrOffOnly_A64 : - Pat<(i32 (int_wasm_atomic_notify (WebAssemblywrapper tglobaladdr:$off), - I32:$count)), - (ATOMIC_NOTIFY_A64 0, tglobaladdr:$off, (CONST_I64 0), I32:$count)>, + Pat<(i32 (int_wasm_memory_atomic_notify (WebAssemblywrapper tglobaladdr:$off), + I32:$count)), + (MEMORY_ATOMIC_NOTIFY_A64 0, tglobaladdr:$off, (CONST_I64 0), I32:$count) + >, Requires<[HasAddr64]>; // Select waits with no constant offset. @@ -135,10 +137,14 @@ (!cast(inst#_A64) 0, 0, I64:$addr, ty:$exp, I64:$timeout)>, Requires<[HasAddr64]>; } -defm : WaitPatNoOffset; -defm : WaitPatNoOffset; -defm : WaitPatNoOffset; -defm : WaitPatNoOffset; +defm : WaitPatNoOffset; +defm : WaitPatNoOffset; +defm : WaitPatNoOffset; +defm : WaitPatNoOffset; // Select waits with a constant offset. @@ -154,16 +160,16 @@ I64:$timeout)>, Requires<[HasAddr64]>; } -defm : WaitPatImmOff; -defm : WaitPatImmOff; -defm : WaitPatImmOff; -defm : WaitPatImmOff; - -// Select wait_i32, "ATOMIC_WAIT_I32s with just a constant offset. +defm : WaitPatImmOff; +defm : WaitPatImmOff; +defm : WaitPatImmOff; +defm : WaitPatImmOff; + +// Select waits with just a constant offset. multiclass WaitPatOffsetOnly { def : Pat<(i32 (kind imm:$off, ty:$exp, I64:$timeout)), (!cast(inst#_A32) 0, imm:$off, (CONST_I32 0), ty:$exp, @@ -174,8 +180,10 @@ I64:$timeout)>, Requires<[HasAddr64]>; } -defm : WaitPatOffsetOnly; -defm : WaitPatOffsetOnly; +defm : WaitPatOffsetOnly; +defm : WaitPatOffsetOnly; multiclass WaitPatGlobalAddrOffOnly { def : Pat<(i32 (kind (WebAssemblywrapper tglobaladdr:$off), ty:$exp, @@ -189,10 +197,10 @@ I64:$timeout)>, Requires<[HasAddr64]>; } -defm : WaitPatGlobalAddrOffOnly; -defm : WaitPatGlobalAddrOffOnly; +defm : WaitPatGlobalAddrOffOnly; +defm : WaitPatGlobalAddrOffOnly; } // Predicates = [HasAtomics] //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/WebAssembly/atomic-fence.mir b/llvm/test/CodeGen/WebAssembly/atomic-fence.mir --- a/llvm/test/CodeGen/WebAssembly/atomic-fence.mir +++ b/llvm/test/CodeGen/WebAssembly/atomic-fence.mir @@ -1,10 +1,10 @@ # RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-reg-stackify -run-pass wasm-explicit-locals %s -o - | FileCheck %s # In the two tests below, without compiler_fence or atomic.fence in between, -# atomic.notify and i32.add will be reordered by register stackify pass to meet -# 'call @foo''s requirements. But because we have fences between atomic.notify -# and i32.add, they cannot be reordered, and local.set and local.get are -# inserted to save and load atomic.notify's return value. +# memory.atomic.notify and i32.add will be reordered by register stackify pass +# to meet 'call @foo''s requirements. But because we have fences between +# memory.atomic.notify and i32.add, they cannot be reordered, and local.set and +# local.get are inserted to save and load memory.atomic.notify's return value. --- | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" @@ -26,7 +26,7 @@ tracksRegLiveness: true body: | bb.0: - ; CHECK: %[[REG:[0-9]+]]:i32 = ATOMIC_NOTIFY_A32 + ; CHECK: %[[REG:[0-9]+]]:i32 = MEMORY_ATOMIC_NOTIFY_A32 ; CHECK: LOCAL_SET_I32 [[LOCAL:[0-9]+]], %[[REG]] ; CHECK: COMPILER_FENCE ; CHECK: ADD_I32 @@ -35,7 +35,7 @@ liveins: $arguments %0:i32 = CONST_I32 0, implicit-def $arguments - %1:i32 = ATOMIC_NOTIFY_A32 2, 0, %0:i32, %0:i32, implicit-def $arguments + %1:i32 = MEMORY_ATOMIC_NOTIFY_A32 2, 0, %0:i32, %0:i32, implicit-def $arguments COMPILER_FENCE implicit-def $arguments %2:i32 = ADD_I32 %0:i32, %0:i32, implicit-def $arguments CALL @foo, %2:i32, %1:i32, implicit-def $arguments @@ -50,7 +50,7 @@ tracksRegLiveness: true body: | bb.0: - ; CHECK: %[[REG:[0-9]+]]:i32 = ATOMIC_NOTIFY_A32 + ; CHECK: %[[REG:[0-9]+]]:i32 = MEMORY_ATOMIC_NOTIFY_A32 ; CHECK: LOCAL_SET_I32 [[LOCAL:[0-9]+]], %[[REG]] ; CHECK: ATOMIC_FENCE ; CHECK: ADD_I32 @@ -59,7 +59,7 @@ liveins: $arguments %0:i32 = CONST_I32 0, implicit-def $arguments - %1:i32 = ATOMIC_NOTIFY_A32 2, 0, %0:i32, %0:i32, implicit-def $arguments + %1:i32 = MEMORY_ATOMIC_NOTIFY_A32 2, 0, %0:i32, %0:i32, implicit-def $arguments ATOMIC_FENCE 0, implicit-def $arguments %2:i32 = ADD_I32 %0:i32, %0:i32, implicit-def $arguments CALL @foo, %2:i32, %1:i32, implicit-def $arguments diff --git a/llvm/test/CodeGen/WebAssembly/offset-atomics.ll b/llvm/test/CodeGen/WebAssembly/offset-atomics.ll --- a/llvm/test/CodeGen/WebAssembly/offset-atomics.ll +++ b/llvm/test/CodeGen/WebAssembly/offset-atomics.ll @@ -1530,94 +1530,94 @@ ; Waits: 32-bit ;===---------------------------------------------------------------------------- -declare i32 @llvm.wasm.atomic.wait.i32(i32*, i32, i64) +declare i32 @llvm.wasm.memory.atomic.wait32(i32*, i32, i64) ; Basic wait. -; CHECK-LABEL: wait_i32_no_offset: -; CHECK: i32.atomic.wait $push0=, 0($0), $1, $2{{$}} +; CHECK-LABEL: wait32_no_offset: +; CHECK: memory.atomic.wait32 $push0=, 0($0), $1, $2{{$}} ; CHECK-NEXT: return $pop0{{$}} -define i32 @wait_i32_no_offset(i32* %p, i32 %exp, i64 %timeout) { - %v = call i32 @llvm.wasm.atomic.wait.i32(i32* %p, i32 %exp, i64 %timeout) +define i32 @wait32_no_offset(i32* %p, i32 %exp, i64 %timeout) { + %v = call i32 @llvm.wasm.memory.atomic.wait32(i32* %p, i32 %exp, i64 %timeout) ret i32 %v } ; With an nuw add, we can fold an offset. -; CHECK-LABEL: wait_i32_with_folded_offset: -; CHECK: i32.atomic.wait $push0=, 24($0), $1, $2{{$}} -define i32 @wait_i32_with_folded_offset(i32* %p, i32 %exp, i64 %timeout) { +; CHECK-LABEL: wait32_with_folded_offset: +; CHECK: memory.atomic.wait32 $push0=, 24($0), $1, $2{{$}} +define i32 @wait32_with_folded_offset(i32* %p, i32 %exp, i64 %timeout) { %q = ptrtoint i32* %p to i32 %r = add nuw i32 %q, 24 %s = inttoptr i32 %r to i32* - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* %s, i32 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* %s, i32 %exp, i64 %timeout) ret i32 %t } ; With an inbounds gep, we can fold an offset. -; CHECK-LABEL: wait_i32_with_folded_gep_offset: -; CHECK: i32.atomic.wait $push0=, 24($0), $1, $2{{$}} -define i32 @wait_i32_with_folded_gep_offset(i32* %p, i32 %exp, i64 %timeout) { +; CHECK-LABEL: wait32_with_folded_gep_offset: +; CHECK: memory.atomic.wait32 $push0=, 24($0), $1, $2{{$}} +define i32 @wait32_with_folded_gep_offset(i32* %p, i32 %exp, i64 %timeout) { %s = getelementptr inbounds i32, i32* %p, i32 6 - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* %s, i32 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* %s, i32 %exp, i64 %timeout) ret i32 %t } ; We can't fold a negative offset though, even with an inbounds gep. -; CHECK-LABEL: wait_i32_with_unfolded_gep_negative_offset: +; CHECK-LABEL: wait32_with_unfolded_gep_negative_offset: ; CHECK: i32.const $push0=, -24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: i32.atomic.wait $push2=, 0($pop1), $1, $2{{$}} -define i32 @wait_i32_with_unfolded_gep_negative_offset(i32* %p, i32 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait32 $push2=, 0($pop1), $1, $2{{$}} +define i32 @wait32_with_unfolded_gep_negative_offset(i32* %p, i32 %exp, i64 %timeout) { %s = getelementptr inbounds i32, i32* %p, i32 -6 - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* %s, i32 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* %s, i32 %exp, i64 %timeout) ret i32 %t } ; Without nuw, and even with nsw, we can't fold an offset. -; CHECK-LABEL: wait_i32_with_unfolded_offset: +; CHECK-LABEL: wait32_with_unfolded_offset: ; CHECK: i32.const $push0=, 24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: i32.atomic.wait $push2=, 0($pop1), $1, $2{{$}} -define i32 @wait_i32_with_unfolded_offset(i32* %p, i32 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait32 $push2=, 0($pop1), $1, $2{{$}} +define i32 @wait32_with_unfolded_offset(i32* %p, i32 %exp, i64 %timeout) { %q = ptrtoint i32* %p to i32 %r = add nsw i32 %q, 24 %s = inttoptr i32 %r to i32* - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* %s, i32 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* %s, i32 %exp, i64 %timeout) ret i32 %t } ; Without inbounds, we can't fold a gep offset. -; CHECK-LABEL: wait_i32_with_unfolded_gep_offset: +; CHECK-LABEL: wait32_with_unfolded_gep_offset: ; CHECK: i32.const $push0=, 24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: i32.atomic.wait $push2=, 0($pop1), $1, $2{{$}} -define i32 @wait_i32_with_unfolded_gep_offset(i32* %p, i32 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait32 $push2=, 0($pop1), $1, $2{{$}} +define i32 @wait32_with_unfolded_gep_offset(i32* %p, i32 %exp, i64 %timeout) { %s = getelementptr i32, i32* %p, i32 6 - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* %s, i32 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* %s, i32 %exp, i64 %timeout) ret i32 %t } ; When waiting from a fixed address, materialize a zero. -; CHECK-LABEL: wait_i32_from_numeric_address +; CHECK-LABEL: wait32_from_numeric_address ; CHECK: i32.const $push0=, 0{{$}} -; CHECK: i32.atomic.wait $push1=, 42($pop0), $0, $1{{$}} -define i32 @wait_i32_from_numeric_address(i32 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait32 $push1=, 42($pop0), $0, $1{{$}} +define i32 @wait32_from_numeric_address(i32 %exp, i64 %timeout) { %s = inttoptr i32 42 to i32* - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* %s, i32 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* %s, i32 %exp, i64 %timeout) ret i32 %t } -; CHECK-LABEL: wait_i32_from_global_address +; CHECK-LABEL: wait32_from_global_address ; CHECK: i32.const $push0=, 0{{$}} -; CHECK: i32.atomic.wait $push1=, gv($pop0), $0, $1{{$}} -define i32 @wait_i32_from_global_address(i32 %exp, i64 %timeout) { - %t = call i32 @llvm.wasm.atomic.wait.i32(i32* @gv, i32 %exp, i64 %timeout) +; CHECK: memory.atomic.wait32 $push1=, gv($pop0), $0, $1{{$}} +define i32 @wait32_from_global_address(i32 %exp, i64 %timeout) { + %t = call i32 @llvm.wasm.memory.atomic.wait32(i32* @gv, i32 %exp, i64 %timeout) ret i32 %t } @@ -1625,75 +1625,75 @@ ; Waits: 64-bit ;===---------------------------------------------------------------------------- -declare i32 @llvm.wasm.atomic.wait.i64(i64*, i64, i64) +declare i32 @llvm.wasm.memory.atomic.wait64(i64*, i64, i64) ; Basic wait. -; CHECK-LABEL: wait_i64_no_offset: -; CHECK: i64.atomic.wait $push0=, 0($0), $1, $2{{$}} +; CHECK-LABEL: wait64_no_offset: +; CHECK: memory.atomic.wait64 $push0=, 0($0), $1, $2{{$}} ; CHECK-NEXT: return $pop0{{$}} -define i32 @wait_i64_no_offset(i64* %p, i64 %exp, i64 %timeout) { - %v = call i32 @llvm.wasm.atomic.wait.i64(i64* %p, i64 %exp, i64 %timeout) +define i32 @wait64_no_offset(i64* %p, i64 %exp, i64 %timeout) { + %v = call i32 @llvm.wasm.memory.atomic.wait64(i64* %p, i64 %exp, i64 %timeout) ret i32 %v } ; With an nuw add, we can fold an offset. -; CHECK-LABEL: wait_i64_with_folded_offset: -; CHECK: i64.atomic.wait $push0=, 24($0), $1, $2{{$}} -define i32 @wait_i64_with_folded_offset(i64* %p, i64 %exp, i64 %timeout) { +; CHECK-LABEL: wait64_with_folded_offset: +; CHECK: memory.atomic.wait64 $push0=, 24($0), $1, $2{{$}} +define i32 @wait64_with_folded_offset(i64* %p, i64 %exp, i64 %timeout) { %q = ptrtoint i64* %p to i32 %r = add nuw i32 %q, 24 %s = inttoptr i32 %r to i64* - %t = call i32 @llvm.wasm.atomic.wait.i64(i64* %s, i64 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait64(i64* %s, i64 %exp, i64 %timeout) ret i32 %t } ; With an inbounds gep, we can fold an offset. -; CHECK-LABEL: wait_i64_with_folded_gep_offset: -; CHECK: i64.atomic.wait $push0=, 24($0), $1, $2{{$}} -define i32 @wait_i64_with_folded_gep_offset(i64* %p, i64 %exp, i64 %timeout) { +; CHECK-LABEL: wait64_with_folded_gep_offset: +; CHECK: memory.atomic.wait64 $push0=, 24($0), $1, $2{{$}} +define i32 @wait64_with_folded_gep_offset(i64* %p, i64 %exp, i64 %timeout) { %s = getelementptr inbounds i64, i64* %p, i32 3 - %t = call i32 @llvm.wasm.atomic.wait.i64(i64* %s, i64 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait64(i64* %s, i64 %exp, i64 %timeout) ret i32 %t } ; We can't fold a negative offset though, even with an inbounds gep. -; CHECK-LABEL: wait_i64_with_unfolded_gep_negative_offset: +; CHECK-LABEL: wait64_with_unfolded_gep_negative_offset: ; CHECK: i32.const $push0=, -24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: i64.atomic.wait $push2=, 0($pop1), $1, $2{{$}} -define i32 @wait_i64_with_unfolded_gep_negative_offset(i64* %p, i64 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait64 $push2=, 0($pop1), $1, $2{{$}} +define i32 @wait64_with_unfolded_gep_negative_offset(i64* %p, i64 %exp, i64 %timeout) { %s = getelementptr inbounds i64, i64* %p, i32 -3 - %t = call i32 @llvm.wasm.atomic.wait.i64(i64* %s, i64 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait64(i64* %s, i64 %exp, i64 %timeout) ret i32 %t } ; Without nuw, and even with nsw, we can't fold an offset. -; CHECK-LABEL: wait_i64_with_unfolded_offset: +; CHECK-LABEL: wait64_with_unfolded_offset: ; CHECK: i32.const $push0=, 24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: i64.atomic.wait $push2=, 0($pop1), $1, $2{{$}} -define i32 @wait_i64_with_unfolded_offset(i64* %p, i64 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait64 $push2=, 0($pop1), $1, $2{{$}} +define i32 @wait64_with_unfolded_offset(i64* %p, i64 %exp, i64 %timeout) { %q = ptrtoint i64* %p to i32 %r = add nsw i32 %q, 24 %s = inttoptr i32 %r to i64* - %t = call i32 @llvm.wasm.atomic.wait.i64(i64* %s, i64 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait64(i64* %s, i64 %exp, i64 %timeout) ret i32 %t } ; Without inbounds, we can't fold a gep offset. -; CHECK-LABEL: wait_i64_with_unfolded_gep_offset: +; CHECK-LABEL: wait64_with_unfolded_gep_offset: ; CHECK: i32.const $push0=, 24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: i64.atomic.wait $push2=, 0($pop1), $1, $2{{$}} -define i32 @wait_i64_with_unfolded_gep_offset(i64* %p, i64 %exp, i64 %timeout) { +; CHECK: memory.atomic.wait64 $push2=, 0($pop1), $1, $2{{$}} +define i32 @wait64_with_unfolded_gep_offset(i64* %p, i64 %exp, i64 %timeout) { %s = getelementptr i64, i64* %p, i32 3 - %t = call i32 @llvm.wasm.atomic.wait.i64(i64* %s, i64 %exp, i64 %timeout) + %t = call i32 @llvm.wasm.memory.atomic.wait64(i64* %s, i64 %exp, i64 %timeout) ret i32 %t } @@ -1701,37 +1701,37 @@ ; Notifies ;===---------------------------------------------------------------------------- -declare i32 @llvm.wasm.atomic.notify(i32*, i32) +declare i32 @llvm.wasm.memory.atomic.notify(i32*, i32) ; Basic notify. ; CHECK-LABEL: notify_no_offset: -; CHECK: atomic.notify $push0=, 0($0), $1{{$}} +; CHECK: memory.atomic.notify $push0=, 0($0), $1{{$}} ; CHECK-NEXT: return $pop0{{$}} define i32 @notify_no_offset(i32* %p, i32 %notify_count) { - %v = call i32 @llvm.wasm.atomic.notify(i32* %p, i32 %notify_count) + %v = call i32 @llvm.wasm.memory.atomic.notify(i32* %p, i32 %notify_count) ret i32 %v } ; With an nuw add, we can fold an offset. ; CHECK-LABEL: notify_with_folded_offset: -; CHECK: atomic.notify $push0=, 24($0), $1{{$}} +; CHECK: memory.atomic.notify $push0=, 24($0), $1{{$}} define i32 @notify_with_folded_offset(i32* %p, i32 %notify_count) { %q = ptrtoint i32* %p to i32 %r = add nuw i32 %q, 24 %s = inttoptr i32 %r to i32* - %t = call i32 @llvm.wasm.atomic.notify(i32* %s, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* %s, i32 %notify_count) ret i32 %t } ; With an inbounds gep, we can fold an offset. ; CHECK-LABEL: notify_with_folded_gep_offset: -; CHECK: atomic.notify $push0=, 24($0), $1{{$}} +; CHECK: memory.atomic.notify $push0=, 24($0), $1{{$}} define i32 @notify_with_folded_gep_offset(i32* %p, i32 %notify_count) { %s = getelementptr inbounds i32, i32* %p, i32 6 - %t = call i32 @llvm.wasm.atomic.notify(i32* %s, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* %s, i32 %notify_count) ret i32 %t } @@ -1740,10 +1740,10 @@ ; CHECK-LABEL: notify_with_unfolded_gep_negative_offset: ; CHECK: i32.const $push0=, -24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: atomic.notify $push2=, 0($pop1), $1{{$}} +; CHECK: memory.atomic.notify $push2=, 0($pop1), $1{{$}} define i32 @notify_with_unfolded_gep_negative_offset(i32* %p, i32 %notify_count) { %s = getelementptr inbounds i32, i32* %p, i32 -6 - %t = call i32 @llvm.wasm.atomic.notify(i32* %s, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* %s, i32 %notify_count) ret i32 %t } @@ -1752,12 +1752,12 @@ ; CHECK-LABEL: notify_with_unfolded_offset: ; CHECK: i32.const $push0=, 24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: atomic.notify $push2=, 0($pop1), $1{{$}} +; CHECK: memory.atomic.notify $push2=, 0($pop1), $1{{$}} define i32 @notify_with_unfolded_offset(i32* %p, i32 %notify_count) { %q = ptrtoint i32* %p to i32 %r = add nsw i32 %q, 24 %s = inttoptr i32 %r to i32* - %t = call i32 @llvm.wasm.atomic.notify(i32* %s, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* %s, i32 %notify_count) ret i32 %t } @@ -1766,10 +1766,10 @@ ; CHECK-LABEL: notify_with_unfolded_gep_offset: ; CHECK: i32.const $push0=, 24{{$}} ; CHECK: i32.add $push1=, $0, $pop0{{$}} -; CHECK: atomic.notify $push2=, 0($pop1), $1{{$}} +; CHECK: memory.atomic.notify $push2=, 0($pop1), $1{{$}} define i32 @notify_with_unfolded_gep_offset(i32* %p, i32 %notify_count) { %s = getelementptr i32, i32* %p, i32 6 - %t = call i32 @llvm.wasm.atomic.notify(i32* %s, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* %s, i32 %notify_count) ret i32 %t } @@ -1777,17 +1777,17 @@ ; CHECK-LABEL: notify_from_numeric_address ; CHECK: i32.const $push0=, 0{{$}} -; CHECK: atomic.notify $push1=, 42($pop0), $0{{$}} +; CHECK: memory.atomic.notify $push1=, 42($pop0), $0{{$}} define i32 @notify_from_numeric_address(i32 %notify_count) { %s = inttoptr i32 42 to i32* - %t = call i32 @llvm.wasm.atomic.notify(i32* %s, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* %s, i32 %notify_count) ret i32 %t } ; CHECK-LABEL: notify_from_global_address ; CHECK: i32.const $push0=, 0{{$}} -; CHECK: atomic.notify $push1=, gv($pop0), $0{{$}} +; CHECK: memory.atomic.notify $push1=, gv($pop0), $0{{$}} define i32 @notify_from_global_address(i32 %notify_count) { - %t = call i32 @llvm.wasm.atomic.notify(i32* @gv, i32 %notify_count) + %t = call i32 @llvm.wasm.memory.atomic.notify(i32* @gv, i32 %notify_count) ret i32 %t } diff --git a/llvm/test/MC/WebAssembly/atomics-encodings.s b/llvm/test/MC/WebAssembly/atomics-encodings.s --- a/llvm/test/MC/WebAssembly/atomics-encodings.s +++ b/llvm/test/MC/WebAssembly/atomics-encodings.s @@ -3,12 +3,12 @@ main: .functype main () -> () - # CHECK: atomic.notify 0 # encoding: [0xfe,0x00,0x02,0x00] - atomic.notify 0 - # CHECK: i32.atomic.wait 0 # encoding: [0xfe,0x01,0x02,0x00] - i32.atomic.wait 0 - # CHECK: i64.atomic.wait 0 # encoding: [0xfe,0x02,0x03,0x00] - i64.atomic.wait 0 + # CHECK: memory.atomic.notify 0 # encoding: [0xfe,0x00,0x02,0x00] + memory.atomic.notify 0 + # CHECK: memory.atomic.wait32 0 # encoding: [0xfe,0x01,0x02,0x00] + memory.atomic.wait32 0 + # CHECK: memory.atomic.wait64 0 # encoding: [0xfe,0x02,0x03,0x00] + memory.atomic.wait64 0 # CHECK: atomic.fence # encoding: [0xfe,0x03,0x00] atomic.fence diff --git a/llvm/test/MC/WebAssembly/basic-assembly.s b/llvm/test/MC/WebAssembly/basic-assembly.s --- a/llvm/test/MC/WebAssembly/basic-assembly.s +++ b/llvm/test/MC/WebAssembly/basic-assembly.s @@ -83,7 +83,7 @@ i32.trunc_f32_s try exnref i32.atomic.load 0 - atomic.notify 0 + memory.atomic.notify 0 .LBB0_3: catch local.set 0 @@ -201,7 +201,7 @@ # CHECK-NEXT: i32.trunc_f32_s # CHECK-NEXT: try exnref # CHECK-NEXT: i32.atomic.load 0 -# CHECK-NEXT: atomic.notify 0 +# CHECK-NEXT: memory.atomic.notify 0 # CHECK-NEXT: .LBB0_3: # CHECK-NEXT: catch # CHECK-NEXT: local.set 0