|
54 | 54 | #include "llvm/Support/ErrorHandling.h" |
55 | 55 | #include "llvm/Support/KnownBits.h" |
56 | 56 | #include "llvm/Support/MathExtras.h" |
| 57 | +#include "llvm/Support/float128.h" |
57 | 58 | #include <cassert> |
58 | 59 | #include <cerrno> |
59 | 60 | #include <cfenv> |
@@ -1741,7 +1742,7 @@ Constant *GetConstantFoldFPValue(double V, Type *Ty) { |
1741 | 1742 | llvm_unreachable("Can only constant fold half/float/double"); |
1742 | 1743 | } |
1743 | 1744 |
|
1744 | | -#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128) |
| 1745 | +#if defined(HAS_IEE754_FLOAT128) |
1745 | 1746 | Constant *GetConstantFoldFPValue128(float128 V, Type *Ty) { |
1746 | 1747 | if (Ty->isFP128Ty()) |
1747 | 1748 | return ConstantFP::get(Ty, V); |
@@ -1781,11 +1782,25 @@ Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V, |
1781 | 1782 | return GetConstantFoldFPValue(Result, Ty); |
1782 | 1783 | } |
1783 | 1784 |
|
1784 | | -#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128) |
| 1785 | +#if defined(HAS_IEE754_FLOAT128) |
| 1786 | +float128 ConvertToQuad(const APFloat &Apf) { |
| 1787 | + APInt Api = Apf.bitcastToAPInt(); |
| 1788 | + __uint128_t Uint128 = |
| 1789 | + ((__uint128_t)Api.extractBitsAsZExtValue(64, 64) << 64) + |
| 1790 | + Api.extractBitsAsZExtValue(64, 0); |
| 1791 | + return llvm::bit_cast<float128>(Uint128); |
| 1792 | +} |
| 1793 | +#endif |
| 1794 | + |
| 1795 | +#if defined(HAS_IEE754_FLOAT128) |
1785 | 1796 | Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V, |
1786 | 1797 | Type *Ty) { |
1787 | 1798 | llvm_fenv_clearexcept(); |
1788 | | - float128 Result = NativeFP(V.convertToQuad()); |
| 1799 | + if (!V.isValidIEEEQuad()) |
| 1800 | + return nullptr; |
| 1801 | + |
| 1802 | + float128 Result = NativeFP(ConvertToQuad(V)); |
| 1803 | + |
1789 | 1804 | if (llvm_fenv_testexcept()) { |
1790 | 1805 | llvm_fenv_clearexcept(); |
1791 | 1806 | return nullptr; |
@@ -2114,13 +2129,16 @@ static Constant *ConstantFoldScalarCall1(StringRef Name, |
2114 | 2129 | if (IntrinsicID == Intrinsic::canonicalize) |
2115 | 2130 | return constantFoldCanonicalize(Ty, Call, U); |
2116 | 2131 |
|
2117 | | -#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128) |
| 2132 | +#if defined(HAS_IEE754_FLOAT128) |
2118 | 2133 | if (Ty->isFP128Ty()) { |
2119 | 2134 | if (IntrinsicID == Intrinsic::log) { |
2120 | | - float128 Result = logf128(Op->getValueAPF().convertToQuad()); |
| 2135 | + APFloat Value = Op->getValueAPF(); |
| 2136 | + if (!Value.isValidIEEEQuad()) |
| 2137 | + return nullptr; |
| 2138 | + |
| 2139 | + float128 Result = logf128(ConvertToQuad(Value)); |
2121 | 2140 | return GetConstantFoldFPValue128(Result, Ty); |
2122 | 2141 | } |
2123 | | - |
2124 | 2142 | LibFunc Fp128Func = NotLibFunc; |
2125 | 2143 | if (TLI->getLibFunc(Name, Fp128Func) && TLI->has(Fp128Func) && |
2126 | 2144 | Fp128Func == LibFunc_logl) |
|
0 commit comments