[llvm] [SDAG] Don't handle non-canonical libcalls in SDAG lowering (PR #171114)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 8 03:46:21 PST 2025
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/171114
SDAG currently tries to lower certain libcalls to ISD opcodes. However, many of these are already canonicalized from libcalls to intrinsic in the middle-end (and often already emitted as intrinsics in the front-end).
I believe that SDAG should not be doing anything for such libcalls. This PR just drops a single libcall to get consensus on the direction, as these changes need a non-trivial amount of test updates.
A lot of the remaining libcalls *should* probably also be canonicalized to intrinsics in the middle-end when annotated with `memory(none)`, but that would require additional work in SimplifyLibCalls.
>From 4068497a9f6c736eccda8fde54a3adfafecb0de2 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 8 Dec 2025 12:31:40 +0100
Subject: [PATCH] [SDAG] Don't handle non-canonical libcalls in SDAG lowering
SDAG currently tries to lower certain libcalls to ISD opcodes.
However, many of these are already canonicalized from libcalls
to intrinsic in the middle-end (and often already emitted as
intrinsics in the front-end).
I believe that SDAG should not be doing anything for such libcalls.
This PR just drops a single libcall to get consensus on the direction,
as these changes need a non-trivial amount of test updates.
A lot of the remaining libcalls *should* probably also be
canonicalized to intrinsics in the middle-end when annotated with
`memory(none)`, but that would require additional work in
SimplifyLibCalls.
---
.../SelectionDAG/SelectionDAGBuilder.cpp | 18 ++++++++++++------
llvm/test/CodeGen/AArch64/arm64-rounding.ll | 8 ++------
llvm/test/CodeGen/AArch64/floatdp_1source.ll | 7 ++-----
llvm/test/CodeGen/ARM/arm32-rounding.ll | 6 ++----
llvm/test/CodeGen/Mips/mips64-f128.ll | 4 +---
llvm/test/CodeGen/RISCV/double-zfa.ll | 4 +---
llvm/test/CodeGen/RISCV/float-zfa.ll | 4 +---
llvm/test/CodeGen/X86/rounding-ops.ll | 8 ++------
8 files changed, 23 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 09a0673bfe1bb..71345509ea429 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -9559,6 +9559,8 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
// Check for well-known libc/libm calls. If the function is internal, it
// can't be a library call. Don't do the check if marked as nobuiltin for
// some reason.
+ // This code should not handle libcalls that are already canonicalized to
+ // intrinsics by the middle-end.
LibFunc Func;
if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() &&
LibInfo->getLibFunc(*F, Func) && LibInfo->hasOptimizedCodeGen(Func)) {
@@ -9584,30 +9586,35 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
case LibFunc_fabs:
case LibFunc_fabsf:
case LibFunc_fabsl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitUnaryFloatCall(I, ISD::FABS))
return;
break;
case LibFunc_fmin:
case LibFunc_fminf:
case LibFunc_fminl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitBinaryFloatCall(I, ISD::FMINNUM))
return;
break;
case LibFunc_fmax:
case LibFunc_fmaxf:
case LibFunc_fmaxl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitBinaryFloatCall(I, ISD::FMAXNUM))
return;
break;
case LibFunc_fminimum_num:
case LibFunc_fminimum_numf:
case LibFunc_fminimum_numl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitBinaryFloatCall(I, ISD::FMINIMUMNUM))
return;
break;
case LibFunc_fmaximum_num:
case LibFunc_fmaximum_numf:
case LibFunc_fmaximum_numl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitBinaryFloatCall(I, ISD::FMAXIMUMNUM))
return;
break;
@@ -9683,36 +9690,35 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
case LibFunc_floor:
case LibFunc_floorf:
case LibFunc_floorl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitUnaryFloatCall(I, ISD::FFLOOR))
return;
break;
- case LibFunc_nearbyint:
- case LibFunc_nearbyintf:
- case LibFunc_nearbyintl:
- if (visitUnaryFloatCall(I, ISD::FNEARBYINT))
- return;
- break;
case LibFunc_ceil:
case LibFunc_ceilf:
case LibFunc_ceill:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitUnaryFloatCall(I, ISD::FCEIL))
return;
break;
case LibFunc_rint:
case LibFunc_rintf:
case LibFunc_rintl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitUnaryFloatCall(I, ISD::FRINT))
return;
break;
case LibFunc_round:
case LibFunc_roundf:
case LibFunc_roundl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitUnaryFloatCall(I, ISD::FROUND))
return;
break;
case LibFunc_trunc:
case LibFunc_truncf:
case LibFunc_truncl:
+ // TODO: Remove this, already canonicalized by the middle-end.
if (visitUnaryFloatCall(I, ISD::FTRUNC))
return;
break;
diff --git a/llvm/test/CodeGen/AArch64/arm64-rounding.ll b/llvm/test/CodeGen/AArch64/arm64-rounding.ll
index 3ce35bfc4537c..618731fb001ca 100644
--- a/llvm/test/CodeGen/AArch64/arm64-rounding.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-rounding.ll
@@ -26,22 +26,18 @@ declare double @floor(double) nounwind readnone
; CHECK: frinti
define float @test3(float %a) #0 {
entry:
- %call = tail call float @nearbyintf(float %a) nounwind readnone
+ %call = tail call float @llvm.nearbyint.f32(float %a) nounwind readnone
ret float %call
}
-declare float @nearbyintf(float) nounwind readnone
-
; CHECK-LABEL: test4:
; CHECK: frinti
define double @test4(double %a) #0 {
entry:
- %call = tail call double @nearbyint(double %a) nounwind readnone
+ %call = tail call double @llvm.nearbyint.f64(double %a) nounwind readnone
ret double %call
}
-declare double @nearbyint(double) nounwind readnone
-
; CHECK-LABEL: test5:
; CHECK: frintp
; CHECK-NOT: frintx
diff --git a/llvm/test/CodeGen/AArch64/floatdp_1source.ll b/llvm/test/CodeGen/AArch64/floatdp_1source.ll
index 1c37f7045342f..8d1620d62ab01 100644
--- a/llvm/test/CodeGen/AArch64/floatdp_1source.ll
+++ b/llvm/test/CodeGen/AArch64/floatdp_1source.ll
@@ -19,9 +19,6 @@ declare double @trunc(double) readonly
declare float @rintf(float) readonly
declare double @rint(double) readonly
-declare float @nearbyintf(float) readonly
-declare double @nearbyint(double) readonly
-
define float @fabs_f(float %v) {
; CHECK-LABEL: fabs_f:
; CHECK: ; %bb.0:
@@ -90,7 +87,7 @@ define float @nearbyint_f(float %v) {
; CHECK: ; %bb.0:
; CHECK-NEXT: frinti s0, s0
; CHECK-NEXT: ret
- %r = call float @nearbyintf(float %v)
+ %r = call float @llvm.nearbyint.f32(float %v)
ret float %r
}
@@ -162,7 +159,7 @@ define double @nearbyint_d(double %v) {
; CHECK: ; %bb.0:
; CHECK-NEXT: frinti d0, d0
; CHECK-NEXT: ret
- %r = call double @nearbyint(double %v)
+ %r = call double @llvm.nearbyint.f64(double %v)
ret double %r
}
diff --git a/llvm/test/CodeGen/ARM/arm32-rounding.ll b/llvm/test/CodeGen/ARM/arm32-rounding.ll
index cc5b5612f49bb..5363f0fd6f081 100644
--- a/llvm/test/CodeGen/ARM/arm32-rounding.ll
+++ b/llvm/test/CodeGen/ARM/arm32-rounding.ll
@@ -74,7 +74,7 @@ entry:
; CHECK: vrintr.f32
define float @test9(float %a) {
entry:
- %call = call float @nearbyintf(float %a) nounwind readnone
+ %call = call float @llvm.nearbyint.f32(float %a) nounwind readnone
ret float %call
}
@@ -83,7 +83,7 @@ entry:
; DP: vrintr.f64
define double @test10(double %a) {
entry:
- %call = call double @nearbyint(double %a) nounwind readnone
+ %call = call double @llvm.nearbyint.f64(double %a) nounwind readnone
ret double %call
}
@@ -128,8 +128,6 @@ declare float @roundf(float) nounwind readnone
declare double @round(double) nounwind readnone
declare float @truncf(float) nounwind readnone
declare double @trunc(double) nounwind readnone
-declare float @nearbyintf(float) nounwind readnone
-declare double @nearbyint(double) nounwind readnone
declare float @rintf(float) nounwind readnone
declare double @rint(double) nounwind readnone
declare float @llvm.roundeven.f32(float)
diff --git a/llvm/test/CodeGen/Mips/mips64-f128.ll b/llvm/test/CodeGen/Mips/mips64-f128.ll
index 04bed7d42bf96..026caa90ef575 100644
--- a/llvm/test/CodeGen/Mips/mips64-f128.ll
+++ b/llvm/test/CodeGen/Mips/mips64-f128.ll
@@ -1736,12 +1736,10 @@ define fp128 @libcall1_nearbyintl() {
; CMP_CC_FMT-NEXT: jrc $ra
entry:
%0 = load fp128, ptr @gld0, align 16
- %call = tail call fp128 @nearbyintl(fp128 %0) nounwind readnone
+ %call = tail call fp128 @llvm.nearbyint.f128(fp128 %0) nounwind readnone
ret fp128 %call
}
-declare fp128 @nearbyintl(fp128) #1
-
define fp128 @libcall1_floorl() {
; C_CC_FMT-LABEL: libcall1_floorl:
; C_CC_FMT: # %bb.0: # %entry
diff --git a/llvm/test/CodeGen/RISCV/double-zfa.ll b/llvm/test/CodeGen/RISCV/double-zfa.ll
index a93ec86e363fc..dec56d2b79e33 100644
--- a/llvm/test/CodeGen/RISCV/double-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/double-zfa.ll
@@ -250,12 +250,10 @@ define double @fround_d_5(double %a) nounwind {
; CHECK: # %bb.0:
; CHECK-NEXT: fround.d fa0, fa0
; CHECK-NEXT: ret
- %call = tail call double @nearbyint(double %a) nounwind readnone
+ %call = tail call double @llvm.nearbyint.f64(double %a) nounwind readnone
ret double %call
}
-declare double @nearbyint(double) nounwind readnone
-
define double @fround_d_6(double %a) nounwind {
; CHECK-LABEL: fround_d_6:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/RISCV/float-zfa.ll b/llvm/test/CodeGen/RISCV/float-zfa.ll
index 7be0d998f38c3..dd9eedfa4cb35 100644
--- a/llvm/test/CodeGen/RISCV/float-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/float-zfa.ll
@@ -183,12 +183,10 @@ define float @fround_s_5(float %a) nounwind {
; CHECK: # %bb.0:
; CHECK-NEXT: fround.s fa0, fa0
; CHECK-NEXT: ret
- %call = tail call float @nearbyintf(float %a) nounwind readnone
+ %call = tail call float @llvm.nearbyint.f32(float %a) nounwind readnone
ret float %call
}
-declare float @nearbyintf(float) nounwind readnone
-
define float @fround_s_6(float %a) nounwind {
; CHECK-LABEL: fround_s_6:
; CHECK: # %bb.0:
diff --git a/llvm/test/CodeGen/X86/rounding-ops.ll b/llvm/test/CodeGen/X86/rounding-ops.ll
index 948449c68b3f0..147663a84d2e0 100644
--- a/llvm/test/CodeGen/X86/rounding-ops.ll
+++ b/llvm/test/CodeGen/X86/rounding-ops.ll
@@ -60,12 +60,10 @@ define float @test3(float %x) nounwind {
; CHECK-AVX512: ## %bb.0:
; CHECK-AVX512-NEXT: vroundss $12, %xmm0, %xmm0, %xmm0
; CHECK-AVX512-NEXT: retq
- %call = tail call float @nearbyintf(float %x) nounwind readnone
+ %call = tail call float @llvm.nearbyint.f32(float %x) nounwind readnone
ret float %call
}
-declare float @nearbyintf(float) nounwind readnone
-
define double @test4(double %x) nounwind {
; CHECK-SSE-LABEL: test4:
; CHECK-SSE: ## %bb.0:
@@ -81,12 +79,10 @@ define double @test4(double %x) nounwind {
; CHECK-AVX512: ## %bb.0:
; CHECK-AVX512-NEXT: vroundsd $12, %xmm0, %xmm0, %xmm0
; CHECK-AVX512-NEXT: retq
- %call = tail call double @nearbyint(double %x) nounwind readnone
+ %call = tail call double @llvm.nearbyint.f64(double %x) nounwind readnone
ret double %call
}
-declare double @nearbyint(double) nounwind readnone
-
define float @test5(float %x) nounwind {
; CHECK-SSE-LABEL: test5:
; CHECK-SSE: ## %bb.0:
More information about the llvm-commits
mailing list