[llvm] [PowerPC] Fix nearbyintl() raising spurious FE_INEXACT on AIX (PR #189084)

Lei Huang via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 07:13:23 PDT 2026


https://github.com/lei137 updated https://github.com/llvm/llvm-project/pull/189084

>From 99501b0cea59d66d5ed6cc68d7ef83453705a94e Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 27 Mar 2026 14:32:11 -0400
Subject: [PATCH 1/2] [PowerPC] Fix nearbyintl() raising spurious FE_INEXACT on
 AIX with ppcf128

Revert back to lib call for nerbyintl() as ppc don't have an
instruction that handles this situation.
---
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp |  9 +++++-
 .../InstCombine/ppcf128-nearbyint.ll          | 29 +++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll

diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 3b68afe8700dd..cfdba3ba5444d 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -4089,8 +4089,15 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
     return replaceUnaryCall(CI, Builder, Intrinsic::round);
   case LibFunc_roundeven:
     return replaceUnaryCall(CI, Builder, Intrinsic::roundeven);
-  case LibFunc_nearbyint:
+  case LibFunc_nearbyint: {
+    // Don't convert ppcf128 nearbyint to intrinsic - it needs to stay as
+    // a library call to avoid incorrect lowering that loses precision and
+    // raises spurious FP exceptions.
+    Type *Ty = CI->getType();
+    if (Ty->isPPC_FP128Ty())
+      return nullptr;
     return replaceUnaryCall(CI, Builder, Intrinsic::nearbyint);
+  }
   case LibFunc_rint:
     return replaceUnaryCall(CI, Builder, Intrinsic::rint);
   case LibFunc_trunc:
diff --git a/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll b/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll
new file mode 100644
index 0000000000000..504a9915d2b99
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; Test that ppcf128 nearbyint is NOT converted to an intrinsic
+; because the backend doesn't properly support it and would incorrectly
+; lower it, causing precision loss and spurious FP exceptions.
+
+declare ppc_fp128 @nearbyintl(ppc_fp128)
+
+; CHECK-LABEL: @test_nearbyintl(
+; CHECK-NEXT:    [[CALL:%.*]] = tail call ppc_fp128 @nearbyintl(ppc_fp128 [[X:%.*]])
+; CHECK-NEXT:    ret ppc_fp128 [[CALL]]
+;
+define ppc_fp128 @test_nearbyintl(ppc_fp128 %x) {
+  %call = tail call ppc_fp128 @nearbyintl(ppc_fp128 %x)
+  ret ppc_fp128 %call
+}
+
+; For comparison, verify that f64 nearbyint IS converted to intrinsic
+declare double @nearbyint(double)
+
+; CHECK-LABEL: @test_nearbyint_f64(
+; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.nearbyint.f64(double [[X:%.*]])
+; CHECK-NEXT:    ret double [[TMP1]]
+;
+define double @test_nearbyint_f64(double %x) {
+  %call = tail call double @nearbyint(double %x)
+  ret double %call
+}
\ No newline at end of file

>From 81f9b3d3c539584c4eb88594c7e60f9f9eee0649 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 27 Mar 2026 15:36:23 -0400
Subject: [PATCH 2/2] udpate expected

---
 llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll b/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll
index 504a9915d2b99..88ee2c52d2b1a 100644
--- a/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll
+++ b/llvm/test/Transforms/InstCombine/ppcf128-nearbyint.ll
@@ -20,8 +20,8 @@ define ppc_fp128 @test_nearbyintl(ppc_fp128 %x) {
 declare double @nearbyint(double)
 
 ; CHECK-LABEL: @test_nearbyint_f64(
-; CHECK-NEXT:    [[TMP1:%.*]] = call double @llvm.nearbyint.f64(double [[X:%.*]])
-; CHECK-NEXT:    ret double [[TMP1]]
+; CHECK-NEXT:    [[CALL:%.*]] = tail call double @llvm.nearbyint.f64(double [[X:%.*]])
+; CHECK-NEXT:    ret double [[CALL]]
 ;
 define double @test_nearbyint_f64(double %x) {
   %call = tail call double @nearbyint(double %x)



More information about the llvm-commits mailing list