| ; 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} | |
| ;. |