| ; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "^vector.ph:" --version 6 |
| ; RUN: opt -passes=loop-vectorize -enable-vplan-native-path -force-vector-width=4 -vplan-print-after=printOptimizedVPlan -disable-output %s 2>&1 | FileCheck %s --check-prefix=OPTIMIZED |
| ; RUN: opt -passes=loop-vectorize -enable-vplan-native-path -force-vector-width=4 -vplan-print-after=printFinalVPlan -disable-output %s 2>&1 | FileCheck %s --check-prefix=FINAL |
| |
| ; The store may alias the load, but the memory both access over the whole nest |
| ; can be bounded. |
| define void @may_alias_load(ptr %A, ptr %B, i64 %N, i64 %M) { |
| ; OPTIMIZED-LABEL: VPlan for loop in 'may_alias_load' |
| ; OPTIMIZED: VPlan ' for VF={4},UF>=1' { |
| ; OPTIMIZED-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF |
| ; OPTIMIZED-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF |
| ; OPTIMIZED-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count |
| ; OPTIMIZED-NEXT: Live-in ir<%N> = original trip-count |
| ; OPTIMIZED-EMPTY: |
| ; OPTIMIZED-NEXT: ir-bb<entry>: |
| ; OPTIMIZED-NEXT: Successor(s): scalar.ph, vector.ph |
| ; OPTIMIZED-EMPTY: |
| ; OPTIMIZED-NEXT: vector.ph: |
| ; |
| ; FINAL-LABEL: VPlan for loop in 'may_alias_load' |
| ; FINAL: VPlan 'Final VPlan for VF={4},UF={1}' { |
| ; FINAL-NEXT: Live-in ir<%N> = original trip-count |
| ; FINAL-EMPTY: |
| ; FINAL-NEXT: ir-bb<entry>: |
| ; FINAL-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%N>, ir<4> |
| ; FINAL-NEXT: EMIT branch-on-cond vp<%min.iters.check> |
| ; FINAL-NEXT: Successor(s): ir-bb<scalar.ph>, vector.ph |
| ; FINAL-EMPTY: |
| ; FINAL-NEXT: vector.ph: |
| ; |
| entry: |
| br label %outer.header |
| |
| outer.header: |
| %outer.iv = phi i64 [ 0, %entry ], [ %outer.iv.next, %outer.latch ] |
| %outer.iv.mul.M = mul nsw i64 %outer.iv, %M |
| br label %inner.body |
| |
| inner.body: |
| %inner.iv = phi i64 [ 0, %outer.header ], [ %inner.iv.next, %inner.body ] |
| %sum = phi float [ 0.000000e+00, %outer.header ], [ %sum.next, %inner.body ] |
| %idx = add nsw i64 %outer.iv.mul.M, %inner.iv |
| %A.ptr = getelementptr inbounds float, ptr %A, i64 %idx |
| %A.val = load float, ptr %A.ptr, align 4 |
| %sum.next = fadd float %sum, %A.val |
| %inner.iv.next = add nuw nsw i64 %inner.iv, 1 |
| %inner.iv.cmp = icmp eq i64 %inner.iv.next, %M |
| br i1 %inner.iv.cmp, label %outer.latch, label %inner.body |
| |
| outer.latch: |
| %B.ptr = getelementptr inbounds float, ptr %B, i64 %outer.iv |
| store float %sum.next, ptr %B.ptr, align 4 |
| %outer.iv.next = add nuw nsw i64 %outer.iv, 1 |
| %outer.iv.cmp = icmp eq i64 %outer.iv.next, %N |
| br i1 %outer.iv.cmp, label %exit, label %outer.header, !llvm.loop !0 |
| |
| exit: |
| ret void |
| } |
| |
| !0 = distinct !{!0, !1} |
| !1 = !{!"llvm.loop.vectorize.enable"} |