Index: lib/Target/WebAssembly/WebAssemblyInstrSIMD.td =================================================================== --- lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -118,6 +118,18 @@ defm "" : SIMDBinary; defm "" : SIMDBinary; } +multiclass SIMDNot { + defm NOT_#vec_t : SIMD_I<(outs V128:$dst), (ins V128:$vec), + (outs), (ins), + [(set + (vec_t V128:$dst), + (vec_t (xor + (vec_t V128:$vec), + (vec_t (splat_pat (lane_t -1))) + )) + )], + "v128.not\t$dst, $vec", "v128.not", 62>; +} let Defs = [ARGUMENTS] in { defm "" : ConstVec; } // isCommutable = 1 +defm "" : SIMDNot; +defm "" : SIMDNot; +defm "" : SIMDNot; +defm "" : SIMDNot; + } // Defs = [ARGUMENTS] // follow convention of making implicit expansions unsigned Index: test/CodeGen/WebAssembly/simd-arith.ll =================================================================== --- test/CodeGen/WebAssembly/simd-arith.ll +++ test/CodeGen/WebAssembly/simd-arith.ll @@ -47,7 +47,7 @@ } ; CHECK-LABEL: and_v16i8 -; NO-SIMD128-NOT: i8x16 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} @@ -58,7 +58,7 @@ } ; CHECK-LABEL: or_v16i8 -; NO-SIMD128-NOT: i8x16 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} @@ -69,7 +69,7 @@ } ; CHECK-LABEL: xor_v16i8 -; NO-SIMD128-NOT: i8x16 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} @@ -79,6 +79,20 @@ ret <16 x i8> %a } +; CHECK-LABEL: not_v16i8 +; NO-SIMD128-NOT: v128 +; SIMD128: .param v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} +; SIMD128: return $pop0 # +define <16 x i8> @not_v16i8(<16 x i8> %x) { + %a = xor <16 x i8> %x, + ret <16 x i8> %a +} + ; ============================================================================== ; 8 x i16 ; ============================================================================== @@ -116,7 +130,7 @@ } ; CHECK-LABEL: and_v8i16 -; NO-SIMD128-NOT: i16x8 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} @@ -127,7 +141,7 @@ } ; CHECK-LABEL: or_v8i16 -; NO-SIMD128-NOT: i16x8 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} @@ -138,7 +152,7 @@ } ; CHECK-LABEL: xor_v8i16 -; NO-SIMD128-NOT: i16x8 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} @@ -148,6 +162,18 @@ ret <8 x i16> %a } +; CHECK-LABEL: not_v8i16 +; NO-SIMD128-NOT: v128 +; SIMD128: .param v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} +; SIMD128: return $pop0 # +define <8 x i16> @not_v8i16(<8 x i16> %x) { + %a = xor <8 x i16> %x, + ret <8 x i16> %a +} + ; ============================================================================== ; 4 x i32 ; ============================================================================== @@ -185,7 +211,7 @@ } ; CHECK-LABEL: and_v4i32 -; NO-SIMD128-NOT: i32x4 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} @@ -196,7 +222,7 @@ } ; CHECK-LABEL: or_v4i32 -; NO-SIMD128-NOT: i32x4 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} @@ -207,7 +233,7 @@ } ; CHECK-LABEL: xor_v4i32 -; NO-SIMD128-NOT: i32x4 +; NO-SIMD128-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} @@ -217,6 +243,17 @@ ret <4 x i32> %a } +; CHECK-LABEL: not_v4i32 +; NO-SIMD128-NOT: v128 +; SIMD128: .param v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} +; SIMD128: return $pop0 # +define <4 x i32> @not_v4i32(<4 x i32> %x) { + %a = xor <4 x i32> %x, + ret <4 x i32> %a +} + ; ============================================================================== ; 2 x i64 ; ============================================================================== @@ -257,7 +294,8 @@ } ; CHECK-LABEL: and_v2i64 -; NO-SIMD128-NOT: i64x2 +; NO-SIMD128-NOT: v128 +; SIMD128-VM-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} @@ -268,7 +306,8 @@ } ; CHECK-LABEL: or_v2i64 -; NO-SIMD128-NOT: i64x2 +; NO-SIMD128-NOT: v128 +; SIMD128-VM-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} @@ -279,7 +318,8 @@ } ; CHECK-LABEL: xor_v2i64 -; NO-SIMD128-NOT: i64x2 +; NO-SIMD128-NOT: v128 +; SIMD128-VM-NOT: v128 ; SIMD128: .param v128, v128{{$}} ; SIMD128: .result v128{{$}} ; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} @@ -289,6 +329,18 @@ ret <2 x i64> %a } +; CHECK-LABEL: not_v2i64 +; NO-SIMD128-NOT: v128 +; SIMD128-VM-NOT: v128 +; SIMD128: .param v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.not $push0=, $0 # encoding: [0xfd,0x3e]{{$}} +; SIMD128: return $pop0 # +define <2 x i64> @not_v2i64(<2 x i64> %x) { + %a = xor <2 x i64> %x, + ret <2 x i64> %a +} + ; ============================================================================== ; 4 x float ; ==============================================================================