diff options
author | Tim Northover <tnorthover@apple.com> | 2016-11-08 00:34:06 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-11-08 00:34:06 +0000 |
commit | 7d88da6a46ba134e045378d77883f9b49f643d3b (patch) | |
tree | dfa7a533a633ce060aa605da2c5197419dfe9ed7 | |
parent | 66b326bc550f569c29094e01cb9ac46c80b93721 (diff) | |
download | llvm-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.cpp | 36 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir | 40 |
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 +... |