@@ -1781,3 +1781,116 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
17811781
17821782 return MadeChange ? I : nullptr ;
17831783}
1784+
1785+ // / For floating-point classes that resolve to a single bit pattern, return that
1786+ // / value.
1787+ static Constant *getFPClassConstant (Type *Ty, FPClassTest Mask) {
1788+ switch (Mask) {
1789+ case fcPosZero:
1790+ return ConstantFP::getZero (Ty);
1791+ case fcNegZero:
1792+ return ConstantFP::getZero (Ty, true );
1793+ case fcPosInf:
1794+ return ConstantFP::getInfinity (Ty);
1795+ case fcNegInf:
1796+ return ConstantFP::getInfinity (Ty, true );
1797+ case fcNone:
1798+ return PoisonValue::get (Ty);
1799+ default :
1800+ return nullptr ;
1801+ }
1802+ }
1803+
1804+ Value *InstCombinerImpl::SimplifyDemandedUseFPClass (
1805+ Value *V, const FPClassTest DemandedMask, KnownFPClass &Known,
1806+ unsigned Depth, Instruction *CxtI) {
1807+ assert (Depth <= MaxAnalysisRecursionDepth && " Limit Search Depth" );
1808+ Type *VTy = V->getType ();
1809+
1810+ assert (Known == KnownFPClass () && " expected uninitialized state" );
1811+
1812+ if (DemandedMask == fcNone)
1813+ return isa<UndefValue>(V) ? nullptr : PoisonValue::get (VTy);
1814+
1815+ if (Depth == MaxAnalysisRecursionDepth)
1816+ return nullptr ;
1817+
1818+ Instruction *I = dyn_cast<Instruction>(V);
1819+ if (!I) {
1820+ // Handle constants and arguments
1821+ Known = computeKnownFPClass (V, fcAllFlags, CxtI, Depth + 1 );
1822+ Value *FoldedToConst =
1823+ getFPClassConstant (VTy, DemandedMask & Known.KnownFPClasses );
1824+ return FoldedToConst == V ? nullptr : FoldedToConst;
1825+ }
1826+
1827+ if (!I->hasOneUse ())
1828+ return nullptr ;
1829+
1830+ // TODO: Should account for nofpclass/FastMathFlags on current instruction
1831+ switch (I->getOpcode ()) {
1832+ case Instruction::FNeg: {
1833+ if (SimplifyDemandedFPClass (I, 0 , llvm::fneg (DemandedMask), Known,
1834+ Depth + 1 ))
1835+ return I;
1836+ Known.fneg ();
1837+ break ;
1838+ }
1839+ case Instruction::Call: {
1840+ CallInst *CI = cast<CallInst>(I);
1841+ switch (CI->getIntrinsicID ()) {
1842+ case Intrinsic::fabs:
1843+ if (SimplifyDemandedFPClass (I, 0 , llvm::inverse_fabs (DemandedMask), Known,
1844+ Depth + 1 ))
1845+ return I;
1846+ Known.fabs ();
1847+ break ;
1848+ case Intrinsic::arithmetic_fence:
1849+ if (SimplifyDemandedFPClass (I, 0 , DemandedMask, Known, Depth + 1 ))
1850+ return I;
1851+ break ;
1852+ default :
1853+ Known = computeKnownFPClass (I, ~DemandedMask, CxtI, Depth + 1 );
1854+ break ;
1855+ }
1856+
1857+ break ;
1858+ }
1859+ case Instruction::Select: {
1860+ KnownFPClass KnownLHS, KnownRHS;
1861+ if (SimplifyDemandedFPClass (I, 2 , DemandedMask, KnownRHS, Depth + 1 ) ||
1862+ SimplifyDemandedFPClass (I, 1 , DemandedMask, KnownLHS, Depth + 1 ))
1863+ return I;
1864+
1865+ if (KnownLHS.isKnownNever (DemandedMask))
1866+ return I->getOperand (2 );
1867+ if (KnownRHS.isKnownNever (DemandedMask))
1868+ return I->getOperand (1 );
1869+
1870+ // TODO: Recognize clamping patterns
1871+ Known = KnownLHS | KnownRHS;
1872+ break ;
1873+ }
1874+ default :
1875+ Known = computeKnownFPClass (I, ~DemandedMask, CxtI, Depth + 1 );
1876+ break ;
1877+ }
1878+
1879+ return getFPClassConstant (VTy, DemandedMask & Known.KnownFPClasses );
1880+ }
1881+
1882+ bool InstCombinerImpl::SimplifyDemandedFPClass (Instruction *I, unsigned OpNo,
1883+ FPClassTest DemandedMask,
1884+ KnownFPClass &Known,
1885+ unsigned Depth) {
1886+ Use &U = I->getOperandUse (OpNo);
1887+ Value *NewVal =
1888+ SimplifyDemandedUseFPClass (U.get (), DemandedMask, Known, Depth, I);
1889+ if (!NewVal)
1890+ return false ;
1891+ if (Instruction *OpInst = dyn_cast<Instruction>(U))
1892+ salvageDebugInfo (*OpInst);
1893+
1894+ replaceUse (U, NewVal);
1895+ return true ;
1896+ }
0 commit comments