[clang] [llvm] Reapply "InstCombine: Introduce SimplifyDemandedUseFPClass"" (PR #74056)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 7 22:20:41 PST 2024
================
@@ -1877,3 +1877,139 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
return MadeChange ? I : nullptr;
}
+
+/// For floating-point classes that resolve to a single bit pattern, return that
+/// value.
+static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask) {
+ switch (Mask) {
+ case fcPosZero:
+ return ConstantFP::getZero(Ty);
+ case fcNegZero:
+ return ConstantFP::getZero(Ty, true);
+ case fcPosInf:
+ return ConstantFP::getInfinity(Ty);
+ case fcNegInf:
+ return ConstantFP::getInfinity(Ty, true);
+ case fcNone:
+ return PoisonValue::get(Ty);
+ default:
+ return nullptr;
+ }
+}
+
+Value *InstCombinerImpl::SimplifyDemandedUseFPClass(
+ Value *V, const FPClassTest DemandedMask, KnownFPClass &Known,
+ unsigned Depth, Instruction *CxtI) {
+ assert(Depth <= MaxAnalysisRecursionDepth && "Limit Search Depth");
+ Type *VTy = V->getType();
+
+ assert(Known == KnownFPClass() && "expected uninitialized state");
+
+ if (DemandedMask == fcNone)
+ return isa<UndefValue>(V) ? nullptr : PoisonValue::get(VTy);
+
+ if (Depth == MaxAnalysisRecursionDepth)
+ return nullptr;
+
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (!I) {
+ // Handle constants and arguments
+ Known = computeKnownFPClass(V, fcAllFlags, CxtI, Depth + 1);
+ Value *FoldedToConst =
+ getFPClassConstant(VTy, DemandedMask & Known.KnownFPClasses);
+ return FoldedToConst == V ? nullptr : FoldedToConst;
+ }
+
+ if (!I->hasOneUse())
+ return nullptr;
+
+ // TODO: Should account for nofpclass/FastMathFlags on current instruction
+ switch (I->getOpcode()) {
+ case Instruction::FNeg: {
+ if (SimplifyDemandedFPClass(I, 0, llvm::fneg(DemandedMask), Known,
+ Depth + 1))
+ return I;
+ Known.fneg();
+ break;
+ }
+ case Instruction::Call: {
+ CallInst *CI = cast<CallInst>(I);
+ switch (CI->getIntrinsicID()) {
+ case Intrinsic::fabs:
+ if (SimplifyDemandedFPClass(I, 0, llvm::inverse_fabs(DemandedMask), Known,
+ Depth + 1))
+ return I;
+ Known.fabs();
+ break;
+ case Intrinsic::arithmetic_fence:
+ if (SimplifyDemandedFPClass(I, 0, DemandedMask, Known, Depth + 1))
+ return I;
+ break;
+ case Intrinsic::copysign: {
+ // Flip on more potentially demanded classes
+ const FPClassTest DemandedMaskAnySign = llvm::unknown_sign(DemandedMask);
+ if (SimplifyDemandedFPClass(I, 0, DemandedMaskAnySign, Known, Depth + 1))
+ return I;
+
+ if ((DemandedMask & fcPositive) == fcNone) {
----------------
arsenm wrote:
This is unnecessarily conservative, copysign/fabs/fneg preserve the sign of nan
https://github.com/llvm/llvm-project/pull/74056
More information about the llvm-commits
mailing list