https://github.com/harrisonGPU updated 
https://github.com/llvm/llvm-project/pull/227737

>From da21cd29a4d5c9d12fdf2e434dde7469cf2fea0b Mon Sep 17 00:00:00 2001
From: Harrison Hao <[email protected]>
Date: Wed, 30 Sep 2026 22:24:25 +0800
Subject: [PATCH 1/5] [InstCombine] Fold select of pow into select of the
 differing operand

When both arms of a select are calls to `llvm.pow` with one use that
differ in exactly one operand, sink the select into that operand:

$$
\mathrm{select}(c,\ x^{y},\ x^{z}) \rightarrow x^{\mathrm{select}(c,\ y,\ z)}
$$

$$
\mathrm{select}(c,\ x^{z},\ y^{z}) \rightarrow \mathrm{select}(c,\ x,\ y)^{z}
$$

This removes one `pow` call. FMF are intersected and debug locations
are merged. The transform is skipped when a differing operand is a
constant, since that may enable a cheaper lowering (e.g.
$x^2 \rightarrow x \cdot x$).
---
 .../InstCombine/InstCombineSelect.cpp         | 35 ++++++++++++
 .../InstCombine/intrinsic-select.ll           | 54 ++++++++-----------
 2 files changed, 58 insertions(+), 31 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index e7ade71ef562ae..594bd93a9ef76b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -507,6 +507,39 @@ Instruction *InstCombinerImpl::foldSelectOpOp(SelectInst 
&SI, Instruction *TI,
   return nullptr;
 }
 
+/// select C, f(..., X, ...), f(..., Y, ...) --> f(..., select C, X, Y, ...)
+static Instruction *
+foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst *TII,
+                           IntrinsicInst *FII,
+                           InstCombiner::BuilderTy &Builder) {
+  std::optional<unsigned> DiffArgNo;
+  for (unsigned I = 0, E = TII->arg_size(); I != E; ++I) {
+    if (TII->getArgOperand(I) == FII->getArgOperand(I))
+      continue;
+    if (DiffArgNo)
+      return nullptr;
+    DiffArgNo = I;
+  }
+  if (!DiffArgNo)
+    return nullptr;
+
+  Value *TV = TII->getArgOperand(*DiffArgNo);
+  Value *FV = FII->getArgOperand(*DiffArgNo);
+  // Constant args may enable cheaper lowering, e.g. pow(X, 2.0) -> X * X.
+  if (isa<Constant>(TV) || isa<Constant>(FV))
+    return nullptr;
+
+  SmallVector<Value *> Args(TII->args());
+  Args[*DiffArgNo] =
+      Builder.CreateSelect(SI.getCondition(), TV, FV, SI.getName() + ".v", 
&SI);
+  auto *NewCall = CallInst::Create(TII->getCalledFunction(), Args);
+  NewCall->copyIRFlags(TII);
+  NewCall->andIRFlags(FII);
+  NewCall->setDebugLoc(
+      DebugLoc::getMergedLocation(TII->getDebugLoc(), FII->getDebugLoc()));
+  return NewCall;
+}
+
 /// This transforms patterns of the form:
 ///   select cond, intrinsic(x, ...), intrinsic(y, ...)
 /// into:
@@ -547,6 +580,8 @@ Instruction 
*InstCombinerImpl::foldSelectIntrinsic(SelectInst &SI) {
 
     return replaceInstUsesWith(SI, NewCall);
   }
+  case Intrinsic::pow:
+    return foldSelectIntoIntrinsicArg(SI, LHSIntrinsic, RHSIntrinsic, Builder);
   default:
     return nullptr;
   }
