Loop peeling removes conditions from loop bodies that become invariant
after a small number of iterations. When triggered, this leads to fewer
compares and possibly PHIs in loop bodies, enabling further
optimizations. The current cost-model of loop peeling should be quite
conservative/safe, i.e. only peel if a condition in the loop becomes
known after peeling.
For example, see PR47671, where loop peeling enables vectorization by
removing a PHI the vectorizer does not understand. Granted, the
loop-vectorizer could also be taught about constant PHIs, but loop
peeling is likely to enable other optimizations as well.
This has an impact on quite a few benchmarks from
MultiSource/SPEC2000/SPEC2006 on X86 with -O3 -flto, for example
Same hash: 186 (filtered out)
Remaining: 51
Metric: loop-vectorize.LoopsVectorized
Program base patch diff
test-suite...ve-susan/automotive-susan.test 8.00 9.00 12.5%
test-suite...nal/skidmarks10/skidmarks.test 35.00 31.00 -11.4%
test-suite...lications/sqlite3/sqlite3.test 41.00 43.00 4.9%
test-suite...s/ASC_Sequoia/AMGmk/AMGmk.test 25.00 26.00 4.0%
test-suite...006/450.soplex/450.soplex.test 88.00 89.00 1.1%
test-suite...TimberWolfMC/timberwolfmc.test 120.00 119.00 -0.8%
test-suite.../CINT2006/403.gcc/403.gcc.test 215.00 216.00 0.5%
test-suite...006/447.dealII/447.dealII.test 957.00 958.00 0.1%
test-suite...ternal/HMMER/hmmcalibrate.test 75.00 75.00 0.0%
Same hash: 186 (filtered out)
Remaining: 51
Metric: loop-vectorize.LoopsAnalyzed
Program base patch diff
test-suite...ks/Prolangs-C/agrep/agrep.test 440.00 434.00 -1.4%
test-suite...nal/skidmarks10/skidmarks.test 312.00 308.00 -1.3%
test-suite...marks/7zip/7zip-benchmark.test 6399.00 6323.00 -1.2%
test-suite...lications/minisat/minisat.test 134.00 135.00 0.7%
test-suite...rks/FreeBench/pifft/pifft.test 295.00 297.00 0.7%
test-suite...TimberWolfMC/timberwolfmc.test 1879.00 1869.00 -0.5%
test-suite...pplications/treecc/treecc.test 689.00 691.00 0.3%
test-suite...T2000/300.twolf/300.twolf.test 1593.00 1597.00 0.3%
test-suite.../Benchmarks/Bullet/bullet.test 1394.00 1392.00 -0.1%
test-suite...ications/JM/ldecod/ldecod.test 1431.00 1429.00 -0.1%
test-suite...6/464.h264ref/464.h264ref.test 2229.00 2230.00 0.0%
test-suite...lications/sqlite3/sqlite3.test 2590.00 2589.00 -0.0%
test-suite...ications/JM/lencod/lencod.test 2732.00 2733.00 0.0%
test-suite...006/453.povray/453.povray.test 3395.00 3394.00 -0.0%
Note the -11% regression in number of loops vectorized for skidmarks. I
suspect this corresponds to the fact that those loops are gone now (see
the reduction in number of loops analyzed by LV).
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D88471
45 lines
1.3 KiB
LLVM
45 lines
1.3 KiB
LLVM
; RUN: opt -O2 -S %s | FileCheck %s
|
|
; RUN: opt -passes='default<O2>' -S %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-apple-macosx"
|
|
|
|
; The loop below needs to be peeled first to eliminate the constant PHI %first
|
|
; before loop vectorization.
|
|
;
|
|
; Test case from PR47671.
|
|
|
|
define i32 @test(i32* readonly %p, i32* readnone %q) {
|
|
; CHECK-LABEL: define i32 @test(
|
|
; CHECK: vector.body:
|
|
; CHECK: %index.next = add i64 %index, 8
|
|
; CHECK: middle.block:
|
|
;
|
|
entry:
|
|
%cmp.not7 = icmp eq i32* %p, %q
|
|
br i1 %cmp.not7, label %exit, label %loop.ph
|
|
|
|
loop.ph:
|
|
br label %loop
|
|
|
|
loop:
|
|
%sum = phi i32 [ %sum.next, %loop ], [ 0, %loop.ph ]
|
|
%first = phi i1 [ false, %loop ], [ true, %loop.ph ]
|
|
%iv = phi i32* [ %iv.next, %loop ], [ %p, %loop.ph ]
|
|
%add = add nsw i32 %sum, 2
|
|
%spec.select = select i1 %first, i32 %sum, i32 %add
|
|
%lv = load i32, i32* %iv, align 4
|
|
%sum.next = add nsw i32 %lv, %spec.select
|
|
%iv.next = getelementptr inbounds i32, i32* %iv, i64 1
|
|
%cmp.not = icmp eq i32* %iv.next, %q
|
|
br i1 %cmp.not, label %loopexit, label %loop
|
|
|
|
loopexit:
|
|
%sum.next.lcssa = phi i32 [ %sum.next, %loop ]
|
|
br label %exit
|
|
|
|
exit:
|
|
%sum.0.lcssa = phi i32 [ 0, %entry ], [ %sum.next.lcssa, %loopexit ]
|
|
ret i32 %sum.0.lcssa
|
|
}
|