}
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));
}
/// 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)
let hasSideEffects = 0;
}
+def G_FABS : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+ let hasSideEffects = 0;
+}
+
//------------------------------------------------------------------------------
// Floating Point Binary ops.
//------------------------------------------------------------------------------
.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))
%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() {
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();