From: Volkan Keles Date: Mon, 5 Mar 2018 22:31:55 +0000 (+0000) Subject: GlobalISel: IRTranslate llvm.fabs.* intrinsic X-Git-Tag: llvmorg-7.0.0-rc1~11368 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2bc42e90ed147c45a1f0c74b61bb9f6176dbb9ef;p=platform%2Fupstream%2Fllvm.git 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 --- diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index e330221..2f31cab 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -287,6 +287,11 @@ m_GFPTrunc(const SrcTy &Src) { } template +inline UnaryOp_match m_GFabs(const SrcTy &Src) { + return UnaryOp_match(Src); +} + +template inline UnaryOp_match m_Copy(SrcTy &&Src) { return UnaryOp_match(std::forward(Src)); } diff --git a/llvm/include/llvm/CodeGen/TargetOpcodes.def b/llvm/include/llvm/CodeGen/TargetOpcodes.def index d3e8483..3016807 100644 --- a/llvm/include/llvm/CodeGen/TargetOpcodes.def +++ b/llvm/include/llvm/CodeGen/TargetOpcodes.def @@ -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) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 28c90bf..1af6a9a 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -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. //------------------------------------------------------------------------------ diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 4f6b41d..7fb82153 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -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)) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 40679fa..077be5e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -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() { diff --git a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp index aa18527..0816084 100644 --- a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -230,6 +230,35 @@ TEST(PatternMatchInstr, MatchBinaryOp) { ASSERT_EQ(Src1, Copies[1]); } +TEST(PatternMatchInstr, MatchFPUnaryOp) { + LLVMContext Context; + std::unique_ptr TM = createTargetMachine(); + if (!TM) + return; + auto ModuleMMIPair = createDummyModule(Context, *TM, ""); + MachineFunction *MF = + getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get()); + SmallVector 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 TM = createTargetMachine();