[llvm] r284073 - GlobalISel: select G_FCMP instructions on AArch64.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 12 15:49:08 PDT 2016
Author: tnorthover
Date: Wed Oct 12 17:49:07 2016
New Revision: 284073
URL: http://llvm.org/viewvc/llvm-project?rev=284073&view=rev
Log:
GlobalISel: select G_FCMP instructions on AArch64.
Another of Ahmed's patches.
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=284073&r1=284072&r2=284073&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Wed Oct 12 17:49:07 2016
@@ -301,6 +301,60 @@ static AArch64CC::CondCode changeICMPPre
}
}
+static void changeFCMPPredToAArch64CC(CmpInst::Predicate P,
+ AArch64CC::CondCode &CondCode,
+ AArch64CC::CondCode &CondCode2) {
+ CondCode2 = AArch64CC::AL;
+ switch (P) {
+ default:
+ llvm_unreachable("Unknown FP condition!");
+ case CmpInst::FCMP_OEQ:
+ CondCode = AArch64CC::EQ;
+ break;
+ case CmpInst::FCMP_OGT:
+ CondCode = AArch64CC::GT;
+ break;
+ case CmpInst::FCMP_OGE:
+ CondCode = AArch64CC::GE;
+ break;
+ case CmpInst::FCMP_OLT:
+ CondCode = AArch64CC::MI;
+ break;
+ case CmpInst::FCMP_OLE:
+ CondCode = AArch64CC::LS;
+ break;
+ case CmpInst::FCMP_ONE:
+ CondCode = AArch64CC::MI;
+ CondCode2 = AArch64CC::GT;
+ break;
+ case CmpInst::FCMP_ORD:
+ CondCode = AArch64CC::VC;
+ break;
+ case CmpInst::FCMP_UNO:
+ CondCode = AArch64CC::VS;
+ break;
+ case CmpInst::FCMP_UEQ:
+ CondCode = AArch64CC::EQ;
+ CondCode2 = AArch64CC::VS;
+ break;
+ case CmpInst::FCMP_UGT:
+ CondCode = AArch64CC::HI;
+ break;
+ case CmpInst::FCMP_UGE:
+ CondCode = AArch64CC::PL;
+ break;
+ case CmpInst::FCMP_ULT:
+ CondCode = AArch64CC::LT;
+ break;
+ case CmpInst::FCMP_ULE:
+ CondCode = AArch64CC::LE;
+ break;
+ case CmpInst::FCMP_UNE:
+ CondCode = AArch64CC::NE;
+ break;
+ }
+}
+
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!");
@@ -648,6 +702,68 @@ bool AArch64InstructionSelector::select(
return true;
}
+ case TargetOpcode::G_FCMP: {
+ if (Ty != LLT::scalar(1)) {
+ DEBUG(dbgs() << "G_FCMP result has type: " << Ty
+ << ", expected: " << LLT::scalar(1) << '\n');
+ return false;
+ }
+
+ unsigned CmpOpc = 0;
+ LLT CmpTy = MRI.getType(I.getOperand(2).getReg());
+ if (CmpTy == LLT::scalar(32)) {
+ CmpOpc = AArch64::FCMPSrr;
+ } else if (CmpTy == LLT::scalar(64)) {
+ CmpOpc = AArch64::FCMPDrr;
+ } else {
+ return false;
+ }
+
+ // FIXME: regbank
+
+ AArch64CC::CondCode CC1, CC2;
+ changeFCMPPredToAArch64CC(
+ (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2);
+
+ MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc))
+ .addUse(I.getOperand(2).getReg())
+ .addUse(I.getOperand(3).getReg());
+
+ const unsigned DefReg = I.getOperand(0).getReg();
+ unsigned Def1Reg = DefReg;
+ if (CC2 != AArch64CC::AL)
+ Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
+
+ MachineInstr &CSetMI =
+ *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
+ .addDef(Def1Reg)
+ .addUse(AArch64::WZR)
+ .addUse(AArch64::WZR)
+ .addImm(CC1);
+
+ if (CC2 != AArch64CC::AL) {
+ unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass);
+ MachineInstr &CSet2MI =
+ *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr))
+ .addDef(Def2Reg)
+ .addUse(AArch64::WZR)
+ .addUse(AArch64::WZR)
+ .addImm(CC2);
+ MachineInstr &OrMI =
+ *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr))
+ .addDef(DefReg)
+ .addUse(Def1Reg)
+ .addUse(Def2Reg);
+ constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI);
+ constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI);
+ }
+
+ 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=284073&r1=284072&r2=284073&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:07 2016
@@ -100,6 +100,7 @@
define void @bitcast_s64_fpr_gpr() { ret void }
define void @icmp() { ret void }
+ define void @fcmp() { ret void }
...
---
@@ -1728,3 +1729,43 @@ body: |
%4(p0) = COPY %x0
%5(s1) = G_ICMP intpred(ne), %4, %4
...
+
+---
+# CHECK-LABEL: name: fcmp
+name: fcmp
+legalized: true
+regBankSelected: true
+
+# CHECK: registers:
+# CHECK-NEXT: - { id: 0, class: fpr32 }
+# CHECK-NEXT: - { id: 1, class: gpr32 }
+# CHECK-NEXT: - { id: 2, class: fpr64 }
+# CHECK-NEXT: - { id: 3, class: gpr32 }
+# CHECK-NEXT: - { id: 4, class: gpr32 }
+# CHECK-NEXT: - { id: 5, class: gpr32 }
+registers:
+ - { id: 0, class: fpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: fpr }
+ - { id: 3, class: gpr }
+
+# CHECK: body:
+# CHECK: FCMPSrr %0, %0, implicit-def %nzcv
+# CHECK: [[TST_MI:%[0-9]+]] = CSINCWr %wzr, %wzr, 4, implicit %nzcv
+# CHECK: [[TST_GT:%[0-9]+]] = CSINCWr %wzr, %wzr, 12, implicit %nzcv
+# CHECK: %1 = ORRWrr [[TST_MI]], [[TST_GT]]
+
+# CHECK: FCMPDrr %2, %2, implicit-def %nzcv
+# CHECK: %3 = CSINCWr %wzr, %wzr, 5, implicit %nzcv
+
+body: |
+ bb.0:
+ liveins: %w0, %x0
+
+ %0(s32) = COPY %s0
+ %1(s1) = G_FCMP floatpred(one), %0, %0
+
+ %2(s64) = COPY %d0
+ %3(s1) = G_FCMP floatpred(uge), %2, %2
+
+...
More information about the llvm-commits
mailing list