diff --git a/llvm/test/Transforms/InstCombine/intrinsic-select.ll 
b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
index 6f77165d910677..3dca90da5aa32f 100644
--- a/llvm/test/Transforms/InstCombine/intrinsic-select.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
@@ -688,10 +688,9 @@ define i32 @select_of_abs(i1 %cond, i32 %x, i32 %y) {
 
 define float @select_of_pow_diff_exp(i1 %cond, float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_of_pow_diff_exp(
-; CHECK-NEXT:    [[POW1:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], 
float [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call float @llvm.pow.f32(float [[X]], float 
[[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1]], float 
[[POW2]]
-; CHECK-NEXT:    ret float [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1:%.*]], 
float [[POW2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], 
float [[SEL]])
+; CHECK-NEXT:    ret float [[SEL1]]
 ;
   %pow1 = call float @llvm.pow.f32(float %x, float %y)
   %pow2 = call float @llvm.pow.f32(float %x, float %z)
@@ -701,10 +700,9 @@ define float @select_of_pow_diff_exp(i1 %cond, float %x, 
float %y, float %z) {
 
 define float @select_of_pow_diff_base(i1 %cond, float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_of_pow_diff_base(
-; CHECK-NEXT:    [[POW1:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], 
float [[Z:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call float @llvm.pow.f32(float [[Y:%.*]], 
float [[Z]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1]], float 
[[POW2]]
-; CHECK-NEXT:    ret float [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1:%.*]], 
float [[POW2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call float @llvm.pow.f32(float [[SEL]], float 
[[Z:%.*]])
+; CHECK-NEXT:    ret float [[SEL1]]
 ;
   %pow1 = call float @llvm.pow.f32(float %x, float %z)
   %pow2 = call float @llvm.pow.f32(float %y, float %z)
@@ -714,10 +712,9 @@ define float @select_of_pow_diff_base(i1 %cond, float %x, 
float %y, float %z) {
 
 define double @select_of_pow_f64(i1 %cond, double %x, double %y, double %z) {
 ; CHECK-LABEL: @select_of_pow_f64(
-; CHECK-NEXT:    [[POW1:%.*]] = call double @llvm.pow.f64(double [[X:%.*]], 
double [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call double @llvm.pow.f64(double [[X]], double 
[[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], double [[POW1]], double 
[[POW2]]
-; CHECK-NEXT:    ret double [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], double [[POW1:%.*]], 
double [[POW2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call double @llvm.pow.f64(double [[X:%.*]], 
double [[SEL]])
+; CHECK-NEXT:    ret double [[SEL1]]
 ;
   %pow1 = call double @llvm.pow.f64(double %x, double %y)
   %pow2 = call double @llvm.pow.f64(double %x, double %z)
@@ -727,10 +724,9 @@ define double @select_of_pow_f64(i1 %cond, double %x, 
double %y, double %z) {
 
 define <2 x float> @select_of_pow_vec(<2 x i1> %cond, <2 x float> %x, <2 x 
float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @select_of_pow_vec(
-; CHECK-NEXT:    [[POW1:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> 
[[X:%.*]], <2 x float> [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> 
[[X]], <2 x float> [[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> 
[[POW1]], <2 x float> [[POW2]]
-; CHECK-NEXT:    ret <2 x float> [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> 
[[POW1:%.*]], <2 x float> [[POW2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> 
[[X:%.*]], <2 x float> [[SEL]])
+; CHECK-NEXT:    ret <2 x float> [[SEL1]]
 ;
   %pow1 = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> %y)
   %pow2 = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> %z)
@@ -740,10 +736,9 @@ define <2 x float> @select_of_pow_vec(<2 x i1> %cond, <2 x 
float> %x, <2 x float
 
 define <2 x float> @select_of_pow_vec_scalar_cond(i1 %cond, <2 x float> %x, <2 
x float> %y, <2 x float> %z) {
 ; CHECK-LABEL: @select_of_pow_vec_scalar_cond(
-; CHECK-NEXT:    [[POW1:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> 
[[X:%.*]], <2 x float> [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> 
[[X]], <2 x float> [[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x float> [[POW1]], 
<2 x float> [[POW2]]
-; CHECK-NEXT:    ret <2 x float> [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x float> 
[[POW1:%.*]], <2 x float> [[POW2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> 
[[X:%.*]], <2 x float> [[SEL]])
+; CHECK-NEXT:    ret <2 x float> [[SEL1]]
 ;
   %pow1 = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> %y)
   %pow2 = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> %z)
@@ -754,10 +749,9 @@ define <2 x float> @select_of_pow_vec_scalar_cond(i1 
%cond, <2 x float> %x, <2 x
 ; Only FMF common to both calls are kept.
 define float @select_of_pow_fmf_intersect(i1 %cond, float %x, float %y, float 
%z) {
 ; CHECK-LABEL: @select_of_pow_fmf_intersect(
-; CHECK-NEXT:    [[POW1:%.*]] = call nnan ninf float @llvm.pow.f32(float 
[[X:%.*]], float [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call ninf nsz float @llvm.pow.f32(float [[X]], 
float [[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1]], float 
[[POW2]]
-; CHECK-NEXT:    ret float [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1:%.*]], 
float [[POW2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call ninf float @llvm.pow.f32(float [[X:%.*]], 
float [[SEL]])
+; CHECK-NEXT:    ret float [[SEL1]]
 ;
   %pow1 = call nnan ninf float @llvm.pow.f32(float %x, float %y)
   %pow2 = call ninf nsz float @llvm.pow.f32(float %x, float %z)
@@ -767,10 +761,9 @@ define float @select_of_pow_fmf_intersect(i1 %cond, float 
%x, float %y, float %z
 
 define float @select_of_pow_select_fmf(i1 %cond, float %x, float %y, float %z) 
{
 ; CHECK-LABEL: @select_of_pow_select_fmf(
-; CHECK-NEXT:    [[POW1:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], 
float [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call float @llvm.pow.f32(float [[X]], float 
[[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select nnan i1 [[COND:%.*]], float [[POW1]], 
float [[POW2]]
-; CHECK-NEXT:    ret float [[SEL]]
+; CHECK-NEXT:    [[Z:%.*]] = select i1 [[COND:%.*]], float [[Y:%.*]], float 
[[Z1:%.*]]
+; CHECK-NEXT:    [[POW2:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], 
float [[Z]])
+; CHECK-NEXT:    ret float [[POW2]]
 ;
   %pow1 = call float @llvm.pow.f32(float %x, float %y)
   %pow2 = call float @llvm.pow.f32(float %x, float %z)
@@ -780,9 +773,8 @@ define float @select_of_pow_select_fmf(i1 %cond, float %x, 
float %y, float %z) {
 
 define float @select_of_pow_prof(i1 %cond, float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_of_pow_prof(
-; CHECK-NEXT:    [[POW1:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], 
float [[Y:%.*]])
-; CHECK-NEXT:    [[POW2:%.*]] = call float @llvm.pow.f32(float [[X]], float 
[[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[POW1]], float 
[[POW2]], !prof [[PROF1]]
+; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[COND:%.*]], float [[Y:%.*]], 
float [[Z:%.*]], !prof [[PROF1]]
+; CHECK-NEXT:    [[SEL:%.*]] = call float @llvm.pow.f32(float [[X:%.*]], float 
[[SEL_V]])
 ; CHECK-NEXT:    ret float [[SEL]]
 ;
   %pow1 = call float @llvm.pow.f32(float %x, float %y)

>From 25ab0e432af10cc0c0320f3b5ed698ffc1bcfbfd Mon Sep 17 00:00:00 2001
From: Harrison Hao <[email protected]>
Date: Thu, 1 Oct 2026 02:13:35 +0800
Subject: [PATCH 2/5] Use TriviallyVectorizable

---
 .../Transforms/InstCombine/InstCombineSelect.cpp   | 14 ++++++++++----
 .../select-fcmp-fmul-zero-absorbing-value.ll       |  5 ++---
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 594bd93a9ef76b..531ec4871a8ca3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -512,6 +512,9 @@ static Instruction *
 foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst *TII,
                            IntrinsicInst *FII,
                            InstCombiner::BuilderTy &Builder) {
+  if (TII->getCalledFunction() != FII->getCalledFunction())
+    return nullptr;
+
   std::optional<unsigned> DiffArgNo;
   for (unsigned I = 0, E = TII->arg_size(); I != E; ++I) {
     if (TII->getArgOperand(I) == FII->getArgOperand(I))
@@ -523,6 +526,10 @@ foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst 
*TII,
   if (!DiffArgNo)
     return nullptr;
 
+  // A select cannot feed a parameter that requires an immediate.
+  if (TII->paramHasAttr(*DiffArgNo, Attribute::ImmArg))
+    return nullptr;
+
   Value *TV = TII->getArgOperand(*DiffArgNo);
   Value *FV = FII->getArgOperand(*DiffArgNo);
   // Constant args may enable cheaper lowering, e.g. pow(X, 2.0) -> X * X.
@@ -535,8 +542,6 @@ foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst 
*TII,
   auto *NewCall = CallInst::Create(TII->getCalledFunction(), Args);
   NewCall->copyIRFlags(TII);
   NewCall->andIRFlags(FII);
-  NewCall->setDebugLoc(
-      DebugLoc::getMergedLocation(TII->getDebugLoc(), FII->getDebugLoc()));
   return NewCall;
 }
 
@@ -580,9 +585,10 @@ Instruction 
*InstCombinerImpl::foldSelectIntrinsic(SelectInst &SI) {
 
     return replaceInstUsesWith(SI, NewCall);
   }
-  case Intrinsic::pow:
-    return foldSelectIntoIntrinsicArg(SI, LHSIntrinsic, RHSIntrinsic, Builder);
   default:
+    if (isTriviallyVectorizable(IID))
+      return foldSelectIntoIntrinsicArg(SI, LHSIntrinsic, RHSIntrinsic,
+                                        Builder);
     return nullptr;
   }
 }
diff --git 
a/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll 
b/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll
index a3f83c9605f336..7a662f0c7fdbe6 100644
--- a/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll
+++ b/llvm/test/Transforms/InstCombine/select-fcmp-fmul-zero-absorbing-value.ll
@@ -496,11 +496,10 @@ define float 
@select_oeq_fmul_nonconst_unknown_fabs_or_fabs_src(float %x, float
 define float @select_oeq_fmul_nonconst_ppos_fabs_or_fabs_src(float %x, float 
%y) {
 ; CHECK-LABEL: define float @select_oeq_fmul_nonconst_ppos_fabs_or_fabs_src(
 ; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT:    [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X]])
 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[X]], [[Y]]
-; CHECK-NEXT:    [[MUL_FABS_X1:%.*]] = call float @llvm.fabs.f32(float 
[[TMP1]])
 ; CHECK-NEXT:    [[X_IS_ZERO:%.*]] = fcmp oeq float [[X]], 0.000000e+00
-; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[X_IS_ZERO]], float 
[[MUL_FABS_X1]], float [[FABS_X]]
+; CHECK-NEXT:    [[SELECT_V:%.*]] = select i1 [[X_IS_ZERO]], float [[TMP1]], 
float [[X]]
+; CHECK-NEXT:    [[SELECT:%.*]] = call float @llvm.fabs.f32(float [[SELECT_V]])
 ; CHECK-NEXT:    ret float [[SELECT]]
 ;
   %fabs.x = call float @llvm.fabs.f32(float %x)

>From d3b943e2c785eef62eeb0dd64d530356e8876981 Mon Sep 17 00:00:00 2001
From: Harrison Hao <[email protected]>
Date: Thu, 1 Oct 2026 02:25:10 +0800
Subject: [PATCH 3/5] Update for comments

---
 .../InstCombine/InstCombineSelect.cpp         |  4 +++
 .../InstCombine/intrinsic-select.ll           | 35 ++++++++-----------
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 531ec4871a8ca3..dba320922d4b3a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -532,6 +532,10 @@ foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst 
*TII,
 
   Value *TV = TII->getArgOperand(*DiffArgNo);
   Value *FV = FII->getArgOperand(*DiffArgNo);
+  // powi keeps a scalar exponent even in its vector form.
+  if (SI.getCondition()->getType()->isVectorTy() &&
+      !TV->getType()->isVectorTy())
+    return nullptr;
   // Constant args may enable cheaper lowering, e.g. pow(X, 2.0) -> X * X.
   if (isa<Constant>(TV) || isa<Constant>(FV))
     return nullptr;
diff --git a/llvm/test/Transforms/InstCombine/intrinsic-select.ll 
b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
index 3dca90da5aa32f..00882a49ee9fed 100644
--- a/llvm/test/Transforms/InstCombine/intrinsic-select.ll
+++ b/llvm/test/Transforms/InstCombine/intrinsic-select.ll
@@ -913,10 +913,9 @@ define float @select_of_pow_negative_not_intrinsic(i1 
%cond, float %x, float %y,
 
 define <2 x float> @select_of_sqrt_vec(<2 x i1> %cond, <2 x float> %x, <2 x 
float> %y) {
 ; CHECK-LABEL: @select_of_sqrt_vec(
-; CHECK-NEXT:    [[SQRT1:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> 
[[X:%.*]])
-; CHECK-NEXT:    [[SQRT2:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> 
[[Y:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> 
[[SQRT1]], <2 x float> [[SQRT2]]
-; CHECK-NEXT:    ret <2 x float> [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> 
[[SQRT1:%.*]], <2 x float> [[SQRT2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> 
[[SEL]])
+; CHECK-NEXT:    ret <2 x float> [[SEL1]]
 ;
   %sqrt1 = call <2 x float> @llvm.sqrt.v2f32(<2 x float> %x)
   %sqrt2 = call <2 x float> @llvm.sqrt.v2f32(<2 x float> %y)
@@ -926,10 +925,9 @@ define <2 x float> @select_of_sqrt_vec(<2 x i1> %cond, <2 
x float> %x, <2 x floa
 
 define float @select_of_fma(i1 %cond, float %x, float %y, float %z, float %w) {
 ; CHECK-LABEL: @select_of_fma(
-; CHECK-NEXT:    [[FMA1:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], 
float [[Y:%.*]], float [[Z:%.*]])
-; CHECK-NEXT:    [[FMA2:%.*]] = call float @llvm.fma.f32(float [[X]], float 
[[Y]], float [[W:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[FMA1]], float 
[[FMA2]]
-; CHECK-NEXT:    ret float [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[FMA1:%.*]], 
float [[FMA2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], 
float [[Y:%.*]], float [[SEL]])
+; CHECK-NEXT:    ret float [[SEL1]]
 ;
   %fma1 = call float @llvm.fma.f32(float %x, float %y, float %z)
   %fma2 = call float @llvm.fma.f32(float %x, float %y, float %w)
@@ -939,10 +937,9 @@ define float @select_of_fma(i1 %cond, float %x, float %y, 
float %z, float %w) {
 
 define float @select_of_copysign(i1 %cond, float %x, float %y, float %z) {
 ; CHECK-LABEL: @select_of_copysign(
-; CHECK-NEXT:    [[COPYSIGN1:%.*]] = call float @llvm.copysign.f32(float 
[[X:%.*]], float [[Y:%.*]])
-; CHECK-NEXT:    [[COPYSIGN2:%.*]] = call float @llvm.copysign.f32(float 
[[X]], float [[Z:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float [[COPYSIGN1]], 
float [[COPYSIGN2]]
-; CHECK-NEXT:    ret float [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], float 
[[COPYSIGN1:%.*]], float [[COPYSIGN2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call float @llvm.copysign.f32(float [[X:%.*]], 
float [[SEL]])
+; CHECK-NEXT:    ret float [[SEL1]]
 ;
   %copysign1 = call float @llvm.copysign.f32(float %x, float %y)
   %copysign2 = call float @llvm.copysign.f32(float %x, float %z)
@@ -952,10 +949,9 @@ define float @select_of_copysign(i1 %cond, float %x, float 
%y, float %z) {
 
 define i32 @select_of_fshl(i1 %cond, i32 %x, i32 %y, i32 %a, i32 %b) {
 ; CHECK-LABEL: @select_of_fshl(
-; CHECK-NEXT:    [[FSHL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 
[[Y:%.*]], i32 [[A:%.*]])
-; CHECK-NEXT:    [[FSHL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[Y]], 
i32 [[B:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[FSHL1]], i32 
[[FSHL2]]
-; CHECK-NEXT:    ret i32 [[SEL]]
+; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 [[FSHL1:%.*]], i32 
[[FSHL2:%.*]]
+; CHECK-NEXT:    [[SEL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 
[[Y:%.*]], i32 [[SEL]])
+; CHECK-NEXT:    ret i32 [[SEL1]]
 ;
   %fshl1 = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %a)
   %fshl2 = call i32 @llvm.fshl.i32(i32 %x, i32 %y, i32 %b)
@@ -965,10 +961,9 @@ define i32 @select_of_fshl(i1 %cond, i32 %x, i32 %y, i32 
%a, i32 %b) {
 
 define <2 x float> @select_of_powi_vec_scalar_cond(i1 %cond, <2 x float> %x, 
i32 %n, i32 %m) {
 ; CHECK-LABEL: @select_of_powi_vec_scalar_cond(
-; CHECK-NEXT:    [[POWI1:%.*]] = call <2 x float> @llvm.powi.v2f32.i32(<2 x 
float> [[X:%.*]], i32 [[N:%.*]])
-; CHECK-NEXT:    [[POWI2:%.*]] = call <2 x float> @llvm.powi.v2f32.i32(<2 x 
float> [[X]], i32 [[M:%.*]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x float> [[POWI1]], 
<2 x float> [[POWI2]]
-; CHECK-NEXT:    ret <2 x float> [[SEL]]
+; CHECK-NEXT:    [[M:%.*]] = select i1 [[COND:%.*]], i32 [[N:%.*]], i32 
[[M1:%.*]]
+; CHECK-NEXT:    [[POWI2:%.*]] = call <2 x float> @llvm.powi.v2f32.i32(<2 x 
float> [[X:%.*]], i32 [[M]])
+; CHECK-NEXT:    ret <2 x float> [[POWI2]]
 ;
   %powi1 = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %x, i32 %n)
   %powi2 = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %x, i32 %m)

>From 45f0ed55950c02d83c893719e02639b54ff57be8 Mon Sep 17 00:00:00 2001
From: Harrison Hao <[email protected]>
Date: Thu, 1 Oct 2026 09:50:50 +0800
Subject: [PATCH 4/5] Fix lit test issue.

---
 .../AMDGPU/amdgpu-simplify-libcall-pow.ll     | 20 ++++---
 .../AMDGPU/amdgpu-simplify-libcall-rootn.ll   | 54 +++++++------------
 llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll |  6 +--
 3 files changed, 29 insertions(+), 51 deletions(-)

diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll 
b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
index ecc9bc6f75d772..a91f127ad43b59 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-pow.ll
@@ -4181,17 +4181,15 @@ define float @test_pow_afn_f32__y_poison(float %x) {
 ; NOPRELINK-NEXT:    [[TMP1:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call afn float @llvm.log2.f32(float 
[[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = call afn float @llvm.exp2.f32(float 
[[TMP2]])
-; NOPRELINK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.copysign.f32(float 
[[TMP3]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
-; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp afn oeq float [[TMP5]], +inf
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
-; NOPRELINK-NEXT:    [[TMP8:%.*]] = or i1 [[TMP6]], [[TMP7]]
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select afn i1 [[TMP7]], float 
0.000000e+00, float +inf
-; NOPRELINK-NEXT:    [[TMP10:%.*]] = call afn float @llvm.copysign.f32(float 
[[TMP9]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP11:%.*]] = select afn i1 [[TMP8]], float [[TMP10]], 
float [[TMP4]]
-; NOPRELINK-NEXT:    [[TMP12:%.*]] = fcmp afn uno float [[X]], 0.000000e+00
-; NOPRELINK-NEXT:    [[TMP13:%.*]] = select afn i1 [[TMP12]], float +qnan, 
float [[TMP11]]
-; NOPRELINK-NEXT:    ret float [[TMP13]]
+; NOPRELINK-NEXT:    [[TMP4:%.*]] = call afn float @llvm.fabs.f32(float [[X]])
+; NOPRELINK-NEXT:    [[TMP5:%.*]] = fcmp afn oeq float [[TMP4]], +inf
+; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp afn oeq float [[X]], 0.000000e+00
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP5]], float +inf, float 
[[TMP3]]
+; NOPRELINK-NEXT:    [[DOTV:%.*]] = select i1 [[TMP6]], float 0.000000e+00, 
float [[TMP7]]
+; NOPRELINK-NEXT:    [[TMP8:%.*]] = call afn float @llvm.copysign.f32(float 
[[DOTV]], float [[X]])
+; NOPRELINK-NEXT:    [[TMP9:%.*]] = fcmp afn uno float [[X]], 0.000000e+00
+; NOPRELINK-NEXT:    [[TMP10:%.*]] = select afn i1 [[TMP9]], float +qnan, 
float [[TMP8]]
+; NOPRELINK-NEXT:    ret float [[TMP10]]
 ;
   %pow = tail call afn float @_Z3powff(float %x, float poison)
   ret float %pow
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll 
b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
index 805e510bde37b0..fa0fa173d88925 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
@@ -1360,12 +1360,10 @@ define float @test_rootn_afn_nnan_ninf_f32__y_3(float 
%x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float 
@llvm.log2.f32(float [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 
f0x3EAAAAAB
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float 
@llvm.exp2.f32(float [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP4]], float [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq float [[X]], 
0.000000e+00
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
0.000000e+00, float +inf
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], float 0.000000e+00, 
float [[TMP4]]
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP7]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
[[TMP8]], float [[TMP5]]
-; NOPRELINK-NEXT:    ret float [[TMP9]]
+; NOPRELINK-NEXT:    ret float [[TMP8]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 3)
   ret float %call
@@ -1383,12 +1381,10 @@ define float 
@test_rootn_afn_nnan_ninf_f32__y_neg3(float %x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float 
@llvm.log2.f32(float [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 
f0xBEAAAAAB
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float 
@llvm.exp2.f32(float [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP4]], float [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une float [[X]], 
0.000000e+00
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
0.000000e+00, float +inf
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], float [[TMP4]], float 
+inf
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP7]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
[[TMP5]], float [[TMP8]]
-; NOPRELINK-NEXT:    ret float [[TMP9]]
+; NOPRELINK-NEXT:    ret float [[TMP8]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -3)
   ret float %call
@@ -1450,12 +1446,10 @@ define float @test_rootn_afn_nnan_ninf_f32__y_5(float 
%x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float 
@llvm.log2.f32(float [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 
2.000000e-01
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float 
@llvm.exp2.f32(float [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP4]], float [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq float [[X]], 
0.000000e+00
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
0.000000e+00, float +inf
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], float 0.000000e+00, 
float [[TMP4]]
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP7]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
[[TMP8]], float [[TMP5]]
-; NOPRELINK-NEXT:    ret float [[TMP9]]
+; NOPRELINK-NEXT:    ret float [[TMP8]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 5)
   ret float %call
@@ -1473,12 +1467,10 @@ define float 
@test_rootn_afn_nnan_ninf_f32__y_neg5(float %x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float 
@llvm.log2.f32(float [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 
-2.000000e-01
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float 
@llvm.exp2.f32(float [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP4]], float [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une float [[X]], 
0.000000e+00
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
0.000000e+00, float +inf
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], float [[TMP4]], float 
+inf
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP7]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
[[TMP5]], float [[TMP8]]
-; NOPRELINK-NEXT:    ret float [[TMP9]]
+; NOPRELINK-NEXT:    ret float [[TMP8]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -5)
   ret float %call
@@ -1496,12 +1488,10 @@ define float @test_rootn_afn_nnan_ninf_f32__y_7(float 
%x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float 
@llvm.log2.f32(float [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 
f0x3E124925
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float 
@llvm.exp2.f32(float [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP4]], float [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq float [[X]], 
0.000000e+00
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
0.000000e+00, float +inf
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], float 0.000000e+00, 
float [[TMP4]]
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP7]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
[[TMP8]], float [[TMP5]]
-; NOPRELINK-NEXT:    ret float [[TMP9]]
+; NOPRELINK-NEXT:    ret float [[TMP8]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 7)
   ret float %call
@@ -1519,12 +1509,10 @@ define float 
@test_rootn_afn_nnan_ninf_f32__y_neg7(float %x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn float 
@llvm.log2.f32(float [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn float [[TMP2]], 
f0xBE124925
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn float 
@llvm.exp2.f32(float [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP4]], float [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une float [[X]], 
0.000000e+00
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
0.000000e+00, float +inf
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select i1 [[TMP6]], float [[TMP4]], float 
+inf
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn float 
@llvm.copysign.f32(float [[TMP7]], float [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn i1 [[TMP6]], float 
[[TMP5]], float [[TMP8]]
-; NOPRELINK-NEXT:    ret float [[TMP9]]
+; NOPRELINK-NEXT:    ret float [[TMP8]]
 ;
   %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -7)
   ret float %call
@@ -1588,12 +1576,10 @@ define <2 x float> 
@test_rootn_afn_nnan_ninf_v2f32__y_3(<2 x float> %x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> 
@llvm.log2.v2f32(<2 x float> [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], 
splat (float f0x3EAAAAAB)
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> 
@llvm.exp2.v2f32(<2 x float> [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> 
@llvm.copysign.v2f32(<2 x float> [[TMP4]], <2 x float> [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], 
zeroinitializer
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 
x float> zeroinitializer, <2 x float> splat (float +inf)
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select <2 x i1> [[TMP6]], <2 x float> 
zeroinitializer, <2 x float> [[TMP4]]
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> 
@llvm.copysign.v2f32(<2 x float> [[TMP7]], <2 x float> [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 
x float> [[TMP8]], <2 x float> [[TMP5]]
-; NOPRELINK-NEXT:    ret <2 x float> [[TMP9]]
+; NOPRELINK-NEXT:    ret <2 x float> [[TMP8]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> 
%x, <2 x i32> <i32 3, i32 3>)
@@ -1639,12 +1625,10 @@ define <2 x float> 
@test_rootn_afn_nnan_ninf_v2f32__y_neg3(<2 x float> %x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> 
@llvm.log2.v2f32(<2 x float> [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], 
splat (float f0xBEAAAAAB)
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> 
@llvm.exp2.v2f32(<2 x float> [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> 
@llvm.copysign.v2f32(<2 x float> [[TMP4]], <2 x float> [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn une <2 x float> [[X]], 
zeroinitializer
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 
x float> zeroinitializer, <2 x float> splat (float +inf)
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select <2 x i1> [[TMP6]], <2 x float> 
[[TMP4]], <2 x float> splat (float +inf)
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> 
@llvm.copysign.v2f32(<2 x float> [[TMP7]], <2 x float> [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 
x float> [[TMP5]], <2 x float> [[TMP8]]
-; NOPRELINK-NEXT:    ret <2 x float> [[TMP9]]
+; NOPRELINK-NEXT:    ret <2 x float> [[TMP8]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> 
%x, <2 x i32> <i32 -3, i32 -3>)
@@ -1690,12 +1674,10 @@ define <2 x float> 
@test_rootn_afn_nnan_ninf_v2f32__y_5(<2 x float> %x) {
 ; NOPRELINK-NEXT:    [[TMP2:%.*]] = call nnan ninf afn <2 x float> 
@llvm.log2.v2f32(<2 x float> [[TMP1]])
 ; NOPRELINK-NEXT:    [[TMP3:%.*]] = fmul nnan ninf afn <2 x float> [[TMP2]], 
splat (float 2.000000e-01)
 ; NOPRELINK-NEXT:    [[TMP4:%.*]] = call nnan ninf afn <2 x float> 
@llvm.exp2.v2f32(<2 x float> [[TMP3]])
-; NOPRELINK-NEXT:    [[TMP5:%.*]] = call nnan ninf afn <2 x float> 
@llvm.copysign.v2f32(<2 x float> [[TMP4]], <2 x float> [[X]])
 ; NOPRELINK-NEXT:    [[TMP6:%.*]] = fcmp nnan ninf afn oeq <2 x float> [[X]], 
zeroinitializer
-; NOPRELINK-NEXT:    [[TMP7:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 
x float> zeroinitializer, <2 x float> splat (float +inf)
+; NOPRELINK-NEXT:    [[TMP7:%.*]] = select <2 x i1> [[TMP6]], <2 x float> 
zeroinitializer, <2 x float> [[TMP4]]
 ; NOPRELINK-NEXT:    [[TMP8:%.*]] = call nnan ninf afn <2 x float> 
@llvm.copysign.v2f32(<2 x float> [[TMP7]], <2 x float> [[X]])
-; NOPRELINK-NEXT:    [[TMP9:%.*]] = select nnan ninf afn <2 x i1> [[TMP6]], <2 
x float> [[TMP8]], <2 x float> [[TMP5]]
-; NOPRELINK-NEXT:    ret <2 x float> [[TMP9]]
+; NOPRELINK-NEXT:    ret <2 x float> [[TMP8]]
 ;
 entry:
   %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> 
%x, <2 x i32> <i32 5, i32 5>)
diff --git a/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll 
b/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll
index 3ae46dbf63b034..e779f1f3d6be87 100644
--- a/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll
+++ b/llvm/test/CodeGen/AMDGPU/simplify-libcalls.ll
@@ -1266,12 +1266,10 @@ define amdgpu_kernel void @test_rootn_3(ptr 
addrspace(1) nocapture %a) {
 ; GCN-POSTLINK-NEXT:    [[TMP1:%.*]] = tail call fast float 
@llvm.log2.f32(float [[TMP0]])
 ; GCN-POSTLINK-NEXT:    [[TMP2:%.*]] = fmul fast float [[TMP1]], f0x3EAAAAAB
 ; GCN-POSTLINK-NEXT:    [[TMP3:%.*]] = tail call fast float 
@llvm.exp2.f32(float [[TMP2]])
-; GCN-POSTLINK-NEXT:    [[TMP4:%.*]] = tail call fast float 
@llvm.copysign.f32(float [[TMP3]], float [[TMP]])
 ; GCN-POSTLINK-NEXT:    [[TMP5:%.*]] = fcmp fast oeq float [[TMP]], 
0.000000e+00
-; GCN-POSTLINK-NEXT:    [[TMP6:%.*]] = select fast i1 [[TMP5]], float 
0.000000e+00, float +inf
+; GCN-POSTLINK-NEXT:    [[TMP6:%.*]] = select i1 [[TMP5]], float 0.000000e+00, 
float [[TMP3]]
 ; GCN-POSTLINK-NEXT:    [[TMP7:%.*]] = tail call fast float 
@llvm.copysign.f32(float [[TMP6]], float [[TMP]])
-; GCN-POSTLINK-NEXT:    [[TMP8:%.*]] = select fast i1 [[TMP5]], float 
[[TMP7]], float [[TMP4]]
-; GCN-POSTLINK-NEXT:    store float [[TMP8]], ptr addrspace(1) [[A]], align 4
+; GCN-POSTLINK-NEXT:    store float [[TMP7]], ptr addrspace(1) [[A]], align 4
 ; GCN-POSTLINK-NEXT:    ret void
 ;
 ; GCN-PRELINK-LABEL: define amdgpu_kernel void @test_rootn_3(

>From 87cd6a7333f48a1717fe74ed77f790c9d2054852 Mon Sep 17 00:00:00 2001
From: Harrison Hao <[email protected]>
Date: Wed, 14 Oct 2026 17:49:13 +0800
Subject: [PATCH 5/5] Update for comments

---
 .../lib/Transforms/InstCombine/InstCombineSelect.cpp | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index dba320922d4b3a..6428a970557e22 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -526,8 +526,7 @@ foldSelectIntoIntrinsicArg(SelectInst &SI, IntrinsicInst 
*TII,
   if (!DiffArgNo)
     return nullptr;
 
-  // A select cannot feed a parameter that requires an immediate.
-  if (TII->paramHasAttr(*DiffArgNo, Attribute::ImmArg))
+  if (!canReplaceOperandWithVariable(TII, *DiffArgNo))
     return nullptr;
 
   Value *TV = TII->getArgOperand(*DiffArgNo);
@@ -580,15 +579,6 @@ Instruction 
*InstCombinerImpl::foldSelectIntrinsic(SelectInst &SI) {
 
     return replaceInstUsesWith(SI, NewCall);
   }
-  case Intrinsic::ctpop: {
-    Value *TV = LHSIntrinsic->getArgOperand(0);
-    Value *FV = RHSIntrinsic->getArgOperand(0);
-
-    Value *NewSel = Builder.CreateSelect(SI.getCondition(), TV, FV, "", &SI);
-    Value *NewCall = Builder.CreateUnaryIntrinsic(IID, NewSel);
-
-    return replaceInstUsesWith(SI, NewCall);
-  }
   default:
     if (isTriviallyVectorizable(IID))
       return foldSelectIntoIntrinsicArg(SI, LHSIntrinsic, RHSIntrinsic,

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to