Open arpilipe opened 8 years ago
mentioned in issue llvm/llvm-bugzilla-archive#30428
Bug llvm/llvm-bugzilla-archive#30428 has been marked as a duplicate of this bug.
After looking at the example, I think even though we could solve this inside SimplifyIndvar::strengthenOverflowingOperation, we should try to do a more general transform. Specifically, I think teaching CorrelatedValuePropagation to mark additions and subtractions as nsw or nuw when legal (checking using LVI) will be more powerful than teaching SimplifyIndvar, since it would kick in for non-induction variables as well (and it would solve this problem too).
If we go with the plan above, I think there are three subtasks to getting the example in this bug working, all of which can be done in parallel:
Teaching CVP to actually do the transform (i.e. if LVI says that a certain operation won't sign/unsign overflow then mark it as nsw/nuw).
Teach LVI that "X s< Unknown" constraints X to be in [INT_MIN, INT_MAX) range (that is, we know that X is not INT_MAX, even though we know nothing about Unknown).
Once the two things above are done, we should be optimizing the post-guard-lowering version of the example you've given. Then what remains is:
after which the example as given should work.
One thing I found suspicious -- the key method for step (1) is this:
/// Return the ConstantRange constraint that is known to hold for the /// specified value at the end of the specified block. This may only be called /// on integer-typed Values. ConstantRange getConstantRange(Value V, BasicBlock BB, Instruction *CxtI = nullptr);
and I couldn't quite figure out what the intended semantics are for CxtI, given that it states the range is valid at the end of BB. Hopefully "fixing" this will just require adjusting the documentation a bit.
assigned to @arpilipe
Extended Description
On the following loop indvars creates a wider IV but fails to eliminate a narrow type increment leading to an extra computation inside of the loop:
After indvars:
The problem is not specific to guards, lowering it before indvars leads to the same result.