This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Match RISCVISD::ADD_LO in SelectAddrRegImm.
ClosedPublic

Authored by craig.topper on Jun 28 2022, 9:45 AM.

Details

Summary

This allows us to fold global and constant pool addresses into
load/store during isel instead of in the post-isel peephole. I
did not copy the alignment check for ConsantPoolSDNode because it
wasn't tested.

Remove the now untested GlobalAddressSDNode and ConsantPoolSDNode
handling from the peephole.

I think the only time the peephole is used now is when we split a
constant add into (addi (addi X, C1), C2) or (addi (add X, C3), C4). I plan to look at folding
that into SelectAddrRegImm next.

Diff Detail

Event Timeline

craig.topper created this revision.Jun 28 2022, 9:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 28 2022, 9:45 AM
craig.topper requested review of this revision.Jun 28 2022, 9:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 28 2022, 9:45 AM
craig.topper edited the summary of this revision. (Show Details)Jun 28 2022, 9:57 AM
reames added inline comments.Jul 1 2022, 8:07 AM
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
1924

Er, correct me if I'm wrong here, but don't we need to be checking the combined offset for safety against the alignment? If the original GV had a base aligned to 16, and an offset of 15, wouldn't adding a new offset of 15 cause problems? We could in theory adjust the base, but do we actually do that?

(If this concern is valid, the original code had it too.)

2312

This seems like we should be able to write a test for this.

Maybe a large constant which is used twice - once in full, and then the second using only some upper bits?

If you don't mind, I'd prefer to have the deletion of untested code done in a separate change than the move of the global handling. Just for clarity of revert attribution if needed.

craig.topper added inline comments.Jul 1 2022, 9:04 AM
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
1924

I think you're right. As far as I know GA->getOffset() is always 0 which is probably why it hasn't caused a problem.

craig.topper added inline comments.Jul 1 2022, 9:35 AM
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
1924

Well partially right. I think we need to calculate commonAlignment(GA->getGlobal()->getPointerAlignment(DL), GA->getOffset()) and make sure CVal is less than that.

What we end up with is an LUI with the global adjusted by getOffset() and a load/store with the global adjusted by getOffset()+CVal. We need to ensure that the address calculated by the LUI is compatible with the address calculated by the load/store.

craig.topper added inline comments.Jul 1 2022, 10:56 AM
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
2312

I'm not sure we share constant pools like that. When a constant pool is created in SelectionDAG, the offset is provided by the caller. It's not calculated based on there being some other constant pool entry with the same bit pattern in upper bits.

reames added inline comments.Jul 1 2022, 12:25 PM
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
1924

Thinking about this, I'm pretty sure that commonAlignment as you describe is sufficient, but not necessary.

If the combined offset is both less than 12 bits, and less than the alignment, then the globals low bits + the offset will be less than 12 bits. (i.e. non-overlapping bits within the low bits) Those bits could be folded either a) back into the ADD_LO or into the using load/store instruction. Either should be legal, and both kill this use of the outer ADDI.

Use commonAlignment to match the recent change to the post-isel peephole.
Don't delete any code from the post-isel peephole.

reames accepted this revision.Jul 2 2022, 8:37 AM

LGTM, remember to update your submission comment per changes.

This revision is now accepted and ready to land.Jul 2 2022, 8:37 AM
This revision was landed with ongoing or failed builds.Jul 2 2022, 10:00 AM
This revision was automatically updated to reflect the committed changes.