[llvm] [LLVM] Add constant folding for llrint, llrintf, llrintl (PR #154799)

via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 8 02:00:49 PST 2025


https://github.com/pratheekhassan21 updated https://github.com/llvm/llvm-project/pull/154799

>From 6b5a018e6805418548cc5af17740ddb7fed7c04b Mon Sep 17 00:00:00 2001
From: Pratheek Gowda BS <pratheekgowdabs at example.com>
Date: Sun, 24 Aug 2025 16:07:03 +0530
Subject: [PATCH 1/2] errors were fixed

---
 .../llvm/Transforms/Utils/SimplifyLibCalls.h  |   1 +
 llvm/lib/Analysis/TargetLibraryInfo.cpp       |   2 +
 llvm/lib/Transforms/Utils/BuildLibCalls.cpp   |   7 ++
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp |  22 ++++
 .../Transforms/InferFunctionAttrs/annotate.ll |  12 ++-
 .../Transforms/InstCombine/llrint_fold.ll     |  87 +++++++++++++++
 .../Transforms/InstCombine/llrintf_fold.ll    | 102 ++++++++++++++++++
 .../Transforms/InstCombine/llrintl_fp80.ll    |  65 +++++++++++
 .../tools/llvm-tli-checker/ps4-tli-check.yaml |  12 +++
 .../Analysis/TargetLibraryInfoTest.cpp        |   3 +
 10 files changed, 312 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/Transforms/InstCombine/llrint_fold.ll
 create mode 100644 llvm/test/Transforms/InstCombine/llrintf_fold.ll
 create mode 100644 llvm/test/Transforms/InstCombine/llrintl_fp80.ll

diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 64d2512308935..4433623cf6a31 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -209,6 +209,7 @@ class LibCallSimplifier {
   Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
   Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
   Value *optimizeFMod(CallInst *CI, IRBuilderBase &B);
+  Value *optimizellrint(CallInst *CI,IRBuilderBase &B);
   Value *mergeSqrtToExp(CallInst *CI, IRBuilderBase &B);
   Value *optimizeSinCosPi(CallInst *CI, bool IsSin, IRBuilderBase &B);
   Value *optimizeTrigInversionPairs(CallInst *CI, IRBuilderBase &B);
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 51b1f5874bcb6..12074632e662c 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -255,6 +255,7 @@ static void initializeLibCalls(TargetLibraryInfoImpl &TLI, const Triple &T,
       TLI.setUnavailable(LibFunc_floorf);
       TLI.setUnavailable(LibFunc_fmodf);
       TLI.setUnavailable(LibFunc_hypotf);
+      TLI.setAvailable(LibFunc_llrintf);
       TLI.setUnavailable(LibFunc_log10f);
       TLI.setUnavailable(LibFunc_logf);
       TLI.setUnavailable(LibFunc_modff);
@@ -288,6 +289,7 @@ static void initializeLibCalls(TargetLibraryInfoImpl &TLI, const Triple &T,
     TLI.setUnavailable(LibFunc_frexpl);
     TLI.setUnavailable(LibFunc_hypotl);
     TLI.setUnavailable(LibFunc_ldexpl);
+    TLI.setUnavailable(LibFunc_llrintl);
     TLI.setUnavailable(LibFunc_log10l);
     TLI.setUnavailable(LibFunc_logl);
     TLI.setUnavailable(LibFunc_modfl);
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index a245b9405cfb7..8e830add51604 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -1383,6 +1383,13 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
     Changed |= setDoesNotFreeMemory(F);
     Changed |= setWillReturn(F);
     break;
+  case LibFunc_llrintf:
+  case LibFunc_llrintl:
+  case LibFunc_llrint:
+    Changed|=setDoesNotThrow(F);
+    Changed|=setDoesNotAccessMemory(F);
+    Changed|=setWillReturn(F);
+    break;  
   case LibFunc_sincos:
   case LibFunc_sincosf:
   case LibFunc_sincosl:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index c3537f544c432..441fca83face7 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3188,6 +3188,28 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
   return ConstantFP::get(CI->getType(), Rem);
 }
 
+Value *LibCallSimplifier::optimizellrint(CallInst *CI,IRBuilderBase &B){
+  const APFloat *X;
+  if(!match(CI->getOperand(0),m_APFloat(X))){
+    return nullptr;
+  }
+  Type *type=CI->getType();
+
+  unsigned width=type->getIntegerBitWidth();
+
+  APSInt Result(width,false);
+  bool Isexact;
+
+  APFloat::opStatus Status=X->convertToInteger(Result,APFloat::rmNearestTiesToEven,&Isexact);
+
+  if(Status==APFloat::opOK || Status==APFloat::opInexact){
+    return ConstantInt::get(type,Result);
+  }
+
+  return nullptr;
+
+}
+
 /// Constant folds fdim
 Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
   // Cannot perform the fold unless the call has attribute memory(none)
diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index 71bc369b062fb..bb075b017f270 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -679,7 +679,16 @@ declare i32 @ilogbf(float)
 ; CHECK: declare i32 @ilogbl(x86_fp80) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
 declare i32 @ilogbl(x86_fp80)
 
-; CHECK: declare double @logb(double) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
+; CHECK: declare i64 @llrint(double) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
+declare i64 @llrint(double)
+
+; CHECK: declare i64 @llrintf(float) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
+declare i64 @llrintf(float)
+
+; CHECK: declare i64 @llrintl(x86_fp80) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
+declare i64 @llrintl(x86_fp80)
+
+; CHECK: declare double @logb(double) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
 declare double @logb(double)
 
 ; CHECK: declare float @logbf(float) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN]]
@@ -1241,6 +1250,7 @@ declare void @memset_pattern16(ptr, ptr, i64)
 ; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(read) }
 ; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
 ; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind memory(read) }
