[llvm] [llvm][codegen] Add lowering to all intrinsics available in `math.h`. (PR #162825)
Ingo Müller via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 10 03:49:12 PDT 2025
https://github.com/ingomueller-net created https://github.com/llvm/llvm-project/pull/162825
This PR adds support to `IntrinsicLowering` for all intrinsics that correspond to functions in `math.h`. Such lowerings existed previously for a subset of them but others (such as `tanh`) were missing. This lead to those intrinsics not working in the LLVM interpreter.
The PR is split in three commits to make its changes more transparent: The first commit replaces the repeated logic in the various `case` statements of the corresponding intrinsics with a newly introduced macro while keeping the order of the supported intrinsics. The second commit reorders the existing calls to the macro. The third commit introduces new macro calls for previously unsupported intrinsics. By looking at the commits in isolation, it is more easy to see that no unintended changes have happened.
I have produced the list of to-be-supported intrinsics by extracting the functions in `math.h` with a bash one-liner and joined that with the list of LLVM intrinsics produced with another bash one-liner, both of which I will share in the comments of the PR.
>From 42df12174eedf904d03f3bc88a2302465cae74d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ingo=20M=C3=BCller?= <ingomueller at google.com>
Date: Fri, 10 Oct 2025 10:25:02 +0000
Subject: [PATCH 1/3] [llvm][codegen] Add lowering to all intrinsics available
in `math.h`.
This PR adds support to `IntrinsicLowering` for all intrinsics that
correspond to functions in `math.h`. Such lowerings existed previously
for a subset of them but others (such as `tanh`) were missing. This lead
to those intrinsics not working in the LLVM interpreter.
The PR is split in three commits to make its changes more transparent:
The first commit replaces the repeated logic in the various `case`
statements of the corresponding intrinsics with a newly introduced
macro while keeping the order of the supported intrinsics. The second
commit reorders the existing calls to the macro. The third commit
introduces new macro calls for previously unsupported intrinsics. By
looking at the commits in isolation, it is more easy to see that no
unintended changes have happened.
I have produced the list of to-be-supported intrinsics by extracting the
functions in `math.h` with a bash one-liner and joined that with the
list of LLVM intrinsics produced with another bash one-liner, both of
which I will share in the comments of the PR.
---
llvm/lib/CodeGen/IntrinsicLowering.cpp | 79 +++++++-------------------
1 file changed, 20 insertions(+), 59 deletions(-)
diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp
index 1518ead7698be..5179dde298d32 100644
--- a/llvm/lib/CodeGen/IntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp
@@ -383,66 +383,27 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType());
break;
}
- case Intrinsic::sqrt: {
- ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl");
- break;
- }
- case Intrinsic::log: {
- ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl");
- break;
- }
- case Intrinsic::log2: {
- ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l");
- break;
- }
- case Intrinsic::log10: {
- ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l");
- break;
- }
- case Intrinsic::exp: {
- ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl");
- break;
- }
- case Intrinsic::exp2: {
- ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l");
- break;
- }
- case Intrinsic::pow: {
- ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl");
- break;
- }
- case Intrinsic::sin: {
- ReplaceFPIntrinsicWithCall(CI, "sinf", "sin", "sinl");
- break;
- }
- case Intrinsic::cos: {
- ReplaceFPIntrinsicWithCall(CI, "cosf", "cos", "cosl");
- break;
- }
- case Intrinsic::floor: {
- ReplaceFPIntrinsicWithCall(CI, "floorf", "floor", "floorl");
- break;
- }
- case Intrinsic::ceil: {
- ReplaceFPIntrinsicWithCall(CI, "ceilf", "ceil", "ceill");
- break;
- }
- case Intrinsic::trunc: {
- ReplaceFPIntrinsicWithCall(CI, "truncf", "trunc", "truncl");
- break;
- }
- case Intrinsic::round: {
- ReplaceFPIntrinsicWithCall(CI, "roundf", "round", "roundl");
- break;
- }
- case Intrinsic::roundeven: {
- ReplaceFPIntrinsicWithCall(CI, "roundevenf", "roundeven", "roundevenl");
- break;
- }
- case Intrinsic::copysign: {
- ReplaceFPIntrinsicWithCall(CI, "copysignf", "copysign", "copysignl");
- break;
+#define MATH_INTRINSIC_CASE(baseName) \
+ case Intrinsic::baseName: { \
+ ReplaceFPIntrinsicWithCall(CI, #baseName "f", #baseName, #baseName "l"); \
+ break; \
}
+ MATH_INTRINSIC_CASE(sqrt)
+ MATH_INTRINSIC_CASE(log)
+ MATH_INTRINSIC_CASE(log2)
+ MATH_INTRINSIC_CASE(log10)
+ MATH_INTRINSIC_CASE(exp)
+ MATH_INTRINSIC_CASE(exp2)
+ MATH_INTRINSIC_CASE(pow)
+ MATH_INTRINSIC_CASE(sin)
+ MATH_INTRINSIC_CASE(cos)
+ MATH_INTRINSIC_CASE(floor)
+ MATH_INTRINSIC_CASE(ceil)
+ MATH_INTRINSIC_CASE(trunc)
+ MATH_INTRINSIC_CASE(round)
+ MATH_INTRINSIC_CASE(roundeven)
+ MATH_INTRINSIC_CASE(copysign)
+#undef MATH_INTRINSIC_CASE
case Intrinsic::get_rounding:
// Lower to "round to the nearest"
if (!CI->getType()->isVoidTy())
>From d26057a0ef6e9d5f0e6fd1e60e1b64f1deebf8dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ingo=20M=C3=BCller?= <ingomueller at google.com>
Date: Fri, 10 Oct 2025 10:38:16 +0000
Subject: [PATCH 2/3] [llvm][codegen] Intrinsics continued: reorder macro
calls.
---
llvm/lib/CodeGen/IntrinsicLowering.cpp | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp
index 5179dde298d32..f132c7f5d5297 100644
--- a/llvm/lib/CodeGen/IntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp
@@ -388,21 +388,21 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
ReplaceFPIntrinsicWithCall(CI, #baseName "f", #baseName, #baseName "l"); \
break; \
}
- MATH_INTRINSIC_CASE(sqrt)
- MATH_INTRINSIC_CASE(log)
- MATH_INTRINSIC_CASE(log2)
- MATH_INTRINSIC_CASE(log10)
+ MATH_INTRINSIC_CASE(ceil)
+ MATH_INTRINSIC_CASE(copysign)
+ MATH_INTRINSIC_CASE(cos)
MATH_INTRINSIC_CASE(exp)
MATH_INTRINSIC_CASE(exp2)
- MATH_INTRINSIC_CASE(pow)
- MATH_INTRINSIC_CASE(sin)
- MATH_INTRINSIC_CASE(cos)
MATH_INTRINSIC_CASE(floor)
- MATH_INTRINSIC_CASE(ceil)
- MATH_INTRINSIC_CASE(trunc)
+ MATH_INTRINSIC_CASE(log)
+ MATH_INTRINSIC_CASE(log10)
+ MATH_INTRINSIC_CASE(log2)
+ MATH_INTRINSIC_CASE(pow)
MATH_INTRINSIC_CASE(round)
MATH_INTRINSIC_CASE(roundeven)
- MATH_INTRINSIC_CASE(copysign)
+ MATH_INTRINSIC_CASE(sin)
+ MATH_INTRINSIC_CASE(sqrt)
+ MATH_INTRINSIC_CASE(trunc)
#undef MATH_INTRINSIC_CASE
case Intrinsic::get_rounding:
// Lower to "round to the nearest"
>From 1becb253dfbced5853989d63f4216fa879cbd770 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ingo=20M=C3=BCller?= <ingomueller at google.com>
Date: Fri, 10 Oct 2025 10:36:18 +0000
Subject: [PATCH 3/3] [llvm][codegen] Intrinsics continued: add new macro
calls.
---
llvm/lib/CodeGen/IntrinsicLowering.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp
index f132c7f5d5297..477db058da07e 100644
--- a/llvm/lib/CodeGen/IntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp
@@ -388,20 +388,36 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
ReplaceFPIntrinsicWithCall(CI, #baseName "f", #baseName, #baseName "l"); \
break; \
}
+ MATH_INTRINSIC_CASE(acos)
+ MATH_INTRINSIC_CASE(asin)
+ MATH_INTRINSIC_CASE(atan)
+ MATH_INTRINSIC_CASE(atan2)
MATH_INTRINSIC_CASE(ceil)
MATH_INTRINSIC_CASE(copysign)
MATH_INTRINSIC_CASE(cos)
+ MATH_INTRINSIC_CASE(cosh)
MATH_INTRINSIC_CASE(exp)
+ MATH_INTRINSIC_CASE(exp10)
MATH_INTRINSIC_CASE(exp2)
+ MATH_INTRINSIC_CASE(fabs)
MATH_INTRINSIC_CASE(floor)
+ MATH_INTRINSIC_CASE(fma)
+ MATH_INTRINSIC_CASE(frexp)
+ MATH_INTRINSIC_CASE(ldexp)
MATH_INTRINSIC_CASE(log)
MATH_INTRINSIC_CASE(log10)
MATH_INTRINSIC_CASE(log2)
+ MATH_INTRINSIC_CASE(modf)
+ MATH_INTRINSIC_CASE(nearbyint)
MATH_INTRINSIC_CASE(pow)
+ MATH_INTRINSIC_CASE(rint)
MATH_INTRINSIC_CASE(round)
MATH_INTRINSIC_CASE(roundeven)
MATH_INTRINSIC_CASE(sin)
+ MATH_INTRINSIC_CASE(sinh)
MATH_INTRINSIC_CASE(sqrt)
+ MATH_INTRINSIC_CASE(tan)
+ MATH_INTRINSIC_CASE(tanh)
MATH_INTRINSIC_CASE(trunc)
#undef MATH_INTRINSIC_CASE
case Intrinsic::get_rounding:
More information about the llvm-commits
mailing list