[llvm] r364446 - [WebAssembly] Omit wrap on i64x2.{shl, shr*} ISel when possible

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 26 09:19:59 PDT 2019


Author: tlively
Date: Wed Jun 26 09:19:59 2019
New Revision: 364446

URL: http://llvm.org/viewvc/llvm-project?rev=364446&view=rev
Log:
[WebAssembly] Omit wrap on i64x2.{shl,shr*} ISel when possible

Summary:
Since the WebAssembly SIMD shift instructions take i32 operands, we
truncate the i64 operand to <2 x i64> shifts during ISel. When the i64
operand is sign extended from i32, this CL makes it so the sign
extension is dropped instead of a wrap instruction added.

Reviewers: dschuff, aheejin

Subscribers: sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D63615

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
    llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td?rev=364446&r1=364445&r2=364446&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td Wed Jun 26 09:19:59 2019
@@ -579,10 +579,16 @@ defm SHL : SIMDShiftInt<shl, "shl", 84>;
 defm SHR_S : SIMDShiftInt<sra, "shr_s", 85>;
 defm SHR_U : SIMDShiftInt<srl, "shr_u", 86>;
 
-// Truncate i64 shift operands to i32s
-foreach shifts = [[shl, SHL_v2i64], [sra, SHR_S_v2i64], [srl, SHR_U_v2i64]] in
+// Truncate i64 shift operands to i32s, except if they are already i32s
+foreach shifts = [[shl, SHL_v2i64], [sra, SHR_S_v2i64], [srl, SHR_U_v2i64]] in {
+def : Pat<(v2i64 (shifts[0]
+            (v2i64 V128:$vec),
+            (v2i64 (splat2 (i64 (sext I32:$x))))
+          )),
+          (v2i64 (shifts[1] (v2i64 V128:$vec), (i32 I32:$x)))>;
 def : Pat<(v2i64 (shifts[0] (v2i64 V128:$vec), (v2i64 (splat2 I64:$x)))),
           (v2i64 (shifts[1] (v2i64 V128:$vec), (I32_WRAP_I64 I64:$x)))>;
+}
 
 // 2xi64 shifts with constant shift amounts are custom lowered to avoid wrapping
 def wasm_shift_t : SDTypeProfile<1, 2,

Modified: llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll?rev=364446&r1=364445&r2=364446&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/simd-arith.ll Wed Jun 26 09:19:59 2019
@@ -730,13 +730,26 @@ define <2 x i64> @shl_v2i64(<2 x i64> %v
   ret <2 x i64> %a
 }
 
-; CHECK-LABEL: shl_nozext_v2i64:
+; CHECK-LABEL: shl_sext_v2i64:
 ; NO-SIMD128-NOT: i64x2
-; SIMD128-NEXT: .functype shl_nozext_v2i64 (v128, i64) -> (v128){{$}}
+; SIMD128-NEXT: .functype shl_sext_v2i64 (v128, i32) -> (v128){{$}}
+; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @shl_sext_v2i64(<2 x i64> %v, i32 %x) {
+  %x2 = sext i32 %x to i64
+  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
+  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+  %a = shl <2 x i64> %v, %s
+  ret <2 x i64> %a
+}
+
+; CHECK-LABEL: shl_noext_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-NEXT: .functype shl_noext_v2i64 (v128, i64) -> (v128){{$}}
 ; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
 ; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
 ; SIMD128-NEXT: return $pop[[R]]{{$}}
-define <2 x i64> @shl_nozext_v2i64(<2 x i64> %v, i64 %x) {
+define <2 x i64> @shl_noext_v2i64(<2 x i64> %v, i64 %x) {
   %t = insertelement <2 x i64> undef, i64 %x, i32 0
   %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
   %a = shl <2 x i64> %v, %s
@@ -784,13 +797,26 @@ define <2 x i64> @shr_s_v2i64(<2 x i64>
   ret <2 x i64> %a
 }
 
-; CHECK-LABEL: shr_s_nozext_v2i64:
+; CHECK-LABEL: shr_s_sext_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-NEXT: .functype shr_s_sext_v2i64 (v128, i32) -> (v128){{$}}
+; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @shr_s_sext_v2i64(<2 x i64> %v, i32 %x) {
+  %x2 = sext i32 %x to i64
+  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
+  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+  %a = ashr <2 x i64> %v, %s
+  ret <2 x i64> %a
+}
+
+; CHECK-LABEL: shr_s_noext_v2i64:
 ; NO-SIMD128-NOT: i64x2
-; SIMD128-NEXT: .functype shr_s_nozext_v2i64 (v128, i64) -> (v128){{$}}
+; SIMD128-NEXT: .functype shr_s_noext_v2i64 (v128, i64) -> (v128){{$}}
 ; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
 ; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
 ; SIMD128-NEXT: return $pop[[R]]{{$}}
-define <2 x i64> @shr_s_nozext_v2i64(<2 x i64> %v, i64 %x) {
+define <2 x i64> @shr_s_noext_v2i64(<2 x i64> %v, i64 %x) {
   %t = insertelement <2 x i64> undef, i64 %x, i32 0
   %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
   %a = ashr <2 x i64> %v, %s
@@ -838,13 +864,26 @@ define <2 x i64> @shr_u_v2i64(<2 x i64>
   ret <2 x i64> %a
 }
 
-; CHECK-LABEL: shr_u_nozext_v2i64:
+; CHECK-LABEL: shr_u_sext_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-NEXT: .functype shr_u_sext_v2i64 (v128, i32) -> (v128){{$}}
+; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+define <2 x i64> @shr_u_sext_v2i64(<2 x i64> %v, i32 %x) {
+  %x2 = sext i32 %x to i64
+  %t = insertelement <2 x i64> undef, i64 %x2, i32 0
+  %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
+  %a = lshr <2 x i64> %v, %s
+  ret <2 x i64> %a
+}
+
+; CHECK-LABEL: shr_u_noext_v2i64:
 ; NO-SIMD128-NOT: i64x2
-; SIMD128-NEXT: .functype shr_u_nozext_v2i64 (v128, i64) -> (v128){{$}}
+; SIMD128-NEXT: .functype shr_u_noext_v2i64 (v128, i64) -> (v128){{$}}
 ; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}}
 ; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}}
 ; SIMD128-NEXT: return $pop[[R]]{{$}}
-define <2 x i64> @shr_u_nozext_v2i64(<2 x i64> %v, i64 %x) {
+define <2 x i64> @shr_u_noext_v2i64(<2 x i64> %v, i64 %x) {
   %t = insertelement <2 x i64> undef, i64 %x, i32 0
   %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0>
   %a = lshr <2 x i64> %v, %s




More information about the llvm-commits mailing list