@@ -1781,3 +1781,116 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
1781
1781
1782
1782
return MadeChange ? I : nullptr ;
1783
1783
}
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