| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s |
| |
| ; Tests for store chains containing both scalar stores and a build-vector store |
| ; at adjacent addresses. The CHECK lines below capture current SLP behavior, |
| ; which leaves the build-vector store unchanged and packs the surrounding |
| ; scalars into a narrower mix. A follow-up patch updates these checks to |
| ; retile the chains as full vector stores. |
| |
| define void @buildvector_store_middle(ptr %p, float %a0, float %a1, float %a2, float %a3, float %a4, float %a5, float %a6, float %a7) { |
| ; CHECK-LABEL: define void @buildvector_store_middle( |
| ; CHECK-SAME: ptr [[P:%.*]], float [[A0:%.*]], float [[A1:%.*]], float [[A2:%.*]], float [[A3:%.*]], float [[A4:%.*]], float [[A5:%.*]], float [[A6:%.*]], float [[A7:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x float> poison, float [[A0]], i32 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[A1]], i32 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = fadd <2 x float> [[TMP1]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: [[V2:%.*]] = fadd float [[A2]], 1.000000e+00 |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> poison, float [[A3]], i32 0 |
| ; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x float> [[TMP3]], float [[A4]], i32 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP4]], float [[A5]], i32 2 |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[A6]], i32 3 |
| ; CHECK-NEXT: [[TMP7:%.*]] = fadd <4 x float> [[TMP6]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: [[V7:%.*]] = fadd float [[A7]], 1.000000e+00 |
| ; CHECK-NEXT: store <2 x float> [[TMP2]], ptr [[P]], align 4 |
| ; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds float, ptr [[P]], i64 2 |
| ; CHECK-NEXT: store float [[V2]], ptr [[P2]], align 4 |
| ; CHECK-NEXT: [[P3:%.*]] = getelementptr inbounds float, ptr [[P]], i64 3 |
| ; CHECK-NEXT: store <4 x float> [[TMP7]], ptr [[P3]], align 4 |
| ; CHECK-NEXT: [[P7:%.*]] = getelementptr inbounds float, ptr [[P]], i64 7 |
| ; CHECK-NEXT: store float [[V7]], ptr [[P7]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %v0 = fadd float %a0, 1.000000e+00 |
| %v1 = fadd float %a1, 1.000000e+00 |
| %v2 = fadd float %a2, 1.000000e+00 |
| %v3 = fadd float %a3, 1.000000e+00 |
| %v4 = fadd float %a4, 1.000000e+00 |
| %v5 = fadd float %a5, 1.000000e+00 |
| %v6 = fadd float %a6, 1.000000e+00 |
| %v7 = fadd float %a7, 1.000000e+00 |
| store float %v0, ptr %p, align 4 |
| %p1 = getelementptr inbounds float, ptr %p, i64 1 |
| store float %v1, ptr %p1, align 4 |
| %p2 = getelementptr inbounds float, ptr %p, i64 2 |
| store float %v2, ptr %p2, align 4 |
| %p3 = getelementptr inbounds float, ptr %p, i64 3 |
| %b0 = insertelement <4 x float> poison, float %v3, i32 0 |
| %b1 = insertelement <4 x float> %b0, float %v4, i32 1 |
| %b2 = insertelement <4 x float> %b1, float %v5, i32 2 |
| %b3 = insertelement <4 x float> %b2, float %v6, i32 3 |
| store <4 x float> %b3, ptr %p3, align 4 |
| %p7 = getelementptr inbounds float, ptr %p, i64 7 |
| store float %v7, ptr %p7, align 4 |
| ret void |
| } |
| |
| define void @buildvector_store_start(ptr %p, float %a0, float %a1, float %a2, float %a3, float %a4, float %a5, float %a6, float %a7) { |
| ; CHECK-LABEL: define void @buildvector_store_start( |
| ; CHECK-SAME: ptr [[P:%.*]], float [[A0:%.*]], float [[A1:%.*]], float [[A2:%.*]], float [[A3:%.*]], float [[A4:%.*]], float [[A5:%.*]], float [[A6:%.*]], float [[A7:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x float> poison, float [[A0]], i32 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> [[TMP0]], float [[A1]], i32 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x float> [[TMP1]], float [[A2]], i32 2 |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> [[TMP2]], float [[A3]], i32 3 |
| ; CHECK-NEXT: [[TMP4:%.*]] = fadd <4 x float> [[TMP3]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> poison, float [[A4]], i32 0 |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[A5]], i32 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x float> [[TMP6]], float [[A6]], i32 2 |
| ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x float> [[TMP7]], float [[A7]], i32 3 |
| ; CHECK-NEXT: [[TMP9:%.*]] = fadd <4 x float> [[TMP8]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: store <4 x float> [[TMP4]], ptr [[P]], align 4 |
| ; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds float, ptr [[P]], i64 4 |
| ; CHECK-NEXT: store <4 x float> [[TMP9]], ptr [[P4]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %v0 = fadd float %a0, 1.000000e+00 |
| %v1 = fadd float %a1, 1.000000e+00 |
| %v2 = fadd float %a2, 1.000000e+00 |
| %v3 = fadd float %a3, 1.000000e+00 |
| %v4 = fadd float %a4, 1.000000e+00 |
| %v5 = fadd float %a5, 1.000000e+00 |
| %v6 = fadd float %a6, 1.000000e+00 |
| %v7 = fadd float %a7, 1.000000e+00 |
| %b0 = insertelement <4 x float> poison, float %v0, i32 0 |
| %b1 = insertelement <4 x float> %b0, float %v1, i32 1 |
| %b2 = insertelement <4 x float> %b1, float %v2, i32 2 |
| %b3 = insertelement <4 x float> %b2, float %v3, i32 3 |
| store <4 x float> %b3, ptr %p, align 4 |
| %p4 = getelementptr inbounds float, ptr %p, i64 4 |
| store float %v4, ptr %p4, align 4 |
| %p5 = getelementptr inbounds float, ptr %p, i64 5 |
| store float %v5, ptr %p5, align 4 |
| %p6 = getelementptr inbounds float, ptr %p, i64 6 |
| store float %v6, ptr %p6, align 4 |
| %p7 = getelementptr inbounds float, ptr %p, i64 7 |
| store float %v7, ptr %p7, align 4 |
| ret void |
| } |
| |
| define void @buildvector_store_end(ptr %p, float %a0, float %a1, float %a2, float %a3, float %a4, float %a5, float %a6, float %a7) { |
| ; CHECK-LABEL: define void @buildvector_store_end( |
| ; CHECK-SAME: ptr [[P:%.*]], float [[A0:%.*]], float [[A1:%.*]], float [[A2:%.*]], float [[A3:%.*]], float [[A4:%.*]], float [[A5:%.*]], float [[A6:%.*]], float [[A7:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x float> poison, float [[A0]], i32 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x float> [[TMP0]], float [[A1]], i32 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x float> [[TMP1]], float [[A2]], i32 2 |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> [[TMP2]], float [[A3]], i32 3 |
| ; CHECK-NEXT: [[TMP4:%.*]] = fadd <4 x float> [[TMP3]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> poison, float [[A4]], i32 0 |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[A5]], i32 1 |
| ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x float> [[TMP6]], float [[A6]], i32 2 |
| ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <4 x float> [[TMP7]], float [[A7]], i32 3 |
| ; CHECK-NEXT: [[TMP9:%.*]] = fadd <4 x float> [[TMP8]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: store <4 x float> [[TMP4]], ptr [[P]], align 4 |
| ; CHECK-NEXT: [[P4:%.*]] = getelementptr inbounds float, ptr [[P]], i64 4 |
| ; CHECK-NEXT: store <4 x float> [[TMP9]], ptr [[P4]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %v0 = fadd float %a0, 1.000000e+00 |
| %v1 = fadd float %a1, 1.000000e+00 |
| %v2 = fadd float %a2, 1.000000e+00 |
| %v3 = fadd float %a3, 1.000000e+00 |
| %v4 = fadd float %a4, 1.000000e+00 |
| %v5 = fadd float %a5, 1.000000e+00 |
| %v6 = fadd float %a6, 1.000000e+00 |
| %v7 = fadd float %a7, 1.000000e+00 |
| store float %v0, ptr %p, align 4 |
| %p1 = getelementptr inbounds float, ptr %p, i64 1 |
| store float %v1, ptr %p1, align 4 |
| %p2 = getelementptr inbounds float, ptr %p, i64 2 |
| store float %v2, ptr %p2, align 4 |
| %p3 = getelementptr inbounds float, ptr %p, i64 3 |
| store float %v3, ptr %p3, align 4 |
| %p4 = getelementptr inbounds float, ptr %p, i64 4 |
| %b0 = insertelement <4 x float> poison, float %v4, i32 0 |
| %b1 = insertelement <4 x float> %b0, float %v5, i32 1 |
| %b2 = insertelement <4 x float> %b1, float %v6, i32 2 |
| %b3 = insertelement <4 x float> %b2, float %v7, i32 3 |
| store <4 x float> %b3, ptr %p4, align 4 |
| ret void |
| } |
| |
| define void @buildvector_store_duplicate_offset(ptr %p, float %a0, float %a1, float %a2, float %a3, float %a4, float %a5, float %a6, float %a7) { |
| ; CHECK-LABEL: define void @buildvector_store_duplicate_offset( |
| ; CHECK-SAME: ptr [[P:%.*]], float [[A0:%.*]], float [[A1:%.*]], float [[A2:%.*]], float [[A3:%.*]], float [[A4:%.*]], float [[A5:%.*]], float [[A6:%.*]], float [[A7:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x float> poison, float [[A0]], i32 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[A1]], i32 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = fadd <2 x float> [[TMP1]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: [[V2:%.*]] = fadd float [[A2]], 1.000000e+00 |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x float> poison, float [[A3]], i32 0 |
| ; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x float> [[TMP3]], float [[A4]], i32 1 |
| ; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x float> [[TMP4]], float [[A5]], i32 2 |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <4 x float> [[TMP5]], float [[A6]], i32 3 |
| ; CHECK-NEXT: [[TMP7:%.*]] = fadd <4 x float> [[TMP6]], splat (float 1.000000e+00) |
| ; CHECK-NEXT: [[V7:%.*]] = fadd float [[A7]], 1.000000e+00 |
| ; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds float, ptr [[P]], i64 1 |
| ; CHECK-NEXT: store <2 x float> [[TMP2]], ptr [[P]], align 4 |
| ; CHECK-NEXT: store float [[V2]], ptr [[P1]], align 4 |
| ; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds float, ptr [[P]], i64 2 |
| ; CHECK-NEXT: store <4 x float> [[TMP7]], ptr [[P2]], align 4 |
| ; CHECK-NEXT: [[P6:%.*]] = getelementptr inbounds float, ptr [[P]], i64 6 |
| ; CHECK-NEXT: store float [[V7]], ptr [[P6]], align 4 |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %v0 = fadd float %a0, 1.000000e+00 |
| %v1 = fadd float %a1, 1.000000e+00 |
| %v2 = fadd float %a2, 1.000000e+00 |
| %v3 = fadd float %a3, 1.000000e+00 |
| %v4 = fadd float %a4, 1.000000e+00 |
| %v5 = fadd float %a5, 1.000000e+00 |
| %v6 = fadd float %a6, 1.000000e+00 |
| %v7 = fadd float %a7, 1.000000e+00 |
| store float %v0, ptr %p, align 4 |
| %p1 = getelementptr inbounds float, ptr %p, i64 1 |
| store float %v1, ptr %p1, align 4 |
| store float %v2, ptr %p1, align 4 |
| %p2 = getelementptr inbounds float, ptr %p, i64 2 |
| %b0 = insertelement <4 x float> poison, float %v3, i32 0 |
| %b1 = insertelement <4 x float> %b0, float %v4, i32 1 |
| %b2 = insertelement <4 x float> %b1, float %v5, i32 2 |
| %b3 = insertelement <4 x float> %b2, float %v6, i32 3 |
| store <4 x float> %b3, ptr %p2, align 4 |
| %p6 = getelementptr inbounds float, ptr %p, i64 6 |
| store float %v7, ptr %p6, align 4 |
| ret void |
| } |