forked from OSchip/llvm-project
GlobalISel: support selection of G_ICMP on AArch64.
Patch from Ahmed Bougaca again. llvm-svn: 284072
This commit is contained in:
parent
5e3dbf326c
commit
6c02ad5e4f
|
@ -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;
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
define void @bitcast_s64_gpr_fpr() { ret void }
|
||||
define void @bitcast_s64_fpr_gpr() { ret void }
|
||||
|
||||
define void @icmp() { ret void }
|
||||
...
|
||||
|
||||
---
|
||||
|
@ -1682,3 +1683,48 @@ body: |
|
|||
%0(s64) = COPY %d0
|
||||
%1(s64) = G_BITCAST %0
|
||||
...
|
||||
|
||||
---
|
||||
# CHECK-LABEL: name: icmp
|
||||
name: icmp
|
||||
legalized: true
|
||||
regBankSelected: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr32 }
|
||||
# CHECK-NEXT: - { id: 2, class: gpr64 }
|
||||
# CHECK-NEXT: - { id: 3, class: gpr32 }
|
||||
# CHECK-NEXT: - { id: 4, class: gpr64 }
|
||||
# CHECK-NEXT: - { id: 5, class: gpr32 }
|
||||
registers:
|
||||
- { id: 0, class: gpr }
|
||||
- { id: 1, class: gpr }
|
||||
- { id: 2, class: gpr }
|
||||
- { id: 3, class: gpr }
|
||||
- { id: 4, class: gpr }
|
||||
- { id: 5, class: gpr }
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: %wzr = SUBSWrr %0, %0, implicit-def %nzcv
|
||||
# CHECK: %1 = CSINCWr %wzr, %wzr, 0, implicit %nzcv
|
||||
|
||||
# CHECK: %xzr = SUBSXrr %2, %2, implicit-def %nzcv
|
||||
# CHECK: %3 = CSINCWr %wzr, %wzr, 2, implicit %nzcv
|
||||
|
||||
# CHECK: %xzr = SUBSXrr %4, %4, implicit-def %nzcv
|
||||
# CHECK: %5 = CSINCWr %wzr, %wzr, 1, implicit %nzcv
|
||||
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %w0, %x0
|
||||
|
||||
%0(s32) = COPY %w0
|
||||
%1(s1) = G_ICMP intpred(eq), %0, %0
|
||||
|
||||
%2(s64) = COPY %x0
|
||||
%3(s1) = G_ICMP intpred(uge), %2, %2
|
||||
|
||||
%4(p0) = COPY %x0
|
||||
%5(s1) = G_ICMP intpred(ne), %4, %4
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue