blob: f1aea1f6f4315af78258e1cde3469b1df95b6b5e [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake-avx512 -S < %s | FileCheck %s
declare void @llvm.lifetime.start.p0(ptr captures(none))
declare void @llvm.lifetime.end.p0(ptr captures(none))
declare void @use(ptr)
define void @static_alloca(ptr %dst, ptr %src, i1 %c) {
; CHECK-LABEL: define void @static_alloca(
; CHECK-SAME: ptr [[DST:%.*]], ptr [[SRC:%.*]], i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[DST2:%.*]] = ptrtoaddr ptr [[DST]] to i64
; CHECK-NEXT: [[SRC1:%.*]] = ptrtoaddr ptr [[SRC]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[SRC1]], 64
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[DST2]], 64
; CHECK-NEXT: [[RT_BOUND0:%.*]] = icmp ult i64 [[DST2]], [[TMP0]]
; CHECK-NEXT: [[RT_BOUND1:%.*]] = icmp ult i64 [[SRC1]], [[TMP1]]
; CHECK-NEXT: [[RT_CONFLICT:%.*]] = and i1 [[RT_BOUND0]], [[RT_BOUND1]]
; CHECK-NEXT: [[RT_GUARD:%.*]] = freeze i1 [[RT_CONFLICT]]
; CHECK-NEXT: [[BUF:%.*]] = alloca double, align 8
; CHECK-NEXT: br i1 [[RT_GUARD]], label %[[ENTRY_RTSCALAR:.*]], label %[[ENTRY_RTVEC:.*]], !prof [[PROF0:![0-9]+]]
; CHECK: [[THEN:.*]]:
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[BUF]])
; CHECK-NEXT: ret void
; CHECK: [[ELSE:.*]]:
; CHECK-NEXT: call void @llvm.lifetime.end.p0(ptr [[BUF]])
; CHECK-NEXT: ret void
; CHECK: [[ENTRY_RTVEC]]:
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[BUF]])
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x double>, ptr [[SRC]], align 8
; CHECK-NEXT: [[TMP3:%.*]] = fdiv <4 x double> [[TMP2]], splat (double 3.000000e+00)
; CHECK-NEXT: store <4 x double> [[TMP3]], ptr [[DST]], align 8
; CHECK-NEXT: [[S4:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 4
; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 4
; CHECK-NEXT: [[TMP4:%.*]] = load <4 x double>, ptr [[S4]], align 8
; CHECK-NEXT: [[TMP5:%.*]] = fdiv <4 x double> [[TMP4]], splat (double 3.000000e+00)
; CHECK-NEXT: store <4 x double> [[TMP5]], ptr [[P4]], align 8
; CHECK-NEXT: br label %[[ENTRY_RTCONT:.*]]
; CHECK: [[ENTRY_RTSCALAR]]:
; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[BUF]])
; CHECK-NEXT: [[X0_SCALAR:%.*]] = load double, ptr [[SRC]], align 8
; CHECK-NEXT: [[D0_SCALAR:%.*]] = fdiv double [[X0_SCALAR]], 3.000000e+00
; CHECK-NEXT: store double [[D0_SCALAR]], ptr [[DST]], align 8
; CHECK-NEXT: [[S1_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 1
; CHECK-NEXT: [[X1_SCALAR:%.*]] = load double, ptr [[S1_SCALAR]], align 8
; CHECK-NEXT: [[D1_SCALAR:%.*]] = fdiv double [[X1_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P1_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 1
; CHECK-NEXT: store double [[D1_SCALAR]], ptr [[P1_SCALAR]], align 8
; CHECK-NEXT: [[S2_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 2
; CHECK-NEXT: [[X2_SCALAR:%.*]] = load double, ptr [[S2_SCALAR]], align 8
; CHECK-NEXT: [[D2_SCALAR:%.*]] = fdiv double [[X2_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P2_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 2
; CHECK-NEXT: store double [[D2_SCALAR]], ptr [[P2_SCALAR]], align 8
; CHECK-NEXT: [[S3_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 3
; CHECK-NEXT: [[X3_SCALAR:%.*]] = load double, ptr [[S3_SCALAR]], align 8
; CHECK-NEXT: [[D3_SCALAR:%.*]] = fdiv double [[X3_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P3_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 3
; CHECK-NEXT: store double [[D3_SCALAR]], ptr [[P3_SCALAR]], align 8
; CHECK-NEXT: [[S4_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 4
; CHECK-NEXT: [[X4_SCALAR:%.*]] = load double, ptr [[S4_SCALAR]], align 8
; CHECK-NEXT: [[D4_SCALAR:%.*]] = fdiv double [[X4_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P4_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 4
; CHECK-NEXT: store double [[D4_SCALAR]], ptr [[P4_SCALAR]], align 8
; CHECK-NEXT: [[S5_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 5
; CHECK-NEXT: [[X5_SCALAR:%.*]] = load double, ptr [[S5_SCALAR]], align 8
; CHECK-NEXT: [[D5_SCALAR:%.*]] = fdiv double [[X5_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P5_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 5
; CHECK-NEXT: store double [[D5_SCALAR]], ptr [[P5_SCALAR]], align 8
; CHECK-NEXT: [[S6_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 6
; CHECK-NEXT: [[X6_SCALAR:%.*]] = load double, ptr [[S6_SCALAR]], align 8
; CHECK-NEXT: [[D6_SCALAR:%.*]] = fdiv double [[X6_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P6_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 6
; CHECK-NEXT: store double [[D6_SCALAR]], ptr [[P6_SCALAR]], align 8
; CHECK-NEXT: [[S7_SCALAR:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 7
; CHECK-NEXT: [[X7_SCALAR:%.*]] = load double, ptr [[S7_SCALAR]], align 8
; CHECK-NEXT: [[D7_SCALAR:%.*]] = fdiv double [[X7_SCALAR]], 3.000000e+00
; CHECK-NEXT: [[P7_SCALAR:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 7
; CHECK-NEXT: store double [[D7_SCALAR]], ptr [[P7_SCALAR]], align 8
; CHECK-NEXT: br label %[[ENTRY_RTCONT]]
; CHECK: [[ENTRY_RTCONT]]:
; CHECK-NEXT: br i1 [[C]], label %[[THEN]], label %[[ELSE]]
;
entry:
%buf = alloca double, align 8
call void @llvm.lifetime.start.p0(ptr %buf)
%x0 = load double, ptr %src, align 8
%d0 = fdiv double %x0, 3.0
store double %d0, ptr %dst, align 8
%s1 = getelementptr inbounds double, ptr %src, i64 1
%x1 = load double, ptr %s1, align 8
%d1 = fdiv double %x1, 3.0
%p1 = getelementptr inbounds double, ptr %dst, i64 1
store double %d1, ptr %p1, align 8
%s2 = getelementptr inbounds double, ptr %src, i64 2
%x2 = load double, ptr %s2, align 8
%d2 = fdiv double %x2, 3.0
%p2 = getelementptr inbounds double, ptr %dst, i64 2
store double %d2, ptr %p2, align 8
%s3 = getelementptr inbounds double, ptr %src, i64 3
%x3 = load double, ptr %s3, align 8
%d3 = fdiv double %x3, 3.0
%p3 = getelementptr inbounds double, ptr %dst, i64 3
store double %d3, ptr %p3, align 8
%s4 = getelementptr inbounds double, ptr %src, i64 4
%x4 = load double, ptr %s4, align 8
%d4 = fdiv double %x4, 3.0
%p4 = getelementptr inbounds double, ptr %dst, i64 4
store double %d4, ptr %p4, align 8
%s5 = getelementptr inbounds double, ptr %src, i64 5
%x5 = load double, ptr %s5, align 8
%d5 = fdiv double %x5, 3.0
%p5 = getelementptr inbounds double, ptr %dst, i64 5
store double %d5, ptr %p5, align 8
%s6 = getelementptr inbounds double, ptr %src, i64 6
%x6 = load double, ptr %s6, align 8
%d6 = fdiv double %x6, 3.0
%p6 = getelementptr inbounds double, ptr %dst, i64 6
store double %d6, ptr %p6, align 8
%s7 = getelementptr inbounds double, ptr %src, i64 7
%x7 = load double, ptr %s7, align 8
%d7 = fdiv double %x7, 3.0
%p7 = getelementptr inbounds double, ptr %dst, i64 7
store double %d7, ptr %p7, align 8
br i1 %c, label %then, label %else
then:
call void @llvm.lifetime.end.p0(ptr %buf)
ret void
else:
call void @llvm.lifetime.end.p0(ptr %buf)
ret void
}
define void @dynamic_alloca(ptr %dst, ptr %src, ptr %z, i1 %c) {
; CHECK-LABEL: define void @dynamic_alloca(
; CHECK-SAME: ptr [[DST:%.*]], ptr [[SRC:%.*]], ptr [[Z:%.*]], i1 [[C:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[N:%.*]] = load i64, ptr [[Z]], align 8
; CHECK-NEXT: [[VLA:%.*]] = alloca double, i64 [[N]], align 8
; CHECK-NEXT: [[X0:%.*]] = load double, ptr [[SRC]], align 8
; CHECK-NEXT: [[D0:%.*]] = fdiv double [[X0]], 3.000000e+00
; CHECK-NEXT: store double [[D0]], ptr [[DST]], align 8
; CHECK-NEXT: [[S1:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 1
; CHECK-NEXT: [[X1:%.*]] = load double, ptr [[S1]], align 8
; CHECK-NEXT: [[D1:%.*]] = fdiv double [[X1]], 3.000000e+00
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 1
; CHECK-NEXT: store double [[D1]], ptr [[P1]], align 8
; CHECK-NEXT: [[S2:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 2
; CHECK-NEXT: [[X2:%.*]] = load double, ptr [[S2]], align 8
; CHECK-NEXT: [[D2:%.*]] = fdiv double [[X2]], 3.000000e+00
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 2
; CHECK-NEXT: store double [[D2]], ptr [[P2]], align 8
; CHECK-NEXT: [[S3:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 3
; CHECK-NEXT: [[X3:%.*]] = load double, ptr [[S3]], align 8
; CHECK-NEXT: [[D3:%.*]] = fdiv double [[X3]], 3.000000e+00
; CHECK-NEXT: [[P3:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 3
; CHECK-NEXT: store double [[D3]], ptr [[P3]], align 8
; CHECK-NEXT: [[S4:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 4
; CHECK-NEXT: [[X4:%.*]] = load double, ptr [[S4]], align 8
; CHECK-NEXT: [[D4:%.*]] = fdiv double [[X4]], 3.000000e+00
; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 4
; CHECK-NEXT: store double [[D4]], ptr [[P4]], align 8
; CHECK-NEXT: [[S5:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 5
; CHECK-NEXT: [[X5:%.*]] = load double, ptr [[S5]], align 8
; CHECK-NEXT: [[D5:%.*]] = fdiv double [[X5]], 3.000000e+00
; CHECK-NEXT: [[P5:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 5
; CHECK-NEXT: store double [[D5]], ptr [[P5]], align 8
; CHECK-NEXT: [[S6:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 6
; CHECK-NEXT: [[X6:%.*]] = load double, ptr [[S6]], align 8
; CHECK-NEXT: [[D6:%.*]] = fdiv double [[X6]], 3.000000e+00
; CHECK-NEXT: [[P6:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 6
; CHECK-NEXT: store double [[D6]], ptr [[P6]], align 8
; CHECK-NEXT: [[S7:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 7
; CHECK-NEXT: [[X7:%.*]] = load double, ptr [[S7]], align 8
; CHECK-NEXT: [[D7:%.*]] = fdiv double [[X7]], 3.000000e+00
; CHECK-NEXT: [[P7:%.*]] = getelementptr inbounds double, ptr [[DST]], i64 7
; CHECK-NEXT: store double [[D7]], ptr [[P7]], align 8
; CHECK-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @use(ptr [[VLA]])
; CHECK-NEXT: ret void
; CHECK: [[ELSE]]:
; CHECK-NEXT: ret void
;
entry:
%n = load i64, ptr %z, align 8
%vla = alloca double, i64 %n, align 8
%x0 = load double, ptr %src, align 8
%d0 = fdiv double %x0, 3.0
store double %d0, ptr %dst, align 8
%s1 = getelementptr inbounds double, ptr %src, i64 1
%x1 = load double, ptr %s1, align 8
%d1 = fdiv double %x1, 3.0
%p1 = getelementptr inbounds double, ptr %dst, i64 1
store double %d1, ptr %p1, align 8
%s2 = getelementptr inbounds double, ptr %src, i64 2
%x2 = load double, ptr %s2, align 8
%d2 = fdiv double %x2, 3.0
%p2 = getelementptr inbounds double, ptr %dst, i64 2
store double %d2, ptr %p2, align 8
%s3 = getelementptr inbounds double, ptr %src, i64 3
%x3 = load double, ptr %s3, align 8
%d3 = fdiv double %x3, 3.0
%p3 = getelementptr inbounds double, ptr %dst, i64 3
store double %d3, ptr %p3, align 8
%s4 = getelementptr inbounds double, ptr %src, i64 4
%x4 = load double, ptr %s4, align 8
%d4 = fdiv double %x4, 3.0
%p4 = getelementptr inbounds double, ptr %dst, i64 4
store double %d4, ptr %p4, align 8
%s5 = getelementptr inbounds double, ptr %src, i64 5
%x5 = load double, ptr %s5, align 8
%d5 = fdiv double %x5, 3.0
%p5 = getelementptr inbounds double, ptr %dst, i64 5
store double %d5, ptr %p5, align 8
%s6 = getelementptr inbounds double, ptr %src, i64 6
%x6 = load double, ptr %s6, align 8
%d6 = fdiv double %x6, 3.0
%p6 = getelementptr inbounds double, ptr %dst, i64 6
store double %d6, ptr %p6, align 8
%s7 = getelementptr inbounds double, ptr %src, i64 7
%x7 = load double, ptr %s7, align 8
%d7 = fdiv double %x7, 3.0
%p7 = getelementptr inbounds double, ptr %dst, i64 7
store double %d7, ptr %p7, align 8
br i1 %c, label %then, label %else
then:
call void @use(ptr %vla)
ret void
else:
ret void
}
;.
; CHECK: [[PROF0]] = !{!"branch_weights", i32 1, i32 1048575}
;.