Skip to content

Commit d38c8a7

Browse files
authored
ConstantFold logl calls (#94944)
This is a follow up patch from #90611 which folds logl calls in the same manner as log.f128 calls. logl suffers from the same problem as logf128 of having slow calls to fp128 log functions which can be constant folded. However, logl is emitted with -fmath-errno and log.f128 is emitted by -fno-math-errno by certain intrinsics.
1 parent d97951e commit d38c8a7

File tree

2 files changed

+82
-8
lines changed

2 files changed

+82
-8
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,9 +1678,9 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
16781678
Name == "floor" || Name == "floorf" ||
16791679
Name == "fmod" || Name == "fmodf";
16801680
case 'l':
1681-
return Name == "log" || Name == "logf" ||
1682-
Name == "log2" || Name == "log2f" ||
1683-
Name == "log10" || Name == "log10f";
1681+
return Name == "log" || Name == "logf" || Name == "log2" ||
1682+
Name == "log2f" || Name == "log10" || Name == "log10f" ||
1683+
Name == "logl";
16841684
case 'n':
16851685
return Name == "nearbyint" || Name == "nearbyintf";
16861686
case 'p':
@@ -1743,6 +1743,14 @@ Constant *GetConstantFoldFPValue(double V, Type *Ty) {
17431743
llvm_unreachable("Can only constant fold half/float/double");
17441744
}
17451745

1746+
#if defined(HAS_IEE754_FLOAT128)
1747+
Constant *GetConstantFoldFPValue128(__float128 V, Type *Ty) {
1748+
if (Ty->isFP128Ty())
1749+
return ConstantFP::get(Ty, V);
1750+
llvm_unreachable("Can only constant fold fp128");
1751+
}
1752+
#endif
1753+
17461754
/// Clear the floating-point exception state.
17471755
inline void llvm_fenv_clearexcept() {
17481756
#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
@@ -1775,6 +1783,20 @@ Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V,
17751783
return GetConstantFoldFPValue(Result, Ty);
17761784
}
17771785

1786+
#if defined(HAS_IEE754_FLOAT128)
1787+
Constant *ConstantFoldFP128(long double (*NativeFP)(long double),
1788+
const APFloat &V, Type *Ty) {
1789+
llvm_fenv_clearexcept();
1790+
__float128 Result = NativeFP(V.convertToQuad());
1791+
if (llvm_fenv_testexcept()) {
1792+
llvm_fenv_clearexcept();
1793+
return nullptr;
1794+
}
1795+
1796+
return GetConstantFoldFPValue128(Result, Ty);
1797+
}
1798+
#endif
1799+
17781800
Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
17791801
const APFloat &V, const APFloat &W, Type *Ty) {
17801802
llvm_fenv_clearexcept();
@@ -2096,12 +2118,15 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
20962118

20972119
#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
20982120
if (Ty->isFP128Ty()) {
2099-
switch (IntrinsicID) {
2100-
default:
2101-
return nullptr;
2102-
case Intrinsic::log:
2103-
return ConstantFP::get(Ty, logf128(Op->getValueAPF().convertToQuad()));
2121+
if (IntrinsicID == Intrinsic::log) {
2122+
__float128 Result = logf128(Op->getValueAPF().convertToQuad());
2123+
return GetConstantFoldFPValue128(Result, Ty);
21042124
}
2125+
2126+
LibFunc Fp128Func = NotLibFunc;
2127+
if (TLI->getLibFunc(Name, Fp128Func) && TLI->has(Fp128Func) &&
2128+
Fp128Func == LibFunc_logl)
2129+
return ConstantFoldFP128(logf128, Op->getValueAPF(), Ty);
21052130
}
21062131
#endif
21072132

@@ -2365,6 +2390,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
23652390
// TODO: What about hosts that lack a C99 library?
23662391
return ConstantFoldFP(log10, APF, Ty);
23672392
break;
2393+
case LibFunc_logl:
2394+
return nullptr;
23682395
case LibFunc_nearbyint:
23692396
case LibFunc_nearbyintf:
23702397
case LibFunc_rint:

llvm/test/Transforms/InstSimplify/ConstProp/logf128.ll

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
; REQUIRES: has_logf128
55
declare fp128 @llvm.log.f128(fp128)
6+
declare fp128 @logl(fp128)
67

78
define fp128 @log_e_64(){
89
; CHECK-LABEL: define fp128 @log_e_64() {
@@ -124,3 +125,49 @@ define <2 x fp128> @log_e_negative_2_vector(){
124125
%A = call <2 x fp128> @llvm.log.v2f128(<2 x fp128> <fp128 0xL0000000000000000C000000000000000, fp128 0xL0000000000000000C000000000000001>)
125126
ret <2 x fp128> %A
126127
}
128+
129+
define fp128 @logl_e_64(){
130+
; CHECK-LABEL: define fp128 @logl_e_64() {
131+
; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000004005000000000000)
132+
; CHECK-NEXT: ret fp128 0xL300000000000000040010A2B23F3BAB7
133+
;
134+
%A = call fp128 @logl(fp128 noundef 0xL00000000000000004005000000000000)
135+
ret fp128 %A
136+
}
137+
138+
define fp128 @logl_e_0(){
139+
; CHECK-LABEL: define fp128 @logl_e_0() {
140+
; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000000000000000000000)
141+
; CHECK-NEXT: ret fp128 [[A]]
142+
;
143+
%A = call fp128 @logl(fp128 noundef 0xL00000000000000000000000000000000)
144+
ret fp128 %A
145+
}
146+
147+
define fp128 @logl_e_infinity(){
148+
; CHECK-LABEL: define fp128 @logl_e_infinity() {
149+
; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000000)
150+
; CHECK-NEXT: ret fp128 0xL00000000000000007FFF000000000000
151+
;
152+
%A = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000000)
153+
ret fp128 %A
154+
}
155+
156+
define fp128 @logl_e_nan(){
157+
; CHECK-LABEL: define fp128 @logl_e_nan() {
158+
; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000001)
159+
; CHECK-NEXT: ret fp128 [[A]]
160+
;
161+
%A = call fp128 @logl(fp128 noundef 0xL00000000000000007FFF000000000001)
162+
ret fp128 %A
163+
}
164+
165+
166+
define fp128 @logl_e_negative_2(){
167+
; CHECK-LABEL: define fp128 @logl_e_negative_2() {
168+
; CHECK-NEXT: [[A:%.*]] = call fp128 @logl(fp128 noundef 0xL0000000000000000C000000000000000)
169+
; CHECK-NEXT: ret fp128 [[A]]
170+
;
171+
%A = call fp128 @logl(fp128 noundef 0xL0000000000000000C000000000000000)
172+
ret fp128 %A
173+
}

0 commit comments

Comments
 (0)