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:
parent
e64219b8ab
commit
5a90613181
@ -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; }
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user