[llvm] bf21ce7 - [InstCombine] Take 3: Perform trivial PHI CSE

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon May 17 15:15:58 PDT 2021


Hi

> On Aug 29, 2020, at 16:24, Roman Lebedev via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> 
> 
> Author: Roman Lebedev
> Date: 2020-08-29T18:21:24+03:00
> New Revision: bf21ce7b908e16db76f5704714ee83e61a9da95b
> 
> URL: https://github.com/llvm/llvm-project/commit/bf21ce7b908e16db76f5704714ee83e61a9da95b
> DIFF: https://github.com/llvm/llvm-project/commit/bf21ce7b908e16db76f5704714ee83e61a9da95b.diff
> 
> LOG: [InstCombine] Take 3: Perform trivial PHI CSE
> 
> The original take 1 was 6102310d814ad73eab60a88b21dd70874f7a056f,
> which taught InstSimplify to do that, which seemed better at time,
> since we got EarlyCSE support for free.
> 
> However, it was proven that we can not do that there,
> the simplified-to PHI would not be reachable from the original PHI,
> and that is not something InstSimplify is allowed to do,
> as noted in the commit ed90f15efb40d26b5d3ead3bb8e9e284218e0186
> that reverted it:
>> It appears to cause compilation non-determinism and caused stage3 mismatches.
> 
> Then there was take 2 3e69871ab5a66fb55913a2a2f5e7f5b42899a4c9,
> which was InstCombine-specific, but it again showed stage2-stage3 differences,
> and reverted in bdaa3f86a040b138c58de41d73d35b76fdec1380.
> This is quite alarming.
> 
> Here, let's try to change how we find existing PHI candidate:
> due to the worklist order, and the way PHI nodes are inserted
> (it may be inserted as the first one, or maybe not), let's look at *all*
> PHI nodes in the block.


Unfortunately I think this approach does not really seem to scale well for blocks which have a huge number of phis (in the order of tens of thousands). In such cases we do a lot of redundant work with no real way to cache it in instcombine :(


Below is a script to reproduce the compile time explosion using something like

for i in seq 4000 2000 20000; do echo $i; python genphis.py $i | time bin/opt -instcombine -o /dev/null; done


import sys

def main():
    if len(sys.argv) < 2:
        print 'Use: genphis.py N'
    N = int(sys.argv[1])
    print """\
define void @foo() {
entry:"""
    for i in range(N):
        print """\
  %a{0} = inttoptr i64 {0} to i64*
  %b{0} = load i64, i64* %a{0}, align 8""".format(i)
    print """\
  br label %for.body
for.body:"""
    for i in range(N):
        print '  %x{0} = phi i64 [ %z{0}, %for.body ], [ %b{0}, %entry ]'.format(i)
    for i in range(N):
        print """\
  %y{0} = inttoptr i64 %x{0} to i32*
  %z{0} = ptrtoint i32* %y{0} to i64
  %q{0} = load i32, i32* %y{0}, align 4
  %r{0} = mul i32 %q{0}, {0}""".format(i)
    print """\
  br i1 undef, label %for.body, label %for.end

for.end:                                          ; preds = %for.body, %entry
  ret void
}
"""

if __name__ == '__main__':
    main()


More information about the llvm-commits mailing list