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 @@ -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 ; ============================================================================== @@ -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 ; ============================================================================== @@ -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 ; ============================================================================== @@ -289,6 +326,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 ; ==============================================================================