[PATCH] D60090: [ARM] Update check for CBZ in Ifcvt

Dave Green via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 1 12:25:00 PDT 2019


dmgreen created this revision.
dmgreen added reviewers: samparker, efriedma, olista01.
Herald added subscribers: hiraditya, kristof.beyls, javed.absar.
Herald added a project: LLVM.

This check in ifcvt mirrors the same one in constant island pass, for when a CBZ will be preferable to a IT block. The version in constant islands was updated recently to search backwards for CMP's, so this version should be updated too. (The code should probably be shared between the two, but I'm not sure exactly where that should go. I'm happy to move it.)

I was having trouble getting this to happen in a llc test without registry spilling or a schedule. MIR tests show the differences though. Test is new, I'm just showing the differences here for clarity.


https://reviews.llvm.org/D60090

Files:
  llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
  llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir


Index: llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir
===================================================================
--- llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir
+++ llvm/test/CodeGen/Thumb2/ifcvt-cbz.mir
@@ -133,10 +133,13 @@
 body:             |
   ; CHECK-LABEL: name: f3
   ; CHECK: bb.0:
+  ; CHECK:   successors: %bb.1(0x40000000), %bb.2(0x40000000)
   ; CHECK:   liveins: $r0, $lr, $r7
   ; CHECK:   t2CMPri killed renamable $r0, 0, 14, $noreg, implicit-def $cpsr
-  ; CHECK:   dead $r1 = t2MOVi 0, 14, $noreg, $noreg
-  ; CHECK:   tBX_RET 1, killed $cpsr
+  ; CHECK:   $r1 = t2MOVi 0, 14, $noreg, $noreg
+  ; CHECK:   t2Bcc %bb.2, 1, killed $cpsr
+  ; CHECK: bb.1:
+  ; CHECK:   liveins: $r7, $lr
   ; CHECK:   $sp = frame-setup t2STMDB_UPD $sp, 14, $noreg, killed $r7, killed $lr
   ; CHECK:   frame-setup CFI_INSTRUCTION def_cfa_offset 8
   ; CHECK:   frame-setup CFI_INSTRUCTION offset $lr, -4
@@ -145,6 +148,9 @@
   ; CHECK:   tBL 14, $noreg, @fn, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp, implicit-def dead $r0
   ; CHECK:   $sp = t2LDMIA_UPD $sp, 14, $noreg, def $r7, def $lr
   ; CHECK:   tBX_RET 14, $noreg
+  ; CHECK: bb.2:
+  ; CHECK:   liveins: $lr, $r7
+  ; CHECK:   tBX_RET 14, $noreg
   bb.0:
     successors: %bb.1(0x40000000), %bb.2(0x40000000)
     liveins: $r0, $lr, $r7
Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1889,6 +1889,16 @@
   return false;
 }
 
+static bool registerDefinedBetween(unsigned Reg,
+                                   MachineBasicBlock::iterator From,
+                                   MachineBasicBlock::iterator To,
+                                   const TargetRegisterInfo *TRI) {
+  for (auto I = From; I != To; ++I)
+    if (I->modifiesRegister(Reg, TRI))
+      return true;
+  return false;
+}
+
 bool ARMBaseInstrInfo::
 isProfitableToIfCvt(MachineBasicBlock &MBB,
                     unsigned NumCycles, unsigned ExtraPredCycles,
@@ -1898,23 +1908,32 @@
 
   // If we are optimizing for size, see if the branch in the predecessor can be
   // lowered to cbn?z by the constant island lowering pass, and return false if
-  // so. This results in a shorter instruction sequence.
+  // so. This results in a shorter instruction sequence. This check mirrors that
+  // in constant island pass.
   if (MBB.getParent()->getFunction().optForSize()) {
     MachineBasicBlock *Pred = *MBB.pred_begin();
     if (!Pred->empty()) {
       MachineInstr *LastMI = &*Pred->rbegin();
       if (LastMI->getOpcode() == ARM::t2Bcc) {
         MachineBasicBlock::iterator CmpMI = LastMI;
-        if (CmpMI != Pred->begin()) {
+        const TargetRegisterInfo *TRI = &getRegisterInfo();
+        while (CmpMI != Pred->begin()) {
           --CmpMI;
-          if (CmpMI->getOpcode() == ARM::tCMPi8 ||
-              CmpMI->getOpcode() == ARM::t2CMPri) {
-            unsigned Reg = CmpMI->getOperand(0).getReg();
-            unsigned PredReg = 0;
-            ARMCC::CondCodes P = getInstrPredicate(*CmpMI, PredReg);
-            if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
-                isARMLowRegister(Reg))
-              return false;
+          if (CmpMI->modifiesRegister(ARM::CPSR, TRI))
+            break;
+          if (CmpMI->readsRegister(ARM::CPSR, TRI))
+            break;
+        }
+
+        if (CmpMI->getOpcode() == ARM::tCMPi8 ||
+            CmpMI->getOpcode() == ARM::t2CMPri) {
+          unsigned Reg = CmpMI->getOperand(0).getReg();
+          unsigned PredReg = 0;
+          ARMCC::CondCodes P = getInstrPredicate(*CmpMI, PredReg);
+          if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
+              isARMLowRegister(Reg) &&
+              !registerDefinedBetween(Reg, CmpMI->getNextNode(), LastMI, TRI)) {
+            return false;
           }
         }
       }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60090.193150.patch
Type: text/x-patch
Size: 3980 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190401/03119a6c/attachment.bin>


More information about the llvm-commits mailing list