1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

GlobalISel: translate floating-point comparisons

llvm-svn: 279319
This commit is contained in:
Tim Northover 2016-08-19 20:48:16 +00:00
parent e64219b8ab
commit 5a90613181
7 changed files with 75 additions and 13 deletions

View File

@ -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; }

View File

@ -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.

View File

@ -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);

View File

@ -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)

View File

@ -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();
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);
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);
return true;
}

View File

@ -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) {

View File

@ -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
}