blob: 6e6cb3990670d1b87562fcb9bb60a0533745aade [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S --passes=slp-vectorizer -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
define void @test(ptr noalias %a, ptr noalias %b, ptr noalias %c) {
; CHECK-LABEL: define void @test(
; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[OUTER:.*]]
; CHECK: [[OUTER]]:
; CHECK-NEXT: [[QZ:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[QZ_NEXT:%.*]], %[[OUTER_LATCH:.*]] ]
; CHECK-NEXT: [[ABASE:%.*]] = mul i64 [[QZ]], 12
; CHECK-NEXT: [[PA00:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[ABASE]]
; CHECK-NEXT: [[PA10:%.*]] = getelementptr inbounds double, ptr [[PA00]], i64 3
; CHECK-NEXT: [[PA20:%.*]] = getelementptr inbounds double, ptr [[PA00]], i64 6
; CHECK-NEXT: [[PA30:%.*]] = getelementptr inbounds double, ptr [[PA00]], i64 9
; CHECK-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[PA00]], align 8
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, ptr [[PA10]], align 8
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x double>, ptr [[PA20]], align 8
; CHECK-NEXT: [[TMP3:%.*]] = load <2 x double>, ptr [[PA30]], align 8
; CHECK-NEXT: [[CBASE:%.*]] = mul i64 [[QZ]], 6
; CHECK-NEXT: br label %[[INNER:.*]]
; CHECK: [[INNER]]:
; CHECK-NEXT: [[DY:%.*]] = phi i64 [ 0, %[[OUTER]] ], [ [[DY_NEXT:%.*]], %[[INNER]] ]
; CHECK-NEXT: [[PB0:%.*]] = getelementptr inbounds double, ptr [[B]], i64 [[DY]]
; CHECK-NEXT: [[S0:%.*]] = load double, ptr [[PB0]], align 8
; CHECK-NEXT: [[PB1:%.*]] = getelementptr inbounds double, ptr [[PB0]], i64 3
; CHECK-NEXT: [[S1:%.*]] = load double, ptr [[PB1]], align 8
; CHECK-NEXT: [[PB2:%.*]] = getelementptr inbounds double, ptr [[PB0]], i64 6
; CHECK-NEXT: [[S2:%.*]] = load double, ptr [[PB2]], align 8
; CHECK-NEXT: [[PB3:%.*]] = getelementptr inbounds double, ptr [[PB0]], i64 9
; CHECK-NEXT: [[S3:%.*]] = load double, ptr [[PB3]], align 8
; CHECK-NEXT: [[DY2:%.*]] = shl i64 [[DY]], 1
; CHECK-NEXT: [[CIDX:%.*]] = add i64 [[CBASE]], [[DY2]]
; CHECK-NEXT: [[PC0:%.*]] = getelementptr inbounds double, ptr [[C]], i64 [[CIDX]]
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x double> poison, double [[S0]], i64 0
; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <2 x double> [[TMP4]], <2 x double> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[TMP6:%.*]] = fmul fast <2 x double> [[TMP0]], [[TMP5]]
; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x double> poison, double [[S1]], i64 0
; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <2 x double> [[TMP7]], <2 x double> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[TMP9:%.*]] = fmul fast <2 x double> [[TMP1]], [[TMP8]]
; CHECK-NEXT: [[TMP10:%.*]] = fadd fast <2 x double> [[TMP9]], [[TMP6]]
; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x double> poison, double [[S2]], i64 0
; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <2 x double> [[TMP11]], <2 x double> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[TMP13:%.*]] = fmul fast <2 x double> [[TMP2]], [[TMP12]]
; CHECK-NEXT: [[TMP14:%.*]] = fadd fast <2 x double> [[TMP13]], [[TMP10]]
; CHECK-NEXT: [[TMP15:%.*]] = insertelement <2 x double> poison, double [[S3]], i64 0
; CHECK-NEXT: [[TMP16:%.*]] = shufflevector <2 x double> [[TMP15]], <2 x double> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[TMP17:%.*]] = fmul fast <2 x double> [[TMP3]], [[TMP16]]
; CHECK-NEXT: [[TMP18:%.*]] = fadd fast <2 x double> [[TMP17]], [[TMP14]]
; CHECK-NEXT: store <2 x double> [[TMP18]], ptr [[PC0]], align 8
; CHECK-NEXT: [[DY_NEXT]] = add nuw nsw i64 [[DY]], 1
; CHECK-NEXT: [[DY_CMP:%.*]] = icmp ult i64 [[DY_NEXT]], 3
; CHECK-NEXT: br i1 [[DY_CMP]], label %[[INNER]], label %[[OUTER_LATCH]]
; CHECK: [[OUTER_LATCH]]:
; CHECK-NEXT: [[QZ_NEXT]] = add nuw nsw i64 [[QZ]], 1
; CHECK-NEXT: [[QZ_CMP:%.*]] = icmp ult i64 [[QZ_NEXT]], 4
; CHECK-NEXT: br i1 [[QZ_CMP]], label %[[OUTER]], label %[[EXIT:.*]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: ret void
;
entry:
br label %outer
outer:
%qz = phi i64 [ 0, %entry ], [ %qz.next, %outer.latch ]
%abase = mul i64 %qz, 12
%pa00 = getelementptr inbounds double, ptr %a, i64 %abase
%a00 = load double, ptr %pa00, align 8
%pa01 = getelementptr inbounds double, ptr %pa00, i64 1
%a01 = load double, ptr %pa01, align 8
%pa10 = getelementptr inbounds double, ptr %pa00, i64 3
%a10 = load double, ptr %pa10, align 8
%pa11 = getelementptr inbounds double, ptr %pa00, i64 4
%a11 = load double, ptr %pa11, align 8
%pa20 = getelementptr inbounds double, ptr %pa00, i64 6
%a20 = load double, ptr %pa20, align 8
%pa21 = getelementptr inbounds double, ptr %pa00, i64 7
%a21 = load double, ptr %pa21, align 8
%pa30 = getelementptr inbounds double, ptr %pa00, i64 9
%a30 = load double, ptr %pa30, align 8
%pa31 = getelementptr inbounds double, ptr %pa00, i64 10
%a31 = load double, ptr %pa31, align 8
%cbase = mul i64 %qz, 6
br label %inner
inner:
%dy = phi i64 [ 0, %outer ], [ %dy.next, %inner ]
%pb0 = getelementptr inbounds double, ptr %b, i64 %dy
%s0 = load double, ptr %pb0, align 8
%pb1 = getelementptr inbounds double, ptr %pb0, i64 3
%s1 = load double, ptr %pb1, align 8
%pb2 = getelementptr inbounds double, ptr %pb0, i64 6
%s2 = load double, ptr %pb2, align 8
%pb3 = getelementptr inbounds double, ptr %pb0, i64 9
%s3 = load double, ptr %pb3, align 8
%m00 = fmul fast double %a00, %s0
%m10 = fmul fast double %a10, %s1
%u10 = fadd fast double %m10, %m00
%m20 = fmul fast double %a20, %s2
%u20 = fadd fast double %m20, %u10
%m30 = fmul fast double %a30, %s3
%u0 = fadd fast double %m30, %u20
%m01 = fmul fast double %a01, %s0
%m11 = fmul fast double %a11, %s1
%u11 = fadd fast double %m11, %m01
%m21 = fmul fast double %a21, %s2
%u21 = fadd fast double %m21, %u11
%m31 = fmul fast double %a31, %s3
%u1 = fadd fast double %m31, %u21
%dy2 = shl i64 %dy, 1
%cidx = add i64 %cbase, %dy2
%pc0 = getelementptr inbounds double, ptr %c, i64 %cidx
store double %u0, ptr %pc0, align 8
%pc1 = getelementptr inbounds double, ptr %pc0, i64 1
store double %u1, ptr %pc1, align 8
%dy.next = add nuw nsw i64 %dy, 1
%dy.cmp = icmp ult i64 %dy.next, 3
br i1 %dy.cmp, label %inner, label %outer.latch
outer.latch:
%qz.next = add nuw nsw i64 %qz, 1
%qz.cmp = icmp ult i64 %qz.next, 4
br i1 %qz.cmp, label %outer, label %exit
exit:
ret void
}