[X86] Fold (trunc (i32 (zextload i16))) into vbroadcast.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Fri, 6 Nov 2015 23:16:48 +0000 (23:16 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Fri, 6 Nov 2015 23:16:48 +0000 (23:16 +0000)
When matching non-LSB-extracting truncating broadcasts, we now insert
the necessary SRL. If the scalar resulted from a load, the SRL will be
folded into it, creating a narrower, offset, load.

However, i16 loads aren't Desirable, so we get i16->i32 zextloads.
We already catch i16 aextloads; catch these as well.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252363 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrSSE.td
test/CodeGen/X86/vector-shuffle-128-v8.ll
test/CodeGen/X86/vector-shuffle-256-v16.ll

index 17edb500d66f9be7ac590945730bc133f3672772..e4ff9b343451aa7717b086762bf196e13af326c4 100644 (file)
@@ -8365,6 +8365,12 @@ let Predicates = [HasAVX2] in {
             (VPBROADCASTWrm addr:$src)>;
   def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
             (VPBROADCASTWYrm addr:$src)>;
             (VPBROADCASTWrm addr:$src)>;
   def : Pat<(v16i16 (X86VBroadcast (i16 (trunc (i32 (load addr:$src)))))),
             (VPBROADCASTWYrm addr:$src)>;
+  def : Pat<(v8i16 (X86VBroadcast
+              (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
+            (VPBROADCASTWrm addr:$src)>;
+  def : Pat<(v16i16 (X86VBroadcast
+              (i16 (trunc (i32 (zextloadi16 addr:$src)))))),
+            (VPBROADCASTWYrm addr:$src)>;
 
   // Provide aliases for broadcast from the same register class that
   // automatically does the extract.
 
   // Provide aliases for broadcast from the same register class that
   // automatically does the extract.
index f4cb64e2c912352177b2d15f21f46e688702dcb3..cd66524870c4e9f3460c981c979f7507b62016cc 100644 (file)
@@ -2258,9 +2258,7 @@ define <8 x i16> @insert_dup_elt1_mem_v8i16_i32(i32* %ptr) {
 ;
 ; AVX2-LABEL: insert_dup_elt1_mem_v8i16_i32:
 ; AVX2:       # BB#0:
 ;
 ; AVX2-LABEL: insert_dup_elt1_mem_v8i16_i32:
 ; AVX2:       # BB#0:
-; AVX2-NEXT:    movzwl 2(%rdi), %eax
-; AVX2-NEXT:    vmovd %eax, %xmm0
-; AVX2-NEXT:    vpbroadcastw %xmm0, %xmm0
+; AVX2-NEXT:    vpbroadcastw 2(%rdi), %xmm0
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 0
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 0
@@ -2298,9 +2296,7 @@ define <8 x i16> @insert_dup_elt3_mem_v8i16_i32(i32* %ptr) {
 ;
 ; AVX2-LABEL: insert_dup_elt3_mem_v8i16_i32:
 ; AVX2:       # BB#0:
 ;
 ; AVX2-LABEL: insert_dup_elt3_mem_v8i16_i32:
 ; AVX2:       # BB#0:
-; AVX2-NEXT:    movzwl 2(%rdi), %eax
-; AVX2-NEXT:    vmovd %eax, %xmm0
-; AVX2-NEXT:    vpbroadcastw %xmm0, %xmm0
+; AVX2-NEXT:    vpbroadcastw 2(%rdi), %xmm0
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 1
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 1
index 4d2bcd9bc8dc3f2dcc0de3d15655f86a2cd3bd99..10e8e3a680c30cb8153e87234e98a3efe9ff0ca9 100644 (file)
@@ -3342,9 +3342,7 @@ define <16 x i16> @insert_dup_elt1_mem_v16i16_i32(i32* %ptr) #0 {
 ;
 ; AVX2-LABEL: insert_dup_elt1_mem_v16i16_i32:
 ; AVX2:       # BB#0:
 ;
 ; AVX2-LABEL: insert_dup_elt1_mem_v16i16_i32:
 ; AVX2:       # BB#0:
-; AVX2-NEXT:    movzwl 2(%rdi), %eax
-; AVX2-NEXT:    vmovd %eax, %xmm0
-; AVX2-NEXT:    vpbroadcastw %xmm0, %ymm0
+; AVX2-NEXT:    vpbroadcastw 2(%rdi), %ymm0
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 0
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 0
@@ -3363,9 +3361,7 @@ define <16 x i16> @insert_dup_elt3_mem_v16i16_i32(i32* %ptr) #0 {
 ;
 ; AVX2-LABEL: insert_dup_elt3_mem_v16i16_i32:
 ; AVX2:       # BB#0:
 ;
 ; AVX2-LABEL: insert_dup_elt3_mem_v16i16_i32:
 ; AVX2:       # BB#0:
-; AVX2-NEXT:    movzwl 2(%rdi), %eax
-; AVX2-NEXT:    vmovd %eax, %xmm0
-; AVX2-NEXT:    vpbroadcastw %xmm0, %ymm0
+; AVX2-NEXT:    vpbroadcastw 2(%rdi), %ymm0
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 1
 ; AVX2-NEXT:    retq
   %tmp = load i32, i32* %ptr, align 4
   %tmp1 = insertelement <4 x i32> zeroinitializer, i32 %tmp, i32 1