[llvm] [ConstantFolding] Add edge cases for llvm.log{, 2, 10} (PR #173304)
Stefan Weigl-Bosker via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 22 13:38:08 PST 2025
https://github.com/sweiglbosker updated https://github.com/llvm/llvm-project/pull/173304
>From d89086949384a6c28ca1fbad82a7a949fb6eaaef Mon Sep 17 00:00:00 2001
From: Stefan Weigl-Bosker <stefan at s00.xyz>
Date: Mon, 22 Dec 2025 15:11:43 -0500
Subject: [PATCH 1/2] [ConstantFolding] Fold llvm.log{,2,10} in cases where
libm errors
---
llvm/lib/Analysis/ConstantFolding.cpp | 18 ++++++++++++++++++
.../InstSimplify/ConstProp/calls.ll | 19 +++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index a9b51065a1d99..3642b7df69cd2 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2719,11 +2719,29 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
switch (IntrinsicID) {
default: break;
case Intrinsic::log:
+ if (U.isZero())
+ return ConstantFP::getInfinity(Ty, true);
+ else if (U.isNegative())
+ return ConstantFP::getNaN(Ty);
+ else if (U.isExactlyValue(1))
+ return ConstantFP::getZero(Ty);
return ConstantFoldFP(log, APF, Ty);
case Intrinsic::log2:
+ if (U.isZero())
+ return ConstantFP::getInfinity(Ty, true);
+ else if (U.isNegative())
+ return ConstantFP::getNaN(Ty);
+ else if (U.isExactlyValue(1))
+ return ConstantFP::getZero(Ty);
// TODO: What about hosts that lack a C99 library?
return ConstantFoldFP(log2, APF, Ty);
case Intrinsic::log10:
+ if (U.isZero())
+ return ConstantFP::getInfinity(Ty, true);
+ else if (U.isNegative())
+ return ConstantFP::getNaN(Ty);
+ else if (U.isExactlyValue(1))
+ return ConstantFP::getZero(Ty);
// TODO: What about hosts that lack a C99 library?
return ConstantFoldFP(log10, APF, Ty);
case Intrinsic::exp:
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll b/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll
index 26fb8c0d7a1c6..b2c3b6a8d460c 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll
@@ -214,5 +214,24 @@ entry:
ret float %1
}
+; log(0.0) -> -inf
+; Check that log instrinsics fold through cases where libc will throw an exception
+define float @test_intrinsic_log_zero() {
+; CHECK-LABEL: @test_intrinsic_log_zero(
+; CHECK-NOT: call
+; CHECK: ret float 0xFFF0000000000000
+ %1 = call float @llvm.log.f32(float 0.0)
+ ret float %1
+}
+
+; log(-x) -> NaN
+define float @test_intrinsic_log_neg() {
+; CHECK-LABEL: @test_intrinsic_log_neg(
+; CHECK-NOT: call
+; CHECK: ret float 0x7FF8000000000000
+ %1 = call float @llvm.log2.f32(float -20.0)
+ ret float %1
+}
+
declare double @llvm.pow.f64(double, double) nounwind readonly
declare float @llvm.pow.f32(float, float) nounwind readonly
>From a104def516b09a6c593b0cbdd3d8f21dce551a5a Mon Sep 17 00:00:00 2001
From: Stefan Weigl-Bosker <stefan at s00.xyz>
Date: Mon, 22 Dec 2025 16:37:32 -0500
Subject: [PATCH 2/2] fixup
---
llvm/lib/Analysis/ConstantFolding.cpp | 12 +--
.../InstSimplify/ConstProp/calls.ll | 92 +++++++++++++++++--
2 files changed, 89 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 3642b7df69cd2..7586b88bedb2f 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2721,26 +2721,26 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
case Intrinsic::log:
if (U.isZero())
return ConstantFP::getInfinity(Ty, true);
- else if (U.isNegative())
+ if (U.isNegative())
return ConstantFP::getNaN(Ty);
- else if (U.isExactlyValue(1))
+ if (U.isExactlyValue(1))
return ConstantFP::getZero(Ty);
return ConstantFoldFP(log, APF, Ty);
case Intrinsic::log2:
if (U.isZero())
return ConstantFP::getInfinity(Ty, true);
- else if (U.isNegative())
+ if (U.isNegative())
return ConstantFP::getNaN(Ty);
- else if (U.isExactlyValue(1))
+ if (U.isExactlyValue(1))
return ConstantFP::getZero(Ty);
// TODO: What about hosts that lack a C99 library?
return ConstantFoldFP(log2, APF, Ty);
case Intrinsic::log10:
if (U.isZero())
return ConstantFP::getInfinity(Ty, true);
- else if (U.isNegative())
+ if (U.isNegative())
return ConstantFP::getNaN(Ty);
- else if (U.isExactlyValue(1))
+ if (U.isExactlyValue(1))
return ConstantFP::getZero(Ty);
// TODO: What about hosts that lack a C99 library?
return ConstantFoldFP(log10, APF, Ty);
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll b/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll
index b2c3b6a8d460c..83a4fd47ddca5 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/calls.ll
@@ -214,22 +214,96 @@ entry:
ret float %1
}
+define float @test_intrinsic_log() {
+; CHECK-LABEL: @test_intrinsic_log(
+ %v = alloca <3 x float>
+ %f = alloca float
+
; log(0.0) -> -inf
-; Check that log instrinsics fold through cases where libc will throw an exception
-define float @test_intrinsic_log_zero() {
-; CHECK-LABEL: @test_intrinsic_log_zero(
; CHECK-NOT: call
-; CHECK: ret float 0xFFF0000000000000
+; CHECK: store float 0xFFF0000000000000
%1 = call float @llvm.log.f32(float 0.0)
+ store float %1, ptr %f
+
+; log(-x) -> NaN
+; CHECK-NOT: call
+; CHECK: store float 0x7FF8000000000000
+ %2 = call float @llvm.log.f32(float -20.0)
+ store float %2, ptr %f
+
+; log(1.0) -> 0.0
+; CHECK-NOT: call
+; CHECK: store float 0.000000e+00
+ %3 = call float @llvm.log.f32(float 1.0)
+ store float %3, ptr %f
+
+; CHECK-NOT: call
+; CHECK: store <3 x float> <float 0xFFF0000000000000, float 0x7FF8000000000000, float 0.000000e+00>
+ %4 = call <3 x float> @llvm.log.v4f32(<3 x float> <float 0.0, float -6.0, float 1.0>)
+ store <3 x float> %4, ptr %v
+
ret float %1
}
-; log(-x) -> NaN
-define float @test_intrinsic_log_neg() {
-; CHECK-LABEL: @test_intrinsic_log_neg(
+define float @test_intrinsic_log2() {
+; CHECK-LABEL: @test_intrinsic_log2(
+ %v = alloca <3 x float>
+ %f = alloca float
+
+; log2(0.0) -> -inf
+; CHECK-NOT: call
+; CHECK: store float 0xFFF0000000000000
+ %1 = call float @llvm.log2.f32(float 0.0)
+ store float %1, ptr %f
+
+; log2(-x) -> NaN
+; CHECK-NOT: call
+; CHECK: store float 0x7FF8000000000000
+ %2 = call float @llvm.log2.f32(float -20.0)
+ store float %2, ptr %f
+
+; log2(1.0) -> 0.0
; CHECK-NOT: call
-; CHECK: ret float 0x7FF8000000000000
- %1 = call float @llvm.log2.f32(float -20.0)
+; CHECK: store float 0.000000e+00
+ %3 = call float @llvm.log2.f32(float 1.0)
+ store float %3, ptr %f
+
+; CHECK-NOT: call
+; CHECK: store <3 x float> <float 0xFFF0000000000000, float 0x7FF8000000000000, float 0.000000e+00>
+ %4 = call <3 x float> @llvm.log2.v4f32(<3 x float> <float 0.0, float -6.0, float 1.0>)
+ store <3 x float> %4, ptr %v
+
+ ret float %1
+}
+
+define float @test_intrinsic_log10() {
+; CHECK-LABEL: @test_intrinsic_log10(
+ %v = alloca <3 x float>
+ %f = alloca float
+
+; log10(0.0) -> -inf
+; CHECK-NOT: call
+; CHECK: store float 0xFFF0000000000000
+ %1 = call float @llvm.log10.f32(float 0.0)
+ store float %1, ptr %f
+
+; log10(-x) -> NaN
+; CHECK-NOT: call
+; CHECK: store float 0x7FF8000000000000
+ %2 = call float @llvm.log10.f32(float -20.0)
+ store float %2, ptr %f
+
+; log10(1.0) -> 0.0
+; CHECK-NOT: call
+; CHECK: store float 0.000000e+00
+ %3 = call float @llvm.log10.f32(float 1.0)
+ store float %3, ptr %f
+
+; CHECK-NOT: call
+; CHECK: store <3 x float> <float 0xFFF0000000000000, float 0x7FF8000000000000, float 0.000000e+00>
+ %4 = call <3 x float> @llvm.log10.v4f32(<3 x float> <float 0.0, float -6.0, float 1.0>)
+ store <3 x float> %4, ptr %v
+
ret float %1
}
More information about the llvm-commits
mailing list