+; CHECK-DAG: attributes [[MATH_NOACCESS]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
 ; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
 ; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
 ; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
diff --git a/llvm/test/Transforms/InstCombine/llrint_fold.ll b/llvm/test/Transforms/InstCombine/llrint_fold.ll
new file mode 100644
index 0000000000000..1e8b71d60f495
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/llrint_fold.ll
@@ -0,0 +1,87 @@
+; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
+
+
+declare i64 @llrint(double)
+
+; Positive number test
+; CHECK-LABEL: define i64 @test_llrint_pos()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 4
+define i64 @test_llrint_pos() {
+entry:
+  %val = call i64 @llrint(double 3.5)
+  ret i64 %val
+}
+
+; Negative number test
+; CHECK-LABEL: define i64 @test_llrint_neg()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 -2
+define i64 @test_llrint_neg() {
+entry:
+  %val = call i64 @llrint(double -2.5)
+  ret i64 %val
+}
+
+; Zero test
+; CHECK-LABEL: define i64 @test_llrint_zero()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 0
+define i64 @test_llrint_zero() {
+entry:
+  %val = call i64 @llrint(double 0.0)
+  ret i64 %val
+}
+
+; Large value test
+; CHECK-LABEL: define i64 @test_llrint_large()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 1000000
+define i64 @test_llrint_large() {
+entry:
+  %val = call i64 @llrint(double 1.0e6)
+  ret i64 %val
+}
+
+; Rounding test (check ties-to-even)
+; CHECK-LABEL: define i64 @test_llrint_round_even()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 2
+define i64 @test_llrint_round_even() {
+entry:
+  %val = call i64 @llrint(double 2.5)
+  ret i64 %val
+}
+
+; NaN test
+; CHECK-LABEL: define i64 @test_llrint_nan()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrint(double 0x7FF8000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrint_nan() {
+entry:
+  %val = call i64 @llrint(double 0x7FF8000000000000) ; NaN
+  ret i64 %val
+}
+
+; +Inf test
+; CHECK-LABEL: define i64 @test_llrint_posinf()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrint(double 0x7FF0000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrint_posinf() {
+entry:
+  %val = call i64 @llrint(double 0x7FF0000000000000) ; +Inf
+  ret i64 %val
+}
+
+; -Inf test
+; CHECK-LABEL: define i64 @test_llrint_neginf()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrint(double 0xFFF0000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrint_neginf() {
+entry:
+  %val = call i64 @llrint(double 0xFFF0000000000000) ; -Inf
+  ret i64 %val
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/InstCombine/llrintf_fold.ll b/llvm/test/Transforms/InstCombine/llrintf_fold.ll
new file mode 100644
index 0000000000000..e611f666fd646
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/llrintf_fold.ll
@@ -0,0 +1,102 @@
+; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
+
+declare i64 @llrintf(float)
+
+; Positive number test
+; CHECK-LABEL: define i64 @test_llrintf_pos()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 4
+define i64 @test_llrintf_pos() {
+entry:
+  %val = call i64 @llrintf(float 3.5)
+  ret i64 %val
+}
+
+; Negative number test
+; CHECK-LABEL: define i64 @test_llrintf_neg()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 -2
+define i64 @test_llrintf_neg() {
+entry:
+  %val = call i64 @llrintf(float -2.5)
+  ret i64 %val
+}
+
+; Zero test
+; CHECK-LABEL: define i64 @test_llrintf_zero()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 0
+define i64 @test_llrintf_zero() {
+entry:
+  %val = call i64 @llrintf(float 0.0)
+  ret i64 %val
+}
+ 65 changes: 65 additions & 0 deletions65  
+llvm/test/Transforms/InstCombine/llrintl_fp80.ll
+Original file line number	Diff line number	Diff line change
+@@ -0,0 +1,65 @@
+; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
+declare i64 @llrintl(x86_fp80)
+
+; Positive number
+; CHECK-LABEL: define i64 @test_llrintl_pos()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 4
+define i64 @test_llrintl_pos() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK4000E000000000000000)
+  ret i64 %val
+}
+
+; Negative number
+; CHECK-LABEL: define i64 @test_llrintl_neg()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 -2
+define i64 @test_llrintl_neg() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xKC000A000000000000000)
+  ret i64 %val
+}
+
+; Zero
+; CHECK-LABEL: define i64 @test_llrintl_zero()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 0
+define i64 @test_llrintl_zero() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK00000000000000000000)
+  ret i64 %val
+}
+
+; NaN
+; CHECK-LABEL: define i64 @test_llrintl_nan()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrintl_nan() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
+  ret i64 %val
+}
+
+; +Inf
+; CHECK-LABEL: define i64 @test_llrintl_posinf()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrintl_posinf() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
+  ret i64 %val
+}
+
+; -Inf
+; CHECK-LABEL: define i64 @test_llrintl_neginf()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrintl_neginf() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
+  ret i64 %val
+}
\ No newline at end of file
diff --git a/llvm/test/Transforms/InstCombine/llrintl_fp80.ll b/llvm/test/Transforms/InstCombine/llrintl_fp80.ll
new file mode 100644
index 0000000000000..04d54d95163ef
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/llrintl_fp80.ll
@@ -0,0 +1,65 @@
+; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
+declare i64 @llrintl(x86_fp80)
+
+; Positive number
+; CHECK-LABEL: define i64 @test_llrintl_pos()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 4
+define i64 @test_llrintl_pos() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK4000E000000000000000)
+  ret i64 %val
+}
+
+; Negative number
+; CHECK-LABEL: define i64 @test_llrintl_neg()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 -2
+define i64 @test_llrintl_neg() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xKC000A000000000000000)
+  ret i64 %val
+}
+
+; Zero
+; CHECK-LABEL: define i64 @test_llrintl_zero()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    ret i64 0
+define i64 @test_llrintl_zero() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK00000000000000000000)
+  ret i64 %val
+}
+
+; NaN
+; CHECK-LABEL: define i64 @test_llrintl_nan()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrintl_nan() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
+  ret i64 %val
+}
+
+; +Inf
+; CHECK-LABEL: define i64 @test_llrintl_posinf()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrintl_posinf() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
+  ret i64 %val
+}
+
+; -Inf
+; CHECK-LABEL: define i64 @test_llrintl_neginf()
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
+; CHECK-NEXT:    ret i64 %val
+define i64 @test_llrintl_neginf() {
+entry:
+  %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
+  ret i64 %val
+}
\ No newline at end of file
diff --git a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
index ff2c9ae00bdb9..e4f3827242944 100644
--- a/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
+++ b/llvm/test/tools/llvm-tli-checker/ps4-tli-check.yaml
@@ -690,6 +690,18 @@ DynamicSymbols:
     Type:            STT_FUNC
     Section:         .text
     Binding:         STB_GLOBAL
