1; RUN: opt -passes='lower-matrix-intrinsics' -S < %s | FileCheck %s 2 3define void @strided_store_volatile(<6 x i32> %in, ptr %out) { 4; CHECK-LABEL: @strided_store_volatile( 5; CHECK-NEXT: [[SPLIT:%.*]] = shufflevector <6 x i32> [[IN:%.*]], <6 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2> 6; CHECK-NEXT: [[SPLIT1:%.*]] = shufflevector <6 x i32> [[IN]], <6 x i32> poison, <3 x i32> <i32 3, i32 4, i32 5> 7; CHECK-NEXT: store volatile <3 x i32> [[SPLIT]], ptr [[OUT:%.*]], align 4 8; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr i32, ptr [[OUT]], i64 5 9; CHECK-NEXT: store volatile <3 x i32> [[SPLIT1]], ptr [[VEC_GEP]], align 4 10; CHECK-NEXT: ret void 11; 12 call void @llvm.matrix.column.major.store(<6 x i32> %in, ptr %out, i64 5, i1 true, i32 3, i32 2) 13 ret void 14} 15 16declare void @llvm.matrix.column.major.store(<6 x i32>, ptr, i64, i1, i32, i32) 17 18 19define void @multiply_store_volatile(<4 x i32> %in, ptr %out) { 20; CHECK-LABEL: @multiply_store_volatile( 21; CHECK: store volatile <2 x i32> {{.*}}, ptr %out, align 4 22; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr i32, ptr %out, i64 2 23; CHECK-NEXT: store volatile <2 x i32> {{.*}}, ptr [[VEC_GEP]], align 4 24; CHECK-NEXT: ret void 25; 26 %res = call <4 x i32> @llvm.matrix.multiply(<4 x i32> %in, <4 x i32> %in, i32 2, i32 2, i32 2) 27 store volatile <4 x i32> %res, ptr %out, align 4 28 ret void 29} 30 31declare <4 x i32> @llvm.matrix.multiply(<4 x i32>, <4 x i32>, i32, i32, i32) 32 33define void @strided_store_align32(<6 x i32> %in, i64 %stride, ptr %out) { 34; CHECK-LABEL: @strided_store_align32( 35; CHECK-NEXT: [[SPLIT:%.*]] = shufflevector <6 x i32> [[IN:%.*]], <6 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2> 36; CHECK-NEXT: [[SPLIT1:%.*]] = shufflevector <6 x i32> [[IN]], <6 x i32> poison, <3 x i32> <i32 3, i32 4, i32 5> 37; CHECK-NEXT: [[VEC_START:%.*]] = mul i64 0, [[STRIDE:%.*]] 38; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr i32, ptr [[OUT:%.*]], i64 [[VEC_START]] 39; CHECK-NEXT: store volatile <3 x i32> [[SPLIT]], ptr [[VEC_GEP]], align 32 40; CHECK-NEXT: [[VEC_START2:%.*]] = mul i64 1, [[STRIDE]] 41; CHECK-NEXT: [[VEC_GEP3:%.*]] = getelementptr i32, ptr [[OUT]], i64 [[VEC_START2]] 42; CHECK-NEXT: store volatile <3 x i32> [[SPLIT1]], ptr [[VEC_GEP3]], align 4 43; CHECK-NEXT: ret void 44; 45 call void @llvm.matrix.column.major.store(<6 x i32> %in, ptr align 32 %out, i64 %stride, i1 true, i32 3, i32 2) 46 ret void 47} 48 49define void @strided_store_align2(<6 x i32> %in, i64 %stride, ptr %out) { 50; CHECK-LABEL: @strided_store_align2( 51; CHECK-NEXT: [[SPLIT:%.*]] = shufflevector <6 x i32> [[IN:%.*]], <6 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2> 52; CHECK-NEXT: [[SPLIT1:%.*]] = shufflevector <6 x i32> [[IN]], <6 x i32> poison, <3 x i32> <i32 3, i32 4, i32 5> 53; CHECK-NEXT: [[VEC_START:%.*]] = mul i64 0, [[STRIDE:%.*]] 54; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr i32, ptr [[OUT:%.*]], i64 [[VEC_START]] 55; CHECK-NEXT: store volatile <3 x i32> [[SPLIT]], ptr [[VEC_GEP]], align 2 56; CHECK-NEXT: [[VEC_START2:%.*]] = mul i64 1, [[STRIDE]] 57; CHECK-NEXT: [[VEC_GEP3:%.*]] = getelementptr i32, ptr [[OUT]], i64 [[VEC_START2]] 58; CHECK-NEXT: store volatile <3 x i32> [[SPLIT1]], ptr [[VEC_GEP3]], align 2 59; CHECK-NEXT: ret void 60; 61 call void @llvm.matrix.column.major.store(<6 x i32> %in, ptr align 2 %out, i64 %stride, i1 true, i32 3, i32 2) 62 ret void 63} 64 65define void @multiply_store_align16_stride8(<4 x i32> %in, ptr %out) { 66; CHECK-LABEL: @multiply_store_align16_stride8( 67; CHECK: store <2 x i32> {{.*}}, ptr %out, align 16 68; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr i32, ptr %out, i64 2 69; CHECK-NEXT: store <2 x i32> {{.*}}, ptr [[VEC_GEP]], align 8 70; CHECK-NEXT: ret void 71; 72 %res = call <4 x i32> @llvm.matrix.multiply(<4 x i32> %in, <4 x i32> %in, i32 2, i32 2, i32 2) 73 store <4 x i32> %res, ptr %out, align 16 74 ret void 75} 76 77define void @strided_store_align8_stride12(<6 x i32> %in, ptr %out) { 78; CHECK-LABEL: @strided_store_align8_stride12( 79; CHECK-NEXT: [[SPLIT:%.*]] = shufflevector <6 x i32> [[IN:%.*]], <6 x i32> poison, <2 x i32> <i32 0, i32 1> 80; CHECK-NEXT: [[SPLIT1:%.*]] = shufflevector <6 x i32> [[IN]], <6 x i32> poison, <2 x i32> <i32 2, i32 3> 81; CHECK-NEXT: [[SPLIT2:%.*]] = shufflevector <6 x i32> [[IN]], <6 x i32> poison, <2 x i32> <i32 4, i32 5> 82; CHECK-NEXT: store <2 x i32> [[SPLIT]], ptr [[OUT:%.*]], align 8 83; CHECK-NEXT: [[VEC_GEP:%.*]] = getelementptr i32, ptr [[OUT]], i64 3 84; CHECK-NEXT: store <2 x i32> [[SPLIT1]], ptr [[VEC_GEP]], align 4 85; CHECK-NEXT: [[VEC_GEP4:%.*]] = getelementptr i32, ptr [[OUT]], i64 6 86; CHECK-NEXT: store <2 x i32> [[SPLIT2]], ptr [[VEC_GEP4]], align 8 87; CHECK-NEXT: ret void 88; 89 call void @llvm.matrix.column.major.store(<6 x i32> %in, ptr align 8 %out, i64 3, i1 false, i32 2, i32 3) 90 ret void 91} 92