Llvm-reduce: short/medium-term directions

llvm-reduce has come a long way this summer! it’s getting really good. @arsenm and @aeubanks have done a bunch of great work.

I wanted to start a discussion and see if people have ideas about where to take this tool in the nearish future. I’ll get started by listing some improvements I was thinking about contributing.

these are some overall improvements to llvm-reduce:

  • I’d like to add a command line option that causes us to do the transformation part of the delta loop in a sub-process, so if a transformation crashes (this happens and it’s super annoying) it doesn’t take out the entire llvm-reduce
  • it would be nice to have some bugpoint-like reduction/attribution for arbitrary middle-end pipelines
  • it might be cool to optimize the order in which the reduction passes execute, though I think the ordering is pretty decent already
  • let’s keep removing crashes and places where we create invalid IR. we should add --abort-on-invalid-reduction to all test cases and perhaps do some focused testing where we run each individual pass on full-size inputs (some of the later passes live a very sheltered life in the default pipeline because earlier passes tend to do a very good job getting rid of a lot of IR)

and some enhancements to specific delta passes:

  • we already call some middle-end optimizer code in a fine-grained way; for example calling InstSimplify on individual instructions and SimplifyCFG on individual basic blocks. it seems like there might be a few more passes such as SROA where we should do this.
  • try to reduce switch instructions by removing individual cases, and by turning the entire switch into an unconditional branch to the default target
  • try to remove nsw, nuw, and friends from instructions, expand “fast” into its sub-flags and then try to get rid of those too
  • try harder to get rid of loads and stores (I don’t have specific ideas yet, other than leaning on SROA)
7 Likes

Just FYI, but the Archives category is not meant to start new topics. I think this should be moved to LLVM subprojects. I can either move it, or you can. I would also tag with llvm-reduce.

1 Like

thanks Tanya, I’m still figuring out discourse :grimacing:, I would be very happy for you to make whatever changes are appropriate

I randomly had the idea that for passes that only apply within one function, we do a sort of “function pass manager” thing where we work on each function individually rather than on all functions at once. That might speed up some of the passes.

1 Like

sounds promising!

A few reductions I want:

  • Sink instructions down to uses. This can be finer grained than the sink pass with fewer semantic restrictions

  • Reduce / remove sync scopes and memory ordering on atomics, eventually making them nonatomic

  • Remove volatiles from memory instructions

  • Replace calls with small, uniform numbers of arguments with a similar intrinsic that won’t codegen to a call

  • Add protected and internal to globals

  • Force generic address space pointers to global (AMDGPU specific)

  • Reduce uses of struct values so the number of fields in struct types can be reduced

2 Likes

I’d also like it it reported some statistics about time taken per reduction, and number of instructions etc. reduced

3 Likes

One thing that would be interesting, although I’m not sure how it would work just yet would be to reduce something down that instead of crashing the compiler uses a large number of downstream resources. An example would be something like high register pressure and reduce it down while keeping the total number of registers used the same. It’s possible this could be done in the interesting-ness test although how is not readily apparent.

it’s not so much that this could be done in the interestingness test, it’s that it has to be done in the interestingness test. llvm-reduce has to remain agnostic about what you care about, that’s just how this sort of thing works.

@regehr if possible could you please provide some example test case where transformation crashes llvm-reduce?

I have never been able to successfully use llvm-reduce. The few times I tried, the tool would die with some internal error about the “interestingness test is no longer interesting”, and would result in the reduction producing an empty file.

So the tool needs to be more robust, from my experience.

I’ll post an issue next time I run across this, I’ve been seeing it happen lately. shall I tag you in the issue?

I guess we’d need more info about the circumstances in which this is happening, ideally with a reproducer of some sort

1 Like

Yes, please tag me, I do have a few bugs on my backlog I could use it on.

There is already a bug on the issue tracker: Re-enable llvm-reduce bitcode-uselistorder.ll test · Issue #64157 · llvm/llvm-project · GitHub

I vaguely remember from previous posts and conversations that @aeubanks and/or @arsenm might have an idea what is going on here, but don’t have the bandwidth to follow.

1 Like

Yes please do tag me :pray:

@arsenm 1, 5 and 6 does not seem like a reduction and they feel optimizations. Could you please elaborate more?

There is a bug where it occurs, but this assertion is also invalid in the case of flaky tests.

There is substantial overlap and no real distinction between “reductions” and “optimizations”. Reductions are just optimizations with no requirements on correctness. It’s easier to follow code where the use immediately follows the def, rather than having to chase it. Plus I’m usually reducing codegen issues, and it’s nicer when all the operations are clustered together in the same block.

5 and 6 also produce smaller codegen

1 Like

perhaps we could reuse optimizations directly for reductions, rather than reimplementing them? Or do the reduction equivalents need to behave differently to benefit from being able to be incorrect/invalid transformations?

Yeah, fair - if that’s crashing the tool, we should address it not to crash, and instead to diagnose the interestingness test as contradictory or flaky.