forked from OSchip/llvm-project
[AVR] Fix expansion of NEGW
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
This commit is contained in:
parent
4f6d7985d4
commit
bbfef8ac95
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue