diff options
| author | Thomas Lively <tlively@google.com> | 2018-09-14 22:35:12 +0000 |
|---|---|---|
| committer | Thomas Lively <tlively@google.com> | 2018-09-14 22:35:12 +0000 |
| commit | 88b7443f9455c45a7df5ca1590d2a051ab6f12e9 (patch) | |
| tree | 8e177b0544fe1b36fd6fe600cf034aca7d833a96 | |
| parent | a98ee586bf6f396b2b6a7deeef24db87bb6736b2 (diff) | |
| download | bcm5719-llvm-88b7443f9455c45a7df5ca1590d2a051ab6f12e9.tar.gz bcm5719-llvm-88b7443f9455c45a7df5ca1590d2a051ab6f12e9.zip | |
[WebAssembly] SIMD neg
Summary: Depends on D52007.
Reviewers: aheejin, dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D52009
llvm-svn: 342296
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 30 | ||||
| -rw-r--r-- | llvm/test/CodeGen/WebAssembly/simd-arith.ll | 69 | ||||
| -rw-r--r-- | llvm/test/MC/WebAssembly/simd-encodings.s | 18 |
3 files changed, 117 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 85eafebe2d6..12f836e392b 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -134,6 +134,29 @@ multiclass SIMDBitwise<SDNode node, string name, bits<32> simdop> { defm "" : SIMDBinary<v4i32, "v128", node, name, simdop>; defm "" : SIMDBinary<v2i64, "v128", node, name, simdop>; } +multiclass SIMDNeg<ValueType vec_t, string vec, PatFrag splat_pat, + ValueType lane_t, SDNode node, dag lane, bits<32> simdop> { + defm NEG_#vec_t : SIMD_I<(outs V128:$dst), (ins V128:$vec), + (outs), (ins), + [(set + (vec_t V128:$dst), + (vec_t (node + (vec_t (splat_pat lane)), + (vec_t V128:$vec) + )) + )], + vec#".neg\t$dst, $vec", vec#".neg", simdop>; +} +multiclass SIMDNegInt<ValueType vec_t, string vec, PatFrag splat_pat, + ValueType lane_t, bits<32> simdop> { + defm "" : SIMDNeg<vec_t, vec, splat_pat, lane_t, sub, (lane_t 0), simdop>; +} +def fpimm0 : FPImmLeaf<fAny, [{ return Imm.isExactlyValue(+0.0); }]>; +multiclass SIMDNegFP<ValueType vec_t, string vec, PatFrag splat_pat, + ValueType lane_t, bits<32> simdop> { + defm "" : SIMDNeg<vec_t, vec, splat_pat, lane_t, fsub, (lane_t fpimm0), + simdop>; +} multiclass SIMDNot<ValueType vec_t, PatFrag splat_pat, ValueType lane_t> { defm NOT_#vec_t : SIMD_I<(outs V128:$dst), (ins V128:$vec), (outs), (ins), @@ -281,6 +304,13 @@ defm SUB : SIMDBinaryInt<sub, "sub", 28>; defm SUB : SIMDBinaryFP<fsub, "sub", 124>; defm DIV : SIMDBinaryFP<fdiv, "div", 126>; +defm "" : SIMDNegInt<v16i8, "i8x16", splat16, i32, 35>; +defm "" : SIMDNegInt<v8i16, "i16x8", splat8, i32, 36>; +defm "" : SIMDNegInt<v4i32, "i32x4", splat4, i32, 37>; +defm "" : SIMDNegInt<v2i64, "i64x2", splat2, i64, 38>; +defm "" : SIMDNegFP<v4f32, "f32x4", splat4, f32, 114>; +defm "" : SIMDNegFP<v2f64, "f64x2", splat2, f64, 115>; + let isCommutable = 1 in { defm AND : SIMDBitwise<and, "and", 59>; defm OR : SIMDBitwise<or, "or", 60>; diff --git a/llvm/test/CodeGen/WebAssembly/simd-arith.ll b/llvm/test/CodeGen/WebAssembly/simd-arith.ll index bfbefb11b41..bc7f8785bbb 100644 --- a/llvm/test/CodeGen/WebAssembly/simd-arith.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-arith.ll @@ -46,6 +46,19 @@ define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) { ret <16 x i8> %a } +; CHECK-LABEL: neg_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128-NEXT: .param v128{{$}} +; SIMD128-NEXT: .result v128{{$}} +; SIMD128-NEXT: i8x16.neg $push0=, $0{{$}} +; SIMD128-NEXT: return $pop0{{$}} +define <16 x i8> @neg_v16i8(<16 x i8> %x) { + %a = sub <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, + i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, + %x + ret <16 x i8> %a +} + ; CHECK-LABEL: and_v16i8: ; NO-SIMD128-NOT: v128 ; SIMD128-NEXT: .param v128, v128{{$}} @@ -129,6 +142,18 @@ define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { ret <8 x i16> %a } +; CHECK-LABEL: neg_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128-NEXT: .param v128{{$}} +; SIMD128-NEXT: .result v128{{$}} +; SIMD128-NEXT: i16x8.neg $push0=, $0{{$}} +; SIMD128-NEXT: return $pop0{{$}} +define <8 x i16> @neg_v8i16(<8 x i16> %x) { + %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, + %x + ret <8 x i16> %a +} + ; CHECK-LABEL: and_v8i16: ; NO-SIMD128-NOT: v128 ; SIMD128-NEXT: .param v128, v128{{$}} @@ -210,6 +235,17 @@ define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { ret <4 x i32> %a } +; CHECK-LABEL: neg_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128-NEXT: .param v128{{$}} +; SIMD128-NEXT: .result v128{{$}} +; SIMD128-NEXT: i32x4.neg $push0=, $0{{$}} +; SIMD128-NEXT: return $pop0{{$}} +define <4 x i32> @neg_v4i32(<4 x i32> %x) { + %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x + ret <4 x i32> %a +} + ; CHECK-LABEL: and_v4i32: ; NO-SIMD128-NOT: v128 ; SIMD128-NEXT: .param v128, v128{{$}} @@ -293,6 +329,17 @@ define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { ret <2 x i64> %a } +; CHECK-LABEL: neg_v2i64: +; NO-SIMD128-NOT: i64x2 +; SIMD128-NEXT: .param v128{{$}} +; SIMD128-NEXT: .result v128{{$}} +; SIMD128-NEXT: i64x2.neg $push0=, $0{{$}} +; SIMD128-NEXT: return $pop0{{$}} +define <2 x i64> @neg_v2i64(<2 x i64> %x) { + %a = sub <2 x i64> <i64 0, i64 0>, %x + ret <2 x i64> %a +} + ; CHECK-LABEL: and_v2i64: ; NO-SIMD128-NOT: v128 ; SIMD128-VM-NOT: v128 @@ -344,6 +391,17 @@ define <2 x i64> @not_v2i64(<2 x i64> %x) { ; ============================================================================== ; 4 x float ; ============================================================================== +; CHECK-LABEL: neg_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128-NEXT: .param v128{{$}} +; SIMD128-NEXT: .result v128{{$}} +; SIMD128-NEXT: f32x4.neg $push0=, $0{{$}} +; SIMD128-NEXT: return $pop0{{$}} +define <4 x float> @neg_v4f32(<4 x float> %x) { + %a = fsub <4 x float> <float 0., float 0., float 0., float 0.>, %x + ret <4 x float> %a +} + ; CHECK-LABEL: add_v4f32: ; NO-SIMD128-NOT: f32x4 ; SIMD128-NEXT: .param v128, v128{{$}} @@ -391,6 +449,17 @@ define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) { ; ============================================================================== ; 2 x double ; ============================================================================== +; CHECK-LABEL: neg_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-NEXT: .param v128{{$}} +; SIMD128-NEXT: .result v128{{$}} +; SIMD128-NEXT: f64x2.neg $push0=, $0{{$}} +; SIMD128-NEXT: return $pop0{{$}} +define <2 x double> @neg_v2f64(<2 x double> %x) { + %a = fsub <2 x double> <double 0., double 0.>, %x + ret <2 x double> %a +} + ; CHECK-LABEL: add_v2f64: ; NO-SIMD128-NOT: f64x2 ; SIMD128-VM-NOT: f62x2 diff --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s index 0c7aa20e45d..469b93efb7e 100644 --- a/llvm/test/MC/WebAssembly/simd-encodings.s +++ b/llvm/test/MC/WebAssembly/simd-encodings.s @@ -133,6 +133,18 @@ # CHECK: i32x4.mul # encoding: [0xfd,0x22] i32x4.mul + # CHECK: i8x16.neg # encoding: [0xfd,0x23] + i8x16.neg + + # CHECK: i16x8.neg # encoding: [0xfd,0x24] + i16x8.neg + + # CHECK: i32x4.neg # encoding: [0xfd,0x25] + i32x4.neg + + # CHECK: i64x2.neg # encoding: [0xfd,0x26] + i64x2.neg + # CHECK: v128.and # encoding: [0xfd,0x3b] v128.and @@ -271,6 +283,12 @@ # CHECK: f64x2.ge # encoding: [0xfd,0x71] f64x2.ge + # CHECK: f32x4.neg # encoding: [0xfd,0x72] + f32x4.neg + + # CHECK: f64x2.neg # encoding: [0xfd,0x73] + f64x2.neg + # CHECK: f32x4.add # encoding: [0xfd,0x7a] f32x4.add |

