[llvm] [SimplifyLibCalls] Constant fold scalbxx (PR #114417)

via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 21 05:42:54 PST 2024


https://github.com/fawdlstty updated https://github.com/llvm/llvm-project/pull/114417

>From 16ff8929b0dd53cda1f22d2a00ff36737a5d03d4 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Thu, 31 Oct 2024 23:36:51 +0800
Subject: [PATCH 01/18] add optimize method & test

---
 .../llvm/Transforms/Utils/SimplifyLibCalls.h  |  1 +
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 43 ++++++++++
 llvm/test/Transforms/InstCombine/scalbn.ll    | 85 +++++++++++++++++++
 3 files changed, 129 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/scalbn.ll

diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 128502b99d9a37..93ab5f5974c189 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -213,6 +213,7 @@ class LibCallSimplifier {
   Value *optimizeSymmetric(CallInst *CI, LibFunc Func, IRBuilderBase &B);
   Value *optimizeRemquo(CallInst *CI, IRBuilderBase &B);
   Value *optimizeFdim(CallInst *CI, IRBuilderBase &B);
+  Value *optimizeScalbn(CallInst *CI, IRBuilderBase &B);
   // Wrapper for all floating point library call optimizations
   Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
                                       IRBuilderBase &B);
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index d85e0d99466022..afa2196243b538 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3157,6 +3157,42 @@ Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
   return ConstantFP::get(CI->getType(), MaxVal);
 }
 
+Value *LibCallSimplifier::optimizeScalbn(CallInst *CI, IRBuilderBase &B) {
+  Value *Base = CI->getArgOperand(0);
+  Value *Expo = CI->getArgOperand(1);
+  // Function *Callee = CI->getCalledFunction();
+  // StringRef Name = Callee->getName();
+  Type *Ty = CI->getType();
+  Module *M = CI->getModule();
+  // bool AllowApprox = CI->hasApproxFunc();
+  // bool Ignored;
+
+  // Propagate the math semantics from the call to any created instructions.
+  IRBuilderBase::FastMathFlagGuard Guard(B);
+  B.setFastMathFlags(CI->getFastMathFlags());
+  // Evaluate special cases related to the base.
+
+  // Scalbn(0.0, exp) -> 0.0
+  if (match(Base, m_SpecificFP(0.0)))
+    return Base;
+
+  // Scalbn(arg, 0) -> arg
+  if (match(Expo, m_Zero()))
+    return Base;
+
+  // Scalbn(arg, 1) -> arg * 2.0
+  if (match(Expo, m_SpecificInt(1)))
+    return B.CreateFMul(Base, ConstantFP::get(Ty, 2.0), "mul");
+
+  // Scalbn(1.0, exp) -> FLT_RADIX ^ exp
+  auto pow = createPowWithIntegerExponent(ConstantFP::get(Ty, 2.0), Expo, M, B);
+  if (match(Base, m_SpecificFP(1.0)))
+    return pow;
+
+  // otherwise
+  return B.CreateFMul(Base, pow, "mul");
+}
+
 //===----------------------------------------------------------------------===//
 // Integer Library Call Optimizations
 //===----------------------------------------------------------------------===//
@@ -4105,6 +4141,13 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
   case LibFunc_remquof:
   case LibFunc_remquol:
     return optimizeRemquo(CI, Builder);
+  case LibFunc_scalbln:
+  case LibFunc_scalblnf:
+  case LibFunc_scalblnl:
+  case LibFunc_scalbn:
+  case LibFunc_scalbnf:
+  case LibFunc_scalbnl:
+    return optimizeScalbn(CI, Builder);
   case LibFunc_nan:
   case LibFunc_nanf:
   case LibFunc_nanl:
