From 82812fb986aa217a69f18390207a683049b7748a Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Wed, 15 Aug 2018 16:18:51 +0000 Subject: [PATCH] [WebAssembly] SIMD replace_lane Implement and test replace_lane instructions. Patch by Thomas Lively Differential Revision: https://reviews.llvm.org/D50750 llvm-svn: 339786 --- .../lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 23 +++++++- llvm/test/CodeGen/WebAssembly/simd.ll | 68 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index fc91b574..be74fb8 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -74,6 +74,27 @@ def : Pat<(i32 (vector_extract (v16i8 V128:$vec), (i32 LaneIdx16:$idx))), def : Pat<(i32 (vector_extract (v8i16 V128:$vec), (i32 LaneIdx8:$idx))), (EXTRACT_LANE_U_I16x8 V128:$vec, (i32 LaneIdx8:$idx))>; +// lane replacement +multiclass ReplaceLane simdop> { + defm REPLACE_LANE_#vec_t : SIMD_I<(outs V128:$dst), + (ins V128:$vec, I32:$idx, reg_t:$x), + (outs), (ins I32:$idx), + [(set V128:$dst, (vector_insert + (vec_t V128:$vec), + (lane_t reg_t:$x), + (i32 imm_t:$idx)))], + vec#".replace_lane\t$dst, $vec, $idx, $x", + vec#".replace_lane\t$idx", simdop>; +} +let Defs = [ARGUMENTS] in { +defm "" : ReplaceLane; +defm "" : ReplaceLane; +defm "" : ReplaceLane; +defm "" : ReplaceLane; +defm "" : ReplaceLane; +defm "" : ReplaceLane; +} // Defs = [ARGUMENTS] // splats def splat2 : PatFrag<(ops node:$x), (build_vector node:$x, node:$x)>; @@ -100,7 +121,7 @@ defm "" : Splat; defm "" : Splat; defm "" : Splat; defm "" : Splat; -} +} // Defs = [ARGUMENTS] // arithmetic let Defs = [ARGUMENTS] in { diff --git a/llvm/test/CodeGen/WebAssembly/simd.ll b/llvm/test/CodeGen/WebAssembly/simd.ll index 50d8b68..414c5b3 100644 --- a/llvm/test/CodeGen/WebAssembly/simd.ll +++ b/llvm/test/CodeGen/WebAssembly/simd.ll @@ -59,6 +59,17 @@ define i8 @extract_v16i8(<16 x i8> %v) { ret i8 %elem } +; CHECK-LABEL: replace_v16i8: +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, i32{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i8x16.replace_lane $push0=, $0, 11, $1 # encoding: [0xfd,0x11,0x0b]{{$}} +; SIMD128: return $pop0 # encoding: [0x0f]{{$}} +define <16 x i8> @replace_v16i8(<16 x i8> %v, i8 %x) { + %res = insertelement <16 x i8> %v, i8 %x, i32 11 + ret <16 x i8> %res +} + ; ============================================================================== ; 8 x i16 ; ============================================================================== @@ -110,6 +121,17 @@ define i16 @extract_v8i16(<8 x i16> %v) { ret i16 %elem } +; CHECK-LABEL: replace_v8i16: +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, i32{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i16x8.replace_lane $push0=, $0, 7, $1 # encoding: [0xfd,0x12,0x07]{{$}} +; SIMD128: return $pop0 # encoding: [0x0f]{{$}} +define <8 x i16> @replace_v8i16(<8 x i16> %v, i16 %x) { + %res = insertelement <8 x i16> %v, i16 %x, i32 7 + ret <8 x i16> %res +} + ; ============================================================================== ; 4 x i32 ; ============================================================================== @@ -137,6 +159,17 @@ define i32 @extract_v4i32(<4 x i32> %v) { ret i32 %elem } +; CHECK-LABEL: replace_v4i32: +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, i32{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i32x4.replace_lane $push0=, $0, 2, $1 # encoding: [0xfd,0x13,0x02]{{$}} +; SIMD128: return $pop0 # encoding: [0x0f]{{$}} +define <4 x i32> @replace_v4i32(<4 x i32> %v, i32 %x) { + %res = insertelement <4 x i32> %v, i32 %x, i32 2 + ret <4 x i32> %res +} + ; ============================================================================== ; 2 x i64 ; ============================================================================== @@ -165,6 +198,18 @@ define i64 @extract_v2i64(<2 x i64> %v) { ret i64 %elem } +; CHECK-LABEL: replace_v2i64: +; NO-SIMD128-NOT: i64x2 +; SIMD128-VM-NOT: i64x2 +; SIMD128: .param v128, i64{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: i64x2.replace_lane $push0=, $0, 0, $1 # encoding: [0xfd,0x14,0x00]{{$}} +; SIMD128: return $pop0 # encoding: [0x0f]{{$}} +define <2 x i64> @replace_v2i64(<2 x i64> %v, i64 %x) { + %res = insertelement <2 x i64> %v, i64 %x, i32 0 + ret <2 x i64> %res +} + ; ============================================================================== ; 4 x f32 ; ============================================================================== @@ -192,6 +237,17 @@ define float @extract_v4f32(<4 x float> %v) { ret float %elem } +; CHECK-LABEL: replace_v4f32: +; NO-SIMD128-NOT: f32x4 +; SIMD128: .param v128, f32{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f32x4.replace_lane $push0=, $0, 2, $1 # encoding: [0xfd,0x15,0x02]{{$}} +; SIMD128: return $pop0 # encoding: [0x0f]{{$}} +define <4 x float> @replace_v4f32(<4 x float> %v, float %x) { + %res = insertelement <4 x float> %v, float %x, i32 2 + ret <4 x float> %res +} + ; ============================================================================== ; 2 x f64 ; ============================================================================== @@ -219,3 +275,15 @@ define double @extract_v2f64(<2 x double> %v) { %elem = extractelement <2 x double> %v, i32 1 ret double %elem } + +; CHECK-LABEL: replace_v2f64: +; NO-SIMD128-NOT: f64x2 +; SIMD128-VM-NOT: f64x2 +; SIMD128: .param v128, f64{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: f64x2.replace_lane $push0=, $0, 0, $1 # encoding: [0xfd,0x16,0x00]{{$}} +; SIMD128: return $pop0 # encoding: [0x0f]{{$}} +define <2 x double> @replace_v2f64(<2 x double> %v, double %x) { + %res = insertelement <2 x double> %v, double %x, i32 0 + ret <2 x double> %res +} -- 2.7.4