]> granicus.if.org Git - llvm/commitdiff
[X86][AVX] Only combine loads to broadcasts for legal types
authorSimon Pilgrim <llvm-dev@redking.me.uk>
Wed, 27 Feb 2019 11:17:25 +0000 (11:17 +0000)
committerSimon Pilgrim <llvm-dev@redking.me.uk>
Wed, 27 Feb 2019 11:17:25 +0000 (11:17 +0000)
Thanks to @echristo for spotting this.

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

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/avx-vbroadcast.ll
test/CodeGen/X86/avx2-vbroadcast.ll

index cb272335e2ba18305ee9af09f058881e1375a720..e5b2f05473e7b1236e49fb792302c8dd671af839 100644 (file)
@@ -7448,15 +7448,17 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
       if (RepeatSize > ScalarSize)
         RepeatVT = EVT::getVectorVT(*DAG.getContext(), RepeatVT,
                                     RepeatSize / ScalarSize);
-      if (SDValue RepeatLoad = EltsFromConsecutiveLoads(
-              RepeatVT, RepeatedLoads, DL, DAG, Subtarget, isAfterLegalize)) {
-        EVT BroadcastVT =
-            EVT::getVectorVT(*DAG.getContext(), RepeatVT.getScalarType(),
-                             VT.getSizeInBits() / ScalarSize);
-        unsigned Opcode = RepeatSize > ScalarSize ? X86ISD::SUBV_BROADCAST
-                                                  : X86ISD::VBROADCAST;
-        SDValue Broadcast = DAG.getNode(Opcode, DL, BroadcastVT, RepeatLoad);
-        return DAG.getBitcast(VT, Broadcast);
+      EVT BroadcastVT =
+          EVT::getVectorVT(*DAG.getContext(), RepeatVT.getScalarType(),
+                           VT.getSizeInBits() / ScalarSize);
+      if (TLI.isTypeLegal(BroadcastVT)) {
+        if (SDValue RepeatLoad = EltsFromConsecutiveLoads(
+                RepeatVT, RepeatedLoads, DL, DAG, Subtarget, isAfterLegalize)) {
+          unsigned Opcode = RepeatSize > ScalarSize ? X86ISD::SUBV_BROADCAST
+                                                    : X86ISD::VBROADCAST;
+          SDValue Broadcast = DAG.getNode(Opcode, DL, BroadcastVT, RepeatLoad);
+          return DAG.getBitcast(VT, Broadcast);
+        }
       }
     }
   }
index 84537cb15dfca8aece66d81040084315ace4c969..3426d6504c04ac67d31580c5b2d6f0fb2d6414d8 100644 (file)
@@ -856,6 +856,32 @@ define <4 x double> @broadcast_shuffle1032(double* %p) {
   ret <4 x double> %4
 }
 
+define void @broadcast_v16i32(i32* %a, <16 x i32>* %b) {
+; X32-LABEL: broadcast_v16i32:
+; X32:       ## %bb.0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    vbroadcastss (%ecx), %ymm0
+; X32-NEXT:    vmovups %ymm0, 32(%eax)
+; X32-NEXT:    vmovups %ymm0, (%eax)
+; X32-NEXT:    vzeroupper
+; X32-NEXT:    retl
+;
+; X64-LABEL: broadcast_v16i32:
+; X64:       ## %bb.0:
+; X64-NEXT:    vbroadcastss (%rdi), %ymm0
+; X64-NEXT:    vmovups %ymm0, 32(%rsi)
+; X64-NEXT:    vmovups %ymm0, (%rsi)
+; X64-NEXT:    vzeroupper
+; X64-NEXT:    retq
+  %1 = load i32, i32* %a, align 4
+  %2 = insertelement <8 x i32> undef, i32 %1, i32 0
+  %3 = shufflevector <8 x i32> %2, <8 x i32> undef, <8 x i32> zeroinitializer
+  %4 = shufflevector <8 x i32> undef, <8 x i32> %3, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
+  store <16 x i32> %4, <16 x i32>* %b, align 4
+  ret void
+}
+
 ;
 ; When VBROADCAST replaces an existing load, ensure it still respects lifetime dependencies.
 ;
index e10dbdaeb4f26657835d91d7005aad94904f804e..e7dd881960b39df5a082c0899e3d802fbcfa1ba9 100644 (file)
@@ -1037,6 +1037,48 @@ define <4 x double> @splat_concat4(double %d) {
   ret <4 x double> %5
 }
 
+define void @broadcast_v16i32(i32* %a, <16 x i32>* %b) {
+; X32-AVX2-LABEL: broadcast_v16i32:
+; X32-AVX2:       ## %bb.0:
+; X32-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-AVX2-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-AVX2-NEXT:    vbroadcastss (%ecx), %ymm0
+; X32-AVX2-NEXT:    vmovups %ymm0, 32(%eax)
+; X32-AVX2-NEXT:    vmovups %ymm0, (%eax)
+; X32-AVX2-NEXT:    vzeroupper
+; X32-AVX2-NEXT:    retl
+;
+; X64-AVX2-LABEL: broadcast_v16i32:
+; X64-AVX2:       ## %bb.0:
+; X64-AVX2-NEXT:    vbroadcastss (%rdi), %ymm0
+; X64-AVX2-NEXT:    vmovups %ymm0, 32(%rsi)
+; X64-AVX2-NEXT:    vmovups %ymm0, (%rsi)
+; X64-AVX2-NEXT:    vzeroupper
+; X64-AVX2-NEXT:    retq
+;
+; X32-AVX512VL-LABEL: broadcast_v16i32:
+; X32-AVX512VL:       ## %bb.0:
+; X32-AVX512VL-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-AVX512VL-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-AVX512VL-NEXT:    vbroadcastss (%ecx), %zmm0
+; X32-AVX512VL-NEXT:    vmovups %zmm0, (%eax)
+; X32-AVX512VL-NEXT:    vzeroupper
+; X32-AVX512VL-NEXT:    retl
+;
+; X64-AVX512VL-LABEL: broadcast_v16i32:
+; X64-AVX512VL:       ## %bb.0:
+; X64-AVX512VL-NEXT:    vbroadcastss (%rdi), %zmm0
+; X64-AVX512VL-NEXT:    vmovups %zmm0, (%rsi)
+; X64-AVX512VL-NEXT:    vzeroupper
+; X64-AVX512VL-NEXT:    retq
+  %1 = load i32, i32* %a, align 4
+  %2 = insertelement <8 x i32> undef, i32 %1, i32 0
+  %3 = shufflevector <8 x i32> %2, <8 x i32> undef, <8 x i32> zeroinitializer
+  %4 = shufflevector <8 x i32> undef, <8 x i32> %3, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
+  store <16 x i32> %4, <16 x i32>* %b, align 4
+  ret void
+}
+
 ; Test cases for <rdar://problem/16074331>.
 ; Instruction selection for broacast instruction fails if
 ; the load cannot be folded into the broadcast.