[x86] fix assert with horizontal math + broadcast of vector (PR43402)
[llvm-core.git] / test / CodeGen / X86 / load-local-v3i1.ll
blob6be3cc1b751a5643ec27b153f56a78082cda60c9
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.2 | FileCheck %s
4 ; widen a v3i1 to v4i1 to do a vector load/store. We would previously
5 ; reconstruct the said v3i1 from the first element of the vector by filling all
6 ; the lanes of the vector with that first element, which was obviously wrong.
7 ; This was done in the type-legalizing of the DAG, when legalizing the load.
9 ; Function Attrs: argmemonly nounwind readonly
10 declare <3 x i32> @llvm.masked.load.v3i32.p1v3i32(<3 x i32> addrspace(1)*, i32, <3 x i1>, <3 x i32>)
12 ; Function Attrs: argmemonly nounwind
13 declare void @llvm.masked.store.v3i32.p1v3i32(<3 x i32>, <3 x i32> addrspace(1)*, i32, <3 x i1>)
15 define  <3 x i32> @masked_load_v3(i32 addrspace(1)*, <3 x i1>) {
16 ; CHECK-LABEL: masked_load_v3:
17 ; CHECK:       # %bb.0: # %entry
18 ; CHECK-NEXT:    andb $1, %sil
19 ; CHECK-NEXT:    andb $1, %dl
20 ; CHECK-NEXT:    addb %dl, %dl
21 ; CHECK-NEXT:    orb %sil, %dl
22 ; CHECK-NEXT:    andb $1, %cl
23 ; CHECK-NEXT:    shlb $2, %cl
24 ; CHECK-NEXT:    orb %dl, %cl
25 ; CHECK-NEXT:    testb $1, %cl
26 ; CHECK-NEXT:    # implicit-def: $xmm0
27 ; CHECK-NEXT:    jne .LBB0_1
28 ; CHECK-NEXT:  # %bb.2: # %else
29 ; CHECK-NEXT:    testb $2, %cl
30 ; CHECK-NEXT:    jne .LBB0_3
31 ; CHECK-NEXT:  .LBB0_4: # %else2
32 ; CHECK-NEXT:    testb $4, %cl
33 ; CHECK-NEXT:    jne .LBB0_5
34 ; CHECK-NEXT:  .LBB0_6: # %else5
35 ; CHECK-NEXT:    retq
36 ; CHECK-NEXT:  .LBB0_1: # %cond.load
37 ; CHECK-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero
38 ; CHECK-NEXT:    testb $2, %cl
39 ; CHECK-NEXT:    je .LBB0_4
40 ; CHECK-NEXT:  .LBB0_3: # %cond.load1
41 ; CHECK-NEXT:    pinsrd $1, 4(%rdi), %xmm0
42 ; CHECK-NEXT:    testb $4, %cl
43 ; CHECK-NEXT:    je .LBB0_6
44 ; CHECK-NEXT:  .LBB0_5: # %cond.load4
45 ; CHECK-NEXT:    pinsrd $2, 8(%rdi), %xmm0
46 ; CHECK-NEXT:    retq
47 entry:
48   %2 = bitcast i32 addrspace(1)* %0 to <3 x i32> addrspace(1)*
49   %3 = call <3 x i32> @llvm.masked.load.v3i32.p1v3i32(<3 x i32> addrspace(1)* %2, i32 4, <3 x i1> %1, <3 x i32> undef)
50   ret <3 x i32> %3
53 define void @masked_store4_v3(<3 x i32>, i32 addrspace(1)*, <3 x i1>) {
54 ; CHECK-LABEL: masked_store4_v3:
55 ; CHECK:       # %bb.0: # %entry
56 ; CHECK-NEXT:    andb $1, %sil
57 ; CHECK-NEXT:    andb $1, %dl
58 ; CHECK-NEXT:    addb %dl, %dl
59 ; CHECK-NEXT:    orb %sil, %dl
60 ; CHECK-NEXT:    andb $1, %cl
61 ; CHECK-NEXT:    shlb $2, %cl
62 ; CHECK-NEXT:    orb %dl, %cl
63 ; CHECK-NEXT:    testb $1, %cl
64 ; CHECK-NEXT:    jne .LBB1_1
65 ; CHECK-NEXT:  # %bb.2: # %else
66 ; CHECK-NEXT:    testb $2, %cl
67 ; CHECK-NEXT:    jne .LBB1_3
68 ; CHECK-NEXT:  .LBB1_4: # %else2
69 ; CHECK-NEXT:    testb $4, %cl
70 ; CHECK-NEXT:    jne .LBB1_5
71 ; CHECK-NEXT:  .LBB1_6: # %else4
72 ; CHECK-NEXT:    retq
73 ; CHECK-NEXT:  .LBB1_1: # %cond.store
74 ; CHECK-NEXT:    movss %xmm0, (%rdi)
75 ; CHECK-NEXT:    testb $2, %cl
76 ; CHECK-NEXT:    je .LBB1_4
77 ; CHECK-NEXT:  .LBB1_3: # %cond.store1
78 ; CHECK-NEXT:    extractps $1, %xmm0, 4(%rdi)
79 ; CHECK-NEXT:    testb $4, %cl
80 ; CHECK-NEXT:    je .LBB1_6
81 ; CHECK-NEXT:  .LBB1_5: # %cond.store3
82 ; CHECK-NEXT:    extractps $2, %xmm0, 8(%rdi)
83 ; CHECK-NEXT:    retq
84 entry:
85   %3 = bitcast i32 addrspace(1)* %1 to <3 x i32> addrspace(1)*
86   call void @llvm.masked.store.v3i32.p1v3i32(<3 x i32> %0, <3 x i32> addrspace(1)* %3, i32 4, <3 x i1> %2)
87   ret void
90 define void @local_load_v3i1(i32 addrspace(1)* %out, i32 addrspace(1)* %in, <3 x i1>* %predicate_ptr) nounwind {
91 ; CHECK-LABEL: local_load_v3i1:
92 ; CHECK:       # %bb.0:
93 ; CHECK-NEXT:    pushq %rbp
94 ; CHECK-NEXT:    pushq %r15
95 ; CHECK-NEXT:    pushq %r14
96 ; CHECK-NEXT:    pushq %rbx
97 ; CHECK-NEXT:    pushq %rax
98 ; CHECK-NEXT:    movq %rdi, %r14
99 ; CHECK-NEXT:    movzbl (%rdx), %ebp
100 ; CHECK-NEXT:    movl %ebp, %eax
101 ; CHECK-NEXT:    shrl %eax
102 ; CHECK-NEXT:    andl $1, %eax
103 ; CHECK-NEXT:    movl %ebp, %ecx
104 ; CHECK-NEXT:    andl $1, %ecx
105 ; CHECK-NEXT:    movd %ecx, %xmm0
106 ; CHECK-NEXT:    pinsrd $1, %eax, %xmm0
107 ; CHECK-NEXT:    shrl $2, %ebp
108 ; CHECK-NEXT:    andl $1, %ebp
109 ; CHECK-NEXT:    pinsrd $2, %ebp, %xmm0
110 ; CHECK-NEXT:    movd %xmm0, %ebx
111 ; CHECK-NEXT:    pextrd $1, %xmm0, %r15d
112 ; CHECK-NEXT:    movq %rsi, %rdi
113 ; CHECK-NEXT:    movl %ebx, %esi
114 ; CHECK-NEXT:    movl %r15d, %edx
115 ; CHECK-NEXT:    movl %ebp, %ecx
116 ; CHECK-NEXT:    callq masked_load_v3
117 ; CHECK-NEXT:    movq %r14, %rdi
118 ; CHECK-NEXT:    movl %ebx, %esi
119 ; CHECK-NEXT:    movl %r15d, %edx
120 ; CHECK-NEXT:    movl %ebp, %ecx
121 ; CHECK-NEXT:    callq masked_store4_v3
122 ; CHECK-NEXT:    addq $8, %rsp
123 ; CHECK-NEXT:    popq %rbx
124 ; CHECK-NEXT:    popq %r14
125 ; CHECK-NEXT:    popq %r15
126 ; CHECK-NEXT:    popq %rbp
127 ; CHECK-NEXT:    retq
128   %predicate = load <3 x i1>, <3 x i1>* %predicate_ptr
129   %load1 = call <3 x i32> @masked_load_v3(i32 addrspace(1)* %in, <3 x i1> %predicate)
130   call void @masked_store4_v3(<3 x i32> %load1, i32 addrspace(1)* %out, <3 x i1> %predicate)
131   ret void