GlobalISel: translate floating-point comparisons
llvm-svn: 279319
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 3fc09fe..8d83538 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -134,8 +134,19 @@
/// Translate a phi instruction.
bool translatePHI(const User &U);
+ /// Translate a comparison (icmp or fcmp) instruction or constant.
+ bool translateCompare(const User &U);
+
/// Translate an integer compare instruction (or constant).
- bool translateICmp(const User &U);
+ bool translateICmp(const User &U) {
+ return translateCompare(U);
+ }
+
+ /// Translate a floating-point compare instruction (or constant).
+ bool translateFCmp(const User &U) {
+ return translateCompare(U);
+ }
+
/// Add remaining operands onto phis we've translated. Executed after all
/// MachineBasicBlocks for the function have been created.
@@ -273,7 +284,6 @@
bool translateAddrSpaceCast(const User &U) { return false; }
bool translateCleanupPad(const User &U) { return false; }
bool translateCatchPad(const User &U) { return false; }
- bool translateFCmp(const User &U) { return false; }
bool translateUserOp1(const User &U) { return false; }
bool translateUserOp2(const User &U) { return false; }
bool translateVAArg(const User &U) { return false; }
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index c8531e2..daaf511 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -320,6 +320,14 @@
MachineInstrBuilder buildICmp(ArrayRef<LLT> Tys, CmpInst::Predicate Pred,
unsigned Res, unsigned Op0, unsigned Op1);
+ /// Build and insert a G_FCMP
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildFCmp(ArrayRef<LLT> Tys, CmpInst::Predicate Pred,
+ unsigned Res, unsigned Op0, unsigned Op1);
+
/// Build and insert a \p Res = G_SELECT { \p Ty, s1 } \p Tst, \p Op0, \p Op1
///
/// \pre setBasicBlock or setMI must have been called.
diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td
index 9a4fde0..f234525 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -190,13 +190,20 @@
let hasSideEffects = 0;
}
-// Generic bitwise or.
+// Generic integer comparison.
def G_ICMP : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins unknown:$tst, unknown:$src1, unknown:$src2);
let hasSideEffects = 0;
}
+// Generic floating-point comparison.
+def G_FCMP : Instruction {
+ let OutOperandList = (outs unknown:$dst);
+ let InOperandList = (ins unknown:$tst, unknown:$src1, unknown:$src2);
+ let hasSideEffects = 0;
+}
+
// Generic select
def G_SELECT : Instruction {
let OutOperandList = (outs unknown:$dst);
diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def
index ad87497..ff06ace 100644
--- a/llvm/include/llvm/Target/TargetOpcodes.def
+++ b/llvm/include/llvm/Target/TargetOpcodes.def
@@ -265,6 +265,9 @@
/// Generic integer-base comparison, also applicable to vectors of integers.
HANDLE_TARGET_OPCODE(G_ICMP)
+/// Generic floating-point comparison, also applicable to vectors.
+HANDLE_TARGET_OPCODE(G_FCMP)
+
/// Generic select.
HANDLE_TARGET_OPCODE(G_SELECT)
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 1a243c5..36150c6 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -100,17 +100,24 @@
return true;
}
-bool IRTranslator::translateICmp(const User &U) {
- const CmpInst &CI = cast<CmpInst>(U);
- unsigned Op0 = getOrCreateVReg(*CI.getOperand(0));
- unsigned Op1 = getOrCreateVReg(*CI.getOperand(1));
- unsigned Res = getOrCreateVReg(CI);
- CmpInst::Predicate Pred = CI.getPredicate();
+bool IRTranslator::translateCompare(const User &U) {
+ const CmpInst *CI = dyn_cast<CmpInst>(&U);
+ unsigned Op0 = getOrCreateVReg(*U.getOperand(0));
+ unsigned Op1 = getOrCreateVReg(*U.getOperand(1));
+ unsigned Res = getOrCreateVReg(U);
+ CmpInst::Predicate Pred =
+ CI ? CI->getPredicate() : static_cast<CmpInst::Predicate>(
+ cast<ConstantExpr>(U).getPredicate());
- assert(isa<ICmpInst>(CI) && "only integer comparisons supported now");
- assert(CmpInst::isIntPredicate(Pred) && "only int comparisons supported now");
- MIRBuilder.buildICmp({LLT{*CI.getType()}, LLT{*CI.getOperand(0)->getType()}},
- Pred, Res, Op0, Op1);
+ if (CmpInst::isIntPredicate(Pred))
+ MIRBuilder.buildICmp(
+ {LLT{*U.getType()}, LLT{*U.getOperand(0)->getType()}}, Pred, Res, Op0,
+ Op1);
+ else
+ MIRBuilder.buildFCmp(
+ {LLT{*U.getType()}, LLT{*U.getOperand(0)->getType()}}, Pred, Res, Op0,
+ Op1);
+
return true;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 2fe6eab..aa64be5 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -222,6 +222,17 @@
.addUse(Op1);
}
+MachineInstrBuilder MachineIRBuilder::buildFCmp(ArrayRef<LLT> Tys,
+ CmpInst::Predicate Pred,
+ unsigned Res, unsigned Op0,
+ unsigned Op1) {
+ return buildInstr(TargetOpcode::G_FCMP, Tys)
+ .addDef(Res)
+ .addPredicate(Pred)
+ .addUse(Op0)
+ .addUse(Op1);
+}
+
MachineInstrBuilder MachineIRBuilder::buildSelect(LLT Ty, unsigned Res,
unsigned Tst,
unsigned Op0, unsigned Op1) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
index fd823f9..d8742e4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
@@ -793,3 +793,19 @@
store float 1.5, float* %addr
ret void
}
+
+; CHECK-LABEL: name: float_comparison
+; CHECK: [[LHSADDR:%[0-9]+]](64) = COPY %x0
+; CHECK: [[RHSADDR:%[0-9]+]](64) = COPY %x1
+; CHECK: [[BOOLADDR:%[0-9]+]](64) = COPY %x2
+; CHECK: [[LHS:%[0-9]+]](32) = G_LOAD { s32, p0 } [[LHSADDR]]
+; CHECK: [[RHS:%[0-9]+]](32) = G_LOAD { s32, p0 } [[RHSADDR]]
+; CHECK: [[TST:%[0-9]+]](1) = G_FCMP { s1, s32 } floatpred(oge), [[LHS]], [[RHS]]
+; CHECK: G_STORE { s1, p0 } [[TST]], [[BOOLADDR]]
+define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
+ %a = load float, float* %a.addr
+ %b = load float, float* %b.addr
+ %res = fcmp oge float %a, %b
+ store i1 %res, i1* %bool.addr
+ ret void
+}