blob: d7ed53b3911b26c506bb50f3c43a416216b6d059 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s --check-prefixes=SSE2
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=SSE42
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=AVX2
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=AVX512BW
; CodeGen tests for X86PartialReduction::tryByteSumReplacement.
; Positive cases should lower to vpsadbw; negative cases should not.
@a = global [1024 x i8] zeroinitializer, align 16
;============================================================================
; POSITIVE: zext <16 x i8> to <16 x i32>, i32 accumulator
;============================================================================
define i32 @byte_sum_v16_i32() nounwind {
; SSE2-LABEL: byte_sum_v16_i32:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB0_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqa (%rcx,%rax), %xmm2
; SSE2-NEXT: psadbw %xmm0, %xmm2
; SSE2-NEXT: paddd %xmm2, %xmm1
; SSE2-NEXT: addq $16, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB0_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: paddd %xmm0, %xmm0
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v16_i32:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB0_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: movdqa (%rcx,%rax), %xmm2
; SSE42-NEXT: psadbw %xmm0, %xmm2
; SSE42-NEXT: paddd %xmm2, %xmm1
; SSE42-NEXT: addq $16, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB0_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: paddd %xmm0, %xmm0
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: movd %xmm0, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v16_i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB0_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpsadbw (%rcx,%rax), %xmm0, %xmm2
; AVX2-NEXT: vpaddd %ymm1, %ymm2, %ymm1
; AVX2-NEXT: addq $16, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB0_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v16_i32:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB0_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpsadbw (%rcx,%rax), %xmm0, %xmm2
; AVX512BW-NEXT: vpaddd %zmm1, %zmm2, %zmm1
; AVX512BW-NEXT: addq $16, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB0_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vextracti64x4 $1, %zmm1, %ymm0
; AVX512BW-NEXT: vpaddd %zmm0, %zmm1, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <16 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <16 x i8>, ptr %p, align 16
%z = zext <16 x i8> %wide.load to <16 x i32>
%add = add nsw <16 x i32> %z, %vec.phi
%index.next = add i64 %index, 16
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %ext
}
;============================================================================
; POSITIVE: zext <32 x i8> to <32 x i32>, i32 accumulator
;============================================================================
define i32 @byte_sum_v32_i32() nounwind {
; SSE2-LABEL: byte_sum_v32_i32:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB1_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqa (%rcx,%rax), %xmm3
; SSE2-NEXT: psadbw %xmm0, %xmm3
; SSE2-NEXT: paddd %xmm3, %xmm1
; SSE2-NEXT: movdqa 16(%rcx,%rax), %xmm3
; SSE2-NEXT: psadbw %xmm0, %xmm3
; SSE2-NEXT: paddd %xmm3, %xmm2
; SSE2-NEXT: addq $32, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB1_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm0, %xmm2
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: paddd %xmm0, %xmm0
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: paddd %xmm2, %xmm0
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v32_i32:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: pxor %xmm2, %xmm2
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB1_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: movdqa (%rcx,%rax), %xmm3
; SSE42-NEXT: psadbw %xmm0, %xmm3
; SSE42-NEXT: paddd %xmm3, %xmm1
; SSE42-NEXT: movdqa 16(%rcx,%rax), %xmm3
; SSE42-NEXT: psadbw %xmm0, %xmm3
; SSE42-NEXT: paddd %xmm3, %xmm2
; SSE42-NEXT: addq $32, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB1_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm0, %xmm2
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: paddd %xmm0, %xmm0
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: paddd %xmm2, %xmm0
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: movd %xmm0, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v32_i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB1_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpsadbw (%rcx,%rax), %ymm0, %ymm2
; AVX2-NEXT: vpaddd %ymm1, %ymm2, %ymm1
; AVX2-NEXT: addq $32, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB1_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm1
; AVX2-NEXT: vpaddd %ymm0, %ymm0, %ymm0
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v32_i32:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB1_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpsadbw (%rcx,%rax), %ymm0, %ymm2
; AVX512BW-NEXT: vpaddd %zmm1, %zmm2, %zmm1
; AVX512BW-NEXT: addq $32, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB1_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vpaddd %zmm0, %zmm1, %zmm0
; AVX512BW-NEXT: vextracti64x4 $1, %zmm0, %ymm1
; AVX512BW-NEXT: vpaddd %zmm1, %zmm0, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <32 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <32 x i8>, ptr %p, align 16
%z = zext <32 x i8> %wide.load to <32 x i32>
%add = add nsw <32 x i32> %z, %vec.phi
%index.next = add i64 %index, 32
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v32i32(<32 x i32> %add)
ret i32 %ext
}
;============================================================================
; POSITIVE: zext <64 x i8> to <64 x i32>, i32 accumulator
;============================================================================
define i32 @byte_sum_v64_i32() nounwind {
; SSE2-LABEL: byte_sum_v64_i32:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm3, %xmm3
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: pxor %xmm4, %xmm4
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB2_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqa (%rcx,%rax), %xmm5
; SSE2-NEXT: psadbw %xmm3, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm0
; SSE2-NEXT: movdqa 16(%rcx,%rax), %xmm5
; SSE2-NEXT: psadbw %xmm3, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm4
; SSE2-NEXT: movdqa 32(%rcx,%rax), %xmm5
; SSE2-NEXT: psadbw %xmm3, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm2
; SSE2-NEXT: movdqa 48(%rcx,%rax), %xmm5
; SSE2-NEXT: psadbw %xmm3, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm1
; SSE2-NEXT: addq $64, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB2_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm3, %xmm2
; SSE2-NEXT: pxor %xmm5, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm5
; SSE2-NEXT: paddd %xmm3, %xmm0
; SSE2-NEXT: paddd %xmm3, %xmm1
; SSE2-NEXT: paddd %xmm3, %xmm4
; SSE2-NEXT: paddd %xmm5, %xmm4
; SSE2-NEXT: paddd %xmm5, %xmm1
; SSE2-NEXT: paddd %xmm4, %xmm1
; SSE2-NEXT: paddd %xmm5, %xmm0
; SSE2-NEXT: paddd %xmm2, %xmm5
; SSE2-NEXT: paddd %xmm0, %xmm5
; SSE2-NEXT: paddd %xmm1, %xmm5
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3]
; SSE2-NEXT: paddd %xmm5, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: movd %xmm1, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v64_i32:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm3, %xmm3
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: pxor %xmm4, %xmm4
; SSE42-NEXT: pxor %xmm2, %xmm2
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB2_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: movdqa (%rcx,%rax), %xmm5
; SSE42-NEXT: psadbw %xmm3, %xmm5
; SSE42-NEXT: paddd %xmm5, %xmm0
; SSE42-NEXT: movdqa 16(%rcx,%rax), %xmm5
; SSE42-NEXT: psadbw %xmm3, %xmm5
; SSE42-NEXT: paddd %xmm5, %xmm4
; SSE42-NEXT: movdqa 32(%rcx,%rax), %xmm5
; SSE42-NEXT: psadbw %xmm3, %xmm5
; SSE42-NEXT: paddd %xmm5, %xmm2
; SSE42-NEXT: movdqa 48(%rcx,%rax), %xmm5
; SSE42-NEXT: psadbw %xmm3, %xmm5
; SSE42-NEXT: paddd %xmm5, %xmm1
; SSE42-NEXT: addq $64, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB2_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm3, %xmm2
; SSE42-NEXT: pxor %xmm5, %xmm5
; SSE42-NEXT: paddd %xmm5, %xmm5
; SSE42-NEXT: paddd %xmm3, %xmm0
; SSE42-NEXT: paddd %xmm3, %xmm1
; SSE42-NEXT: paddd %xmm3, %xmm4
; SSE42-NEXT: paddd %xmm5, %xmm4
; SSE42-NEXT: paddd %xmm5, %xmm1
; SSE42-NEXT: paddd %xmm4, %xmm1
; SSE42-NEXT: paddd %xmm5, %xmm0
; SSE42-NEXT: paddd %xmm2, %xmm5
; SSE42-NEXT: paddd %xmm0, %xmm5
; SSE42-NEXT: paddd %xmm1, %xmm5
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm5[2,3,2,3]
; SSE42-NEXT: paddd %xmm5, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: movd %xmm1, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v64_i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB2_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpsadbw (%rcx,%rax), %ymm0, %ymm3
; AVX2-NEXT: vpsadbw 32(%rcx,%rax), %ymm0, %ymm4
; AVX2-NEXT: vpaddd %ymm1, %ymm3, %ymm1
; AVX2-NEXT: vpaddd %ymm2, %ymm4, %ymm2
; AVX2-NEXT: addq $64, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB2_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddd %ymm0, %ymm2, %ymm2
; AVX2-NEXT: vpaddd %ymm0, %ymm0, %ymm3
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vpaddd %ymm3, %ymm0, %ymm0
; AVX2-NEXT: vpaddd %ymm3, %ymm2, %ymm1
; AVX2-NEXT: vpaddd %ymm1, %ymm0, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v64_i32:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB2_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpsadbw (%rcx,%rax), %zmm0, %zmm2
; AVX512BW-NEXT: vpaddd %zmm1, %zmm2, %zmm1
; AVX512BW-NEXT: addq $64, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB2_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vpaddd %zmm0, %zmm1, %zmm1
; AVX512BW-NEXT: vpaddd %zmm0, %zmm0, %zmm0
; AVX512BW-NEXT: vpaddd %zmm0, %zmm1, %zmm0
; AVX512BW-NEXT: vextracti64x4 $1, %zmm0, %ymm1
; AVX512BW-NEXT: vpaddd %zmm1, %zmm0, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <64 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <64 x i8>, ptr %p, align 16
%z = zext <64 x i8> %wide.load to <64 x i32>
%add = add nsw <64 x i32> %z, %vec.phi
%index.next = add i64 %index, 64
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v64i32(<64 x i32> %add)
ret i32 %ext
}
;============================================================================
; POSITIVE: zext <16 x i8> to <16 x i64>, i64 accumulator
;============================================================================
define i64 @byte_sum_v16_i64() nounwind {
; SSE2-LABEL: byte_sum_v16_i64:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB3_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqa (%rcx,%rax), %xmm2
; SSE2-NEXT: psadbw %xmm0, %xmm2
; SSE2-NEXT: paddq %xmm2, %xmm1
; SSE2-NEXT: addq $16, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB3_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddq %xmm0, %xmm1
; SSE2-NEXT: paddq %xmm0, %xmm0
; SSE2-NEXT: movdqa %xmm0, %xmm2
; SSE2-NEXT: paddq %xmm0, %xmm2
; SSE2-NEXT: paddq %xmm0, %xmm2
; SSE2-NEXT: paddq %xmm1, %xmm2
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3]
; SSE2-NEXT: paddq %xmm2, %xmm0
; SSE2-NEXT: movq %xmm0, %rax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v16_i64:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB3_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: movdqa (%rcx,%rax), %xmm2
; SSE42-NEXT: psadbw %xmm0, %xmm2
; SSE42-NEXT: paddq %xmm2, %xmm1
; SSE42-NEXT: addq $16, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB3_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddq %xmm0, %xmm1
; SSE42-NEXT: paddq %xmm0, %xmm0
; SSE42-NEXT: movdqa %xmm0, %xmm2
; SSE42-NEXT: paddq %xmm0, %xmm2
; SSE42-NEXT: paddq %xmm0, %xmm2
; SSE42-NEXT: paddq %xmm1, %xmm2
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm2[2,3,2,3]
; SSE42-NEXT: paddq %xmm2, %xmm0
; SSE42-NEXT: movq %xmm0, %rax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v16_i64:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB3_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpsadbw (%rcx,%rax), %xmm0, %xmm2
; AVX2-NEXT: vpaddq %ymm1, %ymm2, %ymm1
; AVX2-NEXT: addq $16, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB3_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddq %ymm0, %ymm1, %ymm1
; AVX2-NEXT: vpaddq %ymm0, %ymm0, %ymm0
; AVX2-NEXT: vpaddq %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddq %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddq %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovq %xmm0, %rax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v16_i64:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB3_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpsadbw (%rcx,%rax), %xmm0, %xmm2
; AVX512BW-NEXT: vpaddq %zmm1, %zmm2, %zmm1
; AVX512BW-NEXT: addq $16, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB3_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vpaddq %zmm0, %zmm1, %zmm0
; AVX512BW-NEXT: vextracti64x4 $1, %zmm0, %ymm1
; AVX512BW-NEXT: vpaddq %zmm1, %zmm0, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddq %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddq %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovq %xmm0, %rax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <16 x i64> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <16 x i8>, ptr %p, align 16
%z = zext <16 x i8> %wide.load to <16 x i64>
%add = add nsw <16 x i64> %z, %vec.phi
%index.next = add i64 %index, 16
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> %add)
ret i64 %ext
}
;============================================================================
; NEGATIVE: sext instead of zext
;============================================================================
define i32 @byte_sum_v16_i32_sext() nounwind {
; SSE2-LABEL: byte_sum_v16_i32_sext:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm3, %xmm3
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB4_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqa (%rcx,%rax), %xmm4
; SSE2-NEXT: punpcklbw {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3],xmm5[4],xmm4[4],xmm5[5],xmm4[5],xmm5[6],xmm4[6],xmm5[7],xmm4[7]
; SSE2-NEXT: punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm5[0],xmm6[1],xmm5[1],xmm6[2],xmm5[2],xmm6[3],xmm5[3]
; SSE2-NEXT: psrad $24, %xmm6
; SSE2-NEXT: paddd %xmm6, %xmm0
; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4,4,5,5,6,6,7,7]
; SSE2-NEXT: psrad $24, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm1
; SSE2-NEXT: punpckhbw {{.*#+}} xmm4 = xmm4[8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15]
; SSE2-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3]
; SSE2-NEXT: psrad $24, %xmm5
; SSE2-NEXT: paddd %xmm5, %xmm3
; SSE2-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4,4,5,5,6,6,7,7]
; SSE2-NEXT: psrad $24, %xmm4
; SSE2-NEXT: paddd %xmm4, %xmm2
; SSE2-NEXT: addq $16, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB4_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm3, %xmm0
; SSE2-NEXT: paddd %xmm2, %xmm1
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: movd %xmm1, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v16_i32_sext:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: pxor %xmm3, %xmm3
; SSE42-NEXT: pxor %xmm2, %xmm2
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB4_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: pmovsxbd 12(%rcx,%rax), %xmm4
; SSE42-NEXT: paddd %xmm4, %xmm2
; SSE42-NEXT: pmovsxbd 8(%rcx,%rax), %xmm4
; SSE42-NEXT: paddd %xmm4, %xmm3
; SSE42-NEXT: pmovsxbd (%rcx,%rax), %xmm4
; SSE42-NEXT: pmovsxbd 4(%rcx,%rax), %xmm5
; SSE42-NEXT: paddd %xmm4, %xmm0
; SSE42-NEXT: paddd %xmm5, %xmm1
; SSE42-NEXT: addq $16, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB4_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm3, %xmm0
; SSE42-NEXT: paddd %xmm2, %xmm1
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: movd %xmm1, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v16_i32_sext:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB4_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpmovsxbd (%rcx,%rax), %ymm2
; AVX2-NEXT: vpmovsxbd 8(%rcx,%rax), %ymm3
; AVX2-NEXT: vpaddd %ymm1, %ymm2, %ymm1
; AVX2-NEXT: vpaddd %ymm0, %ymm3, %ymm0
; AVX2-NEXT: addq $16, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB4_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v16_i32_sext:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB4_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpmovsxbd (%rcx,%rax), %zmm1
; AVX512BW-NEXT: vpaddd %zmm0, %zmm1, %zmm0
; AVX512BW-NEXT: addq $16, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB4_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vextracti64x4 $1, %zmm0, %ymm1
; AVX512BW-NEXT: vpaddd %zmm1, %zmm0, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <16 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <16 x i8>, ptr %p, align 16
%z = sext <16 x i8> %wide.load to <16 x i32>
%add = add nsw <16 x i32> %z, %vec.phi
%index.next = add i64 %index, 16
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %ext
}
;============================================================================
; NEGATIVE: i16 source instead of i8
;============================================================================
define i32 @word_sum_v16_i32(ptr nocapture readonly %src) nounwind {
; SSE2-LABEL: word_sum_v16_i32:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: pxor %xmm4, %xmm4
; SSE2-NEXT: pxor %xmm3, %xmm3
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB5_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqu (%rdi,%rax,2), %xmm5
; SSE2-NEXT: movdqu 16(%rdi,%rax,2), %xmm6
; SSE2-NEXT: movdqa %xmm6, %xmm7
; SSE2-NEXT: punpckhwd {{.*#+}} xmm7 = xmm7[4],xmm2[4],xmm7[5],xmm2[5],xmm7[6],xmm2[6],xmm7[7],xmm2[7]
; SSE2-NEXT: paddd %xmm7, %xmm3
; SSE2-NEXT: movdqa %xmm5, %xmm7
; SSE2-NEXT: punpcklwd {{.*#+}} xmm7 = xmm7[0],xmm2[0],xmm7[1],xmm2[1],xmm7[2],xmm2[2],xmm7[3],xmm2[3]
; SSE2-NEXT: paddd %xmm7, %xmm1
; SSE2-NEXT: punpckhwd {{.*#+}} xmm5 = xmm5[4],xmm2[4],xmm5[5],xmm2[5],xmm5[6],xmm2[6],xmm5[7],xmm2[7]
; SSE2-NEXT: paddd %xmm5, %xmm0
; SSE2-NEXT: punpcklwd {{.*#+}} xmm6 = xmm6[0],xmm2[0],xmm6[1],xmm2[1],xmm6[2],xmm2[2],xmm6[3],xmm2[3]
; SSE2-NEXT: paddd %xmm6, %xmm4
; SSE2-NEXT: addq $16, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB5_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm4, %xmm1
; SSE2-NEXT: paddd %xmm3, %xmm0
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: word_sum_v16_i32:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: pxor %xmm3, %xmm3
; SSE42-NEXT: pxor %xmm2, %xmm2
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB5_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: pmovzxwd {{.*#+}} xmm4 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero
; SSE42-NEXT: paddd %xmm4, %xmm2
; SSE42-NEXT: pmovzxwd {{.*#+}} xmm4 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero
; SSE42-NEXT: paddd %xmm4, %xmm3
; SSE42-NEXT: pmovzxwd {{.*#+}} xmm4 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero
; SSE42-NEXT: pmovzxwd {{.*#+}} xmm5 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero
; SSE42-NEXT: paddd %xmm4, %xmm0
; SSE42-NEXT: paddd %xmm5, %xmm1
; SSE42-NEXT: addq $16, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB5_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm3, %xmm0
; SSE42-NEXT: paddd %xmm2, %xmm1
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: movd %xmm1, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: word_sum_v16_i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB5_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm2 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
; AVX2-NEXT: vpmovzxwd {{.*#+}} ymm3 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
; AVX2-NEXT: vpaddd %ymm1, %ymm2, %ymm1
; AVX2-NEXT: vpaddd %ymm0, %ymm3, %ymm0
; AVX2-NEXT: addq $16, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB5_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: word_sum_v16_i32:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB5_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpmovzxwd {{.*#+}} zmm1 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero,mem[8],zero,mem[9],zero,mem[10],zero,mem[11],zero,mem[12],zero,mem[13],zero,mem[14],zero,mem[15],zero
; AVX512BW-NEXT: vpaddd %zmm0, %zmm1, %zmm0
; AVX512BW-NEXT: addq $16, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB5_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vextracti64x4 $1, %zmm0, %ymm1
; AVX512BW-NEXT: vpaddd %zmm1, %zmm0, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <16 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds i16, ptr %src, i64 %index
%wide.load = load <16 x i16>, ptr %p, align 2
%z = zext <16 x i16> %wide.load to <16 x i32>
%add = add nsw <16 x i32> %z, %vec.phi
%index.next = add i64 %index, 16
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %ext
}
;============================================================================
; NEGATIVE: i16 accumulator (element type < 32 bits)
;============================================================================
define i16 @byte_sum_v16_i16() nounwind {
; SSE2-LABEL: byte_sum_v16_i16:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB6_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqa (%rcx,%rax), %xmm3
; SSE2-NEXT: movdqa %xmm3, %xmm4
; SSE2-NEXT: punpcklbw {{.*#+}} xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1],xmm4[2],xmm0[2],xmm4[3],xmm0[3],xmm4[4],xmm0[4],xmm4[5],xmm0[5],xmm4[6],xmm0[6],xmm4[7],xmm0[7]
; SSE2-NEXT: paddw %xmm4, %xmm1
; SSE2-NEXT: punpckhbw {{.*#+}} xmm3 = xmm3[8],xmm0[8],xmm3[9],xmm0[9],xmm3[10],xmm0[10],xmm3[11],xmm0[11],xmm3[12],xmm0[12],xmm3[13],xmm0[13],xmm3[14],xmm0[14],xmm3[15],xmm0[15]
; SSE2-NEXT: paddw %xmm3, %xmm2
; SSE2-NEXT: addq $16, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB6_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddw %xmm2, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE2-NEXT: paddw %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE2-NEXT: paddw %xmm0, %xmm1
; SSE2-NEXT: movdqa %xmm1, %xmm0
; SSE2-NEXT: psrld $16, %xmm0
; SSE2-NEXT: paddw %xmm1, %xmm0
; SSE2-NEXT: movd %xmm0, %eax
; SSE2-NEXT: # kill: def $ax killed $ax killed $eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v16_i16:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB6_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: pmovzxbw {{.*#+}} xmm2 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
; SSE42-NEXT: pmovzxbw {{.*#+}} xmm3 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero
; SSE42-NEXT: paddw %xmm2, %xmm0
; SSE42-NEXT: paddw %xmm3, %xmm1
; SSE42-NEXT: addq $16, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB6_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddw %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE42-NEXT: paddw %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE42-NEXT: paddw %xmm1, %xmm0
; SSE42-NEXT: movdqa %xmm0, %xmm1
; SSE42-NEXT: psrld $16, %xmm1
; SSE42-NEXT: paddw %xmm0, %xmm1
; SSE42-NEXT: movd %xmm1, %eax
; SSE42-NEXT: # kill: def $ax killed $ax killed $eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v16_i16:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB6_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpmovzxbw {{.*#+}} ymm1 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero,mem[8],zero,mem[9],zero,mem[10],zero,mem[11],zero,mem[12],zero,mem[13],zero,mem[14],zero,mem[15],zero
; AVX2-NEXT: vpaddw %ymm0, %ymm1, %ymm0
; AVX2-NEXT: addq $16, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB6_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpsrld $16, %xmm0, %xmm1
; AVX2-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: # kill: def $ax killed $ax killed $eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v16_i16:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB6_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpmovzxbw {{.*#+}} ymm1 = mem[0],zero,mem[1],zero,mem[2],zero,mem[3],zero,mem[4],zero,mem[5],zero,mem[6],zero,mem[7],zero,mem[8],zero,mem[9],zero,mem[10],zero,mem[11],zero,mem[12],zero,mem[13],zero,mem[14],zero,mem[15],zero
; AVX512BW-NEXT: vpaddw %ymm0, %ymm1, %ymm0
; AVX512BW-NEXT: addq $16, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB6_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpsrld $16, %xmm0, %xmm1
; AVX512BW-NEXT: vpaddw %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: # kill: def $ax killed $ax killed $eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <16 x i16> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <16 x i8>, ptr %p, align 16
%z = zext <16 x i8> %wide.load to <16 x i16>
%add = add nsw <16 x i16> %z, %vec.phi
%index.next = add i64 %index, 16
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i16 @llvm.vector.reduce.add.v16i16(<16 x i16> %add)
ret i16 %ext
}
;============================================================================
; NEGATIVE: leaf is not a zext (already i32 values)
;============================================================================
define i32 @dword_sum_v16_i32(ptr nocapture readonly %src) nounwind {
; SSE2-LABEL: dword_sum_v16_i32:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm3, %xmm3
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB7_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movdqu (%rdi,%rax,4), %xmm4
; SSE2-NEXT: paddd %xmm4, %xmm0
; SSE2-NEXT: movdqu 16(%rdi,%rax,4), %xmm4
; SSE2-NEXT: paddd %xmm4, %xmm1
; SSE2-NEXT: movdqu 32(%rdi,%rax,4), %xmm4
; SSE2-NEXT: paddd %xmm4, %xmm3
; SSE2-NEXT: movdqu 48(%rdi,%rax,4), %xmm4
; SSE2-NEXT: paddd %xmm4, %xmm2
; SSE2-NEXT: addq $16, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB7_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm3, %xmm0
; SSE2-NEXT: paddd %xmm2, %xmm1
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: movd %xmm1, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: dword_sum_v16_i32:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: pxor %xmm3, %xmm3
; SSE42-NEXT: pxor %xmm2, %xmm2
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB7_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: movdqu (%rdi,%rax,4), %xmm4
; SSE42-NEXT: paddd %xmm4, %xmm0
; SSE42-NEXT: movdqu 16(%rdi,%rax,4), %xmm4
; SSE42-NEXT: paddd %xmm4, %xmm1
; SSE42-NEXT: movdqu 32(%rdi,%rax,4), %xmm4
; SSE42-NEXT: paddd %xmm4, %xmm3
; SSE42-NEXT: movdqu 48(%rdi,%rax,4), %xmm4
; SSE42-NEXT: paddd %xmm4, %xmm2
; SSE42-NEXT: addq $16, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB7_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm3, %xmm0
; SSE42-NEXT: paddd %xmm2, %xmm1
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: movd %xmm1, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: dword_sum_v16_i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB7_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpaddd (%rdi,%rax,4), %ymm1, %ymm1
; AVX2-NEXT: vpaddd 32(%rdi,%rax,4), %ymm0, %ymm0
; AVX2-NEXT: addq $16, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB7_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: dword_sum_v16_i32:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB7_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpaddd (%rdi,%rax,4), %zmm0, %zmm0
; AVX512BW-NEXT: addq $16, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB7_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vextracti64x4 $1, %zmm0, %ymm1
; AVX512BW-NEXT: vpaddd %zmm1, %zmm0, %zmm0
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <16 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds i32, ptr %src, i64 %index
%wide.load = load <16 x i32>, ptr %p, align 4
%add = add nsw <16 x i32> %wide.load, %vec.phi
%index.next = add i64 %index, 16
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %add)
ret i32 %ext
}
;============================================================================
; NEGATIVE: VF = 8 (fewer than 16 lanes)
;============================================================================
define i32 @byte_sum_v8_i32() nounwind {
; SSE2-LABEL: byte_sum_v8_i32:
; SSE2: # %bb.0: # %entry
; SSE2-NEXT: pxor %xmm0, %xmm0
; SSE2-NEXT: xorl %eax, %eax
; SSE2-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE2-NEXT: pxor %xmm1, %xmm1
; SSE2-NEXT: pxor %xmm2, %xmm2
; SSE2-NEXT: .p2align 4
; SSE2-NEXT: .LBB8_1: # %vector.body
; SSE2-NEXT: # =>This Inner Loop Header: Depth=1
; SSE2-NEXT: movq {{.*#+}} xmm3 = mem[0],zero
; SSE2-NEXT: punpcklbw {{.*#+}} xmm3 = xmm3[0],xmm0[0],xmm3[1],xmm0[1],xmm3[2],xmm0[2],xmm3[3],xmm0[3],xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
; SSE2-NEXT: movdqa %xmm3, %xmm4
; SSE2-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm0[0],xmm4[1],xmm0[1],xmm4[2],xmm0[2],xmm4[3],xmm0[3]
; SSE2-NEXT: paddd %xmm4, %xmm1
; SSE2-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7]
; SSE2-NEXT: paddd %xmm3, %xmm2
; SSE2-NEXT: addq $8, %rax
; SSE2-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE2-NEXT: jne .LBB8_1
; SSE2-NEXT: # %bb.2: # %middle.block
; SSE2-NEXT: paddd %xmm2, %xmm1
; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm1[2,3,2,3]
; SSE2-NEXT: paddd %xmm1, %xmm0
; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; SSE2-NEXT: paddd %xmm0, %xmm1
; SSE2-NEXT: movd %xmm1, %eax
; SSE2-NEXT: retq
;
; SSE42-LABEL: byte_sum_v8_i32:
; SSE42: # %bb.0: # %entry
; SSE42-NEXT: pxor %xmm0, %xmm0
; SSE42-NEXT: xorl %eax, %eax
; SSE42-NEXT: movq a@GOTPCREL(%rip), %rcx
; SSE42-NEXT: pxor %xmm1, %xmm1
; SSE42-NEXT: .p2align 4
; SSE42-NEXT: .LBB8_1: # %vector.body
; SSE42-NEXT: # =>This Inner Loop Header: Depth=1
; SSE42-NEXT: pmovzxbd {{.*#+}} xmm2 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
; SSE42-NEXT: pmovzxbd {{.*#+}} xmm3 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero
; SSE42-NEXT: paddd %xmm2, %xmm0
; SSE42-NEXT: paddd %xmm3, %xmm1
; SSE42-NEXT: addq $8, %rax
; SSE42-NEXT: cmpq $1024, %rax # imm = 0x400
; SSE42-NEXT: jne .LBB8_1
; SSE42-NEXT: # %bb.2: # %middle.block
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; SSE42-NEXT: paddd %xmm0, %xmm1
; SSE42-NEXT: pshufd {{.*#+}} xmm0 = xmm1[1,1,1,1]
; SSE42-NEXT: paddd %xmm1, %xmm0
; SSE42-NEXT: movd %xmm0, %eax
; SSE42-NEXT: retq
;
; AVX2-LABEL: byte_sum_v8_i32:
; AVX2: # %bb.0: # %entry
; AVX2-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX2-NEXT: xorl %eax, %eax
; AVX2-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX2-NEXT: .p2align 4
; AVX2-NEXT: .LBB8_1: # %vector.body
; AVX2-NEXT: # =>This Inner Loop Header: Depth=1
; AVX2-NEXT: vpmovzxbd {{.*#+}} ymm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero,mem[4],zero,zero,zero,mem[5],zero,zero,zero,mem[6],zero,zero,zero,mem[7],zero,zero,zero
; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX2-NEXT: addq $8, %rax
; AVX2-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX2-NEXT: jne .LBB8_1
; AVX2-NEXT: # %bb.2: # %middle.block
; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX2-NEXT: vmovd %xmm0, %eax
; AVX2-NEXT: vzeroupper
; AVX2-NEXT: retq
;
; AVX512BW-LABEL: byte_sum_v8_i32:
; AVX512BW: # %bb.0: # %entry
; AVX512BW-NEXT: vpxor %xmm0, %xmm0, %xmm0
; AVX512BW-NEXT: xorl %eax, %eax
; AVX512BW-NEXT: movq a@GOTPCREL(%rip), %rcx
; AVX512BW-NEXT: .p2align 4
; AVX512BW-NEXT: .LBB8_1: # %vector.body
; AVX512BW-NEXT: # =>This Inner Loop Header: Depth=1
; AVX512BW-NEXT: vpmovzxbd {{.*#+}} ymm1 = mem[0],zero,zero,zero,mem[1],zero,zero,zero,mem[2],zero,zero,zero,mem[3],zero,zero,zero,mem[4],zero,zero,zero,mem[5],zero,zero,zero,mem[6],zero,zero,zero,mem[7],zero,zero,zero
; AVX512BW-NEXT: vpaddd %ymm0, %ymm1, %ymm0
; AVX512BW-NEXT: addq $8, %rax
; AVX512BW-NEXT: cmpq $1024, %rax # imm = 0x400
; AVX512BW-NEXT: jne .LBB8_1
; AVX512BW-NEXT: # %bb.2: # %middle.block
; AVX512BW-NEXT: vextracti128 $1, %ymm0, %xmm1
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vpshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]
; AVX512BW-NEXT: vpaddd %xmm1, %xmm0, %xmm0
; AVX512BW-NEXT: vmovd %xmm0, %eax
; AVX512BW-NEXT: vzeroupper
; AVX512BW-NEXT: retq
entry:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
%vec.phi = phi <8 x i32> [ zeroinitializer, %entry ], [ %add, %vector.body ]
%p = getelementptr inbounds [1024 x i8], ptr @a, i64 0, i64 %index
%wide.load = load <8 x i8>, ptr %p, align 8
%z = zext <8 x i8> %wide.load to <8 x i32>
%add = add nsw <8 x i32> %z, %vec.phi
%index.next = add i64 %index, 8
%cmp = icmp eq i64 %index.next, 1024
br i1 %cmp, label %middle.block, label %vector.body
middle.block:
%ext = call i32 @llvm.vector.reduce.add.v8i32(<8 x i32> %add)
ret i32 %ext
}