[llvm] f3837e7 - [AVR] Fix incorrect expansion of pseudo instruction ROLBRd

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 10 09:22:10 PDT 2023


Author: Ben Shi
Date: 2023-06-11T00:20:43+08:00
New Revision: f3837e726ff9c5e91163213d34e4547bc7f72f40

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

LOG: [AVR] Fix incorrect expansion of pseudo instruction ROLBRd

Since ROLBRd needs an implicit R1 (on AVR) or an implicit R17 (on AVRTiny),
we split ROLBRd to ROLBRdR1 (on AVR) and ROLBRdR17 (on AVRTiny).

Reviewed By: aykevl, Patryk27

Differential Revision: https://reviews.llvm.org/D152248

Added: 
    llvm/test/CodeGen/AVR/pseudo/ROLBRdR1.mir
    llvm/test/CodeGen/AVR/pseudo/ROLBRdR17.mir

Modified: 
    llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
    llvm/lib/Target/AVR/AVRISelLowering.cpp
    llvm/lib/Target/AVR/AVRISelLowering.h
    llvm/lib/Target/AVR/AVRInstrInfo.td
    llvm/test/CodeGen/AVR/rot.ll

Removed: 
    llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir


################################################################################
diff  --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index f9a013b6b153d..f257ccea6c50a 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -101,6 +101,8 @@ class AVRExpandPseudo : public MachineFunctionPass {
   bool expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsELPM);
   // Common implementation of LPMBRdZ and ELPMBRdZ.
   bool expandLPMBELPMB(Block &MBB, BlockIt MBBI, bool IsELPM);
+  // Common implementation of ROLBRdR1 and ROLBRdR17.
+  bool expandROLBRd(Block &MBB, BlockIt MBBI);
 };
 
 char AVRExpandPseudo::ID = 0;
@@ -1479,20 +1481,17 @@ bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
   return true;
 }
 
