Navigation Menu

Skip to content

Commit

Permalink
[AVR] Fix expansion of NEGW
Browse files Browse the repository at this point in the history
The previous expansion used SBCI, which is incorrect because the NEGW
pseudo instruction accepts a DREGS operand (2xGPR8) and SBCI only allows
LD8 registers. One solution could be to correct the NEGW pseudo
instruction, but another solution is to use a different instruction
(sbc) that does accept a GPR8 register and therefore allows more freedom
to the register allocator.

The output now matches avr-gcc for the following code:

    int foo(int n) {
        return -n;
    }

I've found this issue using the machine instruction verifier: it was
complaining about the wrong register class in NEGWRd.mir.

Differential Revision: https://reviews.llvm.org/D97131
  • Loading branch information
aykevl committed Mar 3, 2021
1 parent 4f6d798 commit bbfef8a
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 6 deletions.
6 changes: 3 additions & 3 deletions llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
Expand Up @@ -438,12 +438,12 @@ bool AVRExpandPseudo::expand<AVR::NEGWRd>(Block &MBB, BlockIt MBBI) {
.addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstLoReg, getKillRegState(DstIsKill));

// Do an extra SBCI.
// Do an extra SBC.
auto MISBCI =
buildMI(MBB, MBBI, AVR::SBCIRdK)
buildMI(MBB, MBBI, AVR::SBCRdRr)
.addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstHiReg, getKillRegState(DstIsKill))
.addImm(0);
.addReg(ZERO_REGISTER);
if (ImpIsDead)
MISBCI->getOperand(3).setIsDead();
// SREG is always implicitly killed
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AVR/AVRInstrInfo.td
Expand Up @@ -757,7 +757,7 @@ Defs = [SREG] in
// Expands to:
// neg Rd+1
// neg Rd
// sbci Rd+1, 0
// sbc Rd+1, r1
def NEGWRd : Pseudo<(outs DREGS:$rd),
(ins DREGS:$src),
"negw\t$rd",
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AVR/neg.ll
Expand Up @@ -15,7 +15,7 @@ define i16 @neg16(i16 %x) {
; CHECK: ; %bb.0:
; CHECK-NEXT: neg r25
; CHECK-NEXT: neg r24
; CHECK-NEXT: sbci r25, 0
; CHECK-NEXT: sbc r25, r1
; CHECK-NEXT: ret
%sub = sub i16 0, %x
ret i16 %sub
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/AVR/pseudo/NEGWRd.mir
Expand Up @@ -19,7 +19,7 @@ body: |
; CHECK: $r15 = NEGRd $r15, implicit-def dead $sreg
; CHECK-NEXT: $r14 = NEGRd $r14
; CHECK-NEXT: $r15 = SBCIRdK $r15, 0, implicit-def $sreg, implicit killed $sreg
; CHECK-NEXT: $r15 = SBCRdRr $r15, $r1, implicit-def $sreg, implicit killed $sreg
$r15r14 = NEGWRd $r15r14, implicit-def $sreg
...

0 comments on commit bbfef8a

Please sign in to comment.