[llvm] [SimplifyLibCalls] Preserve !fpmath when replacing libcalls. (PR #227886)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 15:02:22 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Florian Hahn (fhahn)
<details>
<summary>Changes</summary>
As pointed out in https://github.com/llvm/llvm-project/pull/227697, replaceUnaryCall and replaceBinaryCall drop !fpmath.
Transfer it to the created intrinsics.
---
Full diff: https://github.com/llvm/llvm-project/pull/227886.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp (+9)
- (added) llvm/test/Transforms/InstCombine/libcall-fpmath.ll (+43)
``````````diff
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index f6235b5b98fcb..2ca27db66d490 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2022,11 +2022,19 @@ Value *LibCallSimplifier::optimizeNew(CallInst *CI, IRBuilderBase &B,
// Math Library Optimizations
//===----------------------------------------------------------------------===//
+/// Preserve the accuracy requirement of \p Old on the replacement \p New.
+static void copyFPMath(const CallInst &Old, Value *New) {
+ if (auto *NewI = dyn_cast<Instruction>(New))
+ if (MDNode *MD = Old.getMetadata(LLVMContext::MD_fpmath))
+ NewI->setMetadata(LLVMContext::MD_fpmath, MD);
+}
+
// Replace a libcall \p CI with a call to intrinsic \p IID
static Value *replaceUnaryCall(CallInst *CI, IRBuilderBase &B,
Intrinsic::ID IID) {
Value *NewCall = B.CreateUnaryIntrinsic(IID, CI->getArgOperand(0), CI);
NewCall->takeName(CI);
+ copyFPMath(*CI, NewCall);
return copyFlags(*CI, NewCall);
}
@@ -2035,6 +2043,7 @@ static Value *replaceBinaryCall(CallInst *CI, IRBuilderBase &B,
Value *NewCall = B.CreateBinaryIntrinsic(IID, CI->getArgOperand(0),
CI->getArgOperand(1), CI);
NewCall->takeName(CI);
+ copyFPMath(*CI, NewCall);
return copyFlags(*CI, NewCall);
}
diff --git a/llvm/test/Transforms/InstCombine/libcall-fpmath.ll b/llvm/test/Transforms/InstCombine/libcall-fpmath.ll
new file mode 100644
index 0000000000000..7c09c482b620b
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/libcall-fpmath.ll
@@ -0,0 +1,43 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=instcombine -S %s | FileCheck %s
+
+; !fpmath must be preserved when a libcall is replaced by an intrinsic.
+
+define double @floor_fpmath(double %x) {
+; CHECK-LABEL: define double @floor_fpmath(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = call double @llvm.floor.f64(double [[X]]), !fpmath [[META0:![0-9]+]]
+; CHECK-NEXT: ret double [[R]]
+;
+ %r = call double @floor(double %x), !fpmath !0
+ ret double %r
+}
+
+define double @fabs_fpmath(double %x) {
+; CHECK-LABEL: define double @fabs_fpmath(
+; CHECK-SAME: double [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = call double @llvm.fabs.f64(double [[X]]), !fpmath [[META0]]
+; CHECK-NEXT: ret double [[R]]
+;
+ %r = call double @fabs(double %x), !fpmath !0
+ ret double %r
+}
+
+define float @sinf_fpmath(float %x) {
+; CHECK-LABEL: define float @sinf_fpmath(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = call float @llvm.sin.f32(float [[X]]), !fpmath [[META0]]
+; CHECK-NEXT: ret float [[R]]
+;
+ %r = call float @sinf(float %x) memory(none), !fpmath !0
+ ret float %r
+}
+
+declare double @floor(double)
+declare double @fabs(double)
+declare float @sinf(float)
+
+!0 = !{float 2.5}
+;.
+; CHECK: [[META0]] = !{float 2.500000e+00}
+;.
``````````
</details>
https://github.com/llvm/llvm-project/pull/227886
More information about the llvm-commits
mailing list