This is an archive of the discontinued LLVM Phabricator instance.

[WIP][SelectionDAG] Fold shift constants into cmp
AbandonedPublic

Authored by Allen on Mar 9 2022, 11:21 PM.

Details

Summary

Perform the following transform for shift constants if legal

((X+1) >> ShiftBits) <= NewC -> X <  (NewC << ShiftBits)
((X+1) >> ShiftBits) >  NewC -> X >= (NewC << ShiftBits)

Fixes https://github.com/llvm/llvm-project/issues/54283

Diff Detail

Event Timeline

Allen created this revision.Mar 9 2022, 11:21 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 9 2022, 11:21 PM
Allen requested review of this revision.Mar 9 2022, 11:21 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 9 2022, 11:21 PM
craig.topper added inline comments.Mar 9 2022, 11:39 PM
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
4299

This comment doesn't provide much information to the reader outside of the context of this patch. Can you elaborate for future readers?

4326

Same

4555

The first two lines of this have the same thing on both sides. Is that saying we're re-creating the code that is already there?

6069

What changed here?

6327

And here

Allen updated this revision to Diff 414290.Mar 10 2022, 12:49 AM
Allen marked 2 inline comments as done.

update comment for more readable

Allen edited the summary of this revision. (Show Details)Mar 10 2022, 12:50 AM
Allen updated this revision to Diff 414365.Mar 10 2022, 6:10 AM
Allen marked 3 inline comments as done.

rebase to top commit to fix the code premerge conflict

Allen updated this revision to Diff 414531.Mar 10 2022, 5:07 PM

Fixes clang-format: please reformat the code

Allen added a comment.Mar 11 2022, 6:39 PM

@craig.topper please let me know if you have some more idea, thanks

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
4299

Add more detail reason in comment

4326

Done, thanks

4555

Thanks for your quick review, updated.

6069

the origin '-' is not UTF8 code, and it show garbled messages when show with vim

6327

same above

Allen added a comment.Mar 15 2022, 6:50 PM

this is similar to D121449, so I'll abandon it that commit land

this is similar to D121449, so I'll abandon it that commit land

It looks this code works also on arm backend, what I do is only on aarch64.
And D121449 optimize more cases (arm64-xaluo.ll)
So I think both of them are useful.

craig.topper added inline comments.Mar 15 2022, 9:36 PM
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
4300

it's not the type that is opaque, it's the constant value.

4553–4571

Why does the new transform only happen if shouldAvoidTransformToShift returns false? You aren't creating a shift instruction.

4555

This comment makes it look like the pattern (X >> ShiftBits) >= NewC is being matched, but there is no SRL instruction using X is there?

ARMTargetLowering::getARMCmp and AArch64TargetLowering::getAArch64Cmp both have code that tries to adjust the condition code to get the immediate to fit. So it looks like the primary problem is that introduction of the ISD::SRL that blocks the target from seeing a constant they can fix it.

Allen updated this revision to Diff 415787.Mar 16 2022, 5:28 AM
Allen updated this revision to Diff 415789.Mar 16 2022, 5:35 AM

update according comment advise

Allen marked 3 inline comments as done.Mar 21 2022, 8:31 AM

ARMTargetLowering::getARMCmp and AArch64TargetLowering::getAArch64Cmp both have code that tries to adjust the condition code to get the immediate to fit. So it looks like the primary problem is that introduction of the ISD::SRL that blocks the target from seeing a constant they can fix it.

hi, @craig.topper
Yes, ISD::SRL already support the 2^N (isLegalAddImmediate will return false), but SelectionDAG still
fail to match it as it convert the 2^N to (2^N +1)/(2^N -1) , which is not a legal add immediate.
This is because we always do the transform:Canonicalize GE/LE comparisons to use GT/LT comparisons

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
4300

thanks, update comment

4553–4571

good catch, thanks.

4555

thanks, update comment

craig.topper added inline comments.Mar 21 2022, 9:58 PM
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
4556

The first two cases never happen do they?

In those cases C1 == NewC << ShiftBits and we already checked isLegalICmpImmediate on line 4500.

Allen updated this revision to Diff 417487.Mar 22 2022, 9:33 PM
Allen marked 3 inline comments as done.
Allen edited the summary of this revision. (Show Details)
Allen marked an inline comment as done.Mar 28 2022, 9:43 AM
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
4556

Yes, thanks very much!

I think AndRHS->getAPIntValue().isPowerOf2() will be matched, so I update the comment.

4556

hi, @craig.topper:

I had update the comment, do you have other suggestion ?

I'm not sure I like this patch as is.

The fundamental problem isn't directly the shift code. We have conflict between canonicalization and target lowering. Canonicalization prefers to create SET(U)GT/SET(U)LT. But that may create an unsupported constant. Is it the target's responsibility to detect reverse the canonicalization during lowering? We do that already for setgt X, -1 on many targets. ARM and AArch64 do it for even more constant values. Or should canonicalization be consulting isLegalICmpImmediate?

If it's the target's responsibility during, then we should just block the shift transform and leave the unsupported immediate so the target can fix it.
If canonicalization in this code should deal with it, then we should be converting SETGT/SETUGT to SETGE/SETUGE based on isLegalICmpImmediate around line 4363 in the original code. The same idea as the changes in this patch to the SETGE/SETUGE canonicalization.

What we have a right now is somewhere in the middle of these two ideas. We're only considering very specific constants by creating the constant the shift code. But we've made the SETGE/SETUGE canonicalization block transforming a potentially larger set of the constants.

@spatel or @RKSimon what are your thoughts?

I'm a little worried that this is likely to lead to infinite loops with constant/condcode combines fighting - this feels like it should be be backend specific tbh, or maybe even ISelDAGToDAG.

Allen marked an inline comment as done.Mar 29 2022, 1:24 AM

I'm a little worried that this is likely to lead to infinite loops with constant/condcode combines fighting - this feels like it should be be backend specific tbh, or maybe even ISelDAGToDAG.

I added condition isLegalICmpImmediate on line 4335, which will guard the infinite loops.

Allen retitled this revision from [SelectionDAG] Fold shift constants into cmp to [WIP][SelectionDAG] Fold shift constants into cmp.Apr 5 2022, 6:07 PM
Allen abandoned this revision.Jun 1 2022, 6:08 PM