+  - Name:            llrint
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+  - Name:            llrintf
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL
+  - Name:            llrintl
+    Type:            STT_FUNC
+    Section:         .text
+    Binding:         STB_GLOBAL        
   - Name:            logb
     Type:            STT_FUNC
     Section:         .text
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 3029f10b1bb29..1388a0bdf9521 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -258,6 +258,9 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
       "declare double @ldexp(double, i32)\n"
       "declare float @ldexpf(float, i32)\n"
       "declare x86_fp80 @ldexpl(x86_fp80, i32)\n"
+      "declare i64 @llrint(double)\n"
+      "declare i64 @llrintf(float)\n"
+      "declare i64 @llrintl(x86_fp80)\n"
       "declare i64 @llabs(i64)\n"
       "declare double @log(double)\n"
       "declare double @log10(double)\n"

>From bce255aebf797288999ea80ca14edf1cba9b441f Mon Sep 17 00:00:00 2001
From: Pratheek Gowda BS <pratheekgowdabs at example.com>
Date: Mon, 8 Dec 2025 14:28:56 +0530
Subject: [PATCH 2/2] logic moves to constantfolding.cpp

---
 .github/workflows/bazel-checks.yml            |  33 +----
 .../llvm/Transforms/Utils/SimplifyLibCalls.h  |   1 -
 llvm/lib/Analysis/ConstantFolding.cpp         |  41 +++++-
 llvm/lib/Transforms/Utils/BuildLibCalls.cpp   |  10 +-
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp |  24 +---
 .../Transforms/InferFunctionAttrs/annotate.ll |   1 -
 .../Transforms/InstCombine/llrint_fold.ll     | 117 ++++++------------
 .../Transforms/InstCombine/llrintf_fold.ll    | 102 ---------------
 .../Transforms/InstCombine/llrintl_fp80.ll    |  65 ----------
 9 files changed, 82 insertions(+), 312 deletions(-)
 delete mode 100644 llvm/test/Transforms/InstCombine/llrintf_fold.ll
 delete mode 100644 llvm/test/Transforms/InstCombine/llrintl_fp80.ll

