diff options
author | Thomas Lively <tlively@google.com> | 2018-10-11 18:45:48 +0000 |
---|---|---|
committer | Thomas Lively <tlively@google.com> | 2018-10-11 18:45:48 +0000 |
commit | ab37189f7eb05e427170f60902d1964cf9ee4c95 (patch) | |
tree | ad7000a1c824994a10567dd99e9a4f52986266de /llvm/lib | |
parent | e8a6c3eb9628e9833ae41196dc52a5c47041e3e6 (diff) | |
download | bcm5719-llvm-ab37189f7eb05e427170f60902d1964cf9ee4c95.tar.gz bcm5719-llvm-ab37189f7eb05e427170f60902d1964cf9ee4c95.zip |
[WebAssembly] Revert rL344180, which was breaking expensive checks
llvm-svn: 344280
Diffstat (limited to 'llvm/lib')
11 files changed, 94 insertions, 3 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td index f9d092e4b8a..9eff2cfde0a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrAtomics.td @@ -24,8 +24,10 @@ multiclass ATOMIC_I<dag oops_r, dag iops_r, dag oops_s, dag iops_s, Requires<[HasAtomics]>; } +let Defs = [ARGUMENTS] in { defm ATOMIC_LOAD_I32 : WebAssemblyLoad<I32, "i32.atomic.load", 0xfe10>; defm ATOMIC_LOAD_I64 : WebAssemblyLoad<I64, "i64.atomic.load", 0xfe11>; +} // Defs = [ARGUMENTS] // Select loads with no constant offset. let Predicates = [HasAtomics] in { @@ -60,11 +62,13 @@ def : LoadPatExternSymOffOnly<i64, atomic_load_64, ATOMIC_LOAD_I64>; // Extending loads. Note that there are only zero-extending atomic loads, no // sign-extending loads. +let Defs = [ARGUMENTS] in { defm ATOMIC_LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load8_u", 0xfe12>; defm ATOMIC_LOAD16_U_I32 : WebAssemblyLoad<I32, "i32.atomic.load16_u", 0xfe13>; defm ATOMIC_LOAD8_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load8_u", 0xfe14>; defm ATOMIC_LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load16_u", 0xfe15>; defm ATOMIC_LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.atomic.load32_u", 0xfe16>; +} // Defs = [ARGUMENTS] // Fragments for extending loads. These are different from regular loads because // the SDNodes are derived from AtomicSDNode rather than LoadSDNode and @@ -196,8 +200,10 @@ def : LoadPatExternSymOffOnly<i64, sext_aload_16_64, ATOMIC_LOAD16_U_I64>; // Atomic stores //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { defm ATOMIC_STORE_I32 : WebAssemblyStore<I32, "i32.atomic.store", 0xfe17>; defm ATOMIC_STORE_I64 : WebAssemblyStore<I64, "i64.atomic.store", 0xfe18>; +} // Defs = [ARGUMENTS] // We need an 'atomic' version of store patterns because store and atomic_store // nodes have different operand orders: @@ -257,11 +263,13 @@ def : AStorePatExternSymOffOnly<i64, atomic_store_64, ATOMIC_STORE_I64>; } // Predicates = [HasAtomics] // Truncating stores. +let Defs = [ARGUMENTS] in { defm ATOMIC_STORE8_I32 : WebAssemblyStore<I32, "i32.atomic.store8", 0xfe19>; defm ATOMIC_STORE16_I32 : WebAssemblyStore<I32, "i32.atomic.store16", 0xfe1a>; defm ATOMIC_STORE8_I64 : WebAssemblyStore<I64, "i64.atomic.store8", 0xfe1b>; defm ATOMIC_STORE16_I64 : WebAssemblyStore<I64, "i64.atomic.store16", 0xfe1c>; defm ATOMIC_STORE32_I64 : WebAssemblyStore<I64, "i64.atomic.store32", 0xfe1d>; +} // Defs = [ARGUMENTS] // Fragments for truncating stores. @@ -333,6 +341,8 @@ def : AStorePatExternSymOffOnly<i64, trunc_astore_32_64, ATOMIC_STORE32_I64>; // Atomic binary read-modify-writes //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { + multiclass WebAssemblyBinRMW<WebAssemblyRegClass rc, string Name, int Opcode> { defm "" : I<(outs rc:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val), @@ -420,6 +430,7 @@ defm ATOMIC_RMW16_U_XCHG_I64 : WebAssemblyBinRMW<I64, "i64.atomic.rmw16_u.xchg", 0xfe46>; defm ATOMIC_RMW32_U_XCHG_I64 : WebAssemblyBinRMW<I64, "i64.atomic.rmw32_u.xchg", 0xfe47>; +} // Select binary RMWs with no constant offset. class BinRMWPatNoOffset<ValueType ty, PatFrag kind, NI inst> : @@ -663,6 +674,8 @@ defm : BinRMWTruncExtPattern< // Consider adding a pass after instruction selection that optimizes this case // if it is frequent. +let Defs = [ARGUMENTS] in { + multiclass WebAssemblyTerRMW<WebAssemblyRegClass rc, string Name, int Opcode> { defm "" : I<(outs rc:$dst), (ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$exp, @@ -686,6 +699,7 @@ defm ATOMIC_RMW16_U_CMPXCHG_I64 : WebAssemblyTerRMW<I64, "i64.atomic.rmw16_u.cmpxchg", 0xfe4d>; defm ATOMIC_RMW32_U_CMPXCHG_I64 : WebAssemblyTerRMW<I64, "i64.atomic.rmw32_u.cmpxchg", 0xfe4e>; +} // Select ternary RMWs with no constant offset. class TerRMWPatNoOffset<ValueType ty, PatFrag kind, NI inst> : @@ -898,6 +912,7 @@ defm : TerRMWTruncExtPattern< // Atomic wait / notify //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { let hasSideEffects = 1 in { defm ATOMIC_NOTIFY : I<(outs I32:$dst), @@ -920,6 +935,7 @@ defm ATOMIC_WAIT_I64 : "i64.atomic.wait \t${off}, ${p2align}", 0xfe02>; } // mayLoad = 1 } // hasSideEffects = 1 +} // Defs = [ARGUMENTS] let Predicates = [HasAtomics] in { // Select notifys with no constant offset. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td index 07839b79011..3c9caa3f0de 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td @@ -15,6 +15,8 @@ // TODO: addr64: These currently assume the callee address is 32-bit. // FIXME: add $type to first call_indirect asmstr (and maybe $flags) +let Defs = [ARGUMENTS] in { + // Call sequence markers. These have an immediate which represents the amount of // stack space to allocate or free, which is used for varargs lowering. let Uses = [SP32, SP64], Defs = [SP32, SP64], isCodeGenOnly = 1 in { @@ -116,6 +118,8 @@ let Uses = [SP32, SP64], isCall = 1 in { 0x11>; } // Uses = [SP32,SP64], isCall = 1 +} // Defs = [ARGUMENTS] + // Patterns for matching a direct call to a global address. def : Pat<(i32 (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))), (CALL_I32 tglobaladdr:$callee)>; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td index ed9879ae454..e27d81937dd 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td @@ -12,6 +12,8 @@ /// //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { + let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { // The condition operand is a boolean value which WebAssembly represents as i32. defm BR_IF : I<(outs), (ins bb_op:$dst, I32:$cond), @@ -28,11 +30,15 @@ defm BR : NRI<(outs), (ins bb_op:$dst), } // isBarrier = 1 } // isBranch = 1, isTerminator = 1, hasCtrlDep = 1 +} // Defs = [ARGUMENTS] + def : Pat<(brcond (i32 (setne I32:$cond, 0)), bb:$dst), (BR_IF bb_op:$dst, I32:$cond)>; def : Pat<(brcond (i32 (seteq I32:$cond, 0)), bb:$dst), (BR_UNLESS bb_op:$dst, I32:$cond)>; +let Defs = [ARGUMENTS] in { + // TODO: SelectionDAG's lowering insists on using a pointer as the index for // jump tables, so in practice we don't ever use BR_TABLE_I64 in wasm32 mode // currently. @@ -188,3 +194,5 @@ let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1, [(catchret bb:$dst, bb:$from)], "", 0>; } } + +} // Defs = [ARGUMENTS] diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td index 0d772c743a7..6dca96f3ddd 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrConv.td @@ -13,6 +13,8 @@ /// //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { + defm I32_WRAP_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins), [(set I32:$dst, (trunc I64:$src))], "i32.wrap/i64\t$dst, $src", "i32.wrap/i64", 0xa7>; @@ -49,11 +51,15 @@ defm I64_EXTEND32_S_I64 : I<(outs I64:$dst), (ins I64:$src), (outs), (ins), 0xc4>; } // Predicates = [HasSignExt] +} // defs = [ARGUMENTS] + // Expand a "don't care" extend into zero-extend (chosen over sign-extend // somewhat arbitrarily, although it favors popular hardware architectures // and is conceptually a simpler operation). def : Pat<(i64 (anyext I32:$src)), (I64_EXTEND_U_I32 I32:$src)>; +let Defs = [ARGUMENTS] in { + // Conversion from floating point to integer instructions which don't trap on // overflow or invalid. defm I32_TRUNC_S_SAT_F32 : I<(outs I32:$dst), (ins F32:$src), (outs), (ins), @@ -97,6 +103,8 @@ defm I64_TRUNC_U_SAT_F64 : I<(outs I64:$dst), (ins F64:$src), (outs), (ins), "i64.trunc_u:sat/f64", 0xfc07>, Requires<[HasNontrappingFPToInt]>; +} // Defs = [Arguments] + // Lower llvm.wasm.trunc.saturate.* to saturating instructions def : Pat<(int_wasm_trunc_saturate_signed F32:$src), (I32_TRUNC_S_SAT_F32 F32:$src)>; @@ -115,6 +123,8 @@ def : Pat<(int_wasm_trunc_saturate_signed F64:$src), def : Pat<(int_wasm_trunc_saturate_unsigned F64:$src), (I64_TRUNC_U_SAT_F64 F64:$src)>; +let Defs = [ARGUMENTS] in { + // Conversion from floating point to integer pseudo-instructions which don't // trap on overflow or invalid. let usesCustomInserter = 1, isCodeGenOnly = 1 in { @@ -230,3 +240,5 @@ defm F64_REINTERPRET_I64 : I<(outs F64:$dst), (ins I64:$src), (outs), (ins), [(set F64:$dst, (bitconvert I64:$src))], "f64.reinterpret/i64\t$dst, $src", "f64.reinterpret/i64", 0xbf>; + +} // Defs = [ARGUMENTS] diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td index a251d60b89e..41b39f69e51 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrExceptRef.td @@ -12,6 +12,8 @@ /// //===----------------------------------------------------------------------===// +let Defs = [ARGUMENTS] in { + defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst), (ins EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond), (outs), (ins), @@ -21,6 +23,8 @@ defm SELECT_EXCEPT_REF : I<(outs EXCEPT_REF:$dst), "except_ref.select\t$dst, $lhs, $rhs, $cond", "except_ref.select", 0x1b>; +} // Defs = [ARGUMENTS] + def : Pat<(select (i32 (setne I32:$cond, 0)), EXCEPT_REF:$lhs, EXCEPT_REF:$rhs), (SELECT_EXCEPT_REF EXCEPT_REF:$lhs, EXCEPT_REF:$rhs, I32:$cond)>; def : Pat<(select (i32 (seteq I32:$cond, 0)), EXCEPT_REF:$lhs, EXCEPT_REF:$rhs), diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td index 364c485f409..70e27df27e6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td @@ -45,6 +45,8 @@ multiclass ComparisonFP<CondCode cond, string name, bits<32> f32Inst, bits<32> f !strconcat("f64.", name), f64Inst>; } +let Defs = [ARGUMENTS] in { + let isCommutable = 1 in defm ADD : BinaryFP<fadd, "add ", 0x92, 0xa0>; defm SUB : BinaryFP<fsub, "sub ", 0x93, 0xa1>; @@ -67,6 +69,8 @@ defm FLOOR : UnaryFP<ffloor, "floor", 0x8e, 0x9c>; defm TRUNC : UnaryFP<ftrunc, "trunc", 0x8f, 0x9d>; defm NEAREST : UnaryFP<fnearbyint, "nearest", 0x90, 0x9e>; +} // Defs = [ARGUMENTS] + // DAGCombine oddly folds casts into the rhs of copysign. Unfold them. def : Pat<(fcopysign F64:$lhs, F32:$rhs), (COPYSIGN_F64 F64:$lhs, (F64_PROMOTE_F32 F32:$rhs))>; @@ -77,6 +81,8 @@ def : Pat<(fcopysign F32:$lhs, F64:$rhs), def : Pat<(frint f32:$src), (NEAREST_F32 f32:$src)>; def : Pat<(frint f64:$src), (NEAREST_F64 f64:$src)>; +let Defs = [ARGUMENTS] in { + let isCommutable = 1 in { defm EQ : ComparisonFP<SETOEQ, "eq ", 0x5b, 0x61>; defm NE : ComparisonFP<SETUNE, "ne ", 0x5c, 0x62>; @@ -86,6 +92,8 @@ defm LE : ComparisonFP<SETOLE, "le ", 0x5f, 0x65>; defm GT : ComparisonFP<SETOGT, "gt ", 0x5e, 0x64>; defm GE : ComparisonFP<SETOGE, "ge ", 0x60, 0x66>; +} // Defs = [ARGUMENTS] + // Don't care floating-point comparisons, supported via other comparisons. def : Pat<(seteq f32:$lhs, f32:$rhs), (EQ_F32 f32:$lhs, f32:$rhs)>; def : Pat<(setne f32:$lhs, f32:$rhs), (NE_F32 f32:$lhs, f32:$rhs)>; @@ -100,6 +108,8 @@ def : Pat<(setle f64:$lhs, f64:$rhs), (LE_F64 f64:$lhs, f64:$rhs)>; def : Pat<(setgt f64:$lhs, f64:$rhs), (GT_F64 f64:$lhs, f64:$rhs)>; def : Pat<(setge f64:$lhs, f64:$rhs), (GE_F64 f64:$lhs, f64:$rhs)>; +let Defs = [ARGUMENTS] in { + defm SELECT_F32 : I<(outs F32:$dst), (ins F32:$lhs, F32:$rhs, I32:$cond), (outs), (ins), [(set F32:$dst, (select I32:$cond, F32:$lhs, F32:$rhs))], @@ -109,6 +119,8 @@ defm SELECT_F64 : I<(outs F64:$dst), (ins F64:$lhs, F64:$rhs, I32:$cond), [(set F64:$dst, (select I32:$cond, F64:$lhs, F64:$rhs))], "f64.select\t$dst, $lhs, $rhs, $cond", "f64.select", 0x1b>; +} // Defs = [ARGUMENTS] + // ISD::SELECT requires its operand to conform to getBooleanContents, but // WebAssembly's select interprets any non-zero value as true, so we can fold // a setne with 0 into a select. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td index 2d23acfc825..683fb3d981f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td @@ -30,7 +30,6 @@ class NI<dag oops, dag iops, list<dag> pattern, bit stack, string asmstr = "", dag OutOperandList = oops; dag InOperandList = iops; let Pattern = pattern; - let Defs = [ARGUMENTS]; } // Generates both register and stack based versions of one actual instruction. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index 9e1409cf90e..a2ea14cc28b 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -164,8 +164,7 @@ include "WebAssemblyInstrFormats.td" //===----------------------------------------------------------------------===// multiclass ARGUMENT<WebAssemblyRegClass vt> { - let hasSideEffects = 1, isCodeGenOnly = 1, - Defs = []<Register>, Uses = [ARGUMENTS] in + let hasSideEffects = 1, Uses = [ARGUMENTS], isCodeGenOnly = 1 in defm ARGUMENT_#vt : I<(outs vt:$res), (ins i32imm:$argno), (outs), (ins i32imm:$argno), [(set vt:$res, (WebAssemblyargument timm:$argno))]>; @@ -176,6 +175,8 @@ defm "": ARGUMENT<F32>; defm "": ARGUMENT<F64>; defm "": ARGUMENT<EXCEPT_REF>; +let Defs = [ARGUMENTS] in { + // get_local and set_local are not generated by instruction selection; they // are implied by virtual register uses and defs. multiclass LOCAL<WebAssemblyRegClass vt> { @@ -265,6 +266,8 @@ defm CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm), "f64.const\t$res, $imm", "f64.const\t$imm", 0x44>; } // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 +} // Defs = [ARGUMENTS] + def : Pat<(i32 (WebAssemblywrapper tglobaladdr:$addr)), (CONST_I32 tglobaladdr:$addr)>; def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)), diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td index bd41f46214a..44c93de54aa 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td @@ -45,6 +45,9 @@ multiclass ComparisonInt<CondCode cond, string name, bits<32> i32Inst, bits<32> !strconcat("i64.", name), i64Inst>; } + +let Defs = [ARGUMENTS] in { + // The spaces after the names are for aesthetic purposes only, to make // operands line up vertically after tab expansion. let isCommutable = 1 in @@ -94,12 +97,16 @@ defm EQZ_I64 : I<(outs I32:$dst), (ins I64:$src), (outs), (ins), [(set I32:$dst, (setcc I64:$src, 0, SETEQ))], "i64.eqz \t$dst, $src", "i64.eqz", 0x50>; +} // Defs = [ARGUMENTS] + // Optimize away an explicit mask on a rotate count. def : Pat<(rotl I32:$lhs, (and I32:$rhs, 31)), (ROTL_I32 I32:$lhs, I32:$rhs)>; def : Pat<(rotr I32:$lhs, (and I32:$rhs, 31)), (ROTR_I32 I32:$lhs, I32:$rhs)>; def : Pat<(rotl I64:$lhs, (and I64:$rhs, 63)), (ROTL_I64 I64:$lhs, I64:$rhs)>; def : Pat<(rotr I64:$lhs, (and I64:$rhs, 63)), (ROTR_I64 I64:$lhs, I64:$rhs)>; +let Defs = [ARGUMENTS] in { + defm SELECT_I32 : I<(outs I32:$dst), (ins I32:$lhs, I32:$rhs, I32:$cond), (outs), (ins), [(set I32:$dst, (select I32:$cond, I32:$lhs, I32:$rhs))], @@ -109,6 +116,8 @@ defm SELECT_I64 : I<(outs I64:$dst), (ins I64:$lhs, I64:$rhs, I32:$cond), [(set I64:$dst, (select I32:$cond, I64:$lhs, I64:$rhs))], "i64.select\t$dst, $lhs, $rhs, $cond", "i64.select", 0x1b>; +} // Defs = [ARGUMENTS] + // ISD::SELECT requires its operand to conform to getBooleanContents, but // WebAssembly's select interprets any non-zero value as true, so we can fold // a setne with 0 into a select. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td index ccc331d1bf0..76ef1461d22 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td @@ -53,6 +53,8 @@ def regPlusGA : PatFrag<(ops node:$addr, node:$off), // We don't need a regPlusES because external symbols never have constant // offsets folded into them, so we can just use add. +let Defs = [ARGUMENTS] in { + // Defines atomic and non-atomic loads, regular and extending. multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> { let mayLoad = 1 in @@ -71,6 +73,8 @@ defm LOAD_I64 : WebAssemblyLoad<I64, "i64.load", 0x29>; defm LOAD_F32 : WebAssemblyLoad<F32, "f32.load", 0x2a>; defm LOAD_F64 : WebAssemblyLoad<F64, "f64.load", 0x2b>; +} // Defs = [ARGUMENTS] + // Select loads with no constant offset. class LoadPatNoOffset<ValueType ty, PatFrag kind, NI inst> : Pat<(ty (kind I32:$addr)), (inst 0, 0, I32:$addr)>; @@ -140,6 +144,8 @@ def : LoadPatExternSymOffOnly<i64, load, LOAD_I64>; def : LoadPatExternSymOffOnly<f32, load, LOAD_F32>; def : LoadPatExternSymOffOnly<f64, load, LOAD_F64>; +let Defs = [ARGUMENTS] in { + // Extending load. defm LOAD8_S_I32 : WebAssemblyLoad<I32, "i32.load8_s", 0x2c>; defm LOAD8_U_I32 : WebAssemblyLoad<I32, "i32.load8_u", 0x2d>; @@ -152,6 +158,8 @@ defm LOAD16_U_I64 : WebAssemblyLoad<I64, "i64.load16_u", 0x33>; defm LOAD32_S_I64 : WebAssemblyLoad<I64, "i64.load32_s", 0x34>; defm LOAD32_U_I64 : WebAssemblyLoad<I64, "i64.load32_u", 0x35>; +} // Defs = [ARGUMENTS] + // Select extending loads with no constant offset. def : LoadPatNoOffset<i32, sextloadi8, LOAD8_S_I32>; def : LoadPatNoOffset<i32, zextloadi8, LOAD8_U_I32>; @@ -295,6 +303,9 @@ def : LoadPatExternSymOffOnly<i64, extloadi8, LOAD8_U_I64>; def : LoadPatExternSymOffOnly<i64, extloadi16, LOAD16_U_I64>; def : LoadPatExternSymOffOnly<i64, extloadi32, LOAD32_U_I64>; + +let Defs = [ARGUMENTS] in { + // Defines atomic and non-atomic stores, regular and truncating multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> { let mayStore = 1 in @@ -312,6 +323,8 @@ defm STORE_I64 : WebAssemblyStore<I64, "i64.store", 0x37>; defm STORE_F32 : WebAssemblyStore<F32, "f32.store", 0x38>; defm STORE_F64 : WebAssemblyStore<F64, "f64.store", 0x39>; +} // Defs = [ARGUMENTS] + // Select stores with no constant offset. class StorePatNoOffset<ValueType ty, PatFrag node, NI inst> : Pat<(node ty:$val, I32:$addr), (inst 0, 0, I32:$addr, ty:$val)>; @@ -376,6 +389,9 @@ def : StorePatExternSymOffOnly<i64, store, STORE_I64>; def : StorePatExternSymOffOnly<f32, store, STORE_F32>; def : StorePatExternSymOffOnly<f64, store, STORE_F64>; + +let Defs = [ARGUMENTS] in { + // Truncating store. defm STORE8_I32 : WebAssemblyStore<I32, "i32.store8", 0x3a>; defm STORE16_I32 : WebAssemblyStore<I32, "i32.store16", 0x3b>; @@ -383,6 +399,8 @@ defm STORE8_I64 : WebAssemblyStore<I64, "i64.store8", 0x3c>; defm STORE16_I64 : WebAssemblyStore<I64, "i64.store16", 0x3d>; defm STORE32_I64 : WebAssemblyStore<I64, "i64.store32", 0x3e>; +} // Defs = [ARGUMENTS] + // Select truncating stores with no constant offset. def : StorePatNoOffset<i32, truncstorei8, STORE8_I32>; def : StorePatNoOffset<i32, truncstorei16, STORE16_I32>; @@ -430,6 +448,8 @@ def : StorePatExternSymOffOnly<i64, truncstorei8, STORE8_I64>; def : StorePatExternSymOffOnly<i64, truncstorei16, STORE16_I64>; def : StorePatExternSymOffOnly<i64, truncstorei32, STORE32_I64>; +let Defs = [ARGUMENTS] in { + // Current memory size. defm MEMORY_SIZE_I32 : I<(outs I32:$dst), (ins i32imm:$flags), (outs), (ins i32imm:$flags), @@ -473,6 +493,8 @@ defm GROW_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta), 0x40>, Requires<[HasAddr32]>; +} // Defs = [ARGUMENTS] + def : Pat<(int_wasm_current_memory), (CURRENT_MEMORY_I32 0)>; def : Pat<(int_wasm_grow_memory I32:$delta), diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 419aa0b437f..57024616f3f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -55,6 +55,7 @@ multiclass ConstVec<ValueType vec_t, dag ops, dag pat, string args> { "v128.const\t"#args, 0>; } +let Defs = [ARGUMENTS] in { defm "" : ConstVec<v16i8, (ins vec_i8imm_op:$i0, vec_i8imm_op:$i1, vec_i8imm_op:$i2, vec_i8imm_op:$i3, @@ -99,6 +100,7 @@ defm "" : ConstVec<v2f64, (ins f64imm_op:$i0, f64imm_op:$i1), (build_vector (f64 fpimm:$i0), (f64 fpimm:$i1)), "$i0, $i1">; +} // Defs = [ARGUMENTS] // Create vector with identical lanes: splat def splat2 : PatFrag<(ops node:$x), (build_vector node:$x, node:$x)>; |