forked from OSchip/llvm-project
GlobalISel: IRTranslate llvm.fabs.* intrinsic
Summary: Fabs is a common floating-point operation, especially for some expansions. This patch adds a new generic opcode for llvm.fabs.* intrinsic in order to avoid building/matching this intrinsic. Reviewers: qcolombet, aditya_nandakumar, dsanders, rovka Reviewed By: aditya_nandakumar Subscribers: kristof.beyls, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D43864 llvm-svn: 326749
This commit is contained in:
parent
82daad31fe
commit
2bc42e90ed
|
@ -286,6 +286,11 @@ m_GFPTrunc(const SrcTy &Src) {
|
|||
return UnaryOp_match<SrcTy, TargetOpcode::G_FPTRUNC>(Src);
|
||||
}
|
||||
|
||||
template <typename SrcTy>
|
||||
inline UnaryOp_match<SrcTy, TargetOpcode::G_FABS> m_GFabs(const SrcTy &Src) {
|
||||
return UnaryOp_match<SrcTy, TargetOpcode::G_FABS>(Src);
|
||||
}
|
||||
|
||||
template <typename SrcTy>
|
||||
inline UnaryOp_match<SrcTy, TargetOpcode::COPY> m_Copy(SrcTy &&Src) {
|
||||
return UnaryOp_match<SrcTy, TargetOpcode::COPY>(std::forward<SrcTy>(Src));
|
||||
|
|
|
@ -427,6 +427,9 @@ HANDLE_TARGET_OPCODE(G_SITOFP)
|
|||
/// Generic unsigned-int to float conversion
|
||||
HANDLE_TARGET_OPCODE(G_UITOFP)
|
||||
|
||||
/// Generic FP absolute value.
|
||||
HANDLE_TARGET_OPCODE(G_FABS)
|
||||
|
||||
/// Generic pointer offset
|
||||
HANDLE_TARGET_OPCODE(G_GEP)
|
||||
|
||||
|
|
|
@ -378,6 +378,12 @@ def G_UITOFP : GenericInstruction {
|
|||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
def G_FABS : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src);
|
||||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Floating Point Binary ops.
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -746,6 +746,11 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
|
|||
.addDef(getOrCreateVReg(CI))
|
||||
.addUse(getOrCreateVReg(*CI.getArgOperand(0)));
|
||||
return true;
|
||||
case Intrinsic::fabs:
|
||||
MIRBuilder.buildInstr(TargetOpcode::G_FABS)
|
||||
.addDef(getOrCreateVReg(CI))
|
||||
.addUse(getOrCreateVReg(*CI.getArgOperand(0)));
|
||||
return true;
|
||||
case Intrinsic::fma:
|
||||
MIRBuilder.buildInstr(TargetOpcode::G_FMA)
|
||||
.addDef(getOrCreateVReg(CI))
|
||||
|
|
|
@ -1318,6 +1318,17 @@ define float @test_log2_intrin(float %a) {
|
|||
%res = call float @llvm.log2.f32(float %a)
|
||||
ret float %res
|
||||
}
|
||||
|
||||
declare float @llvm.fabs.f32(float)
|
||||
define float @test_fabs_intrin(float %a) {
|
||||
; CHECK-LABEL: name: test_fabs_intrin
|
||||
; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
|
||||
; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FABS [[A]]
|
||||
; CHECK: $s0 = COPY [[RES]]
|
||||
%res = call float @llvm.fabs.f32(float %a)
|
||||
ret float %res
|
||||
}
|
||||
|
||||
declare void @llvm.lifetime.start.p0i8(i64, i8*)
|
||||
declare void @llvm.lifetime.end.p0i8(i64, i8*)
|
||||
define void @test_lifetime_intrin() {
|
||||
|
|
|
@ -230,6 +230,35 @@ TEST(PatternMatchInstr, MatchBinaryOp) {
|
|||
ASSERT_EQ(Src1, Copies[1]);
|
||||
}
|
||||
|
||||
TEST(PatternMatchInstr, MatchFPUnaryOp) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<TargetMachine> TM = createTargetMachine();
|
||||
if (!TM)
|
||||
return;
|
||||
auto ModuleMMIPair = createDummyModule(Context, *TM, "");
|
||||
MachineFunction *MF =
|
||||
getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
|
||||
SmallVector<unsigned, 4> Copies;
|
||||
collectCopies(Copies, MF);
|
||||
MachineBasicBlock *EntryMBB = &*MF->begin();
|
||||
MachineIRBuilder B(*MF);
|
||||
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||
B.setInsertPt(*EntryMBB, EntryMBB->end());
|
||||
|
||||
// Truncate s64 to s32.
|
||||
LLT s32 = LLT::scalar(32);
|
||||
auto Copy0s32 = B.buildFPTrunc(s32, Copies[0]);
|
||||
|
||||
// Match G_FABS.
|
||||
auto MIBFabs = B.buildInstr(TargetOpcode::G_FABS, s32, Copy0s32);
|
||||
bool match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg()));
|
||||
ASSERT_TRUE(match);
|
||||
unsigned Src;
|
||||
match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg(Src)));
|
||||
ASSERT_TRUE(match);
|
||||
ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
|
||||
}
|
||||
|
||||
TEST(PatternMatchInstr, MatchExtendsTrunc) {
|
||||
LLVMContext Context;
|
||||
std::unique_ptr<TargetMachine> TM = createTargetMachine();
|
||||
|
|
Loading…
Reference in New Issue