aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-11-08 00:34:06 +0000
committerTim Northover <tnorthover@apple.com>2016-11-08 00:34:06 +0000
commit7d88da6a46ba134e045378d77883f9b49f643d3b (patch)
treedfa7a533a633ce060aa605da2c5197419dfe9ed7
parent66b326bc550f569c29094e01cb9ac46c80b93721 (diff)
downloadllvm-7d88da6a46ba134e045378d77883f9b49f643d3b.zip
llvm-7d88da6a46ba134e045378d77883f9b49f643d3b.tar.gz
llvm-7d88da6a46ba134e045378d77883f9b49f643d3b.tar.bz2
GlobalISel: constrain PHI registers on AArch64.
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. llvm-svn: 286183
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp36
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir40
2 files changed, 73 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
index 0dd725e..7f2ce77 100644
--- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -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;
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
index b91cc7c..7d0ec02 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
@@ -147,6 +147,9 @@
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
+...