-template <>
-bool AVRExpandPseudo::expand<AVR::ROLBRd>(Block &MBB, BlockIt MBBI) {
+bool AVRExpandPseudo::expandROLBRd(Block &MBB, BlockIt MBBI) {
   // In AVR, the rotate instructions behave quite unintuitively. They rotate
   // bits through the carry bit in SREG, effectively rotating over 9 bits,
   // instead of 8. This is useful when we are dealing with numbers over
   // multiple registers, but when we actually need to rotate stuff, we have
   // to explicitly add the carry bit.
 
-  const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
-
   MachineInstr &MI = *MBBI;
   unsigned OpShift, OpCarry;
   Register DstReg = MI.getOperand(0).getReg();
-  Register ZeroReg = STI.getZeroRegister();
+  Register ZeroReg = MI.getOperand(3).getReg();
   bool DstIsDead = MI.getOperand(0).isDead();
   bool DstIsKill = MI.getOperand(1).isKill();
   OpShift = AVR::ADDRdRr;
@@ -1520,6 +1519,16 @@ bool AVRExpandPseudo::expand<AVR::ROLBRd>(Block &MBB, BlockIt MBBI) {
   return true;
 }
 
+template <>
+bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(Block &MBB, BlockIt MBBI) {
+  return expandROLBRd(MBB, MBBI);
+}
+
+template <>
+bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(Block &MBB, BlockIt MBBI) {
+  return expandROLBRd(MBB, MBBI);
+}
+
 template <>
 bool AVRExpandPseudo::expand<AVR::RORBRd>(Block &MBB, BlockIt MBBI) {
   // In AVR, the rotate instructions behave quite unintuitively. They rotate
@@ -2604,7 +2613,8 @@ bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
     EXPAND(AVR::OUTWARr);
     EXPAND(AVR::PUSHWRr);
     EXPAND(AVR::POPWRd);
-    EXPAND(AVR::ROLBRd);
+    EXPAND(AVR::ROLBRdR1);
+    EXPAND(AVR::ROLBRdR17);
     EXPAND(AVR::RORBRd);
     EXPAND(AVR::LSLWRd);
     EXPAND(AVR::LSRWRd);

diff  --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 5d7d08a5b9587..606e70b32f170 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1747,7 +1747,8 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
 //===----------------------------------------------------------------------===//
 
 MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
-                                                  MachineBasicBlock *BB) const {
+                                                  MachineBasicBlock *BB,
+                                                  bool Tiny) const {
   unsigned Opc;
   const TargetRegisterClass *RC;
   bool HasRepeatedOperand = false;
@@ -1785,7 +1786,7 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
     RC = &AVR::DREGSRegClass;
     break;
   case AVR::Rol8:
-    Opc = AVR::ROLBRd;
+    Opc = Tiny ? AVR::ROLBRdR17 : AVR::ROLBRdR1;
     RC = &AVR::GPR8RegClass;
     break;
   case AVR::Rol16:
@@ -2328,6 +2329,7 @@ MachineBasicBlock *
 AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
                                                MachineBasicBlock *MBB) const {
   int Opc = MI.getOpcode();
+  const AVRSubtarget &STI = MBB->getParent()->getSubtarget<AVRSubtarget>();
 
   // Pseudo shift instructions with a non constant shift amount are expanded
   // into a loop.
@@ -2342,7 +2344,7 @@ AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case AVR::Ror16:
   case AVR::Asr8:
   case AVR::Asr16:
-    return insertShift(MI, MBB);
+    return insertShift(MI, MBB, STI.hasTinyEncoding());
   case AVR::Lsl32:
   case AVR::Lsr32:
   case AVR::Asr32:

diff  --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h
index c4f73b0ffc919..b696bebe7136f 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -194,7 +194,8 @@ class AVRTargetLowering : public TargetLowering {
   const AVRSubtarget &Subtarget;
 
 private:
-  MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const;
+  MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB,
+                                 bool Tiny) const;
   MachineBasicBlock *insertWideShift(MachineInstr &MI,
                                      MachineBasicBlock *BB) const;
   MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const;

diff  --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index d0e75733114ac..f93248b4940c1 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -2028,16 +2028,21 @@ let Constraints = "$src = $rd", Defs = [SREG] in {
 
   def ASRWLoRd : Pseudo<(outs DREGS:$rd), (ins DREGS:$src), "asrwlo\t$rd",
                         [(set i16:$rd, (AVRasrlo i16:$src)), (implicit SREG)]>;
-
-  def ROLBRd : Pseudo<(outs GPR8
-                       : $rd),
-                      (ins GPR8
-                       : $src),
-                      "rolb\t$rd",
-                      [(set i8
-                        : $rd, (AVRrol i8
-                                : $src)),
-                       (implicit SREG)]>;
+  let Uses = [R1] in
+  def ROLBRdR1 : Pseudo<(outs GPR8:$rd),
+                        (ins GPR8:$src),
+                        "rolb\t$rd",
+                        [(set i8:$rd, (AVRrol i8:$src)),
+                        (implicit SREG)]>,
+                 Requires<[HasNonTinyEncoding]>;
+
+  let Uses = [R17] in
+  def ROLBRdR17 : Pseudo<(outs GPR8:$rd),
+                         (ins GPR8:$src),
+                         "rolb\t$rd",
+                         [(set i8:$rd, (AVRrol i8:$src)),
+                         (implicit SREG)]>,
+                  Requires<[HasTinyEncoding]>;
 
   def RORBRd : Pseudo<(outs GPR8
                        : $rd),

diff  --git a/llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir b/llvm/test/CodeGen/AVR/pseudo/ROLBRdR1.mir
similarity index 59%
rename from llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir
rename to llvm/test/CodeGen/AVR/pseudo/ROLBRdR1.mir
index 023120b2bad2a..10f70413ebf28 100644
--- a/llvm/test/CodeGen/AVR/pseudo/ROLBrd.mir
+++ b/llvm/test/CodeGen/AVR/pseudo/ROLBRdR1.mir
@@ -17,8 +17,8 @@ body: |
     liveins: $r14
 
     ; CHECK-LABEL: test_rolbrd
+    ; CHECK:         $r14 = ADDRdRr killed $r14, killed $r14, implicit-def $sreg
+    ; CHECK-NEXT:    $r14 = ADCRdRr $r14, $r1, implicit-def dead $sreg, implicit killed $sreg
 
-    ; CHECK:      $r14 = ADDRdRr killed $r14, killed $r14, implicit-def $sreg
-    ; CHECK-NEXT: $r14 = ADCRdRr $r14, $r1, implicit-def dead $sreg, implicit killed $sreg
-    $r14 = ROLBRd $r14, implicit-def $sreg
+    $r14 = ROLBRdR1  $r14, implicit-def $sreg, implicit $r1
 ...

diff  --git a/llvm/test/CodeGen/AVR/pseudo/ROLBRdR17.mir b/llvm/test/CodeGen/AVR/pseudo/ROLBRdR17.mir
new file mode 100644
index 0000000000000..2a26d18c65240
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/pseudo/ROLBRdR17.mir
@@ -0,0 +1,24 @@
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mattr=+avrtiny %s -o - | FileCheck %s
+
+# This test checks the expansion of the 8-bit ROLB (rotate) pseudo instruction
+# on AVRTiny.
+
+--- |
+  target triple = "avr--"
+  define void @test_rolbrd() {
+  entry:
+    ret void
+  }
+...
+
+---
+name:            test_rolbrd
+body: |
+  bb.0.entry:
+    liveins: $r24
+
+    ; CHECK-LABEL: test_rolbrd
+    ; CHECK:         $r24 = ADDRdRr killed $r24, killed $r24, implicit-def $sreg
+    ; CHECK-NEXT:    $r24 = ADCRdRr $r24, $r17, implicit-def dead $sreg, implicit killed $sreg
+    $r24 = ROLBRdR17 $r24, implicit-def $sreg, implicit $r17
+...

diff  --git a/llvm/test/CodeGen/AVR/rot.ll b/llvm/test/CodeGen/AVR/rot.ll
index 210031588005d..1a6b917af95b7 100644
--- a/llvm/test/CodeGen/AVR/rot.ll
+++ b/llvm/test/CodeGen/AVR/rot.ll
@@ -1,58 +1,75 @@
-; RUN: llc < %s -march=avr | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc < %s -mtriple=avr | FileCheck %s
+; RUN: llc < %s -mtriple=avr -mattr=+avrtiny | FileCheck --check-prefix=TINY %s
 
-; Bit rotation tests.
-
-; CHECK-LABEL: rol8:
 define i8 @rol8(i8 %val, i8 %amt) {
-  ; CHECK:      andi r22, 7
-
-  ; CHECK-NEXT: dec r22
-  ; CHECK-NEXT: brmi .LBB0_2
-
-; CHECK-NEXT: .LBB0_1:
-  ; CHECK-NEXT: lsl r24
-  ; CHECK-NEXT: adc r24, r1
-  ; CHECK-NEXT: dec r22
-  ; CHECK-NEXT: brpl .LBB0_1
-
-; CHECK-NEXT: .LBB0_2:
-  ; CHECK-NEXT: ret
+; CHECK-LABEL: rol8:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    andi r22, 7
+; CHECK-NEXT:    dec r22
+; CHECK-NEXT:    brmi .LBB0_2
+; CHECK-NEXT:  .LBB0_1: ; =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    lsl r24
+; CHECK-NEXT:    adc r24, r1
+; CHECK-NEXT:    dec r22
+; CHECK-NEXT:    brpl .LBB0_1
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:    ret
+;
+; TINY-LABEL: rol8:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    andi r22, 7
+; TINY-NEXT:    dec r22
+; TINY-NEXT:    brmi .LBB0_2
+; TINY-NEXT:  .LBB0_1: ; =>This Inner Loop Header: Depth=1
+; TINY-NEXT:    lsl r24
+; TINY-NEXT:    adc r24, r17
+; TINY-NEXT:    dec r22
+; TINY-NEXT:    brpl .LBB0_1
+; TINY-NEXT:  .LBB0_2:
+; TINY-NEXT:    ret
   %mod = urem i8 %amt, 8
-
   %inv = sub i8 8, %mod
   %parta = shl i8 %val, %mod
   %partb = lshr i8 %val, %inv
-
   %rotl = or i8 %parta, %partb
-
   ret i8 %rotl
 }
 
 
-; CHECK-LABEL: ror8:
 define i8 @ror8(i8 %val, i8 %amt) {
-  ; CHECK:      andi r22, 7
-
-  ; CHECK-NEXT: dec r22
-  ; CHECK-NEXT: brmi .LBB1_2
-
-; CHECK-NEXT: .LBB1_1:
-  ; CHECK-NEXT: bst r24, 0
-  ; CHECK-NEXT: ror r24
-  ; CHECK-NEXT: bld r24, 7
-  ; CHECK-NEXT: dec r22
-  ; CHECK-NEXT: brpl .LBB1_1
-
-; CHECK-NEXT: .LBB1_2:
-  ; CHECK-NEXT: ret
+; CHECK-LABEL: ror8:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    andi r22, 7
+; CHECK-NEXT:    dec r22
+; CHECK-NEXT:    brmi .LBB1_2
+; CHECK-NEXT:  .LBB1_1: ; =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    bst r24, 0
+; CHECK-NEXT:    ror r24
+; CHECK-NEXT:    bld r24, 7
+; CHECK-NEXT:    dec r22
+; CHECK-NEXT:    brpl .LBB1_1
+; CHECK-NEXT:  .LBB1_2:
+; CHECK-NEXT:    ret
+;
+; TINY-LABEL: ror8:
+; TINY:       ; %bb.0:
+; TINY-NEXT:    andi r22, 7
+; TINY-NEXT:    dec r22
+; TINY-NEXT:    brmi .LBB1_2
+; TINY-NEXT:  .LBB1_1: ; =>This Inner Loop Header: Depth=1
+; TINY-NEXT:    bst r24, 0
+; TINY-NEXT:    ror r24
+; TINY-NEXT:    bld r24, 7
+; TINY-NEXT:    dec r22
+; TINY-NEXT:    brpl .LBB1_1
+; TINY-NEXT:  .LBB1_2:
+; TINY-NEXT:    ret
   %mod = urem i8 %amt, 8
-
   %inv = sub i8 8, %mod
   %parta = lshr i8 %val, %mod
   %partb = shl i8 %val, %inv
-
   %rotr = or i8 %parta, %partb
-
   ret i8 %rotr
 }
 


        


More information about the llvm-commits mailing list