[llvm] r284072 - GlobalISel: support selection of G_ICMP on AArch64.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 12 15:49:04 PDT 2016
Author: tnorthover
Date: Wed Oct 12 17:49:04 2016
New Revision: 284072
URL: http://llvm.org/viewvc/llvm-project?rev=284072&view=rev
Log:
GlobalISel: support selection of G_ICMP on AArch64.
Patch from Ahmed Bougaca again.
Modified:
llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=284072&r1=284071&r2=284072&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Wed Oct 12 17:49:04 2016
@@ -274,6 +274,33 @@ static bool selectCopy(MachineInstr &I,
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(
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;
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir?rev=284072&r1=284071&r2=284072&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir Wed Oct 12 17:49:04 2016
@@ -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
+...
More information about the llvm-commits
mailing list