[llvm] [LLVM] Add constant folding for llrint, llrintf, llrintl (PR #154799)
    via llvm-commits 
    llvm-commits at lists.llvm.org
       
    Sun Aug 24 03:37:28 PDT 2025
    
    
  
https://github.com/pratheekhassan21 updated https://github.com/llvm/llvm-project/pull/154799
>From 98e7f6ee9364b772564f7659de256346a48e9cde 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] errors were fixed
---
 .../llvm/Analysis/TargetLibraryInfo.def       |  16 +++
 .../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 |  10 ++
 .../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 +
 11 files changed, 327 insertions(+)
 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/Analysis/TargetLibraryInfo.def b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
index 014988299d37f..01290698da9df 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.def
@@ -1731,6 +1731,22 @@ TLI_DEFINE_ENUM_INTERNAL(llabs)
 TLI_DEFINE_STRING_INTERNAL("llabs")
 TLI_DEFINE_SIG_INTERNAL(LLong, LLong)
 
+//long long llrint ( double num );
+TLI_DEFINE_ENUM_INTERNAL(llrint)
+TLI_DEFINE_STRING_INTERNAL("llrint")
+TLI_DEFINE_SIG_INTERNAL(LLong,Dbl)
+
+
+//long long llrintf( float arg );
+TLI_DEFINE_ENUM_INTERNAL(llrintf)
+TLI_DEFINE_STRING_INTERNAL("llrintf")
+TLI_DEFINE_SIG_INTERNAL(LLong,Flt)
+
+//long long llrintl( long double arg );
+TLI_DEFINE_ENUM_INTERNAL(llrintl)
+TLI_DEFINE_STRING_INTERNAL("llrintl")
+TLI_DEFINE_SIG_INTERNAL(LLong,LDbl)
+
 /// double log(double x);
 TLI_DEFINE_ENUM_INTERNAL(log)
 TLI_DEFINE_STRING_INTERNAL("log")
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 128502b99d9a3..1c630783c029d 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -207,6 +207,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 6e9276669eb70..431e91f2584ea 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -309,6 +309,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);
@@ -342,6 +343,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 573a78150ff3d..737d59081fd43 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -1368,6 +1368,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 2d6a748f45079..f40a771453790 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3111,6 +3111,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 51e22bb86f331..4c8cf6b747602 100644
--- a/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
+++ b/llvm/test/Transforms/InferFunctionAttrs/annotate.ll
@@ -661,6 +661,15 @@ declare i32 @ilogbf(float)
 ; CHECK: declare i32 @ilogbl(x86_fp80) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
 declare i32 @ilogbl(x86_fp80)
 
+; CHECK: declare noundef i64 @llrint(double) [[MATH_NOACCESS:#[0-9]+]]
+declare i64 @llrint(double)
+
+; CHECK: declare noundef i64 @llrintf(float) [[MATH_NOACCESS:#[0-9]+]]
+declare i64 @llrintf(float)
+
+; CHECK: declare noundef i64 @llrintl(x86_fp80) [[MATH_NOACCESS:#[0-9]+]]
+declare i64 @llrintl(x86_fp80)
+
 ; CHECK: declare double @logb(double) [[ERRNOMEMONLY_NOFREE_NOUNWIND_WILLRETURN:#[0-9]+]]
 declare double @logb(double)
 
@@ -1196,6 +1205,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 51a5a63ba370c..9f52c5a3a5b02 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 b33419545efa8..86eae5da2baa4 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"
    
    
More information about the llvm-commits
mailing list