diff --git a/llvm/test/Transforms/InstCombine/scalbn.ll b/llvm/test/Transforms/InstCombine/scalbn.ll
new file mode 100644
index 00000000000000..4dccef967973cf
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/scalbn.ll
@@ -0,0 +1,85 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+declare double @scalbln(double, i64)
+declare float @scalblnf(float, i64)
+declare x86_fp80 @scalblnl(x86_fp80, i64)
+declare double @scalbn(double, i32)
+declare float @scalbnf(float, i32)
+declare x86_fp80 @scalbnl(x86_fp80, i32)
+
+;---------------------------------------------------------------------
+; scalbn(scalbn(x, a), b) -> scalbn(x, a + b)
+;---------------------------------------------------------------------
+
+define double @scalbln_scalbln(double %x, i64 %a, i64 %b) {
+; CHECK-LABEL: define double @scalbln
+; CHECK-SAME: (double [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT:    [[SCALBXX0:%.*]] = call double @scalbln(double [[X]], i64 [[A]])
+; CHECK-NEXT:    [[SCALBXX1:%.*]] = call double @scalbln(double [[SCALBXX0]], i64 [[B]])
+; CHECK-NEXT:    ret double [[SCALBXX1]]
+;
+  %scalbxx0 = call double @scalbln(double %x, i64 %a)
+  %scalbxx1 = call double @scalbln(double %scalbxx0, i64 %b)
+  ret double %scalbxx1
+}
+
+define float @scalblnf_scalblnf(float %x, i64 %a, i64 %b) {
+; CHECK-LABEL: define float @scalblnf
+; CHECK-SAME: (float [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT:    [[SCALBXX0:%.*]] = call float @scalblnf(float [[X]], i64 [[A]])
+; CHECK-NEXT:    [[SCALBXX1:%.*]] = call float @scalblnf(float [[SCALBXX0]], i64 [[B]])
+; CHECK-NEXT:    ret float [[SCALBXX1]]
+;
+  %scalbxx0 = call float @scalblnf(float %x, i64 %a)
+  %scalbxx1 = call float @scalblnf(float %scalbxx0, i64 %b)
+  ret float %scalbxx1
+}
+
+define x86_fp80 @scalblnl_scalblnl(x86_fp80 %x, i64 %a, i64 %b) {
+; CHECK-LABEL: define x86_fp80 @scalblnl
+; CHECK-SAME: (x86_fp80 [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT:    [[SCALBXX0:%.*]] = call x86_fp80 @scalblnl(x86_fp80 [[X]], i64 [[A]])
+; CHECK-NEXT:    [[SCALBXX1:%.*]] = call x86_fp80 @scalblnl(x86_fp80 [[SCALBXX0]], i64 [[B]])
+; CHECK-NEXT:    ret x86_fp80 [[SCALBXX1]]
+;
+  %scalbxx0 = call x86_fp80 @scalblnl(x86_fp80 %x, i64 %a)
+  %scalbxx1 = call x86_fp80 @scalblnl(x86_fp80 %scalbxx0, i64 %b)
+  ret x86_fp80 %scalbxx1
+}
+
+define double @scalbn_scalbn(double %x, i32 %a, i32 %b) {
+; CHECK-LABEL: define double @scalbn
+; CHECK-SAME: (double [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:    [[SCALBXX0:%.*]] = call double @scalbn(double [[X]], i32 [[A]])
+; CHECK-NEXT:    [[SCALBXX1:%.*]] = call double @scalbn(double [[SCALBXX0]], i32 [[B]])
+; CHECK-NEXT:    ret double [[SCALBXX1]]
+;
+  %scalbxx0 = call double @scalbn(double %x, i32 %a)
+  %scalbxx1 = call double @scalbn(double %scalbxx0, i32 %b)
+  ret double %scalbxx1
+}
+
+define float @scalbnf_scalbnf(float %x, i32 %a, i32 %b) {
+; CHECK-LABEL: define float @scalbnf
+; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:    [[SCALBXX0:%.*]] = call float @scalbnf(float [[X]], i32 [[A]])
+; CHECK-NEXT:    [[SCALBXX1:%.*]] = call float @scalbnf(float [[SCALBXX0]], i32 [[B]])
+; CHECK-NEXT:    ret float [[SCALBXX1]]
+;
+  %scalbxx0 = call float @scalbnf(float %x, i32 %a)
+  %scalbxx1 = call float @scalbnf(float %scalbxx0, i32 %b)
+  ret float %scalbxx1
+}
+
+define x86_fp80 @scalbnl_scalbnl(x86_fp80 %x, i32 %a, i32 %b) {
+; CHECK-LABEL: define x86_fp80 @scalbnl
+; CHECK-SAME: (x86_fp80 [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT:    [[SCALBXX0:%.*]] = call x86_fp80 @scalbnl(x86_fp80 [[X]], i32 [[A]])
+; CHECK-NEXT:    [[SCALBXX1:%.*]] = call x86_fp80 @scalbnl(x86_fp80 [[SCALBXX0]], i32 [[B]])
+; CHECK-NEXT:    ret x86_fp80 [[SCALBXX1]]
+;
+  %scalbxx0 = call x86_fp80 @scalbnl(x86_fp80 %x, i32 %a)
+  %scalbxx1 = call x86_fp80 @scalbnl(x86_fp80 %scalbxx0, i32 %b)
+  ret x86_fp80 %scalbxx1
+}

>From 11b33db7f51162a6caba02a1a9e98a5441bc810a Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sat, 2 Nov 2024 23:53:03 +0800
Subject: [PATCH 02/18] impl in Analysis/ConstantFolding.cpp

---
 llvm/include/llvm/IR/Intrinsics.td            |  1 +
 .../llvm/Transforms/Utils/SimplifyLibCalls.h  |  1 -
 llvm/lib/Analysis/ConstantFolding.cpp         | 19 ++++++++--
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 36 -------------------
 4 files changed, 18 insertions(+), 39 deletions(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 8ed57f818d6006..a9a015a51e2286 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1034,6 +1034,7 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
   def int_tanh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
   def int_pow  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
                            [LLVMMatchType<0>, LLVMMatchType<0>]>;
+  def int_ldexp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>]>;
   def int_log  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
   def int_log10: DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
   def int_log2 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 93ab5f5974c189..128502b99d9a37 100644
--- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -213,7 +213,6 @@ class LibCallSimplifier {
   Value *optimizeSymmetric(CallInst *CI, LibFunc Func, IRBuilderBase &B);
   Value *optimizeRemquo(CallInst *CI, IRBuilderBase &B);
   Value *optimizeFdim(CallInst *CI, IRBuilderBase &B);
-  Value *optimizeScalbn(CallInst *CI, IRBuilderBase &B);
   // Wrapper for all floating point library call optimizations
   Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
                                       IRBuilderBase &B);
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index c5a2c2f52f8dc2..dbbd3621d5e34e 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1681,7 +1681,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   case 'i':
     return Name == "ilogb" || Name == "ilogbf";
   case 'l':
-    return Name == "log" || Name == "logf" || Name == "logl" ||
+    return Name == "ldexp" || Name == "ldexpf" || Name == "ldexpl" ||
+           Name == "log" || Name == "logf" || Name == "logl" ||
            Name == "log2" || Name == "log2f" || Name == "log10" ||
            Name == "log10f" || Name == "logb" || Name == "logbf" ||
            Name == "log1p" || Name == "log1pf";
@@ -1694,7 +1695,9 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
            Name == "rint" || Name == "rintf" ||
            Name == "round" || Name == "roundf";
   case 's':
-    return Name == "sin" || Name == "sinf" ||
+    return Name == "scalbn" || Name == "scalbnf" || Name == "scalbnl" ||
+           Name == "scalbln" || Name == "scalblnf" || Name == "scalblnl" ||
+           Name == "sin" || Name == "sinf" ||
            Name == "sinh" || Name == "sinhf" ||
            Name == "sqrt" || Name == "sqrtf";
   case 't':
@@ -2372,6 +2375,18 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
         return ConstantFP::get(Ty->getContext(), U);
       }
       break;
+    case LibFunc_ldexp:
+    case LibFunc_ldexpf:
+    case LibFunc_ldexpl:
+    case LibFunc_scalbn:
+    case LibFunc_scalbnf:
+    case LibFunc_scalbnl:
+    case LibFunc_scalbln:
+    case LibFunc_scalblnf:
+    case LibFunc_scalblnl:
+      if (TLI->has(Func))
+        return ConstantFoldFP(ldexp, APF, Ty);
+      break;
     case LibFunc_log:
     case LibFunc_logf:
     case LibFunc_log_finite:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index afa2196243b538..d333242762eb9e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -3157,42 +3157,6 @@ Value *LibCallSimplifier::optimizeFdim(CallInst *CI, IRBuilderBase &B) {
   return ConstantFP::get(CI->getType(), MaxVal);
 }
 
-Value *LibCallSimplifier::optimizeScalbn(CallInst *CI, IRBuilderBase &B) {
-  Value *Base = CI->getArgOperand(0);
-  Value *Expo = CI->getArgOperand(1);
-  // Function *Callee = CI->getCalledFunction();
-  // StringRef Name = Callee->getName();
-  Type *Ty = CI->getType();
-  Module *M = CI->getModule();
-  // bool AllowApprox = CI->hasApproxFunc();
-  // bool Ignored;
-
-  // Propagate the math semantics from the call to any created instructions.
-  IRBuilderBase::FastMathFlagGuard Guard(B);
-  B.setFastMathFlags(CI->getFastMathFlags());
-  // Evaluate special cases related to the base.
-
-  // Scalbn(0.0, exp) -> 0.0
-  if (match(Base, m_SpecificFP(0.0)))
-    return Base;
-
-  // Scalbn(arg, 0) -> arg
-  if (match(Expo, m_Zero()))
-    return Base;
-
-  // Scalbn(arg, 1) -> arg * 2.0
-  if (match(Expo, m_SpecificInt(1)))
-    return B.CreateFMul(Base, ConstantFP::get(Ty, 2.0), "mul");
-
-  // Scalbn(1.0, exp) -> FLT_RADIX ^ exp
-  auto pow = createPowWithIntegerExponent(ConstantFP::get(Ty, 2.0), Expo, M, B);
-  if (match(Base, m_SpecificFP(1.0)))
-    return pow;
-
-  // otherwise
-  return B.CreateFMul(Base, pow, "mul");
-}
-
 //===----------------------------------------------------------------------===//
 // Integer Library Call Optimizations
 //===----------------------------------------------------------------------===//

>From 0d7c62cf833fec6d5e3205a4403c75623d03586e Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sat, 2 Nov 2024 23:55:35 +0800
Subject: [PATCH 03/18] remove unused codes

---
 llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index d333242762eb9e..d85e0d99466022 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -4105,13 +4105,6 @@ Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
   case LibFunc_remquof:
   case LibFunc_remquol:
     return optimizeRemquo(CI, Builder);
-  case LibFunc_scalbln:
-  case LibFunc_scalblnf:
-  case LibFunc_scalblnl:
-  case LibFunc_scalbn:
-  case LibFunc_scalbnf:
-  case LibFunc_scalbnl:
-    return optimizeScalbn(CI, Builder);
   case LibFunc_nan:
   case LibFunc_nanf:
   case LibFunc_nanl:

>From 6ed6ba35846e7f614ce50c070756335bb5618eaf Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 00:09:55 +0800
Subject: [PATCH 04/18] fix format error

---
 llvm/lib/Analysis/ConstantFolding.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index dbbd3621d5e34e..2e07b300bb3c8f 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1697,9 +1697,8 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
   case 's':
     return Name == "scalbn" || Name == "scalbnf" || Name == "scalbnl" ||
            Name == "scalbln" || Name == "scalblnf" || Name == "scalblnl" ||
-           Name == "sin" || Name == "sinf" ||
-           Name == "sinh" || Name == "sinhf" ||
-           Name == "sqrt" || Name == "sqrtf";
+           Name == "sin" || Name == "sinf" || Name == "sinh" ||
+          Name == "sinhf" || Name == "sqrt" || Name == "sqrtf";
   case 't':
     return Name == "tan" || Name == "tanf" ||
            Name == "tanh" || Name == "tanhf" ||

>From 96955a6dd9c8d8194cd15f3563c223e6462dce63 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 00:17:02 +0800
Subject: [PATCH 05/18] a

---
 llvm/lib/Analysis/ConstantFolding.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 2e07b300bb3c8f..55d5b71bb28032 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1698,7 +1698,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
     return Name == "scalbn" || Name == "scalbnf" || Name == "scalbnl" ||
            Name == "scalbln" || Name == "scalblnf" || Name == "scalblnl" ||
            Name == "sin" || Name == "sinf" || Name == "sinh" ||
-          Name == "sinhf" || Name == "sqrt" || Name == "sqrtf";
+           Name == "sinhf" || Name == "sqrt" || Name == "sqrtf";
   case 't':
     return Name == "tan" || Name == "tanf" ||
            Name == "tanh" || Name == "tanhf" ||

>From bea62a32e89b1570b86fdfd79e1177035f84cb24 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 14:00:59 +0800
Subject: [PATCH 06/18] remove repeated item

---
 llvm/include/llvm/IR/Intrinsics.td | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index a9a015a51e2286..8ed57f818d6006 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1034,7 +1034,6 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
   def int_tanh : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
   def int_pow  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
                            [LLVMMatchType<0>, LLVMMatchType<0>]>;
-  def int_ldexp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>]>;
   def int_log  : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
   def int_log10: DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
   def int_log2 : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;

>From cdbc5408c4cc873c2423cf1a38c6a7b0fb99da69 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 14:53:56 +0800
Subject: [PATCH 07/18] 1

---
 llvm/lib/Analysis/ConstantFolding.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 55d5b71bb28032..32e160a3dfb06d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2384,7 +2384,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
     case LibFunc_scalblnf:
     case LibFunc_scalblnl:
       if (TLI->has(Func))
-        return ConstantFoldFP(ldexp, APF, Ty);
+        return ConstantFoldBinaryFP(ldexp, APF, Ty);
       break;
     case LibFunc_log:
     case LibFunc_logf:

>From e6b21d0c5421722aa86f98b84f47c6621cdfa3f4 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 15:02:35 +0800
Subject: [PATCH 08/18] mov eval method

---
 llvm/lib/Analysis/ConstantFolding.cpp | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 32e160a3dfb06d..ba1a1c374e4fed 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2374,18 +2374,6 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
         return ConstantFP::get(Ty->getContext(), U);
       }
       break;
-    case LibFunc_ldexp:
-    case LibFunc_ldexpf:
-    case LibFunc_ldexpl:
-    case LibFunc_scalbn:
-    case LibFunc_scalbnf:
-    case LibFunc_scalbnl:
-    case LibFunc_scalbln:
-    case LibFunc_scalblnf:
-    case LibFunc_scalblnl:
-      if (TLI->has(Func))
-        return ConstantFoldBinaryFP(ldexp, APF, Ty);
-      break;
     case LibFunc_log:
     case LibFunc_logf:
     case LibFunc_log_finite:
@@ -2635,6 +2623,18 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   switch (Func) {
   default:
     break;
+  case LibFunc_ldexp:
+  case LibFunc_ldexpf:
+  case LibFunc_ldexpl:
+  case LibFunc_scalbn:
+  case LibFunc_scalbnf:
+  case LibFunc_scalbnl:
+  case LibFunc_scalbln:
+  case LibFunc_scalblnf:
+  case LibFunc_scalblnl:
+    if (TLI->has(Func))
+      return ConstantFoldBinaryFP(ldexp, Op1V, Op2V, Ty);
+    break;
   case LibFunc_pow:
   case LibFunc_powf:
   case LibFunc_pow_finite:

>From 810520f0f754db31a658b5cc58c297ee74880bee Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 15:09:30 +0800
Subject: [PATCH 09/18] modify eval

---
 llvm/lib/Analysis/ConstantFolding.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index ba1a1c374e4fed..d0e2f0095a71d4 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2632,8 +2632,11 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   case LibFunc_scalbln:
   case LibFunc_scalblnf:
   case LibFunc_scalblnl:
-    if (TLI->has(Func))
-      return ConstantFoldBinaryFP(ldexp, Op1V, Op2V, Ty);
+    if (TLI->has(Func)) {
+      APFloat V = Op1->getValueAPF();
+      if (APFloat::opStatus::opOK == V.ldexp(Op2->getValueAPF()))
+        return ConstantFP::get(Ty->getContext(), V);
+    }
     break;
   case LibFunc_pow:
   case LibFunc_powf:

>From 0ec862d932c26f2de83d9dea8fbd8a861c191b05 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Sun, 3 Nov 2024 23:07:27 +0800
Subject: [PATCH 10/18] update eval

---
 llvm/lib/Analysis/ConstantFolding.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index d0e2f0095a71d4..2292643e20cbde 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2633,9 +2633,13 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   case LibFunc_scalblnf:
   case LibFunc_scalblnl:
     if (TLI->has(Func)) {
-      APFloat V = Op1->getValueAPF();
-      if (APFloat::opStatus::opOK == V.ldexp(Op2->getValueAPF()))
-        return ConstantFP::get(Ty->getContext(), V);
+      if (const auto *ConstrIntr =
+              dyn_cast_if_present<ConstrainedFPIntrinsic>(Call)) {
+        RoundingMode RM = getEvaluationRoundingMode(ConstrIntr);
+        auto tmp = ConstantFoldBinaryFP(pow, APFloat(2.0), Op2V, Ty);
+        Op1V.multiply(APFloat(tmp, RM));
+        return ConstantFP::get(Ty->getContext(), Op1V);
+      }
     }
     break;
   case LibFunc_pow:

>From b5d5da5ba5d6b649fbb10bcdfb4eff7edd779e22 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Mon, 4 Nov 2024 00:13:23 +0800
Subject: [PATCH 11/18] fix eval

---
 llvm/lib/Analysis/ConstantFolding.cpp | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 2292643e20cbde..b90d6d821ada32 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2633,13 +2633,14 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   case LibFunc_scalblnf:
   case LibFunc_scalblnl:
     if (TLI->has(Func)) {
-      if (const auto *ConstrIntr =
-              dyn_cast_if_present<ConstrainedFPIntrinsic>(Call)) {
-        RoundingMode RM = getEvaluationRoundingMode(ConstrIntr);
-        auto tmp = ConstantFoldBinaryFP(pow, APFloat(2.0), Op2V, Ty);
-        Op1V.multiply(APFloat(tmp, RM));
-        return ConstantFP::get(Ty->getContext(), Op1V);
-      }
+      Constant *tmp = ConstantFoldBinaryFP(pow, APFloat(2.0), Op2V, Ty);
+      const auto *tmp1 = dyn_cast<ConstantFP>(tmp);
+      if (!tmp1)
+        return nullptr;
+      APFloat Op1V2(Op1V);
+      auto eval_ret = Op1V2.multiply(tmp1->getValueAPF(), RoundingMode::TowardZero);
+      if (APFloat::opStatus::opOK == eval_ret)
+        return ConstantFP::get(Ty->getContext(), Op1V2);
     }
     break;
   case LibFunc_pow:

>From 4e7db059732ca0690698d16313c6db9107d77e68 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Tue, 5 Nov 2024 00:29:52 +0800
Subject: [PATCH 12/18] use apfloat scalbn impl

---
 llvm/lib/Analysis/ConstantFolding.cpp | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index b90d6d821ada32..c48cdc198706a4 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2633,14 +2633,8 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   case LibFunc_scalblnf:
   case LibFunc_scalblnl:
     if (TLI->has(Func)) {
-      Constant *tmp = ConstantFoldBinaryFP(pow, APFloat(2.0), Op2V, Ty);
-      const auto *tmp1 = dyn_cast<ConstantFP>(tmp);
-      if (!tmp1)
-        return nullptr;
-      APFloat Op1V2(Op1V);
-      auto eval_ret = Op1V2.multiply(tmp1->getValueAPF(), RoundingMode::TowardZero);
-      if (APFloat::opStatus::opOK == eval_ret)
-        return ConstantFP::get(Ty->getContext(), Op1V2);
+      APFloat ret = llvm::scalbn(Op1V, (int)Op2V.convertToDouble(), RoundingMode::TowardZero);
+      return ConstantFP::get(Ty->getContext(), ret);
     }
     break;
   case LibFunc_pow:

>From ab6d16161bbca330877c46f98a03791a1d3a1442 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Tue, 5 Nov 2024 21:32:32 +0800
Subject: [PATCH 13/18] remove convert & fix test

---
 llvm/lib/Analysis/ConstantFolding.cpp      | 2 +-
 llvm/test/Transforms/InstCombine/scalbn.ll | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index c48cdc198706a4..be163666ae1e45 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2633,7 +2633,7 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   case LibFunc_scalblnf:
   case LibFunc_scalblnl:
     if (TLI->has(Func)) {
-      APFloat ret = llvm::scalbn(Op1V, (int)Op2V.convertToDouble(), RoundingMode::TowardZero);
+      APFloat ret = llvm::scalbn(Op1V, Op2V.convertToDouble(), RoundingMode::TowardZero);
       return ConstantFP::get(Ty->getContext(), ret);
     }
     break;
diff --git a/llvm/test/Transforms/InstCombine/scalbn.ll b/llvm/test/Transforms/InstCombine/scalbn.ll
index 4dccef967973cf..59be867dfd2469 100644
--- a/llvm/test/Transforms/InstCombine/scalbn.ll
+++ b/llvm/test/Transforms/InstCombine/scalbn.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
 
 declare double @scalbln(double, i64)
 declare float @scalblnf(float, i64)

>From 3c64e380c298bd36cd383c25c2d7fddcfa8aeb31 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Tue, 5 Nov 2024 21:37:30 +0800
Subject: [PATCH 14/18] fix format check

---
 llvm/lib/Analysis/ConstantFolding.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index be163666ae1e45..b6ccc9dc81194d 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2633,7 +2633,8 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   case LibFunc_scalblnf:
   case LibFunc_scalblnl:
     if (TLI->has(Func)) {
-      APFloat ret = llvm::scalbn(Op1V, Op2V.convertToDouble(), RoundingMode::TowardZero);
+      APFloat ret =
+          llvm::scalbn(Op1V, Op2V.convertToDouble(), RoundingMode::TowardZero);
       return ConstantFP::get(Ty->getContext(), ret);
     }
     break;

>From 4dddafa85ed4d1e2f4e5853d50c85000f779f71a Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Thu, 7 Nov 2024 00:15:09 +0800
Subject: [PATCH 15/18] move test file

---
 llvm/test/Transforms/InstCombine/scalbn.ll  | 85 ---------------------
 llvm/test/Transforms/InstSimplify/scalbn.ll | 69 +++++++++++++++++
 2 files changed, 69 insertions(+), 85 deletions(-)
 delete mode 100644 llvm/test/Transforms/InstCombine/scalbn.ll
 create mode 100644 llvm/test/Transforms/InstSimplify/scalbn.ll

diff --git a/llvm/test/Transforms/InstCombine/scalbn.ll b/llvm/test/Transforms/InstCombine/scalbn.ll
deleted file mode 100644
index 59be867dfd2469..00000000000000
--- a/llvm/test/Transforms/InstCombine/scalbn.ll
+++ /dev/null
@@ -1,85 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
-
-declare double @scalbln(double, i64)
-declare float @scalblnf(float, i64)
-declare x86_fp80 @scalblnl(x86_fp80, i64)
-declare double @scalbn(double, i32)
-declare float @scalbnf(float, i32)
-declare x86_fp80 @scalbnl(x86_fp80, i32)
-
-;---------------------------------------------------------------------
-; scalbn(scalbn(x, a), b) -> scalbn(x, a + b)
-;---------------------------------------------------------------------
-
-define double @scalbln_scalbln(double %x, i64 %a, i64 %b) {
-; CHECK-LABEL: define double @scalbln
-; CHECK-SAME: (double [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
-; CHECK-NEXT:    [[SCALBXX0:%.*]] = call double @scalbln(double [[X]], i64 [[A]])
-; CHECK-NEXT:    [[SCALBXX1:%.*]] = call double @scalbln(double [[SCALBXX0]], i64 [[B]])
-; CHECK-NEXT:    ret double [[SCALBXX1]]
-;
-  %scalbxx0 = call double @scalbln(double %x, i64 %a)
-  %scalbxx1 = call double @scalbln(double %scalbxx0, i64 %b)
-  ret double %scalbxx1
-}
-
-define float @scalblnf_scalblnf(float %x, i64 %a, i64 %b) {
-; CHECK-LABEL: define float @scalblnf
-; CHECK-SAME: (float [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
-; CHECK-NEXT:    [[SCALBXX0:%.*]] = call float @scalblnf(float [[X]], i64 [[A]])
-; CHECK-NEXT:    [[SCALBXX1:%.*]] = call float @scalblnf(float [[SCALBXX0]], i64 [[B]])
-; CHECK-NEXT:    ret float [[SCALBXX1]]
-;
-  %scalbxx0 = call float @scalblnf(float %x, i64 %a)
-  %scalbxx1 = call float @scalblnf(float %scalbxx0, i64 %b)
-  ret float %scalbxx1
-}
-
-define x86_fp80 @scalblnl_scalblnl(x86_fp80 %x, i64 %a, i64 %b) {
-; CHECK-LABEL: define x86_fp80 @scalblnl
-; CHECK-SAME: (x86_fp80 [[X:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
-; CHECK-NEXT:    [[SCALBXX0:%.*]] = call x86_fp80 @scalblnl(x86_fp80 [[X]], i64 [[A]])
-; CHECK-NEXT:    [[SCALBXX1:%.*]] = call x86_fp80 @scalblnl(x86_fp80 [[SCALBXX0]], i64 [[B]])
-; CHECK-NEXT:    ret x86_fp80 [[SCALBXX1]]
-;
-  %scalbxx0 = call x86_fp80 @scalblnl(x86_fp80 %x, i64 %a)
-  %scalbxx1 = call x86_fp80 @scalblnl(x86_fp80 %scalbxx0, i64 %b)
-  ret x86_fp80 %scalbxx1
-}
-
-define double @scalbn_scalbn(double %x, i32 %a, i32 %b) {
-; CHECK-LABEL: define double @scalbn
-; CHECK-SAME: (double [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
-; CHECK-NEXT:    [[SCALBXX0:%.*]] = call double @scalbn(double [[X]], i32 [[A]])
-; CHECK-NEXT:    [[SCALBXX1:%.*]] = call double @scalbn(double [[SCALBXX0]], i32 [[B]])
-; CHECK-NEXT:    ret double [[SCALBXX1]]
-;
-  %scalbxx0 = call double @scalbn(double %x, i32 %a)
-  %scalbxx1 = call double @scalbn(double %scalbxx0, i32 %b)
-  ret double %scalbxx1
-}
-
-define float @scalbnf_scalbnf(float %x, i32 %a, i32 %b) {
-; CHECK-LABEL: define float @scalbnf
-; CHECK-SAME: (float [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
-; CHECK-NEXT:    [[SCALBXX0:%.*]] = call float @scalbnf(float [[X]], i32 [[A]])
-; CHECK-NEXT:    [[SCALBXX1:%.*]] = call float @scalbnf(float [[SCALBXX0]], i32 [[B]])
-; CHECK-NEXT:    ret float [[SCALBXX1]]
-;
-  %scalbxx0 = call float @scalbnf(float %x, i32 %a)
-  %scalbxx1 = call float @scalbnf(float %scalbxx0, i32 %b)
-  ret float %scalbxx1
-}
-
-define x86_fp80 @scalbnl_scalbnl(x86_fp80 %x, i32 %a, i32 %b) {
-; CHECK-LABEL: define x86_fp80 @scalbnl
-; CHECK-SAME: (x86_fp80 [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
-; CHECK-NEXT:    [[SCALBXX0:%.*]] = call x86_fp80 @scalbnl(x86_fp80 [[X]], i32 [[A]])
-; CHECK-NEXT:    [[SCALBXX1:%.*]] = call x86_fp80 @scalbnl(x86_fp80 [[SCALBXX0]], i32 [[B]])
-; CHECK-NEXT:    ret x86_fp80 [[SCALBXX1]]
-;
-  %scalbxx0 = call x86_fp80 @scalbnl(x86_fp80 %x, i32 %a)
-  %scalbxx1 = call x86_fp80 @scalbnl(x86_fp80 %scalbxx0, i32 %b)
-  ret x86_fp80 %scalbxx1
-}
diff --git a/llvm/test/Transforms/InstSimplify/scalbn.ll b/llvm/test/Transforms/InstSimplify/scalbn.ll
new file mode 100644
index 00000000000000..1c9925b0c6431d
--- /dev/null
+++ b/llvm/test/Transforms/InstSimplify/scalbn.ll
@@ -0,0 +1,69 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
+
+declare double @scalbln(double, i64)
+declare float @scalblnf(float, i64)
+declare x86_fp80 @scalblnl(x86_fp80, i64)
+declare double @scalbn(double, i32)
+declare float @scalbnf(float, i32)
+declare x86_fp80 @scalbnl(x86_fp80, i32)
+
+;
+
+define double @scalbln_undef() {
+; CHECK-LABEL: @scalbln_undef(
+; CHECK-NEXT:    ret double 0x7FF8000000000000
+;
+  %call = call double @scalbln(double undef, i64 undef)
+  ret double %call
+}
+
+define float @scalblnf_undef() {
+; CHECK-LABEL: @scalblnf_undef(
+; CHECK-NEXT:    ret float 0x7FF8000000000000
+;
+  %call = call float @scalblnf(float undef, i64 undef)
+  ret float %call
+}
+
+define x86_fp80 @scalblnl_undef() {
+; CHECK-LABEL: @scalblnl_undef(
+; CHECK-NEXT:    ret x86_fp80 0x7FF8000000000000
+;
+  %call = call x86_fp80 @scalblnl(x86_fp80 undef, i64 undef)
+  ret x86_fp80 %call
+}
+
+define double @scalbn_undef() {
+; CHECK-LABEL: @scalbn_undef(
+; CHECK-NEXT:    ret double 0x7FF8000000000000
+;
+  %call = call double @scalbn(double undef, i32 undef)
+  ret double %call
+}
+
+define float @scalbnf_undef() {
+; CHECK-LABEL: @scalbnf_undef(
+; CHECK-NEXT:    ret float 0x7FF8000000000000
+;
+  %call = call float @scalbnf(float undef, i32 undef)
+  ret float %call
+}
+
+define x86_fp80 @scalbnl_undef() {
+; CHECK-LABEL: @scalbnl_undef(
+; CHECK-NEXT:    ret x86_fp80 0x7FF8000000000000
+;
+  %call = call x86_fp80 @scalbnl(x86_fp80 undef, i32 undef)
+  ret x86_fp80 %call
+}
+
+;
+
+define double @scalbn_check() {
+; CHECK-LABEL: @scalbn_check(
+; CHECK-NEXT:    ret double 12
+;
+  %call = call double @scalbn(double 3.0, i32 2)
+  ret %call
+}

>From a4f80c70fdbe6566cd11ad5c23464548977f5d47 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Wed, 20 Nov 2024 22:16:08 +0800
Subject: [PATCH 16/18] fix review

---
 llvm/lib/Analysis/ConstantFolding.cpp       | 41 +++++++++++++--------
 llvm/test/Transforms/InstSimplify/scalbn.ll | 30 ++++++++++++---
 2 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index b6ccc9dc81194d..3f967231ae92a4 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2614,8 +2614,32 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
     return nullptr;
 
   const auto *Op2 = dyn_cast<ConstantFP>(Operands[1]);
-  if (!Op2)
+  if (!Op2) {
+    const auto *Op2i = dyn_cast<ConstantInt>(Operands[1]);
+    if (!Op2i)
+      return nullptr;
+    const APFloat &Op1V = Op1->getValueAPF();
+    const APInt &Op2Vi = Op2i->getValue();
+    switch (Func) {
+    default:
+      break;
+    case LibFunc_ldexp:
+    case LibFunc_ldexpf:
+    case LibFunc_ldexpl:
+    case LibFunc_scalbn:
+    case LibFunc_scalbnf:
+    case LibFunc_scalbnl:
+    case LibFunc_scalbln:
+    case LibFunc_scalblnf:
+    case LibFunc_scalblnl:
+      if (TLI->has(Func)) {
+        APFloat ret = scalbn(Op1V, Op2Vi.getSExtValue(), RoundingMode::TowardZero);
+        return ConstantFP::get(Ty->getContext(), ret);
+      }
+      break;
+    }
     return nullptr;
+  }
 
   const APFloat &Op1V = Op1->getValueAPF();
   const APFloat &Op2V = Op2->getValueAPF();
@@ -2623,21 +2647,6 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
   switch (Func) {
   default:
     break;
-  case LibFunc_ldexp:
-  case LibFunc_ldexpf:
-  case LibFunc_ldexpl:
-  case LibFunc_scalbn:
-  case LibFunc_scalbnf:
-  case LibFunc_scalbnl:
-  case LibFunc_scalbln:
-  case LibFunc_scalblnf:
-  case LibFunc_scalblnl:
-    if (TLI->has(Func)) {
-      APFloat ret =
-          llvm::scalbn(Op1V, Op2V.convertToDouble(), RoundingMode::TowardZero);
-      return ConstantFP::get(Ty->getContext(), ret);
-    }
-    break;
   case LibFunc_pow:
   case LibFunc_powf:
   case LibFunc_pow_finite:
diff --git a/llvm/test/Transforms/InstSimplify/scalbn.ll b/llvm/test/Transforms/InstSimplify/scalbn.ll
index 1c9925b0c6431d..8dac72a2137a88 100644
--- a/llvm/test/Transforms/InstSimplify/scalbn.ll
+++ b/llvm/test/Transforms/InstSimplify/scalbn.ll
@@ -8,8 +8,6 @@ declare double @scalbn(double, i32)
 declare float @scalbnf(float, i32)
 declare x86_fp80 @scalbnl(x86_fp80, i32)
 
-;
-
 define double @scalbln_undef() {
 ; CHECK-LABEL: @scalbln_undef(
 ; CHECK-NEXT:    ret double 0x7FF8000000000000
@@ -58,12 +56,34 @@ define x86_fp80 @scalbnl_undef() {
   ret x86_fp80 %call
 }
 
-;
-
 define double @scalbn_check() {
 ; CHECK-LABEL: @scalbn_check(
-; CHECK-NEXT:    ret double 12
+; CHECK-NEXT:    ret double 12.0
 ;
   %call = call double @scalbn(double 3.0, i32 2)
   ret %call
 }
+
+define double @scalbn_check0() {
+; CHECK-LABEL: @scalbn_check0(
+; CHECK-NEXT:    ret double 0.0
+;
+  %call = call double @scalbn(double 0.0, i32 2)
+  ret %call
+}
+
+define double @scalbn_check0n() {
+; CHECK-LABEL: @scalbn_check0n(
+; CHECK-NEXT:    ret double 0.0
+;
+  %call = call double @scalbn(double -0.0, i32 2)
+  ret %call
+}
+
+define double @scalbn_check0n() {
+; CHECK-LABEL: @scalbn_check0n(
+; CHECK-NEXT:    ret double 0.5
+;
+  %call = call double @scalbn(double 1.0, i32 -1)
+  ret %call
+}

>From 42b46a12e331492946d2f271565dc0d8256d019e Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Wed, 20 Nov 2024 22:25:26 +0800
Subject: [PATCH 17/18] modify format

---
 llvm/lib/Analysis/ConstantFolding.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 3f967231ae92a4..c5ccf52f9f59c1 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2633,7 +2633,8 @@ static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,
     case LibFunc_scalblnf:
     case LibFunc_scalblnl:
       if (TLI->has(Func)) {
-        APFloat ret = scalbn(Op1V, Op2Vi.getSExtValue(), RoundingMode::TowardZero);
+        APFloat ret =
+            scalbn(Op1V, Op2Vi.getSExtValue(), RoundingMode::TowardZero);
         return ConstantFP::get(Ty->getContext(), ret);
       }
       break;

>From ac10a25ee2756256731545250c67c6356e8f73b1 Mon Sep 17 00:00:00 2001
From: fawdlstty <f at fawdlstty.com>
Date: Thu, 21 Nov 2024 21:42:28 +0800
Subject: [PATCH 18/18] modify method name

---
 llvm/test/Transforms/InstSimplify/scalbn.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/InstSimplify/scalbn.ll b/llvm/test/Transforms/InstSimplify/scalbn.ll
index 8dac72a2137a88..a2c86defb14b98 100644
--- a/llvm/test/Transforms/InstSimplify/scalbn.ll
+++ b/llvm/test/Transforms/InstSimplify/scalbn.ll
@@ -80,8 +80,8 @@ define double @scalbn_check0n() {
   ret %call
 }
 
-define double @scalbn_check0n() {
-; CHECK-LABEL: @scalbn_check0n(
+define double @scalbn_check0n2() {
+; CHECK-LABEL: @scalbn_check0n2(
 ; CHECK-NEXT:    ret double 0.5
 ;
   %call = call double @scalbn(double 1.0, i32 -1)



More information about the llvm-commits mailing list