diff options
| author | Tim Northover <tnorthover@apple.com> | 2016-10-12 22:49:04 +0000 |
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2016-10-12 22:49:04 +0000 |
| commit | 6c02ad5e4fcedbb0c53b522406fb574a03a7a916 (patch) | |
| tree | ec9324ff3d72fa41f54dcb48d260ff30f6678a99 /llvm/lib | |
| parent | 5e3dbf326c9c28180d66334a1ee6d3e98e14c9a2 (diff) | |
| download | bcm5719-llvm-6c02ad5e4fcedbb0c53b522406fb574a03a7a916.tar.gz bcm5719-llvm-6c02ad5e4fcedbb0c53b522406fb574a03a7a916.zip | |
GlobalISel: support selection of G_ICMP on AArch64.
Patch from Ahmed Bougaca again.
llvm-svn: 284072
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index 5be437d610b..63f59cfd003 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -274,6 +274,33 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, return true; } +static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) { + switch (P) { + default: + llvm_unreachable("Unknown condition code!"); + case CmpInst::ICMP_NE: + return AArch64CC::NE; + case CmpInst::ICMP_EQ: + return AArch64CC::EQ; + case CmpInst::ICMP_SGT: + return AArch64CC::GT; + case CmpInst::ICMP_SGE: + return AArch64CC::GE; + case CmpInst::ICMP_SLT: + return AArch64CC::LT; + case CmpInst::ICMP_SLE: + return AArch64CC::LE; + case CmpInst::ICMP_UGT: + return AArch64CC::HI; + case CmpInst::ICMP_UGE: + return AArch64CC::HS; + case CmpInst::ICMP_ULT: + return AArch64CC::LO; + case CmpInst::ICMP_ULE: + return AArch64CC::LS; + } +} + bool AArch64InstructionSelector::select(MachineInstr &I) const { assert(I.getParent() && "Instruction should be in a basic block!"); assert(I.getParent()->getParent() && "Instruction should be in a function!"); @@ -577,6 +604,50 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { case TargetOpcode::G_PTRTOINT: case TargetOpcode::G_BITCAST: return selectCopy(I, TII, MRI, TRI, RBI); + + case TargetOpcode::G_ICMP: { + if (Ty != LLT::scalar(1)) { + DEBUG(dbgs() << "G_ICMP result has type: " << Ty + << ", expected: " << LLT::scalar(1) << '\n'); + return false; + } + + unsigned CmpOpc = 0; + unsigned ZReg = 0; + + LLT CmpTy = MRI.getType(I.getOperand(2).getReg()); + if (CmpTy == LLT::scalar(32)) { + CmpOpc = AArch64::SUBSWrr; + ZReg = AArch64::WZR; + } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) { + CmpOpc = AArch64::SUBSXrr; + ZReg = AArch64::XZR; + } else { + return false; + } + + const AArch64CC::CondCode CC = changeICMPPredToAArch64CC( + (CmpInst::Predicate)I.getOperand(1).getPredicate()); + + MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) + .addDef(ZReg) + .addUse(I.getOperand(2).getReg()) + .addUse(I.getOperand(3).getReg()); + + MachineInstr &CSetMI = + *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) + .addDef(I.getOperand(0).getReg()) + .addUse(AArch64::WZR) + .addUse(AArch64::WZR) + .addImm(CC); + + constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI); + constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI); + + I.eraseFromParent(); + return true; + } + } return false; |

