[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / X86 / AMX / lat-combine-amx-bitcast.ll
blob4aa5c7e3e1b9a650edff92803aa6bc4147aabf7a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt --codegen-opt-level=2 -mtriple=x86_64 -lower-amx-type %s -S | FileCheck %s
4 define void @combine_amx_cast_inside_bb() {
5 ; CHECK-LABEL: @combine_amx_cast_inside_bb(
6 ; CHECK-NEXT:  wrapper_entry:
7 ; CHECK-NEXT:    [[TMP0:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
8 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP0]])
9 ; CHECK-NEXT:    ret void
11 wrapper_entry:
12   %0 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
13   %tmp = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %0)
14   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %tmp)
15   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %1)
16   ret void
19 ; Cases where amxcast can be combined across bb
20 ; %5 and %6 is combined together since %goodphi's incoming is phi or amxcast
21 define void @combine_amx_cast_and_phi() {
22 ; CHECK-LABEL: @combine_amx_cast_and_phi(
23 ; CHECK-NEXT:  wrapper_entry:
24 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <560 x i8>, align 64
25 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca <616 x i8>, align 64
26 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca <110 x i32>, align 64
27 ; CHECK-NEXT:    [[TMP3:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
28 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I:%.*]], label [[FOR_BODY_I_LR_PH_I:%.*]]
29 ; CHECK:       for.body.i.lr.ph.i:
30 ; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <110 x i32>* [[TMP2]] to i8*
31 ; CHECK-NEXT:    store <110 x i32> undef, <110 x i32>* [[TMP2]], align 512
32 ; CHECK-NEXT:    [[TMP5:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP4]], i64 40)
33 ; CHECK-NEXT:    [[TMP6:%.*]] = bitcast <616 x i8>* [[TMP1]] to i8*
34 ; CHECK-NEXT:    store <616 x i8> undef, <616 x i8>* [[TMP1]], align 1024
35 ; CHECK-NEXT:    [[TMP7:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* [[TMP6]], i64 56)
36 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <560 x i8>* [[TMP0]] to i8*
37 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP0]], align 1024
38 ; CHECK-NEXT:    [[TMP9:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP8]], i64 40)
39 ; CHECK-NEXT:    [[TMP10:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP5]], x86_amx [[TMP7]], x86_amx [[TMP9]])
40 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_I_I]]
41 ; CHECK:       for.cond.cleanup.i.i:
42 ; CHECK-NEXT:    [[TMP11:%.*]] = phi x86_amx [ [[TMP3]], [[WRAPPER_ENTRY:%.*]] ], [ [[TMP10]], [[FOR_BODY_I_LR_PH_I]] ]
43 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP11]])
44 ; CHECK-NEXT:    ret void
46 wrapper_entry:
47   %0 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
48   %tmp = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %0)
49   br i1 undef, label %for.cond.cleanup.i.i, label %for.body.i.lr.ph.i
51 for.body.i.lr.ph.i:                               ; preds = %wrapper_entry
52   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> undef)
53   %2 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> undef)
54   %3 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
55   %4 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %1, x86_amx %2, x86_amx %3)
56   %5 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %4)
57   br label %for.cond.cleanup.i.i
59 for.cond.cleanup.i.i:                             ; preds = %for.body.i.lr.ph.i, %wrapper_entry
60   %goodphi = phi <110 x i32> [ %tmp, %wrapper_entry ], [ %5, %for.body.i.lr.ph.i ]
61   %6 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %goodphi)
62   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %6)
63   ret void
66 ; Cases where amxcast can't be combined across bb
67 ; %5 and %6 is not combined together since %evilphi's incoming is not phi or amxcast
68 define void @fail_to_combine_amx_cast_and_phi(<110 x i32> %tmp) {
69 ; CHECK-LABEL: @fail_to_combine_amx_cast_and_phi(
70 ; CHECK-NEXT:  wrapper_entry:
71 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <110 x i32>, align 64
72 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca <110 x i32>, align 64
73 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca <560 x i8>, align 64
74 ; CHECK-NEXT:    [[TMP3:%.*]] = alloca <616 x i8>, align 64
75 ; CHECK-NEXT:    [[TMP4:%.*]] = alloca <110 x i32>, align 64
76 ; CHECK-NEXT:    [[TMP5:%.*]] = add <110 x i32> [[TMP:%.*]], [[TMP]]
77 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I:%.*]], label [[FOR_BODY_I_LR_PH_I:%.*]]
78 ; CHECK:       for.body.i.lr.ph.i:
79 ; CHECK-NEXT:    [[TMP6:%.*]] = bitcast <110 x i32>* [[TMP4]] to i8*
80 ; CHECK-NEXT:    store <110 x i32> undef, <110 x i32>* [[TMP4]], align 512
81 ; CHECK-NEXT:    [[TMP7:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP6]], i64 40)
82 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <616 x i8>* [[TMP3]] to i8*
83 ; CHECK-NEXT:    store <616 x i8> undef, <616 x i8>* [[TMP3]], align 1024
84 ; CHECK-NEXT:    [[TMP9:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* [[TMP8]], i64 56)
85 ; CHECK-NEXT:    [[TMP10:%.*]] = bitcast <560 x i8>* [[TMP2]] to i8*
86 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP2]], align 1024
87 ; CHECK-NEXT:    [[TMP11:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP10]], i64 40)
88 ; CHECK-NEXT:    [[TMP12:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP7]], x86_amx [[TMP9]], x86_amx [[TMP11]])
89 ; CHECK-NEXT:    [[TMP13:%.*]] = bitcast <110 x i32>* [[TMP1]] to i8*
90 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* [[TMP13]], i64 40, x86_amx [[TMP12]])
91 ; CHECK-NEXT:    [[TMP14:%.*]] = load <110 x i32>, <110 x i32>* [[TMP1]], align 512
92 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_I_I]]
93 ; CHECK:       for.cond.cleanup.i.i:
94 ; CHECK-NEXT:    [[EVILPHI:%.*]] = phi <110 x i32> [ [[TMP5]], [[WRAPPER_ENTRY:%.*]] ], [ [[TMP14]], [[FOR_BODY_I_LR_PH_I]] ]
95 ; CHECK-NEXT:    [[TMP15:%.*]] = bitcast <110 x i32>* [[TMP0]] to i8*
96 ; CHECK-NEXT:    store <110 x i32> [[EVILPHI]], <110 x i32>* [[TMP0]], align 512
97 ; CHECK-NEXT:    [[TMP16:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP15]], i64 40)
98 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP16]])
99 ; CHECK-NEXT:    ret void
101 wrapper_entry:
102   %0 = add <110 x i32> %tmp, %tmp
103   br i1 undef, label %for.cond.cleanup.i.i, label %for.body.i.lr.ph.i
105 for.body.i.lr.ph.i:                               ; preds = %wrapper_entry
106   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> undef)
107   %2 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> undef)
108   %3 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
109   %4 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %1, x86_amx %2, x86_amx %3)
110   %5 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %4)
111   br label %for.cond.cleanup.i.i
113 for.cond.cleanup.i.i:                             ; preds = %for.body.i.lr.ph.i, %wrapper_entry
114   %evilphi = phi <110 x i32> [ %0, %wrapper_entry ], [ %5, %for.body.i.lr.ph.i ]
115   %6 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %evilphi)
116   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %6)
117   ret void
120 ; Cases where amxcast can't be combined across bb
121 ; %5 and %6 is not combined together since %evilphi's user aka %evilphi2 is not inside phi web.
122 define void @fail_to_combine_amx_cast_and_phi2() {
123 ; CHECK-LABEL: @fail_to_combine_amx_cast_and_phi2(
124 ; CHECK-NEXT:  wrapper_entry:
125 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <110 x i32>, align 64
126 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca <110 x i32>, align 64
127 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca <560 x i8>, align 64
128 ; CHECK-NEXT:    [[TMP3:%.*]] = alloca <616 x i8>, align 64
129 ; CHECK-NEXT:    [[TMP4:%.*]] = alloca <110 x i32>, align 64
130 ; CHECK-NEXT:    [[TMP5:%.*]] = alloca <110 x i32>, align 64
131 ; CHECK-NEXT:    [[TMP6:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
132 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast <110 x i32>* [[TMP5]] to i8*
133 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* [[TMP7]], i64 40, x86_amx [[TMP6]])
134 ; CHECK-NEXT:    [[TMP8:%.*]] = load <110 x i32>, <110 x i32>* [[TMP5]], align 512
135 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I:%.*]], label [[FOR_BODY_I_LR_PH_I:%.*]]
136 ; CHECK:       for.body.i.lr.ph.i:
137 ; CHECK-NEXT:    [[TMP9:%.*]] = bitcast <110 x i32>* [[TMP4]] to i8*
138 ; CHECK-NEXT:    store <110 x i32> undef, <110 x i32>* [[TMP4]], align 512
139 ; CHECK-NEXT:    [[TMP10:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP9]], i64 40)
140 ; CHECK-NEXT:    [[TMP11:%.*]] = bitcast <616 x i8>* [[TMP3]] to i8*
141 ; CHECK-NEXT:    store <616 x i8> undef, <616 x i8>* [[TMP3]], align 1024
142 ; CHECK-NEXT:    [[TMP12:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* [[TMP11]], i64 56)
143 ; CHECK-NEXT:    [[TMP13:%.*]] = bitcast <560 x i8>* [[TMP2]] to i8*
144 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP2]], align 1024
145 ; CHECK-NEXT:    [[TMP14:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP13]], i64 40)
146 ; CHECK-NEXT:    [[TMP15:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP10]], x86_amx [[TMP12]], x86_amx [[TMP14]])
147 ; CHECK-NEXT:    [[TMP16:%.*]] = bitcast <110 x i32>* [[TMP1]] to i8*
148 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* [[TMP16]], i64 40, x86_amx [[TMP15]])
149 ; CHECK-NEXT:    [[TMP17:%.*]] = load <110 x i32>, <110 x i32>* [[TMP1]], align 512
150 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I]], label [[EXIT:%.*]]
151 ; CHECK:       for.cond.cleanup.i.i:
152 ; CHECK-NEXT:    [[GOODPHI:%.*]] = phi <110 x i32> [ [[TMP8]], [[WRAPPER_ENTRY:%.*]] ], [ [[TMP17]], [[FOR_BODY_I_LR_PH_I]] ]
153 ; CHECK-NEXT:    [[TMP18:%.*]] = bitcast <110 x i32>* [[TMP0]] to i8*
154 ; CHECK-NEXT:    store <110 x i32> [[GOODPHI]], <110 x i32>* [[TMP0]], align 512
155 ; CHECK-NEXT:    [[TMP19:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP18]], i64 40)
156 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP19]])
157 ; CHECK-NEXT:    br i1 undef, label [[EXIT]], label [[FOR_BODY_I_LR_PH_I]]
158 ; CHECK:       exit:
159 ; CHECK-NEXT:    [[EVILPHI2:%.*]] = phi <110 x i32> [ [[GOODPHI]], [[FOR_COND_CLEANUP_I_I]] ], [ [[TMP17]], [[FOR_BODY_I_LR_PH_I]] ]
160 ; CHECK-NEXT:    store <110 x i32> [[EVILPHI2]], <110 x i32>* undef, align 512
161 ; CHECK-NEXT:    ret void
163 wrapper_entry:
164   %0 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
165   %tmp = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %0)
166   br i1 undef, label %for.cond.cleanup.i.i, label %for.body.i.lr.ph.i
168 for.body.i.lr.ph.i:                               ; preds = %wrapper_entry
169   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> undef)
170   %2 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> undef)
171   %3 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
172   %4 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %1, x86_amx %2, x86_amx %3)
173   %5 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %4)
174   br i1 undef, label %for.cond.cleanup.i.i, label %exit
176 for.cond.cleanup.i.i:                             ; preds = %for.body.i.lr.ph.i, %wrapper_entry
177   %goodphi = phi <110 x i32> [ %tmp, %wrapper_entry ], [ %5, %for.body.i.lr.ph.i ]
178   %6 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %goodphi)
179   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %6)
180   br i1 undef, label %exit, label %for.body.i.lr.ph.i
181 exit:
182   %evilphi2 = phi <110 x i32> [ %goodphi, %for.cond.cleanup.i.i ], [ %5, %for.body.i.lr.ph.i ]
183   store <110 x i32> %evilphi2, <110 x i32>* undef, align 512
184   ret void
187 define void @fail_to_combine_amx_cast_and_phi_due_to_const_value() {
188 ; CHECK-LABEL: @fail_to_combine_amx_cast_and_phi_due_to_const_value(
189 ; CHECK-NEXT:  wrapper_entry:
190 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <110 x i32>, align 64
191 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca <110 x i32>, align 64
192 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca <560 x i8>, align 64
193 ; CHECK-NEXT:    [[TMP3:%.*]] = alloca <616 x i8>, align 64
194 ; CHECK-NEXT:    [[TMP4:%.*]] = alloca <110 x i32>, align 64
195 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I:%.*]], label [[FOR_BODY_I_LR_PH_I:%.*]]
196 ; CHECK:       for.body.i.lr.ph.i:
197 ; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <110 x i32>* [[TMP4]] to i8*
198 ; CHECK-NEXT:    store <110 x i32> undef, <110 x i32>* [[TMP4]], align 512
199 ; CHECK-NEXT:    [[TMP6:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP5]], i64 40)
200 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast <616 x i8>* [[TMP3]] to i8*
201 ; CHECK-NEXT:    store <616 x i8> undef, <616 x i8>* [[TMP3]], align 1024
202 ; CHECK-NEXT:    [[TMP8:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* [[TMP7]], i64 56)
203 ; CHECK-NEXT:    [[TMP9:%.*]] = bitcast <560 x i8>* [[TMP2]] to i8*
204 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP2]], align 1024
205 ; CHECK-NEXT:    [[TMP10:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP9]], i64 40)
206 ; CHECK-NEXT:    [[TMP11:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP6]], x86_amx [[TMP8]], x86_amx [[TMP10]])
207 ; CHECK-NEXT:    [[TMP12:%.*]] = bitcast <110 x i32>* [[TMP1]] to i8*
208 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* [[TMP12]], i64 40, x86_amx [[TMP11]])
209 ; CHECK-NEXT:    [[TMP13:%.*]] = load <110 x i32>, <110 x i32>* [[TMP1]], align 512
210 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_I_I]]
211 ; CHECK:       for.cond.cleanup.i.i:
212 ; CHECK-NEXT:    [[EVILPHI:%.*]] = phi <110 x i32> [ undef, [[WRAPPER_ENTRY:%.*]] ], [ [[TMP13]], [[FOR_BODY_I_LR_PH_I]] ]
213 ; CHECK-NEXT:    [[TMP14:%.*]] = bitcast <110 x i32>* [[TMP0]] to i8*
214 ; CHECK-NEXT:    store <110 x i32> [[EVILPHI]], <110 x i32>* [[TMP0]], align 512
215 ; CHECK-NEXT:    [[TMP15:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP14]], i64 40)
216 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP15]])
217 ; CHECK-NEXT:    ret void
219 wrapper_entry:
220   br i1 undef, label %for.cond.cleanup.i.i, label %for.body.i.lr.ph.i
222 for.body.i.lr.ph.i:                               ; preds = %wrapper_entry
223   %0 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> undef)
224   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> undef)
225   %2 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
226   %3 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %0, x86_amx %1, x86_amx %2)
227   %4 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %3)
228   br label %for.cond.cleanup.i.i
230 for.cond.cleanup.i.i:                             ; preds = %for.body.i.lr.ph.i, %wrapper_entry
231   %evilphi = phi <110 x i32> [ undef, %wrapper_entry ], [ %4, %for.body.i.lr.ph.i ]
232   %5 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %evilphi)
233   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %5)
234   ret void
237 ; Cases where amxcast can be combined across bb
238 ; When optimizeAMXCastFromPhi process %6 and %goodphi, %goodphi2 is outside the phi-web, so the optimization stop
239 ; When optimizeAMXCastFromPhi process %7 and %goodphi2, the optimization continue.
240 define void @combine_amx_cast_and_multiple_phi() {
241 ; CHECK-LABEL: @combine_amx_cast_and_multiple_phi(
242 ; CHECK-NEXT:  wrapper_entry:
243 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <560 x i8>, align 64
244 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca <616 x i8>, align 64
245 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca <110 x i32>, align 64
246 ; CHECK-NEXT:    [[TMP3:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
247 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I:%.*]], label [[FOR_BODY_I_LR_PH_I:%.*]]
248 ; CHECK:       for.body.i.lr.ph.i:
249 ; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <110 x i32>* [[TMP2]] to i8*
250 ; CHECK-NEXT:    store <110 x i32> undef, <110 x i32>* [[TMP2]], align 512
251 ; CHECK-NEXT:    [[TMP5:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP4]], i64 40)
252 ; CHECK-NEXT:    [[TMP6:%.*]] = bitcast <616 x i8>* [[TMP1]] to i8*
253 ; CHECK-NEXT:    store <616 x i8> undef, <616 x i8>* [[TMP1]], align 1024
254 ; CHECK-NEXT:    [[TMP7:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* [[TMP6]], i64 56)
255 ; CHECK-NEXT:    [[TMP8:%.*]] = bitcast <560 x i8>* [[TMP0]] to i8*
256 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP0]], align 1024
257 ; CHECK-NEXT:    [[TMP9:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP8]], i64 40)
258 ; CHECK-NEXT:    [[TMP10:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP5]], x86_amx [[TMP7]], x86_amx [[TMP9]])
259 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I]], label [[EXIT:%.*]]
260 ; CHECK:       for.cond.cleanup.i.i:
261 ; CHECK-NEXT:    [[TMP11:%.*]] = phi x86_amx [ [[TMP3]], [[WRAPPER_ENTRY:%.*]] ], [ [[TMP10]], [[FOR_BODY_I_LR_PH_I]] ]
262 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP11]])
263 ; CHECK-NEXT:    br i1 undef, label [[EXIT]], label [[FOR_BODY_I_LR_PH_I]]
264 ; CHECK:       exit:
265 ; CHECK-NEXT:    [[TMP12:%.*]] = phi x86_amx [ [[TMP11]], [[FOR_COND_CLEANUP_I_I]] ], [ [[TMP10]], [[FOR_BODY_I_LR_PH_I]] ]
266 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP12]])
267 ; CHECK-NEXT:    ret void
269 wrapper_entry:
270   %0 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
271   %tmp = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %0)
272   br i1 undef, label %for.cond.cleanup.i.i, label %for.body.i.lr.ph.i
274 for.body.i.lr.ph.i:                               ; preds = %wrapper_entry
275   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> undef)
276   %2 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> undef)
277   %3 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
278   %4 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %1, x86_amx %2, x86_amx %3)
279   %5 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %4)
280   br i1 undef, label %for.cond.cleanup.i.i, label %exit
282 for.cond.cleanup.i.i:                             ; preds = %for.body.i.lr.ph.i, %wrapper_entry
283   %goodphi = phi <110 x i32> [ %tmp, %wrapper_entry ], [ %5, %for.body.i.lr.ph.i ]
284   %6 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %goodphi)
285   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %6)
286   br i1 undef, label %exit, label %for.body.i.lr.ph.i
287 exit:
288   %evilphi2 = phi <110 x i32> [ %goodphi, %for.cond.cleanup.i.i ], [ %5, %for.body.i.lr.ph.i ]
289   %7 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %evilphi2)
290   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %7)
291   ret void
294 ; Currently we are not able to delete DeadPHICycle, later we will handle with them
295 define void @combine_amx_cast_and_phi_in_a_circle() {
296 ; CHECK-LABEL: @combine_amx_cast_and_phi_in_a_circle(
297 ; CHECK-NEXT:  wrapper_entry:
298 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <110 x i32>, align 64
299 ; CHECK-NEXT:    [[TMP1:%.*]] = alloca <560 x i8>, align 64
300 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca <616 x i8>, align 64
301 ; CHECK-NEXT:    [[TMP3:%.*]] = alloca <110 x i32>, align 64
302 ; CHECK-NEXT:    [[TMP4:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
303 ; CHECK-NEXT:    br label [[BB1:%.*]]
304 ; CHECK:       bb1:
305 ; CHECK-NEXT:    [[TMP5:%.*]] = bitcast <110 x i32>* [[TMP3]] to i8*
306 ; CHECK-NEXT:    store <110 x i32> undef, <110 x i32>* [[TMP3]], align 512
307 ; CHECK-NEXT:    [[TMP6:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* [[TMP5]], i64 40)
308 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast <616 x i8>* [[TMP2]] to i8*
309 ; CHECK-NEXT:    store <616 x i8> undef, <616 x i8>* [[TMP2]], align 1024
310 ; CHECK-NEXT:    [[TMP8:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* [[TMP7]], i64 56)
311 ; CHECK-NEXT:    [[TMP9:%.*]] = bitcast <560 x i8>* [[TMP1]] to i8*
312 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP1]], align 1024
313 ; CHECK-NEXT:    [[TMP10:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP9]], i64 40)
314 ; CHECK-NEXT:    [[TMP11:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP6]], x86_amx [[TMP8]], x86_amx [[TMP10]])
315 ; CHECK-NEXT:    [[TMP12:%.*]] = bitcast <110 x i32>* [[TMP0]] to i8*
316 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* [[TMP12]], i64 40, x86_amx [[TMP11]])
317 ; CHECK-NEXT:    [[TMP13:%.*]] = load <110 x i32>, <110 x i32>* [[TMP0]], align 512
318 ; CHECK-NEXT:    br i1 undef, label [[BB2:%.*]], label [[BB3:%.*]]
319 ; CHECK:       bb2:
320 ; CHECK-NEXT:    [[TMP14:%.*]] = phi x86_amx [ [[TMP15:%.*]], [[BB3]] ], [ [[TMP11]], [[BB1]] ]
321 ; CHECK-NEXT:    [[GOODPHI:%.*]] = phi <110 x i32> [ [[EVILPHI2:%.*]], [[BB3]] ], [ [[TMP13]], [[BB1]] ]
322 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP14]])
323 ; CHECK-NEXT:    br label [[BB3]]
324 ; CHECK:       bb3:
325 ; CHECK-NEXT:    [[TMP15]] = phi x86_amx [ [[TMP14]], [[BB2]] ], [ [[TMP11]], [[BB1]] ]
326 ; CHECK-NEXT:    [[EVILPHI2]] = phi <110 x i32> [ [[GOODPHI]], [[BB2]] ], [ [[TMP13]], [[BB1]] ]
327 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP15]])
328 ; CHECK-NEXT:    br i1 undef, label [[BB2]], label [[EXIT:%.*]]
329 ; CHECK:       exit:
330 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP15]])
331 ; CHECK-NEXT:    ret void
333 wrapper_entry:
334   %0 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
335   %tmp = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %0)
336   br label %bb1
338 bb1:                               ; preds = %wrapper_entry
339   %1 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> undef)
340   %2 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> undef)
341   %3 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
342   %4 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %1, x86_amx %2, x86_amx %3)
343   %5 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %4)
344   br i1 undef, label %bb2, label %bb3
346 bb2:                             ; preds = %bb1, %wrapper_entry
347   %goodphi = phi <110 x i32> [ %evilphi2, %bb3], [ %5, %bb1 ]
348   %6 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %goodphi)
349   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %6)
350   br label %bb3
351 bb3:
352   %evilphi2 = phi <110 x i32> [ %goodphi, %bb2 ], [ %5, %bb1 ]
353   %7 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %evilphi2)
354   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %7)
355   br i1 undef, label %bb2, label %exit
356 exit:
357   %8 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %evilphi2)
358   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %8)
359   ret void
362 define void @eliminate_unused_phi_and_cast() {
363 ; CHECK-LABEL: @eliminate_unused_phi_and_cast(
364 ; CHECK-NEXT:  wrapper_entry:
365 ; CHECK-NEXT:    [[TMP0:%.*]] = alloca <560 x i8>, align 64
366 ; CHECK-NEXT:    [[TMP1:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
367 ; CHECK-NEXT:    br i1 undef, label [[FOR_COND_CLEANUP_I_I:%.*]], label [[FOR_BODY_I_LR_PH_I:%.*]]
368 ; CHECK:       for.body.i.lr.ph.i:
369 ; CHECK-NEXT:    [[TMP2:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* undef, i64 undef)
370 ; CHECK-NEXT:    [[TMP3:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* undef, i64 undef)
371 ; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <560 x i8>* [[TMP0]] to i8*
372 ; CHECK-NEXT:    store <560 x i8> undef, <560 x i8>* [[TMP0]], align 1024
373 ; CHECK-NEXT:    [[TMP5:%.*]] = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* [[TMP4]], i64 40)
374 ; CHECK-NEXT:    [[TMP6:%.*]] = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx [[TMP2]], x86_amx [[TMP3]], x86_amx [[TMP5]])
375 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_I_I]]
376 ; CHECK:       for.cond.cleanup.i.i:
377 ; CHECK-NEXT:    [[TMP7:%.*]] = phi x86_amx [ [[TMP1]], [[WRAPPER_ENTRY:%.*]] ], [ [[TMP6]], [[FOR_BODY_I_LR_PH_I]] ]
378 ; CHECK-NEXT:    call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx [[TMP7]])
379 ; CHECK-NEXT:    ret void
381 wrapper_entry:
382   %0 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 40, i8* undef, i64 undef)
383   %tmp = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %0)
384   br i1 undef, label %for.cond.cleanup.i.i, label %for.body.i.lr.ph.i
386 for.body.i.lr.ph.i:                               ; preds = %wrapper_entry
387   %1 = call x86_amx @llvm.x86.tileloadd64.internal(i16 11, i16 56, i8* undef, i64 undef)
388   %v1 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %1)
389   %2 = call x86_amx @llvm.x86.tileloadd64.internal(i16 14, i16 40, i8* undef, i64 undef)
390   %v2 = call <616 x i8> @llvm.x86.cast.tile.to.vector.v616i8(x86_amx %2)
391   %3 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %v1)
392   %4 = call x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8> %v2)
393   %5 = call x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8> undef)
394   %6 = call x86_amx @llvm.x86.tdpbssd.internal(i16 11, i16 40, i16 56, x86_amx %3, x86_amx %4, x86_amx %5)
395   %7 = call <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx %6)
396   br label %for.cond.cleanup.i.i
398 for.cond.cleanup.i.i:                             ; preds = %for.body.i.lr.ph.i, %wrapper_entry
399   %goodphi = phi <110 x i32> [ %tmp, %wrapper_entry ], [ %7, %for.body.i.lr.ph.i ]
400   %8 = call x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32> %goodphi)
401   call void @llvm.x86.tilestored64.internal(i16 11, i16 40, i8* undef, i64 undef, x86_amx %8)
402   ret void
405 declare x86_amx @llvm.x86.tileloadd64.internal(i16, i16, i8*, i64)
406 declare <110 x i32> @llvm.x86.cast.tile.to.vector.v110i32(x86_amx)
407 declare <616 x i8> @llvm.x86.cast.tile.to.vector.v616i8(x86_amx)
408 declare x86_amx @llvm.x86.cast.vector.to.tile.v110i32(<110 x i32>)
409 declare void @llvm.x86.tilestored64.internal(i16, i16, i8*, i64, x86_amx)
410 declare x86_amx @llvm.x86.cast.vector.to.tile.v616i8(<616 x i8>)
411 declare x86_amx @llvm.x86.cast.vector.to.tile.v560i8(<560 x i8>)
412 declare x86_amx @llvm.x86.tdpbssd.internal(i16, i16, i16, x86_amx, x86_amx, x86_amx)