summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-08-19 20:48:16 +0000
committerTim Northover <tnorthover@apple.com>2016-08-19 20:48:16 +0000
commitd5c23bcfc9287a21280116ec1a5364f54c2df10c (patch)
tree82ba06131c63b20db973d6749e01faaacce7c57a
parent8075b823223ea465d8fc7d7720a8abbee5798b77 (diff)
downloadbcm5719-llvm-d5c23bcfc9287a21280116ec1a5364f54c2df10c.tar.gz
bcm5719-llvm-d5c23bcfc9287a21280116ec1a5364f54c2df10c.zip
GlobalISel: translate floating-point comparisons
llvm-svn: 279319
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h14
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h8
-rw-r--r--llvm/include/llvm/Target/GenericOpcodes.td9
-rw-r--r--llvm/include/llvm/Target/TargetOpcodes.def3
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp29
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp11
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll16
7 files changed, 76 insertions, 14 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 3fc09fed2d1..8d8353882b6 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -134,8 +134,19 @@ private:
/// 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 @@ private:
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 c8531e25377..daaf511fd74 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -320,6 +320,14 @@ public:
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 9a4fde0ff72..f2345254f5e 100644
--- a/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/llvm/include/llvm/Target/GenericOpcodes.td
@@ -190,13 +190,20 @@ def G_ASHR : Instruction {
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 ad87497ff2a..ff06ace97e3 100644
--- a/llvm/include/llvm/Target/TargetOpcodes.def
+++ b/llvm/include/llvm/Target/TargetOpcodes.def
@@ -265,6 +265,9 @@ HANDLE_TARGET_OPCODE(G_ASHR)
/// 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 1a243c54887..36150c6c444 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -100,17 +100,24 @@ bool IRTranslator::translateBinaryOp(unsigned Opcode, const User &U) {
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();
-
- 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);
+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());
+
+ 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 2fe6eab8cb3..aa64be5a4c3 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -222,6 +222,17 @@ MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
.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 fd823f9d397..d8742e45dc3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
@@ -793,3 +793,19 @@ define void @test_constant_float(float* %addr) {
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
+}
OpenPOWER on IntegriCloud