]> granicus.if.org Git - llvm/commitdiff
GlobalISel: constrain PHI registers on AArch64.
authorTim Northover <tnorthover@apple.com>
Tue, 8 Nov 2016 00:34:06 +0000 (00:34 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 8 Nov 2016 00:34:06 +0000 (00:34 +0000)
Self-referencing PHI nodes need their destination operands to be constrained
because nothing else is likely to do so. For now we just pick a register class
naively.

Patch mostly by Ahmed again.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286183 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64InstructionSelector.cpp
test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir

index 0dd725ea1d1de8887c73c2c791508c4756b81b9b..7f2ce779a0cb34d7969d261e82472c8f352b5696 100644 (file)
@@ -484,10 +484,40 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const {
 
     if (Opcode ==  TargetOpcode::LOAD_STACK_GUARD)
       return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
-    else if (I.isCopy())
+
+    if (Opcode == TargetOpcode::PHI) {
+      const unsigned DefReg = I.getOperand(0).getReg();
+      const LLT DefTy = MRI.getType(DefReg);
+
+      const TargetRegisterClass *DefRC = nullptr;
+      if (TargetRegisterInfo::isPhysicalRegister(DefReg)) {
+        DefRC = TRI.getRegClass(DefReg);
+      } else {
+        const RegClassOrRegBank &RegClassOrBank =
+            MRI.getRegClassOrRegBank(DefReg);
+
+        DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>();
+        if (!DefRC) {
+          if (!DefTy.isValid()) {
+            DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");
+            return false;
+          }
+          const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>();
+          DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI);
+          if (!DefRC) {
+            DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");
+            return false;
+          }
+        }
+      }
+
+      return RBI.constrainGenericRegister(DefReg, *DefRC, MRI);
+    }
+
+    if (I.isCopy())
       return selectCopy(I, TII, MRI, TRI, RBI);
-    else
-      return true;
+
+    return true;
   }
 
 
index b91cc7c2b7b4951663e43a051d6e5376da890115..7d0ec021239c8d05a2e005739ea5a6641da5d53d 100644 (file)
 
   define void @icmp() { ret void }
   define void @fcmp() { ret void }
+
+  define void @phi() { ret void }
+
 ...
 
 ---
@@ -2834,3 +2837,40 @@ body:             |
     %3(s1) = G_FCMP floatpred(uge), %2, %2
 
 ...
+
+---
+# CHECK-LABEL: name: phi
+name:            phi
+legalized:       true
+regBankSelected: true
+tracksRegLiveness: true
+
+# CHECK:      registers:
+# CHECK-NEXT:  - { id: 0, class: fpr32 }
+# CHECK-NEXT:  - { id: 1, class: gpr32 }
+# CHECK-NEXT:  - { id: 2, class: fpr32 }
+registers:
+  - { id: 0, class: fpr }
+  - { id: 1, class: gpr }
+  - { id: 2, class: fpr }
+
+# CHECK:  body:
+# CHECK:    bb.1:
+# CHECK:      %2 = PHI %0, %bb.0, %2, %bb.1
+
+body:             |
+  bb.0:
+    liveins: %s0, %w0
+    successors: %bb.1
+    %0(s32) = COPY %s0
+    %1(s1) = COPY %w0
+
+  bb.1:
+    successors: %bb.1, %bb.2
+    %2(s32) = PHI %0, %bb.0, %2, %bb.1
+    G_BRCOND %1, %bb.1
+
+  bb.2:
+    %s0 = COPY %2
+    RET_ReallyLR implicit %s0
+...