ADT: Move some FPClassTest utility functions out of instcombine

This commit is contained in:
Matt Arsenault 2023-03-02 05:47:52 -04:00 committed by Matt Arsenault
parent 0eb59cab95
commit 18fa83ed36
3 changed files with 47 additions and 30 deletions

View File

@ -217,11 +217,20 @@ enum FPClassTest : unsigned {
fcPosFinite = fcPosNormal | fcPosSubnormal | fcPosZero,
fcNegFinite = fcNegNormal | fcNegSubnormal | fcNegZero,
fcFinite = fcPosFinite | fcNegFinite,
fcPositive = fcPosFinite | fcPosInf,
fcNegative = fcNegFinite | fcNegInf,
fcAllFlags = fcNan | fcInf | fcFinite,
};
LLVM_DECLARE_ENUM_AS_BITMASK(FPClassTest, /* LargestValue */ fcPosInf);
/// Return the test mask which returns true if the value's sign bit is flipped.
FPClassTest fneg(FPClassTest Mask);
/// Return the test mask which returns true if the value's sign bit is cleared.
FPClassTest fabs(FPClassTest Mask);
/// Write a human readable form of \p Mask to \p OS
raw_ostream &operator<<(raw_ostream &OS, FPClassTest Mask);

View File

@ -11,6 +11,40 @@
using namespace llvm;
FPClassTest llvm::fneg(FPClassTest Mask) {
FPClassTest NewMask = Mask & fcNan;
if (Mask & fcNegInf)
NewMask |= fcPosInf;
if (Mask & fcNegNormal)
NewMask |= fcPosNormal;
if (Mask & fcNegSubnormal)
NewMask |= fcPosSubnormal;
if (Mask & fcNegZero)
NewMask |= fcPosZero;
if (Mask & fcPosZero)
NewMask |= fcNegZero;
if (Mask & fcPosSubnormal)
NewMask |= fcNegSubnormal;
if (Mask & fcPosNormal)
NewMask |= fcNegNormal;
if (Mask & fcPosInf)
NewMask |= fcNegInf;
return NewMask;
}
FPClassTest llvm::fabs(FPClassTest Mask) {
FPClassTest NewMask = Mask & fcNan;
if (Mask & fcPosZero)
NewMask |= fcZero;
if (Mask & fcPosSubnormal)
NewMask |= fcSubnormal;
if (Mask & fcPosNormal)
NewMask |= fcNormal;
if (Mask & fcPosInf)
NewMask |= fcInf;
return NewMask;
}
// Every bitfield has a unique name and one or more aliasing names that cover
// multiple bits. Names should be listed in order of preference, with higher
// popcounts listed first.

View File

@ -834,47 +834,21 @@ Instruction *InstCombinerImpl::foldIntrinsicIsFPClass(IntrinsicInst &II) {
Value *Src0 = II.getArgOperand(0);
Value *Src1 = II.getArgOperand(1);
const ConstantInt *CMask = cast<ConstantInt>(Src1);
uint32_t Mask = CMask->getZExtValue();
FPClassTest Mask = static_cast<FPClassTest>(CMask->getZExtValue());
const bool IsStrict = II.isStrictFP();
Value *FNegSrc;
if (match(Src0, m_FNeg(m_Value(FNegSrc)))) {
// is.fpclass (fneg x), mask -> is.fpclass x, (fneg mask)
unsigned NewMask = Mask & fcNan;
if (Mask & fcNegInf)
NewMask |= fcPosInf;
if (Mask & fcNegNormal)
NewMask |= fcPosNormal;
if (Mask & fcNegSubnormal)
NewMask |= fcPosSubnormal;
if (Mask & fcNegZero)
NewMask |= fcPosZero;
if (Mask & fcPosZero)
NewMask |= fcNegZero;
if (Mask & fcPosSubnormal)
NewMask |= fcNegSubnormal;
if (Mask & fcPosNormal)
NewMask |= fcNegNormal;
if (Mask & fcPosInf)
NewMask |= fcNegInf;
II.setArgOperand(1, ConstantInt::get(Src1->getType(), NewMask));
II.setArgOperand(1, ConstantInt::get(Src1->getType(), fneg(Mask)));
return replaceOperand(II, 0, FNegSrc);
}
Value *FAbsSrc;
if (match(Src0, m_FAbs(m_Value(FAbsSrc)))) {
unsigned NewMask = Mask & fcNan;
if (Mask & fcPosZero)
NewMask |= fcZero;
if (Mask & fcPosSubnormal)
NewMask |= fcSubnormal;
if (Mask & fcPosNormal)
NewMask |= fcNormal;
if (Mask & fcPosInf)
NewMask |= fcInf;
II.setArgOperand(1, ConstantInt::get(Src1->getType(), NewMask));
II.setArgOperand(1, ConstantInt::get(Src1->getType(), fabs(Mask)));
return replaceOperand(II, 0, FAbsSrc);
}