[llvm] 352b901 - [ConstantFolding] Handle roundeven libcalls (#170692)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 5 03:07:32 PST 2025


Author: valadaptive
Date: 2025-12-05T12:07:28+01:00
New Revision: 352b90182839024a87e2234092f6b3ea49bf8c23

URL: https://github.com/llvm/llvm-project/commit/352b90182839024a87e2234092f6b3ea49bf8c23
DIFF: https://github.com/llvm/llvm-project/commit/352b90182839024a87e2234092f6b3ea49bf8c23.diff

LOG: [ConstantFolding] Handle roundeven libcalls (#170692)

Basically identical to nearbyint and rint, which we already treat as
rounding to nearest with ties to even during constant folding.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/test/Transforms/InstSimplify/ConstProp/roundeven.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 63d12ee585e64..b39b32042dd2f 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1984,6 +1984,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   switch (Name[0]) {
   default:
     return false;
+    // clang-format off
   case 'a':
     return Name == "acos" || Name == "acosf" ||
            Name == "asin" || Name == "asinf" ||
@@ -2014,7 +2015,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   case 'r':
     return Name == "remainder" || Name == "remainderf" ||
            Name == "rint" || Name == "rintf" ||
-           Name == "round" || Name == "roundf";
+           Name == "round" || Name == "roundf" ||
+           Name == "roundeven" || Name == "roundevenf";
   case 's':
     return Name == "sin" || Name == "sinf" ||
            Name == "sinh" || Name == "sinhf" ||
@@ -2052,6 +2054,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
     case 's':
       return Name == "__sinh_finite" || Name == "__sinhf_finite";
     }
+    // clang-format on
   }
 }
 
@@ -2516,7 +2519,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
 
     // Use internal versions of these intrinsics.
 
-    if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {
+    if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint ||
+        IntrinsicID == Intrinsic::roundeven) {
       U.roundToIntegral(APFloat::rmNearestTiesToEven);
       return ConstantFP::get(Ty->getContext(), U);
     }
@@ -2988,6 +2992,8 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
     case LibFunc_nearbyintf:
     case LibFunc_rint:
     case LibFunc_rintf:
+    case LibFunc_roundeven:
+    case LibFunc_roundevenf:
       if (TLI->has(Func)) {
         U.roundToIntegral(APFloat::rmNearestTiesToEven);
         return ConstantFP::get(Ty->getContext(), U);

diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/roundeven.ll b/llvm/test/Transforms/InstSimplify/ConstProp/roundeven.ll
index 77b2d61138e19..b9c1635026489 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/roundeven.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/roundeven.ll
@@ -9,8 +9,7 @@ declare double @llvm.roundeven.f64(double)
 define float @constant_fold_roundeven_f32_01() #0 {
 ; CHECK-LABEL: define float @constant_fold_roundeven_f32_01(
 ; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:    [[X:%.*]] = call float @roundevenf(float 1.250000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret float [[X]]
+; CHECK-NEXT:    ret float 1.000000e+00
 ;
   %x = call float @roundevenf(float 1.25) #0
   ret float %x
@@ -29,8 +28,7 @@ define float @constant_fold_roundeven_f32_02() #0 {
 define float @constant_fold_roundeven_f32_03() #0 {
 ; CHECK-LABEL: define float @constant_fold_roundeven_f32_03(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call float @roundevenf(float 1.500000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret float [[X]]
+; CHECK-NEXT:    ret float 2.000000e+00
 ;
   %x = call float @roundevenf(float 1.5) #0
   ret float %x
@@ -50,8 +48,7 @@ define float @constant_fold_roundeven_f32_04() #0 {
 define float @constant_fold_roundeven_f32_05() #0 {
 ; CHECK-LABEL: define float @constant_fold_roundeven_f32_05(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call float @roundevenf(float 2.500000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret float [[X]]
+; CHECK-NEXT:    ret float 2.000000e+00
 ;
   %x = call float @roundevenf(float 2.5) #0
   ret float %x
@@ -70,8 +67,7 @@ define float @constant_fold_roundeven_f32_06() #0 {
 define float @constant_fold_roundeven_f32_07() #0 {
 ; CHECK-LABEL: define float @constant_fold_roundeven_f32_07(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call float @roundevenf(float 2.750000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret float [[X]]
+; CHECK-NEXT:    ret float 3.000000e+00
 ;
   %x = call float @roundevenf(float 2.75) #0
   ret float %x
@@ -89,8 +85,7 @@ define float @constant_fold_roundeven_f32_08() #0 {
 define double @constant_fold_roundeven_f64_01() #0 {
 ; CHECK-LABEL: define double @constant_fold_roundeven_f64_01(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call double @roundeven(double 1.300000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret double [[X]]
+; CHECK-NEXT:    ret double 1.000000e+00
 ;
   %x = call double @roundeven(double 1.3) #0
   ret double %x
@@ -108,8 +103,7 @@ define double @constant_fold_roundeven_f64_02() #0 {
 define double @constant_fold_roundeven_f64_03() #0 {
 ; CHECK-LABEL: define double @constant_fold_roundeven_f64_03(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call double @roundeven(double 1.500000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret double [[X]]
+; CHECK-NEXT:    ret double 2.000000e+00
 ;
   %x = call double @roundeven(double 1.5) #0
   ret double %x
@@ -127,8 +121,7 @@ define double @constant_fold_roundeven_f64_04() #0 {
 define double @constant_fold_roundeven_f64_05() #0 {
 ; CHECK-LABEL: define double @constant_fold_roundeven_f64_05(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call double @roundeven(double 2.500000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret double [[X]]
+; CHECK-NEXT:    ret double 2.000000e+00
 ;
   %x = call double @roundeven(double 2.5) #0
   ret double %x
@@ -146,8 +139,7 @@ define double @constant_fold_roundeven_f64_06() #0 {
 define double @constant_fold_roundeven_f64_07() #0 {
 ; CHECK-LABEL: define double @constant_fold_roundeven_f64_07(
 ; CHECK-SAME: ) #[[ATTR0]] {
-; CHECK-NEXT:    [[X:%.*]] = call double @roundeven(double 2.700000e+00) #[[ATTR0]]
-; CHECK-NEXT:    ret double [[X]]
+; CHECK-NEXT:    ret double 3.000000e+00
 ;
   %x = call double @roundeven(double 2.7) #0
   ret double %x


        


More information about the llvm-commits mailing list