diff --git a/.github/workflows/bazel-checks.yml b/.github/workflows/bazel-checks.yml
index aa318569532ec..65d51649dd9e7 100644
--- a/.github/workflows/bazel-checks.yml
+++ b/.github/workflows/bazel-checks.yml
@@ -22,40 +22,11 @@ jobs:
     if: github.repository == 'llvm/llvm-project'
     steps:
       - name: Fetch LLVM sources
-        uses: actions/checkout at 1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
+        uses: actions/checkout at 08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
       - name: Setup Buildifier
         run: |
-          sudo curl -L https://github.com/bazelbuild/buildtools/releases/download/v8.2.1/buildifier-linux-amd64 -o /usr/bin/buildifier --fail
+          sudo curl -L https://github.com/bazelbuild/buildtools/releases/download/v8.2.1/buildifier-linux-amd64 -o /usr/bin/buildifier
           sudo chmod +x /usr/bin/buildifier
       - name: Run Buildifier
         run: |
           buildifier --mode=check $(find ./utils/bazel -name *BUILD*)
-  
-  bazel-build:
-    name: "Bazel Build/Test"
-    # Only run on US Central workers so we only have to keep one cache warm as
-    # the cache buckets are per cluster.
-    runs-on:
-      group: llvm-premerge-cluster-us-central
-      labels: llvm-premerge-linux-runners
-    if: github.repository == 'llvm/llvm-project'
-    steps:
-      - name: Fetch LLVM sources
-        uses: actions/checkout at 1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
-        # TODO(boomanaiden154): We should use a purpose built container for this. Move
-        # over when we have fixed the issues with using custom containers with Github
-        # ARC in GKE.
-      - name: Setup System Dependencies
-        run: |
-          sudo apt-get update
-          sudo apt-get install -y libmpfr-dev libpfm4-dev m4 libedit-dev
-          sudo curl -L https://github.com/bazelbuild/bazelisk/releases/download/v1.27.0/bazelisk-amd64.deb --fail > /tmp/bazelisk.deb
-          sudo apt-get install -y /tmp/bazelisk.deb
-          rm /tmp/bazelisk.deb
-      - name: Build/Test
-        working-directory: utils/bazel
-        run: |
-          bazelisk test --config=ci --sandbox_base="" \
-            --remote_cache=https://storage.googleapis.com/$CACHE_GCS_BUCKET-bazel \
-            --google_default_credentials \
-            @llvm-project//... //...
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 4433623cf6a31..64d2512308935 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -209,7 +209,6 @@ class LibCallSimplifier {
   Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
   Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
   Value *optimizeFMod(CallInst *CI, IRBuilderBase &B);
-  Value *optimizellrint(CallInst *CI,IRBuilderBase &B);
   Value *mergeSqrtToExp(CallInst *CI, IRBuilderBase &B);
   Value *optimizeSinCosPi(CallInst *CI, bool IsSin, IRBuilderBase &B);
   Value *optimizeTrigInversionPairs(CallInst *CI, IRBuilderBase &B);
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index b39b32042dd2f..2df20ffe41ba6 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1943,6 +1943,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   // environment, they can be folded in any case.
   case Intrinsic::ceil:
   case Intrinsic::floor:
+  case Intrinsic::llrint:
   case Intrinsic::round:
   case Intrinsic::roundeven:
   case Intrinsic::trunc:
@@ -2007,7 +2008,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
     return Name == "log" || Name == "logf" || Name == "logl" ||
            Name == "log2" || Name == "log2f" || Name == "log10" ||
            Name == "log10f" || Name == "logb" || Name == "logbf" ||
-           Name == "log1p" || Name == "log1pf";
+           Name == "log1p" || Name == "log1pf" || Name=="llrint" ||
+           Name=="llrintf";
   case 'n':
     return Name == "nearbyint" || Name == "nearbyintf";
   case 'p':
@@ -2521,9 +2523,34 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
 
     if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint ||
         IntrinsicID == Intrinsic::roundeven) {
-      U.roundToIntegral(APFloat::rmNearestTiesToEven);
-      return ConstantFP::get(Ty->getContext(), U);
-    }
+      if (IntrinsicID == Intrinsic::llrint) {
+
+        // Use IEEE round-to-nearest, ties-to-even
+        unsigned Width = Ty->getIntegerBitWidth();
+
+        // llrint returns a signed long long, so result is signed.
+        APSInt Result(Width, /*isUnsigned=*/false);
+
+        bool IsExact = false;
+
+        // convertToInteger mutates, so use a temporary APFloat.
+        APFloat Tmp = U;
+        APFloat::opStatus Status = Tmp.convertToInteger(
+            Result, APFloat::rmNearestTiesToEven, &IsExact);
+
+        // Allowed: opOK or opInexact
+        // Disallowed: opInvalidOp (overflow)
+        if (Status == APFloat::opOK || Status == APFloat::opInexact)
+          return ConstantInt::get(Ty, Result);
+
+        return nullptr;
+      }
+
+      if (IntrinsicID == Intrinsic::nearbyint ||
+          IntrinsicID == Intrinsic::rint) {
+        U.roundToIntegral(APFloat::rmNearestTiesToEven);
+        return ConstantFP::get(Ty->getContext(), U);
+      }
 
     if (IntrinsicID == Intrinsic::round) {
       U.roundToIntegral(APFloat::rmNearestTiesToAway);
@@ -2940,6 +2967,12 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
         return ConstantFP::get(Ty->getContext(), U);
       }
       break;
