rewriteNonIntergerIVs will attemps to transform the floating-point recurrences to integer recurrences.
so int->fp->int will generate when the original floating-point recurrences need cast type integer.
ie. Fold (fptosi (sitofp iN to float)) to i32 --> i32 iN
Details
Diff Detail
Unit Tests
Event Timeline
Specifically detecting this exact case doesn't really seem very useful... we should be leveraging some sort of range analysis (known bits, CorrelatedValuePropagation, etc.)
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1532 ↗ | (On Diff #435835) | I'm very confused by this code. You're taking the binary operator, checking if the first use in the use list is an icmp, then... assuming the result of the icmp somehow constraints the result of the add? If you need some sort of reasoning about control flow, maybe look at LazyValueInfo? |
llvm/test/Transforms/InstCombine/sitofp.ll | ||
228 ↗ | (On Diff #435835) | We probably want a few more testcases like this to verify the exact boundary conditions. |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1532 ↗ | (On Diff #435835) | Thanks @efriedma very much. I'll take a look at LazyValueInfo. Since I'm not familiar with this module, more detailed guidance is welcome. In current implementation, by using matchSimpleRecurrence, we can know that the initial value of the %indvar.phi is R, and the step is L. Then, according to the icmp operand, we know that the end value is KnownEnd, that is, the current value range is [KnownEnd. Known2]. Therefore, if we can know that the most significant n bits of both KnownEnd and Known2 are 0, the most significant n bits of the currently analyzed value %indvar.phi are also necessarily 0. for.body: ; preds = %for.body, %entry %indvar.phi = phi i32 [ 16777215, %entry ], [ %dec.int, %for.body ] ... %dec.int = add nsw i32 %indvar.phi, -1 %cmp = icmp ugt i32 %dec.int, 0 br i1 %cmp, label %for.body, label %cleanup |
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | ||
---|---|---|
1757–1758 ↗ | (On Diff #435835) | This part is mentioned in the TODO right under here (update that...) and independent of any control-flow changes, so you could remove the changes to ValueTracking and just focus on this part. |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1532 ↗ | (On Diff #435835) | You're missing a bunch of steps here. matchSimpleRecurrence only checks that the PHI has an invariant start, and increases by some "step" each iteration. It doesn't check that the step is loop-invariant, and it doesn't check that the loop's trip count is actually related to the PHI at all. It might be possible to add the additional checks necessary to make this work here, directly, but it's a lot of complicated code. Instcombine normally doesn't compute LazyValueInfo or ScalarEvolution; a solution involving those probably means moving the transform somewhere else. Maybe CorrelatedValuePropagation. |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1532 ↗ | (On Diff #435835) | Thanks @efriedma very much for your detail explanation. |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1532 ↗ | (On Diff #435835) | You'd want to compute the actual value range in LazyValueInfo, not CorrelatedValuePropagation itself. I think LazyValueInfoImpl::solveBlockValuePHINode should do that already for your testcase? It at least has the right kind of logic. |
Add checking the step is loop-invariant, and its loop's trip count is actually related to the PHI
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1532 ↗ | (On Diff #435835) | Thanks @efriedma for your patience. Therefore, I directly add the both check on the original basis. (Check the step is loop-invariant, and its loop's trip count is related to current PHI) |
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | ||
1757–1758 ↗ | (On Diff #435835) | Apply your comment, thanks @spatel |
llvm/lib/Analysis/ValueTracking.cpp | ||
---|---|---|
1536 ↗ | (On Diff #437074) | This doesn't seem to be taking the predicate of the icmp into account? |
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | ||
1757–1758 ↗ | (On Diff #435835) | It doesn't look like this comment was applied: You need to create a separate patch that includes only this change, without any changes to ValueTracking. |
I'm not strongly opposed to adding some basic IV reasoning to computeKnownBits(), but the implementation needs to be much more careful. I think there are at least three bugs here (missing check for predicate, no check whether this is a loop exit or continue condition, no reasoning about how the start value range relates to the end value). This requires much more extensive testing (and those tests should be simpler, not involving float operations).
If you want to add this, you'd probably want to start over with just handling a canonical IV (step 1 incrementing IV with start smaller and end and ult or ne condition), and expand from there.
Generally, the utility that handles this kind of simplification based on IV ranges is SimplifyIndVars -- that one is based on the full power of SCEV, and will be able to deal with non-trivial recurrences. Extending it to handle this case is probably the most correct approach. Maybe there are complications with looking through float operations there though.
Probably ill-considered, I think a basic IV start with positive A, end with positive B,and whatever his predicate of the icmp, the IV is always in the range [A, B], so if we can know that the most significant n bits of both A and B are 0, the most significant n bits of the currently IV is also necessarily 0, that's why I associate the start value with the end value.
If you want to add this, you'd probably want to start over with just handling a canonical IV (step 1 incrementing IV with start smaller and end and ult or ne condition), and expand from there.
Generally, the utility that handles this kind of simplification based on IV ranges is SimplifyIndVars -- that one is based on the full power of SCEV, and will be able to deal with non-trivial recurrences. Extending it to handle this case is probably the most correct approach. Maybe there are complications with looking through float operations there though.
Thanks @nikic so much for pointing out the derection to resolve this issue, I have redo in the SCEV.
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | ||
---|---|---|
1757–1758 ↗ | (On Diff #435835) | sorry, misssd mention https://reviews.llvm.org/D127854 |