aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td59
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
//===----------------------------------------------------------------------===//