diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index fc5d73dac52e..64033c993e3f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -72,35 +72,30 @@ defm "" : SIMDLoadSplat<"v16x8", 195>; defm "" : SIMDLoadSplat<"v32x4", 196>; defm "" : SIMDLoadSplat<"v64x2", 197>; -def wasm_load_splat_t : SDTypeProfile<1, 1, []>; -def wasm_load_splat : SDNode<"WebAssemblyISD::LOAD_SPLAT", wasm_load_splat_t>; - -foreach args = [["v16i8", "i32", "extloadi8"], ["v8i16", "i32", "extloadi16"], - ["v4i32", "i32", "load"], ["v2i64", "i64", "load"], - ["v4f32", "f32", "load"], ["v2f64", "f64", "load"]] in -def load_splat_#args[0] : - PatFrag<(ops node:$addr), (wasm_load_splat - (!cast<ValueType>(args[1]) (!cast<PatFrag>(args[2]) node:$addr)))>; +def wasm_load_splat_t : SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>; +def wasm_load_splat : SDNode<"WebAssemblyISD::LOAD_SPLAT", wasm_load_splat_t, + [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; +def load_splat : PatFrag<(ops node:$addr), (wasm_load_splat node:$addr)>; let Predicates = [HasUnimplementedSIMD128] in foreach args = [["v16i8", "v8x16"], ["v8i16", "v16x8"], ["v4i32", "v32x4"], ["v2i64", "v64x2"], ["v4f32", "v32x4"], ["v2f64", "v64x2"]] in { def : LoadPatNoOffset<!cast<ValueType>(args[0]), - !cast<PatFrag>("load_splat_"#args[0]), + load_splat, !cast<NI>("LOAD_SPLAT_"#args[1])>; def : LoadPatImmOff<!cast<ValueType>(args[0]), - !cast<PatFrag>("load_splat_"#args[0]), + load_splat, regPlusImm, !cast<NI>("LOAD_SPLAT_"#args[1])>; def : LoadPatImmOff<!cast<ValueType>(args[0]), - !cast<PatFrag>("load_splat_"#args[0]), + load_splat, or_is_add, !cast<NI>("LOAD_SPLAT_"#args[1])>; def : LoadPatOffsetOnly<!cast<ValueType>(args[0]), - !cast<PatFrag>("load_splat_"#args[0]), + load_splat, !cast<NI>("LOAD_SPLAT_"#args[1])>; def : LoadPatGlobalAddrOffOnly<!cast<ValueType>(args[0]), - !cast<PatFrag>("load_splat_"#args[0]), + load_splat, !cast<NI>("LOAD_SPLAT_"#args[1])>; } @@ -732,8 +727,44 @@ defm SUB_SAT_U : SIMDBinaryIntSmall<int_wasm_sub_saturate_unsigned, "sub_saturate_u", 92>; // Integer multiplication: mul +let isCommutable = 1 in defm MUL : SIMDBinaryIntNoI64x2<mul, "mul", 93>; +// Integer min_s / min_u / max_s / max_u +let isCommutable = 1 in { +defm MIN_S : SIMDBinaryIntNoI64x2<smin, "min_s", 94>; +defm MIN_U : SIMDBinaryIntNoI64x2<umin, "min_u", 95>; +defm MAX_S : SIMDBinaryIntNoI64x2<smax, "max_s", 96>; +defm MAX_U : SIMDBinaryIntNoI64x2<umax, "max_u", 97>; +} // isCommutable = 1 + +// Integer unsigned rounding average: avgr_u +let isCommutable = 1, Predicates = [HasUnimplementedSIMD128] in { +defm AVGR_U : SIMDBinary<v16i8, "i8x16", int_wasm_avgr_unsigned, "avgr_u", 217>; +defm AVGR_U : SIMDBinary<v8i16, "i16x8", int_wasm_avgr_unsigned, "avgr_u", 218>; +} + +def add_nuw : PatFrag<(ops node:$lhs, node:$rhs), + (add node:$lhs, node:$rhs), + "return N->getFlags().hasNoUnsignedWrap();">; + +foreach nodes = [[v16i8, splat16], [v8i16, splat8]] in +def : Pat<(srl + (add_nuw + (add_nuw (nodes[0] V128:$lhs), (nodes[0] V128:$rhs)), + (nodes[1] (i32 1)) + ), + (nodes[0] (nodes[1] (i32 1))) + ), + (!cast<NI>("AVGR_U_"#nodes[0]) V128:$lhs, V128:$rhs)>; + +// Widening dot product: i32x4.dot_i16x8_s +let isCommutable = 1 in +defm DOT : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs), (outs), (ins), + [(set V128:$dst, (int_wasm_dot V128:$lhs, V128:$rhs))], + "i32x4.dot_i16x8_s\t$dst, $lhs, $rhs", "i32x4.dot_i16x8_s", + 219>; + //===----------------------------------------------------------------------===// // Floating-point unary arithmetic //===----------------------------------------------------------------------===// |