133 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-vectorize,interleaved-access -mattr=+sve -S -o - %s | FileCheck %s3 4target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"5target triple = "aarch64"6 7%struct.xyzt = type { i32, i32, i32, i32 }8; for (int i = 0; i < 1024; ++i) {9; dst[i].x = a[i].x + b[i].x;10; dst[i].y = a[i].y - b[i].y;11; dst[i].z = a[i].z << b[i].z;12; dst[i].t = a[i].t >> b[i].t;13; }14 15define void @interleave_deinterleave(ptr noalias %dst, ptr %a, ptr %b) {16; CHECK-LABEL: @interleave_deinterleave(17; CHECK-NEXT: entry:18; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64()19; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 220; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]21; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY_PREHEADER:%.*]], label [[VECTOR_PH:%.*]]22; CHECK: vector.ph:23; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64()24; CHECK-NEXT: [[TMP3:%.*]] = mul nuw i64 [[TMP2]], 425; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]26; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]27; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]28; CHECK: vector.body:29; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]30; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT_XYZT:%.*]], ptr [[A:%.*]], i64 [[INDEX]]31; CHECK-NEXT: [[LDN:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld4.sret.nxv4i32(<vscale x 4 x i1> splat (i1 true), ptr [[TMP7]])32; CHECK-NEXT: [[TMP9:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN]], 033; CHECK-NEXT: [[TMP10:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN]], 134; CHECK-NEXT: [[TMP11:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN]], 235; CHECK-NEXT: [[TMP12:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN]], 336; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds [[STRUCT_XYZT]], ptr [[B:%.*]], i64 [[INDEX]]37; CHECK-NEXT: [[LDN9:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.ld4.sret.nxv4i32(<vscale x 4 x i1> splat (i1 true), ptr [[TMP13]])38; CHECK-NEXT: [[TMP16:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN9]], 039; CHECK-NEXT: [[TMP17:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN9]], 140; CHECK-NEXT: [[TMP18:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN9]], 241; CHECK-NEXT: [[TMP19:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } [[LDN9]], 342; CHECK-NEXT: [[TMP20:%.*]] = add nsw <vscale x 4 x i32> [[TMP16]], [[TMP9]]43; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds [[STRUCT_XYZT]], ptr [[DST:%.*]], i64 [[INDEX]]44; CHECK-NEXT: [[TMP22:%.*]] = sub nsw <vscale x 4 x i32> [[TMP10]], [[TMP17]]45; CHECK-NEXT: [[TMP23:%.*]] = shl <vscale x 4 x i32> [[TMP11]], [[TMP18]]46; CHECK-NEXT: [[TMP24:%.*]] = ashr <vscale x 4 x i32> [[TMP12]], [[TMP19]]47; CHECK-NEXT: call void @llvm.aarch64.sve.st4.nxv4i32(<vscale x 4 x i32> [[TMP20]], <vscale x 4 x i32> [[TMP22]], <vscale x 4 x i32> [[TMP23]], <vscale x 4 x i32> [[TMP24]], <vscale x 4 x i1> splat (i1 true), ptr [[TMP21]])48; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP3]]49; CHECK-NEXT: [[TMP25:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]50; CHECK-NEXT: br i1 [[TMP25]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]51; CHECK: middle.block:52; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]53; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER]]54; CHECK: scalar.ph:55; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]56; CHECK-NEXT: br label [[FOR_BODY:%.*]]57; CHECK: for.body:58; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]59; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_XYZT]], ptr [[A]], i64 [[INDVARS_IV]]60; CHECK-NEXT: [[TMP31:%.*]] = load i32, ptr [[ARRAYIDX]], align 461; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_XYZT]], ptr [[B]], i64 [[INDVARS_IV]]62; CHECK-NEXT: [[TMP32:%.*]] = load i32, ptr [[ARRAYIDX2]], align 463; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP32]], [[TMP31]]64; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [[STRUCT_XYZT]], ptr [[DST]], i64 [[INDVARS_IV]]65; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX5]], align 466; CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX]], i64 467; CHECK-NEXT: [[TMP33:%.*]] = load i32, ptr [[Y]], align 468; CHECK-NEXT: [[Y11:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX2]], i64 469; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr [[Y11]], align 470; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[TMP33]], [[TMP26]]71; CHECK-NEXT: [[Y14:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX5]], i64 472; CHECK-NEXT: store i32 [[SUB]], ptr [[Y14]], align 473; CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX]], i64 874; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[Z]], align 475; CHECK-NEXT: [[Z19:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX2]], i64 876; CHECK-NEXT: [[TMP28:%.*]] = load i32, ptr [[Z19]], align 477; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[TMP27]], [[TMP28]]78; CHECK-NEXT: [[Z22:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX5]], i64 879; CHECK-NEXT: store i32 [[SHL]], ptr [[Z22]], align 480; CHECK-NEXT: [[T:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX]], i64 1281; CHECK-NEXT: [[TMP29:%.*]] = load i32, ptr [[T]], align 482; CHECK-NEXT: [[T27:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX2]], i64 1283; CHECK-NEXT: [[TMP30:%.*]] = load i32, ptr [[T27]], align 484; CHECK-NEXT: [[SHR:%.*]] = ashr i32 [[TMP29]], [[TMP30]]85; CHECK-NEXT: [[T30:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX5]], i64 1286; CHECK-NEXT: store i32 [[SHR]], ptr [[T30]], align 487; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 188; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 102489; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]90; CHECK: for.end:91; CHECK-NEXT: ret void92;93entry:94 br label %for.body95 96for.body:97 %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]98 %gep.a = getelementptr inbounds %struct.xyzt, ptr %a, i64 %iv99 %a.0 = load i32, ptr %gep.a, align 4100 %gep.b = getelementptr inbounds %struct.xyzt, ptr %b, i64 %iv101 %b.0 = load i32, ptr %gep.b, align 4102 %add = add nsw i32 %b.0, %a.0103 %gep.dst = getelementptr inbounds %struct.xyzt, ptr %dst, i64 %iv104 store i32 %add, ptr %gep.dst, align 4105 %gep.a.1 = getelementptr inbounds nuw i8, ptr %gep.a, i64 4106 %a.1 = load i32, ptr %gep.a.1, align 4107 %gep.b.1 = getelementptr inbounds nuw i8, ptr %gep.b, i64 4108 %b.1 = load i32, ptr %gep.b.1, align 4109 %sub = sub nsw i32 %a.1, %b.1110 %gep.dst.1 = getelementptr inbounds nuw i8, ptr %gep.dst, i64 4111 store i32 %sub, ptr %gep.dst.1, align 4112 %gep.a.2 = getelementptr inbounds nuw i8, ptr %gep.a, i64 8113 %a.2 = load i32, ptr %gep.a.2, align 4114 %gep.b.2 = getelementptr inbounds nuw i8, ptr %gep.b, i64 8115 %b.2 = load i32, ptr %gep.b.2, align 4116 %shl = shl i32 %a.2, %b.2117 %gep.dst.2 = getelementptr inbounds nuw i8, ptr %gep.dst, i64 8118 store i32 %shl, ptr %gep.dst.2, align 4119 %gep.a.3 = getelementptr inbounds nuw i8, ptr %gep.a, i64 12120 %a.3 = load i32, ptr %gep.a.3, align 4121 %gep.b.3 = getelementptr inbounds nuw i8, ptr %gep.b, i64 12122 %b.3 = load i32, ptr %gep.b.3, align 4123 %shr = ashr i32 %a.3, %b.3124 %gep.dst.3 = getelementptr inbounds nuw i8, ptr %gep.dst, i64 12125 store i32 %shr, ptr %gep.dst.3, align 4126 %iv.next = add nuw nsw i64 %iv, 1127 %exitcond.not = icmp eq i64 %iv.next, 1024128 br i1 %exitcond.not, label %for.end, label %for.body129 130for.end:131 ret void132}133