[PATCH] D152059: [AVR] Replace shift-to-loop IR pass with common shift code
Patryk Wychowaniec via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 17 04:16:16 PDT 2023
Patryk27 abandoned this revision.
Patryk27 marked 11 inline comments as done.
Patryk27 added a comment.
I've addressed all the comments and I'll create a new revision with them in a moment :-)
================
Comment at: llvm/lib/Target/AVR/AVRISelLowering.cpp:2219
+ // Shift the registers by one.
+ insertMultibyteShift(LoopBB->end(), LoopBB, dl, PhiRegPairs, Opc, 1);
+
----------------
benshi001 wrote:
> Will the field `second` of `PhiRegPairs` be over written to `sub_lo` or `sub_hi` by `insertMultibyteShift` ?
I'm not sure what you mean 🤔
`sub_lo` and `sub_hi` are used in `insertWideShift` which is not called here - and `insertMultibyteShift`, given `ShiftAmt = 1` (like in here), reduces down to this block:
```
while (ShiftLeft && ShiftAmt) {
// Shift one to the left.
for (ssize_t I = Regs.size() - 1; I >= 0; I--) {
Register Out = MRI.createVirtualRegister(&AVR::GPR8RegClass);
Register In = Regs[I].first;
Register InSubreg = Regs[I].second;
if (I == (ssize_t)Regs.size() - 1) { // first iteration
BuildMI(*BB, MBBI, DL, TII.get(AVR::ADDRdRr), Out)
.addReg(In, 0, InSubreg)
.addReg(In, 0, InSubreg);
} else {
BuildMI(*BB, MBBI, DL, TII.get(AVR::ADCRdRr), Out)
.addReg(In, 0, InSubreg)
.addReg(In, 0, InSubreg);
}
Regs[I] = std::pair(Out, 0);
}
ShiftAmt--;
}
```
... which does overwrite `PhiRegPairs` with the output register.
================
Comment at: llvm/lib/Target/AVR/AVRISelLowering.cpp:2229
+ .addMBB(LoopBB);
+ Regs[I] = std::pair(PhiRegs[I], 0);
+ }
----------------
benshi001 wrote:
> After this line, how is the field `second` of `Regs[I]` set to `sub_lo` or `sub_hi`? Would it be better to
>
> ```
> Regs[I] = PhiRegPairs[I];
> ```
>
> ?
Note that `insertMultibyteShift` modifies given `Regs` - it changes them from input-registers into output-registers (see the comment above with the related code block), and so doing:
```
Regs[I] = PhiRegPairs[I];
```
... is different from doing:
```
Regs[I] = std::pair(PhiRegs[I], 0);
```
... in the sense that `PhiRegPairs` there contains output-registers (with shifted values), while `PhiRegs` continues to refer to the input-registers, so both fragments do something else.
================
Comment at: llvm/lib/Target/AVR/AVRISelLowering.cpp:2246
+
+ return ExitBB;
+}
----------------
benshi001 wrote:
> Don't we need to erase the 32-bit shift pseudo instruction from EntryBB ?
>
> ```
> ExitBB = EntryBB->splitAt(MI, false);
> ```
This already happens at the end of `insertWideShift`:
```
// Remove the pseudo instruction.
MI.eraseFromParent();
return BB;
}
```
================
Comment at: llvm/test/CodeGen/AVR/shift-loop.ll:22
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ADDRdRr:%[0-9]+]]:gpr8 = ADDRdRr %10, %10, implicit-def $sreg
+ ; CHECK-NEXT: [[ADCRdRr:%[0-9]+]]:gpr8 = ADCRdRr %9, %9, implicit-def $sreg, implicit $sreg
----------------
benshi001 wrote:
> Where is `%10` defined ?
Nice catch - it seems that `update_mir_test_checks.py` cannot resolve cases where declaration happens after usage, i.e. the current approach generates:
```
body: |
bb.0 (%ir-block.0):
successors: %bb.2(0x80000000)
liveins: $r23r22, $r25r24, $r19r18
%2:dregs = COPY $r19r18
%1:dregs = COPY $r25r24
%0:dregs = COPY $r23r22
%4:gpr8 = COPY %2.sub_lo
RJMPk %bb.2
bb.1 (%ir-block.0):
successors: %bb.2(0x80000000)
%12:gpr8 = ADDRdRr %10, %10, implicit-def $sreg
%13:gpr8 = ADCRdRr %9, %9, implicit-def $sreg, implicit $sreg
%14:gpr8 = ADCRdRr %8, %8, implicit-def $sreg, implicit $sreg
%15:gpr8 = ADCRdRr %7, %7, implicit-def $sreg, implicit $sreg
bb.2 (%ir-block.0):
successors: %bb.1(0x40000000), %bb.3(0x40000000)
%7:gpr8 = PHI %1.sub_hi, %bb.0, %15, %bb.1
%8:gpr8 = PHI %1.sub_lo, %bb.0, %14, %bb.1
%9:gpr8 = PHI %0.sub_hi, %bb.0, %13, %bb.1
%10:gpr8 = PHI %0.sub_lo, %bb.0, %12, %bb.1
%16:gpr8 = PHI %4, %bb.0, %17, %bb.1
%17:gpr8 = DECRd %16, implicit-def $sreg
BRPLk %bb.1, implicit $sreg
bb.3 (%ir-block.0):
%6:dregs = REG_SEQUENCE %7, %subreg.sub_hi, %8, %subreg.sub_lo
%5:dregs = REG_SEQUENCE %9, %subreg.sub_hi, %10, %subreg.sub_lo
$r23r22 = COPY %5
$r25r24 = COPY %6
RET implicit $r23r22, implicit $r25r24, implicit $r1
```
To be fair, I'm not sure why those blocks are generated in this order - I switched it now to a simpler approach (note different block order and `BRMIk`):
```
body: |
bb.0 (%ir-block.0):
successors: %bb.1(0x80000000)
liveins: $r23r22, $r25r24, $r19r18
%2:dregs = COPY $r19r18
%1:dregs = COPY $r25r24
%0:dregs = COPY $r23r22
%4:gpr8 = COPY %2.sub_lo
bb.1 (%ir-block.0):
successors: %bb.2(0x40000000), %bb.3(0x40000000)
%7:gpr8 = PHI %1.sub_hi, %bb.0, %15, %bb.2
%8:gpr8 = PHI %1.sub_lo, %bb.0, %14, %bb.2
%9:gpr8 = PHI %0.sub_hi, %bb.0, %13, %bb.2
%10:gpr8 = PHI %0.sub_lo, %bb.0, %12, %bb.2
%16:gpr8 = PHI %4, %bb.0, %17, %bb.2
%17:gpr8 = DECRd %16, implicit-def $sreg
BRMIk %bb.3, implicit $sreg
bb.2 (%ir-block.0):
successors: %bb.1(0x80000000)
%12:gpr8 = ADDRdRr %10, %10, implicit-def $sreg
%13:gpr8 = ADCRdRr %9, %9, implicit-def $sreg, implicit $sreg
%14:gpr8 = ADCRdRr %8, %8, implicit-def $sreg, implicit $sreg
%15:gpr8 = ADCRdRr %7, %7, implicit-def $sreg, implicit $sreg
RJMPk %bb.1
bb.3 (%ir-block.0):
%6:dregs = REG_SEQUENCE %7, %subreg.sub_hi, %8, %subreg.sub_lo
%5:dregs = REG_SEQUENCE %9, %subreg.sub_hi, %10, %subreg.sub_lo
$r23r22 = COPY %5
$r25r24 = COPY %6
RET implicit $r23r22, implicit $r25r24, implicit $r1
```
... and it works correctly (+ generates the same assembly, even), so I guess we'll stick to that.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D152059/new/
https://reviews.llvm.org/D152059
More information about the llvm-commits
mailing list