Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LowerMatrixIntrinsics / dot-product-transpose-int.ll
blob2fd77e245a34e5f0bcec97b919f258fa8fbd0178
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; REQUIRES: aarch64-registered-target
3 ; RUN: opt -passes='lower-matrix-intrinsics' -mtriple=arm64-apple-iphoneos -S < %s | FileCheck %s
5 define void @transposed_multiply_feeding_dot_product_v4i322(<4 x i32> %a, <4 x i32> %b) {
6 ; CHECK-LABEL: @transposed_multiply_feeding_dot_product_v4i322(
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[TMP0:%.*]] = mul <4 x i32> [[A:%.*]], [[B:%.*]]
9 ; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP0]])
10 ; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <1 x i32> poison, i32 [[TMP1]], i64 0
11 ; CHECK-NEXT:    ret void
13 entry:
14   %0 = call <4 x i32> @llvm.matrix.transpose.v4i32(<4 x i32> %a, i32 4, i32 1)
15   %1 = call <1 x i32> @llvm.matrix.multiply.v1i32.v4i32.v4i32(<4 x i32> %0, <4 x i32> %b, i32 1, i32 4, i32 1)
16   ret void
19 define void @transposed_multiply_feeding_dot_produc_v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
20 ; CHECK-LABEL: @transposed_multiply_feeding_dot_produc_v4i32(
21 ; CHECK-NEXT:  entry:
22 ; CHECK-NEXT:    [[SPLIT:%.*]] = shufflevector <4 x i32> [[A:%.*]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
23 ; CHECK-NEXT:    [[SPLIT1:%.*]] = shufflevector <4 x i32> [[A]], <4 x i32> poison, <2 x i32> <i32 2, i32 3>
24 ; CHECK-NEXT:    [[SPLIT2:%.*]] = shufflevector <4 x i32> [[B:%.*]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
25 ; CHECK-NEXT:    [[SPLIT3:%.*]] = shufflevector <4 x i32> [[B]], <4 x i32> poison, <2 x i32> <i32 2, i32 3>
26 ; CHECK-NEXT:    [[BLOCK:%.*]] = shufflevector <2 x i32> [[SPLIT]], <2 x i32> poison, <2 x i32> <i32 0, i32 1>
27 ; CHECK-NEXT:    [[TMP0:%.*]] = extractelement <2 x i32> [[SPLIT2]], i64 0
28 ; CHECK-NEXT:    [[SPLAT_SPLATINSERT:%.*]] = insertelement <2 x i32> poison, i32 [[TMP0]], i64 0
29 ; CHECK-NEXT:    [[SPLAT_SPLAT:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT]], <2 x i32> poison, <2 x i32> zeroinitializer
30 ; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[BLOCK]], [[SPLAT_SPLAT]]
31 ; CHECK-NEXT:    [[BLOCK4:%.*]] = shufflevector <2 x i32> [[SPLIT1]], <2 x i32> poison, <2 x i32> <i32 0, i32 1>
32 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i32> [[SPLIT2]], i64 1
33 ; CHECK-NEXT:    [[SPLAT_SPLATINSERT5:%.*]] = insertelement <2 x i32> poison, i32 [[TMP2]], i64 0
34 ; CHECK-NEXT:    [[SPLAT_SPLAT6:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT5]], <2 x i32> poison, <2 x i32> zeroinitializer
35 ; CHECK-NEXT:    [[TMP3:%.*]] = mul <2 x i32> [[BLOCK4]], [[SPLAT_SPLAT6]]
36 ; CHECK-NEXT:    [[TMP4:%.*]] = add <2 x i32> [[TMP1]], [[TMP3]]
37 ; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <2 x i32> [[TMP4]], <2 x i32> poison, <2 x i32> <i32 0, i32 1>
38 ; CHECK-NEXT:    [[TMP6:%.*]] = shufflevector <2 x i32> poison, <2 x i32> [[TMP5]], <2 x i32> <i32 2, i32 3>
39 ; CHECK-NEXT:    [[BLOCK7:%.*]] = shufflevector <2 x i32> [[SPLIT]], <2 x i32> poison, <2 x i32> <i32 0, i32 1>
40 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x i32> [[SPLIT3]], i64 0
41 ; CHECK-NEXT:    [[SPLAT_SPLATINSERT8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i64 0
42 ; CHECK-NEXT:    [[SPLAT_SPLAT9:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT8]], <2 x i32> poison, <2 x i32> zeroinitializer
43 ; CHECK-NEXT:    [[TMP8:%.*]] = mul <2 x i32> [[BLOCK7]], [[SPLAT_SPLAT9]]
44 ; CHECK-NEXT:    [[BLOCK10:%.*]] = shufflevector <2 x i32> [[SPLIT1]], <2 x i32> poison, <2 x i32> <i32 0, i32 1>
45 ; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x i32> [[SPLIT3]], i64 1
46 ; CHECK-NEXT:    [[SPLAT_SPLATINSERT11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP9]], i64 0
47 ; CHECK-NEXT:    [[SPLAT_SPLAT12:%.*]] = shufflevector <2 x i32> [[SPLAT_SPLATINSERT11]], <2 x i32> poison, <2 x i32> zeroinitializer
48 ; CHECK-NEXT:    [[TMP10:%.*]] = mul <2 x i32> [[BLOCK10]], [[SPLAT_SPLAT12]]
49 ; CHECK-NEXT:    [[TMP11:%.*]] = add <2 x i32> [[TMP8]], [[TMP10]]
50 ; CHECK-NEXT:    [[TMP12:%.*]] = shufflevector <2 x i32> [[TMP11]], <2 x i32> poison, <2 x i32> <i32 0, i32 1>
51 ; CHECK-NEXT:    [[TMP13:%.*]] = shufflevector <2 x i32> poison, <2 x i32> [[TMP12]], <2 x i32> <i32 2, i32 3>
52 ; CHECK-NEXT:    [[TMP14:%.*]] = shufflevector <2 x i32> [[TMP6]], <2 x i32> [[TMP13]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
53 ; CHECK-NEXT:    [[TMP15:%.*]] = mul <4 x i32> [[TMP14]], [[C:%.*]]
54 ; CHECK-NEXT:    [[TMP16:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP15]])
55 ; CHECK-NEXT:    [[TMP17:%.*]] = insertelement <1 x i32> poison, i32 [[TMP16]], i64 0
56 ; CHECK-NEXT:    ret void
58 entry:
59   %0 = call <4 x i32> @llvm.matrix.multiply.v4i32.v4i32.v4i32(<4 x i32> %a, <4 x i32> %b, i32 2, i32 2, i32 2)
60   %1 = call <4 x i32> @llvm.matrix.transpose.v4i32(<4 x i32> %0, i32 4, i32 1)
61   %2 = call <1 x i32> @llvm.matrix.multiply.v1i32.v4i32.v4i32(<4 x i32> %1, <4 x i32> %c, i32 1, i32 4, i32 1)
62   ret void
65 declare <1 x i32> @llvm.matrix.multiply.v1i32.v4i32.v4i32(<4 x i32>, <4 x i32>, i32, i32, i32)
67 declare <4 x i32> @llvm.matrix.transpose.v4i32(<4 x i32>, i32 immarg, i32 immarg)
69 declare <4 x i32> @llvm.matrix.multiply.v4i32.v4i32.v4i32(<4 x i32>, <4 x i32>, i32 immarg, i32 immarg, i32 immarg)
71 define <1 x i32> @test_load_multiuse(ptr %src, <4 x i32> %b) {
72 ; CHECK-LABEL: @test_load_multiuse(
73 ; CHECK-NEXT:    [[COL_LOAD:%.*]] = load <1 x i32>, ptr [[SRC:%.*]], align 16
74 ; CHECK-NEXT:    [[VEC_GEP:%.*]] = getelementptr i32, ptr [[SRC]], i64 1
75 ; CHECK-NEXT:    [[COL_LOAD1:%.*]] = load <1 x i32>, ptr [[VEC_GEP]], align 4
76 ; CHECK-NEXT:    [[VEC_GEP2:%.*]] = getelementptr i32, ptr [[SRC]], i64 2
77 ; CHECK-NEXT:    [[COL_LOAD3:%.*]] = load <1 x i32>, ptr [[VEC_GEP2]], align 8
78 ; CHECK-NEXT:    [[VEC_GEP4:%.*]] = getelementptr i32, ptr [[SRC]], i64 3
79 ; CHECK-NEXT:    [[COL_LOAD5:%.*]] = load <1 x i32>, ptr [[VEC_GEP4]], align 4
80 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <1 x i32> [[COL_LOAD]], <1 x i32> [[COL_LOAD1]], <2 x i32> <i32 0, i32 1>
81 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <1 x i32> [[COL_LOAD3]], <1 x i32> [[COL_LOAD5]], <2 x i32> <i32 0, i32 1>
82 ; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
83 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <1 x i32> [[COL_LOAD]], i64 0
84 ; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0
85 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <1 x i32> [[COL_LOAD1]], i64 0
86 ; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <4 x i32> [[TMP5]], i32 [[TMP6]], i64 1
87 ; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <1 x i32> [[COL_LOAD3]], i64 0
88 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <4 x i32> [[TMP7]], i32 [[TMP8]], i64 2
89 ; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <1 x i32> [[COL_LOAD5]], i64 0
90 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x i32> [[TMP9]], i32 [[TMP10]], i64 3
91 ; CHECK-NEXT:    call void @use.v4i32(<4 x i32> [[TMP11]])
92 ; CHECK-NEXT:    [[TMP12:%.*]] = mul <4 x i32> [[TMP3]], [[B:%.*]]
93 ; CHECK-NEXT:    [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP12]])
94 ; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <1 x i32> poison, i32 [[TMP13]], i64 0
95 ; CHECK-NEXT:    ret <1 x i32> [[TMP14]]
97   %l = load <4 x i32>, ptr %src
98   %t = call <4 x i32> @llvm.matrix.transpose.v4i32(<4 x i32> %l, i32 1, i32 4)
99   call void @use.v4i32(<4 x i32> %t)
100   %res = call <1 x i32> @llvm.matrix.multiply.v1i32.v4i32.v4i32(<4 x i32> %l, <4 x i32> %b, i32 1, i32 4, i32 1)
101   ret <1 x i32> %res
104 define <1 x i32> @test_builtin_column_major_load_multiuse(ptr %src, <4 x i32> %b) {
105 ; CHECK-LABEL: @test_builtin_column_major_load_multiuse(
106 ; CHECK-NEXT:    [[COL_LOAD:%.*]] = load <1 x i32>, ptr [[SRC:%.*]], align 4
107 ; CHECK-NEXT:    [[VEC_GEP:%.*]] = getelementptr i32, ptr [[SRC]], i64 1
108 ; CHECK-NEXT:    [[COL_LOAD1:%.*]] = load <1 x i32>, ptr [[VEC_GEP]], align 4
109 ; CHECK-NEXT:    [[VEC_GEP2:%.*]] = getelementptr i32, ptr [[SRC]], i64 2
110 ; CHECK-NEXT:    [[COL_LOAD3:%.*]] = load <1 x i32>, ptr [[VEC_GEP2]], align 4
111 ; CHECK-NEXT:    [[VEC_GEP4:%.*]] = getelementptr i32, ptr [[SRC]], i64 3
112 ; CHECK-NEXT:    [[COL_LOAD5:%.*]] = load <1 x i32>, ptr [[VEC_GEP4]], align 4
113 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <1 x i32> [[COL_LOAD]], <1 x i32> [[COL_LOAD1]], <2 x i32> <i32 0, i32 1>
114 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <1 x i32> [[COL_LOAD3]], <1 x i32> [[COL_LOAD5]], <2 x i32> <i32 0, i32 1>
115 ; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
116 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <1 x i32> [[COL_LOAD]], i64 0
117 ; CHECK-NEXT:    [[TMP5:%.*]] = insertelement <4 x i32> poison, i32 [[TMP4]], i64 0
118 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <1 x i32> [[COL_LOAD1]], i64 0
119 ; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <4 x i32> [[TMP5]], i32 [[TMP6]], i64 1
120 ; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <1 x i32> [[COL_LOAD3]], i64 0
121 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <4 x i32> [[TMP7]], i32 [[TMP8]], i64 2
122 ; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <1 x i32> [[COL_LOAD5]], i64 0
123 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <4 x i32> [[TMP9]], i32 [[TMP10]], i64 3
124 ; CHECK-NEXT:    call void @use.v4i32(<4 x i32> [[TMP11]])
125 ; CHECK-NEXT:    [[TMP12:%.*]] = mul <4 x i32> [[TMP3]], [[B:%.*]]
126 ; CHECK-NEXT:    [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[TMP12]])
127 ; CHECK-NEXT:    [[TMP14:%.*]] = insertelement <1 x i32> poison, i32 [[TMP13]], i64 0
128 ; CHECK-NEXT:    ret <1 x i32> [[TMP14]]
130   %l = call <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(ptr %src, i64 1, i1 false, i32 1, i32 4)
131   %t = call <4 x i32> @llvm.matrix.transpose.v4i32(<4 x i32> %l, i32 1, i32 4)
132   call void @use.v4i32(<4 x i32> %t)
133   %res = call <1 x i32> @llvm.matrix.multiply.v1i32.v4i32.v4i32(<4 x i32> %l, <4 x i32> %b, i32 1, i32 4, i32 1)
134   ret <1 x i32> %res
137 declare <4 x i32> @llvm.matrix.column.major.load.v4i32.i64(ptr, i64, i1, i32, i32)
139 declare void @use.v4i32(<4 x i32>)
141 define <1 x i32> @test_builtin_column_major_variable_stride_multiuse(ptr %src, <5 x i32> %a, i64 %stride) {
142 ; CHECK-LABEL: @test_builtin_column_major_variable_stride_multiuse(
143 ; CHECK-NEXT:    [[VEC_START:%.*]] = mul i64 0, [[STRIDE:%.*]]
144 ; CHECK-NEXT:    [[VEC_GEP:%.*]] = getelementptr i32, ptr [[SRC:%.*]], i64 [[VEC_START]]
145 ; CHECK-NEXT:    [[COL_LOAD:%.*]] = load <1 x i32>, ptr [[VEC_GEP]], align 4
146 ; CHECK-NEXT:    [[VEC_START1:%.*]] = mul i64 1, [[STRIDE]]
147 ; CHECK-NEXT:    [[VEC_GEP2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[VEC_START1]]
148 ; CHECK-NEXT:    [[COL_LOAD3:%.*]] = load <1 x i32>, ptr [[VEC_GEP2]], align 4
149 ; CHECK-NEXT:    [[VEC_START4:%.*]] = mul i64 2, [[STRIDE]]
150 ; CHECK-NEXT:    [[VEC_GEP5:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[VEC_START4]]
151 ; CHECK-NEXT:    [[COL_LOAD6:%.*]] = load <1 x i32>, ptr [[VEC_GEP5]], align 4
152 ; CHECK-NEXT:    [[VEC_START7:%.*]] = mul i64 3, [[STRIDE]]
153 ; CHECK-NEXT:    [[VEC_GEP8:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[VEC_START7]]
154 ; CHECK-NEXT:    [[COL_LOAD9:%.*]] = load <1 x i32>, ptr [[VEC_GEP8]], align 4
155 ; CHECK-NEXT:    [[VEC_START10:%.*]] = mul i64 4, [[STRIDE]]
156 ; CHECK-NEXT:    [[VEC_GEP11:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[VEC_START10]]
157 ; CHECK-NEXT:    [[COL_LOAD12:%.*]] = load <1 x i32>, ptr [[VEC_GEP11]], align 4
158 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <1 x i32> [[COL_LOAD]], <1 x i32> [[COL_LOAD3]], <2 x i32> <i32 0, i32 1>
159 ; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <1 x i32> [[COL_LOAD6]], <1 x i32> [[COL_LOAD9]], <2 x i32> <i32 0, i32 1>
160 ; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
161 ; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <1 x i32> [[COL_LOAD12]], <1 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
162 ; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <4 x i32> [[TMP3]], <4 x i32> [[TMP4]], <5 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4>
163 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <1 x i32> [[COL_LOAD]], i64 0
164 ; CHECK-NEXT:    [[TMP7:%.*]] = insertelement <5 x i32> poison, i32 [[TMP6]], i64 0
165 ; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <1 x i32> [[COL_LOAD3]], i64 0
166 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <5 x i32> [[TMP7]], i32 [[TMP8]], i64 1
167 ; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <1 x i32> [[COL_LOAD6]], i64 0
168 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <5 x i32> [[TMP9]], i32 [[TMP10]], i64 2
169 ; CHECK-NEXT:    [[TMP12:%.*]] = extractelement <1 x i32> [[COL_LOAD9]], i64 0
170 ; CHECK-NEXT:    [[TMP13:%.*]] = insertelement <5 x i32> [[TMP11]], i32 [[TMP12]], i64 3
171 ; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <1 x i32> [[COL_LOAD12]], i64 0
172 ; CHECK-NEXT:    [[TMP15:%.*]] = insertelement <5 x i32> [[TMP13]], i32 [[TMP14]], i64 4
173 ; CHECK-NEXT:    call void @use.v5i32(<5 x i32> [[TMP15]])
174 ; CHECK-NEXT:    [[TMP16:%.*]] = mul <5 x i32> [[TMP5]], [[A:%.*]]
175 ; CHECK-NEXT:    [[TMP17:%.*]] = call i32 @llvm.vector.reduce.add.v5i32(<5 x i32> [[TMP16]])
176 ; CHECK-NEXT:    [[TMP18:%.*]] = insertelement <1 x i32> poison, i32 [[TMP17]], i64 0
177 ; CHECK-NEXT:    ret <1 x i32> [[TMP18]]
179   %l = call <5 x i32> @llvm.matrix.column.major.load.v5i32.i64(ptr %src, i64 %stride, i1 false, i32 1, i32 5)
180   %t = call <5 x i32> @llvm.matrix.transpose.v5i32(<5 x i32> %l, i32 1, i32 5)
181   call void @use.v5i32(<5 x i32> %t)
182   %r = call <1 x i32> @llvm.matrix.multiply.v1i32.v5i32.v5i32(<5 x i32> %l, <5 x i32> %a, i32 1, i32 5, i32 1)
183   ret <1 x i32> %r
186 declare void @use.v5i32(<5 x i32>)
188 declare <1 x i32> @llvm.matrix.multiply.v1i32.v5i32.v5i32(<5 x i32>, <5 x i32>, i32 immarg, i32 immarg, i32 immarg) #0
190 declare <5 x i32> @llvm.matrix.column.major.load.v5i32.i64(ptr nocapture, i64, i1 immarg, i32 immarg, i32 immarg) #1
192 declare <5 x i32> @llvm.matrix.transpose.v5i32(<5 x i32>, i32 immarg, i32 immarg) #0