[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