Index: llvm/trunk/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -287,6 +287,11 @@ } 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)); } Index: llvm/trunk/include/llvm/CodeGen/TargetOpcodes.def =================================================================== --- llvm/trunk/include/llvm/CodeGen/TargetOpcodes.def +++ llvm/trunk/include/llvm/CodeGen/TargetOpcodes.def @@ -427,6 +427,9 @@ /// 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) Index: llvm/trunk/include/llvm/Target/GenericOpcodes.td =================================================================== --- llvm/trunk/include/llvm/Target/GenericOpcodes.td +++ llvm/trunk/include/llvm/Target/GenericOpcodes.td @@ -378,6 +378,12 @@ let hasSideEffects = 0; } +def G_FABS : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Floating Point Binary ops. //------------------------------------------------------------------------------ Index: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -746,6 +746,11 @@ .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)) Index: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1318,6 +1318,17 @@ %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() { Index: llvm/trunk/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp =================================================================== --- llvm/trunk/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ llvm/trunk/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -230,6 +230,35 @@ 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();