The ARM backend breaks some specific immediates to two parts
in binary operations. And this patch adds more tests
for that.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
This patch does two optimization:
- mov Rx, 0x1ffff
before:
ldr ... .long ...
after:
mov Rx, # 0x20000 sub Rx, Rx, 1
- add Rx, Rx, # 0x1ffff
before
ldr add ... .long ...
after:
add Rx, # 0x20000 sub Rx, # 1
The patch depends on https://reviews.llvm.org/D83928, it will show improvements based on it.
llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | ||
---|---|---|
3319 ↗ | (On Diff #284204) | NewUseOpc2 = NewUseOpc1, same for below. |
3365 ↗ | (On Diff #284204) | NewUseOpc2 = NewUseOpc1, same for below. |
llvm/test/CodeGen/ARM/add-sub-imm.ll | ||
0 | We should have a test run for a Thumb2 target as well. It would also be a good idea for some edge-case negative tests to exercise isSOImmTwoPartValSub some more. |
I have added tests for thumb2, however current patch does not apply to thumb2.
I will submit another patch for thumb2 later, since smaller patches are easy to review.
Thanks for the test changes.
I have added tests for thumb2, however current patch does not apply to thumb2.
I'm a bit confused then why there are Thumb2 changes in FoldImmediate?
I do not think there are Thumb2 changes in FoldImmediate. You can see NewUseOpc1 and NewUseOpc2 are identical
for all thumb2 related code. Actually the original NewUseOpc is enough for thumb2. So I should change it back (only) for thumb2 in FoldImmediate?
If the logic isn't needed, then yes, I'd recommend removing. Currently I'm seeing logic added for Thumb2 opcodes so I would expect some changes and testing and if that isn't case, then I guess the changes aren't needed. Looks like the ORR and EOR paths also need to be tested?
Sorry, I made a mistake, the changes to thumb are necessary, since
- BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc), + BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc1), NewReg) .addReg(Reg1, getKillRegState(isKill)) .addImm(SOImmValV1) .add(predOps(ARMCC::AL)) .add(condCodeOp());
- UseMI.setDesc(get(NewUseOpc)); + UseMI.setDesc(get(NewUseOpc2));
This piece of code is in the critical path, all cases will walk though it.
It is necessary to substitute NewUseOpc with NewUseOpc1 & NewUseOpc2.
I will upload a new patch later, with tests of orr and eor.
Sorry, I made a mistake, the changes to thumb are necessary, since
\- BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc), \+ BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc1), NewReg) .addReg(Reg1, getKillRegState(isKill)) .addImm(SOImmValV1) .add(predOps(ARMCC::AL)) .add(condCodeOp()); \- UseMI.setDesc(get(NewUseOpc)); \+ UseMI.setDesc(get(NewUseOpc2));
This piece of code is in the critical path, all cases will walk though it.
It is necessary to substitute NewUseOpc with NewUseOpc1 & NewUseOpc2.
I will upload a new patch later, with tests of orr and eor.
Sorry, I made a mistake, the changes to thumb are necessary, since
BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc), NewReg) .addReg(Reg1, getKillRegState(isKill)) .addImm(SOImmValV1) .add(predOps(ARMCC::AL)) .add(condCodeOp()); UseMI.setDesc(get(NewUseOpc));
is changed to
BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(), get(NewUseOpc1), NewReg) .addReg(Reg1, getKillRegState(isKill)) .addImm(SOImmValV1) .add(predOps(ARMCC::AL)) .add(condCodeOp()); UseMI.setDesc(get(NewUseOpc2));
This piece of code is in the critical path, all cases will walk though it.
It is necessary to substitute NewUseOpc with NewUseOpc1 & NewUseOpc2.
I will upload a new patch later, with tests of orr and eor.
I have uploaded a new patch with tests of eor and orr.
The changes for Thumb2 are unavoidable due to the piece of code in the critical path.
I have uploaded a new patch, in which more tests for orr and eor are added.
My patch also affect (improve) eor and orr, which I did not realize.
Currently, 12 positive test cases and 2 negative test cases are introduced, which should cover all corners.
I think the fact that you're having to make some Thumb2 changes to get around how the code is organised, suggests that the code should be reorganised instead. I'd suggest:
- Pre-commit the two-part-imm.ll test.
- Split the arm and thumb paths in an NFC patch, refactoring common code.
- Then make your arm changes.
Thanks. This patch now only contains the improved test case two-part-imm.ll. And I will
submit the split of the arm and thumb paths in another NFC patch.
Really appreciate your suggestion.