On Wed, May 21, 2025 at 6:05 PM MCC CS <mc...@gmx.com> wrote: > > Dear Richard, > > Thank you so much for your reply. I submitted the patch for the third case to > LLVM before I've received your reply, and they said the same thing, > that it would probably be used outside of loops as well and it would inflict > a branch misprediction, so it should be implemented at the level > of loop code generation only (because branch predictor could handle it > inside loops). > > I didn't know that the second pattern would cause disassociation > from division. Unexpectedly LLVM has that pattern in their match.pd > equivalent but what you've said makes more sense. > > For the first pattern, I verified that trunk GCC, for: > > void d(unsigned x) > { > if (x >= 5) __builtin_unreachable(); > x %= 5; > g(x); > } > > optimizes away the "%=", as you've said. However, > for the code: > > void a(void) > { > unsigned m = 0; > for(int i = 0; i < 300; i++) > { > m++; > m %= 600; > g(m); > } > } > > it gets optimized only with the patch, which is surprising.
Indeed. So the code that should handle this is in vr-values.cc in the simplify_using_ranges::simplify_div_or_mod_using_ranges function. I don't know where this is wired in, specifically whether or why we do not take into account loop niter information when folding but we do seem to have global range information at some point. I'll note that SCEV will of course fail to analyze the 'm' IV because of the modulo expression which is unhandled. That said, I don't understand why it doesn't work currently or why it would work with your patch for the loop case. Richard. > > Thanks > MCCCS