+    case LibFunc_llrint:
+    case LibFunc_llrintf:
+      if (TLI->has(Func)) {
+        return ConstantFP::get(Ty->getContext(), U);
+      }
+      break;
     case LibFunc_log:
     case LibFunc_logf:
     case LibFunc_log_finite:
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index 8e830add51604..16f89126d8dd8 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -1361,6 +1361,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
   case LibFunc_fminimum_numl:
   case LibFunc_labs:
   case LibFunc_llabs:
+  case LibFunc_llrintf:
+  case LibFunc_llrintl:
+  case LibFunc_llrint:
   case LibFunc_nearbyint:
   case LibFunc_nearbyintf:
   case LibFunc_nearbyintl:
@@ -1383,13 +1386,6 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
     Changed |= setDoesNotFreeMemory(F);
     Changed |= setWillReturn(F);
     break;
-  case LibFunc_llrintf:
-  case LibFunc_llrintl:
-  case LibFunc_llrint:
-    Changed|=setDoesNotThrow(F);
-    Changed|=setDoesNotAccessMemory(F);
-    Changed|=setWillReturn(F);
-    break;  
   case LibFunc_sincos:
   case LibFunc_sincosf:
   case LibFunc_sincosl:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 441fca83face7..b6891ab294787 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3188,28 +3188,6 @@ Value *LibCallSimplifier::optimizeRemquo(CallInst *CI, IRBuilderBase &B) {
   return ConstantFP::get(CI->getType(), Rem);
 }
 
