Index: lib/Target/WebAssembly/WebAssemblyInstrAtomics.td =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrAtomics.td +++ lib/Target/WebAssembly/WebAssemblyInstrAtomics.td @@ -11,20 +11,156 @@ /// //===----------------------------------------------------------------------===// +multiclass ATOMIC_I pattern_r, string asmstr_r = "", + string asmstr_s = "", bits<32> atomic_op = -1> { + defm "" : I, + Requires<[HasAtomics]>; +} + +multiclass ATOMIC_NRI pattern, string asmstr = "", + bits<32> atomic_op = -1> { + defm "" : NRI, + Requires<[HasAtomics]>; +} + +//===----------------------------------------------------------------------===// +// Atomic wait / notify +//===----------------------------------------------------------------------===// + +let hasSideEffects = 1 in { +defm ATOMIC_NOTIFY : + 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>; +let mayLoad = 1 in { +defm ATOMIC_WAIT_I32 : + 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>; +defm ATOMIC_WAIT_I64 : + 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>; +} // mayLoad = 1 +} // hasSideEffects = 1 + +let Predicates = [HasAtomics] in { +// Select notifys with no constant offset. +def NotifyPatNoOffset : + Pat<(i32 (int_wasm_atomic_notify I32:$addr, I32:$count)), + (ATOMIC_NOTIFY 0, 0, I32:$addr, I32:$count)>; + +// Select notifys with a constant offset. + +// Pattern with address + immediate offset +class NotifyPatImmOff : + Pat<(i32 (int_wasm_atomic_notify (operand I32:$addr, imm:$off), I32:$count)), + (ATOMIC_NOTIFY 0, imm:$off, I32:$addr, I32:$count)>; +def : NotifyPatImmOff; +def : NotifyPatImmOff; + +def NotifyPatGlobalAddr : + Pat<(i32 (int_wasm_atomic_notify (regPlusGA I32:$addr, + (WebAssemblywrapper tglobaladdr:$off)), + I32:$count)), + (ATOMIC_NOTIFY 0, tglobaladdr:$off, I32:$addr, I32:$count)>; + +def NotifyPatExternalSym : + Pat<(i32 (int_wasm_atomic_notify (add I32:$addr, + (WebAssemblywrapper texternalsym:$off)), + I32:$count)), + (ATOMIC_NOTIFY 0, texternalsym:$off, I32:$addr, I32:$count)>; + +// Select notifys with just a constant offset. +def NotifyPatOffsetOnly : + Pat<(i32 (int_wasm_atomic_notify imm:$off, I32:$count)), + (ATOMIC_NOTIFY 0, imm:$off, (CONST_I32 0), I32:$count)>; + +def NotifyPatGlobalAddrOffOnly : + Pat<(i32 (int_wasm_atomic_notify (WebAssemblywrapper tglobaladdr:$off), + I32:$count)), + (ATOMIC_NOTIFY 0, tglobaladdr:$off, (CONST_I32 0), I32:$count)>; + +def NotifyPatExternSymOffOnly : + Pat<(i32 (int_wasm_atomic_notify (WebAssemblywrapper texternalsym:$off), + I32:$count)), + (ATOMIC_NOTIFY 0, texternalsym:$off, (CONST_I32 0), I32:$count)>; + +// Select waits with no constant offset. +class WaitPatNoOffset : + Pat<(i32 (kind I32:$addr, ty:$exp, I64:$timeout)), + (inst 0, 0, I32:$addr, ty:$exp, I64:$timeout)>; +def : WaitPatNoOffset; +def : WaitPatNoOffset; + +// Select waits with a constant offset. + +// Pattern with address + immediate offset +class WaitPatImmOff : + Pat<(i32 (kind (operand I32:$addr, imm:$off), ty:$exp, I64:$timeout)), + (inst 0, imm:$off, I32:$addr, ty:$exp, I64:$timeout)>; +def : WaitPatImmOff; +def : WaitPatImmOff; +def : WaitPatImmOff; +def : WaitPatImmOff; + +class WaitPatGlobalAddr : + Pat<(i32 (kind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)), + ty:$exp, I64:$timeout)), + (inst 0, tglobaladdr:$off, I32:$addr, ty:$exp, I64:$timeout)>; +def : WaitPatGlobalAddr; +def : WaitPatGlobalAddr; + +class WaitPatExternalSym : + Pat<(i32 (kind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)), + ty:$exp, I64:$timeout)), + (inst 0, texternalsym:$off, I32:$addr, ty:$exp, I64:$timeout)>; +def : WaitPatExternalSym; +def : WaitPatExternalSym; + +// Select wait_i32, ATOMIC_WAIT_I32s with just a constant offset. +class WaitPatOffsetOnly : + Pat<(i32 (kind imm:$off, ty:$exp, I64:$timeout)), + (inst 0, imm:$off, (CONST_I32 0), ty:$exp, I64:$timeout)>; +def : WaitPatOffsetOnly; +def : WaitPatOffsetOnly; + +class WaitPatGlobalAddrOffOnly : + Pat<(i32 (kind (WebAssemblywrapper tglobaladdr:$off), ty:$exp, I64:$timeout)), + (inst 0, tglobaladdr:$off, (CONST_I32 0), ty:$exp, I64:$timeout)>; +def : WaitPatGlobalAddrOffOnly; +def : WaitPatGlobalAddrOffOnly; + +class WaitPatExternSymOffOnly : + Pat<(i32 (kind (WebAssemblywrapper texternalsym:$off), ty:$exp, + I64:$timeout)), + (inst 0, texternalsym:$off, (CONST_I32 0), ty:$exp, I64:$timeout)>; +def : WaitPatExternSymOffOnly; +def : WaitPatExternSymOffOnly; +} // Predicates = [HasAtomics] + //===----------------------------------------------------------------------===// // Atomic loads //===----------------------------------------------------------------------===// -multiclass ATOMIC_I pattern_r, string asmstr_r = "", - string asmstr_s = "", bits<32> inst = -1> { - defm "" : I, +multiclass AtomicLoad { + defm "" : WebAssemblyLoad, Requires<[HasAtomics]>; } -defm ATOMIC_LOAD_I32 : WebAssemblyLoad; -defm ATOMIC_LOAD_I64 : WebAssemblyLoad; +defm ATOMIC_LOAD_I32 : AtomicLoad; +defm ATOMIC_LOAD_I64 : AtomicLoad; // Select loads with no constant offset. let Predicates = [HasAtomics] in { @@ -59,11 +195,11 @@ // Extending loads. Note that there are only zero-extending atomic loads, no // sign-extending loads. -defm ATOMIC_LOAD8_U_I32 : WebAssemblyLoad; -defm ATOMIC_LOAD16_U_I32 : WebAssemblyLoad; -defm ATOMIC_LOAD8_U_I64 : WebAssemblyLoad; -defm ATOMIC_LOAD16_U_I64 : WebAssemblyLoad; -defm ATOMIC_LOAD32_U_I64 : WebAssemblyLoad; +defm ATOMIC_LOAD8_U_I32 : AtomicLoad; +defm ATOMIC_LOAD16_U_I32 : AtomicLoad; +defm ATOMIC_LOAD8_U_I64 : AtomicLoad; +defm ATOMIC_LOAD16_U_I64 : AtomicLoad; +defm ATOMIC_LOAD32_U_I64 : AtomicLoad; // Fragments for extending loads. These are different from regular loads because // the SDNodes are derived from AtomicSDNode rather than LoadSDNode and @@ -195,8 +331,13 @@ // Atomic stores //===----------------------------------------------------------------------===// -defm ATOMIC_STORE_I32 : WebAssemblyStore; -defm ATOMIC_STORE_I64 : WebAssemblyStore; +multiclass AtomicStore { + defm "" : WebAssemblyStore, + Requires<[HasAtomics]>; +} + +defm ATOMIC_STORE_I32 : AtomicStore; +defm ATOMIC_STORE_I64 : AtomicStore; // We need an 'atomic' version of store patterns because store and atomic_store // nodes have different operand orders: @@ -256,11 +397,11 @@ } // Predicates = [HasAtomics] // Truncating stores. -defm ATOMIC_STORE8_I32 : WebAssemblyStore; -defm ATOMIC_STORE16_I32 : WebAssemblyStore; -defm ATOMIC_STORE8_I64 : WebAssemblyStore; -defm ATOMIC_STORE16_I64 : WebAssemblyStore; -defm ATOMIC_STORE32_I64 : WebAssemblyStore; +defm ATOMIC_STORE8_I32 : AtomicStore; +defm ATOMIC_STORE16_I32 : AtomicStore; +defm ATOMIC_STORE8_I64 : AtomicStore; +defm ATOMIC_STORE16_I64 : AtomicStore; +defm ATOMIC_STORE32_I64 : AtomicStore; // Fragments for truncating stores. @@ -332,93 +473,95 @@ // Atomic binary read-modify-writes //===----------------------------------------------------------------------===// -multiclass WebAssemblyBinRMW { - defm "" : I<(outs rc:$dst), - (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val), - (outs), (ins P2Align:$p2align, offset32_op:$off), [], - !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}, $val"), - !strconcat(Name, "\t${off}${p2align}"), Opcode>; +multiclass WebAssemblyBinRMW { + defm "" : + ATOMIC_I<(outs rc:$dst), + (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val), + (outs), (ins P2Align:$p2align, offset32_op:$off), [], + !strconcat(name, "\t$dst, ${off}(${addr})${p2align}, $val"), + !strconcat(name, "\t${off}${p2align}"), atomic_op>; } -defm ATOMIC_RMW_ADD_I32 : WebAssemblyBinRMW; -defm ATOMIC_RMW_ADD_I64 : WebAssemblyBinRMW; +defm ATOMIC_RMW_ADD_I32 : WebAssemblyBinRMW; +defm ATOMIC_RMW_ADD_I64 : WebAssemblyBinRMW; defm ATOMIC_RMW8_U_ADD_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_ADD_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_ADD_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_ADD_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW32_U_ADD_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; -defm ATOMIC_RMW_SUB_I32 : WebAssemblyBinRMW; -defm ATOMIC_RMW_SUB_I64 : WebAssemblyBinRMW; +defm ATOMIC_RMW_SUB_I32 : WebAssemblyBinRMW; +defm ATOMIC_RMW_SUB_I64 : WebAssemblyBinRMW; defm ATOMIC_RMW8_U_SUB_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_SUB_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_SUB_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_SUB_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW32_U_SUB_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; -defm ATOMIC_RMW_AND_I32 : WebAssemblyBinRMW; -defm ATOMIC_RMW_AND_I64 : WebAssemblyBinRMW; +defm ATOMIC_RMW_AND_I32 : WebAssemblyBinRMW; +defm ATOMIC_RMW_AND_I64 : WebAssemblyBinRMW; defm ATOMIC_RMW8_U_AND_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_AND_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_AND_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_AND_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW32_U_AND_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; -defm ATOMIC_RMW_OR_I32 : WebAssemblyBinRMW; -defm ATOMIC_RMW_OR_I64 : WebAssemblyBinRMW; +defm ATOMIC_RMW_OR_I32 : WebAssemblyBinRMW; +defm ATOMIC_RMW_OR_I64 : WebAssemblyBinRMW; defm ATOMIC_RMW8_U_OR_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_OR_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_OR_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_OR_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW32_U_OR_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; -defm ATOMIC_RMW_XOR_I32 : WebAssemblyBinRMW; -defm ATOMIC_RMW_XOR_I64 : WebAssemblyBinRMW; +defm ATOMIC_RMW_XOR_I32 : WebAssemblyBinRMW; +defm ATOMIC_RMW_XOR_I64 : WebAssemblyBinRMW; defm ATOMIC_RMW8_U_XOR_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_XOR_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_XOR_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_XOR_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW32_U_XOR_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW_XCHG_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW_XCHG_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_XCHG_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_XCHG_I32 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW8_U_XCHG_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW16_U_XCHG_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; defm ATOMIC_RMW32_U_XCHG_I64 : - WebAssemblyBinRMW; + WebAssemblyBinRMW; // Select binary RMWs with no constant offset. class BinRMWPatNoOffset : @@ -662,29 +805,31 @@ // Consider adding a pass after instruction selection that optimizes this case // if it is frequent. -multiclass WebAssemblyTerRMW { - defm "" : I<(outs rc:$dst), - (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$exp, - rc:$new), - (outs), (ins P2Align:$p2align, offset32_op:$off), [], - !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}, $exp, $new"), - !strconcat(Name, "\t${off}${p2align}"), Opcode>; +multiclass WebAssemblyTerRMW { + defm "" : + ATOMIC_I<(outs rc:$dst), + (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$exp, + rc:$new), + (outs), (ins P2Align:$p2align, offset32_op:$off), [], + !strconcat(name, "\t$dst, ${off}(${addr})${p2align}, $exp, $new"), + !strconcat(name, "\t${off}${p2align}"), atomic_op>; } defm ATOMIC_RMW_CMPXCHG_I32 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; defm ATOMIC_RMW_CMPXCHG_I64 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; defm ATOMIC_RMW8_U_CMPXCHG_I32 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; defm ATOMIC_RMW16_U_CMPXCHG_I32 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; defm ATOMIC_RMW8_U_CMPXCHG_I64 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; defm ATOMIC_RMW16_U_CMPXCHG_I64 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; defm ATOMIC_RMW32_U_CMPXCHG_I64 : - WebAssemblyTerRMW; + WebAssemblyTerRMW; // Select ternary RMWs with no constant offset. class TerRMWPatNoOffset : @@ -890,127 +1035,3 @@ ATOMIC_RMW8_U_CMPXCHG_I32, ATOMIC_RMW16_U_CMPXCHG_I32, ATOMIC_RMW8_U_CMPXCHG_I64, ATOMIC_RMW16_U_CMPXCHG_I64, ATOMIC_RMW32_U_CMPXCHG_I64>; - -//===----------------------------------------------------------------------===// -// Atomic wait / notify -//===----------------------------------------------------------------------===// - -let hasSideEffects = 1 in { -defm ATOMIC_NOTIFY : - 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}", 0xfe00>; -let mayLoad = 1 in { -defm ATOMIC_WAIT_I32 : - 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}", 0xfe01>; -defm ATOMIC_WAIT_I64 : - 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}", 0xfe02>; -} // mayLoad = 1 -} // hasSideEffects = 1 - -let Predicates = [HasAtomics] in { -// Select notifys with no constant offset. -class NotifyPatNoOffset : - Pat<(i32 (kind I32:$addr, I32:$count)), - (ATOMIC_NOTIFY 0, 0, I32:$addr, I32:$count)>; -def : NotifyPatNoOffset; - -// Select notifys with a constant offset. - -// Pattern with address + immediate offset -class NotifyPatImmOff : - Pat<(i32 (kind (operand I32:$addr, imm:$off), I32:$count)), - (ATOMIC_NOTIFY 0, imm:$off, I32:$addr, I32:$count)>; -def : NotifyPatImmOff; -def : NotifyPatImmOff; - -class NotifyPatGlobalAddr : - Pat<(i32 (kind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)), - I32:$count)), - (ATOMIC_NOTIFY 0, tglobaladdr:$off, I32:$addr, I32:$count)>; -def : NotifyPatGlobalAddr; - -class NotifyPatExternalSym : - Pat<(i32 (kind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)), - I32:$count)), - (ATOMIC_NOTIFY 0, texternalsym:$off, I32:$addr, I32:$count)>; -def : NotifyPatExternalSym; - -// Select notifys with just a constant offset. -class NotifyPatOffsetOnly : - Pat<(i32 (kind imm:$off, I32:$count)), - (ATOMIC_NOTIFY 0, imm:$off, (CONST_I32 0), I32:$count)>; -def : NotifyPatOffsetOnly; - -class NotifyPatGlobalAddrOffOnly : - Pat<(i32 (kind (WebAssemblywrapper tglobaladdr:$off), I32:$count)), - (ATOMIC_NOTIFY 0, tglobaladdr:$off, (CONST_I32 0), I32:$count)>; -def : NotifyPatGlobalAddrOffOnly; - -class NotifyPatExternSymOffOnly : - Pat<(i32 (kind (WebAssemblywrapper texternalsym:$off), I32:$count)), - (ATOMIC_NOTIFY 0, texternalsym:$off, (CONST_I32 0), I32:$count)>; -def : NotifyPatExternSymOffOnly; - -// Select waits with no constant offset. -class WaitPatNoOffset : - Pat<(i32 (kind I32:$addr, ty:$exp, I64:$timeout)), - (inst 0, 0, I32:$addr, ty:$exp, I64:$timeout)>; -def : WaitPatNoOffset; -def : WaitPatNoOffset; - -// Select waits with a constant offset. - -// Pattern with address + immediate offset -class WaitPatImmOff : - Pat<(i32 (kind (operand I32:$addr, imm:$off), ty:$exp, I64:$timeout)), - (inst 0, imm:$off, I32:$addr, ty:$exp, I64:$timeout)>; -def : WaitPatImmOff; -def : WaitPatImmOff; -def : WaitPatImmOff; -def : WaitPatImmOff; - -class WaitPatGlobalAddr : - Pat<(i32 (kind (regPlusGA I32:$addr, (WebAssemblywrapper tglobaladdr:$off)), - ty:$exp, I64:$timeout)), - (inst 0, tglobaladdr:$off, I32:$addr, ty:$exp, I64:$timeout)>; -def : WaitPatGlobalAddr; -def : WaitPatGlobalAddr; - -class WaitPatExternalSym : - Pat<(i32 (kind (add I32:$addr, (WebAssemblywrapper texternalsym:$off)), - ty:$exp, I64:$timeout)), - (inst 0, texternalsym:$off, I32:$addr, ty:$exp, I64:$timeout)>; -def : WaitPatExternalSym; -def : WaitPatExternalSym; - -// Select wait_i32, ATOMIC_WAIT_I32s with just a constant offset. -class WaitPatOffsetOnly : - Pat<(i32 (kind imm:$off, ty:$exp, I64:$timeout)), - (inst 0, imm:$off, (CONST_I32 0), ty:$exp, I64:$timeout)>; -def : WaitPatOffsetOnly; -def : WaitPatOffsetOnly; - -class WaitPatGlobalAddrOffOnly : - Pat<(i32 (kind (WebAssemblywrapper tglobaladdr:$off), ty:$exp, I64:$timeout)), - (inst 0, tglobaladdr:$off, (CONST_I32 0), ty:$exp, I64:$timeout)>; -def : WaitPatGlobalAddrOffOnly; -def : WaitPatGlobalAddrOffOnly; - -class WaitPatExternSymOffOnly : - Pat<(i32 (kind (WebAssemblywrapper texternalsym:$off), ty:$exp, - I64:$timeout)), - (inst 0, texternalsym:$off, (CONST_I32 0), ty:$exp, I64:$timeout)>; -def : WaitPatExternSymOffOnly; -def : WaitPatExternSymOffOnly; -} // Predicates = [HasAtomics]