[llvm] bbfef8a - [AVR] Fix expansion of NEGW

Ayke van Laethem via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 3 06:36:29 PST 2021


Author: Ayke van Laethem
Date: 2021-03-03T15:36:05+01:00
New Revision: bbfef8ac952bffb01a7a471a2953cbda77231054

URL: https://github.com/llvm/llvm-project/commit/bbfef8ac952bffb01a7a471a2953cbda77231054
DIFF: https://github.com/llvm/llvm-project/commit/bbfef8ac952bffb01a7a471a2953cbda77231054.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
    llvm/lib/Target/AVR/AVRInstrInfo.td
    llvm/test/CodeGen/AVR/neg.ll
    llvm/test/CodeGen/AVR/pseudo/NEGWRd.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 2f7e017e550a..f266bdbb4cfa 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -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

diff  --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index 3eb983688471..3ec77a4f6d65 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -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",

diff  --git a/llvm/test/CodeGen/AVR/neg.ll b/llvm/test/CodeGen/AVR/neg.ll
index 3a029d5fcee3..ddb5832dfd9f 100644
--- a/llvm/test/CodeGen/AVR/neg.ll
+++ b/llvm/test/CodeGen/AVR/neg.ll
@@ -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

diff  --git a/llvm/test/CodeGen/AVR/pseudo/NEGWRd.mir b/llvm/test/CodeGen/AVR/pseudo/NEGWRd.mir
index 0a534ad0c3f2..5cf947e8830a 100644
--- a/llvm/test/CodeGen/AVR/pseudo/NEGWRd.mir
+++ b/llvm/test/CodeGen/AVR/pseudo/NEGWRd.mir
@@ -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
 ...


        


More information about the llvm-commits mailing list