-Value *LibCallSimplifier::optimizellrint(CallInst *CI,IRBuilderBase &B){
-  const APFloat *X;
-  if(!match(CI->getOperand(0),m_APFloat(X))){
-    return nullptr;
-  }
-  Type *type=CI->getType();
-
-  unsigned width=type->getIntegerBitWidth();
-
-  APSInt Result(width,false);
-  bool Isexact;
-
-  APFloat::opStatus Status=X->convertToInteger(Result,APFloat::rmNearestTiesToEven,&Isexact);
-
-  if(Status==APFloat::opOK || Status==APFloat::opInexact){
-    return ConstantInt::get(type,Result);
-  }
-
-  return nullptr;
-
-}
-
 /// Constant folds fdim
 Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
   // Cannot perform the fold unless the call has attribute memory(none)
@@ -4130,6 +4108,8 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
     return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
   case LibFunc_floor:
     return replaceUnaryCall(CI, Builder, Intrinsic::floor);
+  case LibFunc_llrint:
+    return replaceUnaryCall(CI, Builder, Intrinsic::llrint);
   case LibFunc_round:
     return replaceUnaryCall(CI, Builder, Intrinsic::round);
   case LibFunc_roundeven:
diff --git a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
index bb075b017f270..2eec18dec8a18 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -1250,7 +1250,6 @@ declare void @memset_pattern16(ptr, ptr, i64)
 ; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(read) }
 ; CHECK-DAG: attributes [[ARGMEMONLY_NOFREE_NOUNWIND_WILLRETURN]] = { mustprogress nocallback nofree nounwind willreturn memory(argmem: readwrite) }
 ; CHECK-DAG: attributes [[NOFREE_NOUNWIND_READONLY]] = { nofree nounwind memory(read) }
-; CHECK-DAG: attributes [[MATH_NOACCESS]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
 ; CHECK-DAG: attributes [[INACCESSIBLEMEMORARGMEMONLY_NOUNWIND_WILLRETURN_ALLOCKIND_FREE_FAMILY_MALLOC]] = { mustprogress nounwind willreturn allockind("free") memory(argmem: readwrite, inaccessiblemem: readwrite) "alloc-family"="malloc" }
 ; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_ALLOCSIZE0_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") allocsize(0) memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
 ; CHECK-DAG: attributes [[INACCESSIBLEMEMONLY_NOFREE_NOUNWIND_WILLRETURN_ALLOCKIND_ALLOCUNINIT_FAMILY_MALLOC]] = { mustprogress nofree nounwind willreturn allockind("alloc,uninitialized") memory(inaccessiblemem: readwrite) "alloc-family"="malloc" }
diff --git a/llvm/test/Transforms/InstCombine/llrint_fold.ll b/llvm/test/Transforms/InstCombine/llrint_fold.ll
index 1e8b71d60f495..345530431a494 100644
--- a/llvm/test/Transforms/InstCombine/llrint_fold.ll
+++ b/llvm/test/Transforms/InstCombine/llrint_fold.ll
@@ -1,87 +1,46 @@
-; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
-
-
-declare i64 @llrint(double)
-
-; Positive number test
-; CHECK-LABEL: define i64 @test_llrint_pos()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 4
-define i64 @test_llrint_pos() {
-entry:
-  %val = call i64 @llrint(double 3.5)
-  ret i64 %val
-}
-
-; Negative number test
-; CHECK-LABEL: define i64 @test_llrint_neg()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 -2
-define i64 @test_llrint_neg() {
-entry:
-  %val = call i64 @llrint(double -2.5)
-  ret i64 %val
-}
-
-; Zero test
-; CHECK-LABEL: define i64 @test_llrint_zero()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 0
-define i64 @test_llrint_zero() {
-entry:
-  %val = call i64 @llrint(double 0.0)
-  ret i64 %val
-}
-
-; Large value test
-; CHECK-LABEL: define i64 @test_llrint_large()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 1000000
-define i64 @test_llrint_large() {
-entry:
-  %val = call i64 @llrint(double 1.0e6)
-  ret i64 %val
+; RUN: opt -S -passes=instcombine %s | FileCheck %s
+
+; ============================================================
+;  Test constant folding of overloaded @llvm.llrint intrinsic
+; ============================================================
+
+; LLVM intrinsic declarations (typed overloads)
+declare i64 @llvm.llrint.f32(float)
+declare i64 @llvm.llrint.f64(double)
+declare i64 @llvm.llrint.f80(x86_fp80)
+declare i64 @llvm.llrint.f128(fp128)
+
+; ============================================================
+; float overload
+; ============================================================
+define i64 @test_f32_pos() {
+; CHECK-LABEL: @test_f32_pos(
+; CHECK-NEXT: ret i64 4
+  %v = call i64 @llvm.llrint.f32(float 3.5)
+  ret i64 %v
 }
 
-; Rounding test (check ties-to-even)
-; CHECK-LABEL: define i64 @test_llrint_round_even()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 2
-define i64 @test_llrint_round_even() {
-entry:
-  %val = call i64 @llrint(double 2.5)
-  ret i64 %val
+define i64 @test_f32_neg() {
+; CHECK-LABEL: @test_f32_neg(
+; CHECK-NEXT: ret i64 -2
+  %v = call i64 @llvm.llrint.f32(float -2.5)
+  ret i64 %v
 }
 
-; NaN test
-; CHECK-LABEL: define i64 @test_llrint_nan()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrint(double 0x7FF8000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrint_nan() {
-entry:
-  %val = call i64 @llrint(double 0x7FF8000000000000) ; NaN
-  ret i64 %val
+; ============================================================
+; double overload
+; ============================================================
+define i64 @test_f64_pos() {
+; CHECK-LABEL: @test_f64_pos(
+; CHECK-NEXT: ret i64 4
+  %v = call i64 @llvm.llrint.f64(double 3.5)
+  ret i64 %v
 }
 
-; +Inf test
-; CHECK-LABEL: define i64 @test_llrint_posinf()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrint(double 0x7FF0000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrint_posinf() {
-entry:
-  %val = call i64 @llrint(double 0x7FF0000000000000) ; +Inf
-  ret i64 %val
+define i64 @test_f64_neg() {
+; CHECK-LABEL: @test_f64_neg(
+; CHECK-NEXT: ret i64 -2
+  %v = call i64 @llvm.llrint.f64(double -2.5)
+  ret i64 %v
 }
 
-; -Inf test
-; CHECK-LABEL: define i64 @test_llrint_neginf()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrint(double 0xFFF0000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrint_neginf() {
-entry:
-  %val = call i64 @llrint(double 0xFFF0000000000000) ; -Inf
-  ret i64 %val
-}
\ No newline at end of file
diff --git a/llvm/test/Transforms/InstCombine/llrintf_fold.ll b/llvm/test/Transforms/InstCombine/llrintf_fold.ll
deleted file mode 100644
index e611f666fd646..0000000000000
--- a/llvm/test/Transforms/InstCombine/llrintf_fold.ll
+++ /dev/null
@@ -1,102 +0,0 @@
-; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
-
-declare i64 @llrintf(float)
-
-; Positive number test
-; CHECK-LABEL: define i64 @test_llrintf_pos()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 4
-define i64 @test_llrintf_pos() {
-entry:
-  %val = call i64 @llrintf(float 3.5)
-  ret i64 %val
-}
-
-; Negative number test
-; CHECK-LABEL: define i64 @test_llrintf_neg()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 -2
-define i64 @test_llrintf_neg() {
-entry:
-  %val = call i64 @llrintf(float -2.5)
-  ret i64 %val
-}
-
-; Zero test
-; CHECK-LABEL: define i64 @test_llrintf_zero()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 0
-define i64 @test_llrintf_zero() {
-entry:
-  %val = call i64 @llrintf(float 0.0)
-  ret i64 %val
-}
- 65 changes: 65 additions & 0 deletions65  
-llvm/test/Transforms/InstCombine/llrintl_fp80.ll
-Original file line number	Diff line number	Diff line change
-@@ -0,0 +1,65 @@
-; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
-declare i64 @llrintl(x86_fp80)
-
-; Positive number
-; CHECK-LABEL: define i64 @test_llrintl_pos()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 4
-define i64 @test_llrintl_pos() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK4000E000000000000000)
-  ret i64 %val
-}
-
-; Negative number
-; CHECK-LABEL: define i64 @test_llrintl_neg()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 -2
-define i64 @test_llrintl_neg() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xKC000A000000000000000)
-  ret i64 %val
-}
-
-; Zero
-; CHECK-LABEL: define i64 @test_llrintl_zero()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 0
-define i64 @test_llrintl_zero() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK00000000000000000000)
-  ret i64 %val
-}
-
-; NaN
-; CHECK-LABEL: define i64 @test_llrintl_nan()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrintl_nan() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
-  ret i64 %val
-}
-
-; +Inf
-; CHECK-LABEL: define i64 @test_llrintl_posinf()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrintl_posinf() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
-  ret i64 %val
-}
-
-; -Inf
-; CHECK-LABEL: define i64 @test_llrintl_neginf()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrintl_neginf() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
-  ret i64 %val
-}
\ No newline at end of file
diff --git a/llvm/test/Transforms/InstCombine/llrintl_fp80.ll b/llvm/test/Transforms/InstCombine/llrintl_fp80.ll
deleted file mode 100644
index 04d54d95163ef..0000000000000
--- a/llvm/test/Transforms/InstCombine/llrintl_fp80.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; RUN: opt -S -passes=instcombine %s -o - | FileCheck %s
-declare i64 @llrintl(x86_fp80)
-
-; Positive number
-; CHECK-LABEL: define i64 @test_llrintl_pos()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 4
-define i64 @test_llrintl_pos() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK4000E000000000000000)
-  ret i64 %val
-}
-
-; Negative number
-; CHECK-LABEL: define i64 @test_llrintl_neg()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 -2
-define i64 @test_llrintl_neg() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xKC000A000000000000000)
-  ret i64 %val
-}
-
-; Zero
-; CHECK-LABEL: define i64 @test_llrintl_zero()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i64 0
-define i64 @test_llrintl_zero() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK00000000000000000000)
-  ret i64 %val
-}
-
-; NaN
-; CHECK-LABEL: define i64 @test_llrintl_nan()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrintl_nan() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK7FFF8000000000000000)
-  ret i64 %val
-}
-
-; +Inf
-; CHECK-LABEL: define i64 @test_llrintl_posinf()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrintl_posinf() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xK7FFF0000000000000000)
-  ret i64 %val
-}
-
-; -Inf
-; CHECK-LABEL: define i64 @test_llrintl_neginf()
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
-; CHECK-NEXT:    ret i64 %val
-define i64 @test_llrintl_neginf() {
-entry:
-  %val = call i64 @llrintl(x86_fp80 0xKFFFF0000000000000000)
-  ret i64 %val
-}
\ No newline at end of file



More information about the llvm-commits mailing list