[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-24 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From e2f1df9225a3953e9344ba887c03a631132f8fdd Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 899b52fdc951b..ff1df59b54cf4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2064,9 +2064,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2094,6 +2094,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2998,6 +3021,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -3019,7 +3050,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index 0520fef0f0e79..7a05e27d88184 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -214,7 +214,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -228,7 +228,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-24 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From e2f1df9225a3953e9344ba887c03a631132f8fdd Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 899b52fdc951b..ff1df59b54cf4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2064,9 +2064,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2094,6 +2094,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2998,6 +3021,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -3019,7 +3050,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index 0520fef0f0e79..7a05e27d88184 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -214,7 +214,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -228,7 +228,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-24 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 9bdfe6aabfa77e12d19d09f5a9fe558ce336318b Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 31c962dbae502..043896b96921f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2061,9 +2061,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2091,6 +2091,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2865,6 +2888,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2886,7 +2917,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-24 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 9bdfe6aabfa77e12d19d09f5a9fe558ce336318b Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 31c962dbae502..043896b96921f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2061,9 +2061,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2091,6 +2091,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2865,6 +2888,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2886,7 +2917,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 290308872e026304dc598e83153779d5f6245eee Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 1ae0395814fe6..afab0796edaf0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2061,9 +2061,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2091,6 +2091,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2821,6 +2844,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2842,7 +2873,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-22 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 290308872e026304dc598e83153779d5f6245eee Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 1ae0395814fe6..afab0796edaf0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2061,9 +2061,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2091,6 +2091,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2821,6 +2844,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2842,7 +2873,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-21 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 4d3dbfe8dc0e49fc6e6d67db09114e1ad1057caa Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 2746671b1b048..6e49fcf7e754c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2061,9 +2061,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2091,6 +2091,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2824,6 +2847,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2845,7 +2876,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-21 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 4d3dbfe8dc0e49fc6e6d67db09114e1ad1057caa Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 2746671b1b048..6e49fcf7e754c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2061,9 +2061,9 @@ static Value *simplifyDemandedFPClassFabs(KnownFPClass 
&Known, Value *Src,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2091,6 +2091,29 @@ static FPClassTest 
adjustDemandedMaskFromFlags(FPClassTest DemandedMask,
   return DemandedMask;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2824,6 +2847,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2845,7 +2876,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float 

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From d7ada803fcf8772d893dc72db5f55a3c7b9468b0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3c15400d90b48..5fe889df057bf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,29 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2788,6 +2811,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2809,7 +2840,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From d7ada803fcf8772d893dc72db5f55a3c7b9468b0 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3c15400d90b48..5fe889df057bf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,29 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2788,6 +2811,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2809,7 +2840,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread via llvm-branch-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

* 168128 tests passed
* 2995 tests skipped
* 2 tests failed

## Failed Tests
(click on a test name to see its output)

### LLVM

LLVM.CodeGen/PowerPC/peephole-mma-phi-liveness.ll

```
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc 
-verify-machineinstrs -mcpu=ppc -mtriple=powerpc64-ibm-aix < 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/PowerPC/peephole-mma-phi-liveness.ll
 | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/PowerPC/peephole-mma-phi-liveness.ll
# executed command: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/llc 
-verify-machineinstrs -mcpu=ppc -mtriple=powerpc64-ibm-aix
# note: command had no output on stdout or stderr
# executed command: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/PowerPC/peephole-mma-phi-liveness.ll
# .---command stderr
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/PowerPC/peephole-mma-phi-liveness.ll:22:15:
 error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: stxv 2, 0(3)
# |   ^
# | :28:2: note: 'next' match was here
# |  stxv 2, 0(3)
# |  ^
# | :25:19: note: previous match ended here
# |  xvmaddadp 0, 1, 1
# |   ^
# | :26:1: note: non-matching line after previous match is here
# |  xvadddp 2, 2, 1
# | ^
# | 
# | Input file: 
# | Check file: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/CodeGen/PowerPC/peephole-mma-phi-liveness.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<
# |  .
# |  .
# |  .
# | 23:  xvmuldp 0, 0, 1 
# | 24:  xvmaddadp 2, 1, 1 
# | 25:  xvmaddadp 0, 1, 1 
# | 26:  xvadddp 2, 2, 1 
# | 27:  xvadddp 0, 0, 1 
# | 28:  stxv 2, 0(3) 
# | next:22  !~~~  error: match on wrong line
# | 29:  stxv 0, 0(3) 
# | 30:  # implicit-def: $acc0 
# | 31:  bc 12, 20, L..BB0_2 
# | 32: # %bb.1: # %bb10 
# | 33:  xvf64gerpp 0, 34, 0 
# |  .
# |  .
# |  .
# | >>
# `-
# error: command failed with exit status: 1

--

```


LLVM.Transforms/InstCombine/fabs.ll

```
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/opt 
-mtriple=x86_64-unknown-linux-gnu < 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/InstCombine/fabs.ll
 -passes=instcombine -S | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/InstCombine/fabs.ll
# executed command: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/opt 
-mtriple=x86_64-unknown-linux-gnu -passes=instcombine -S
# note: command had no output on stdout or stderr
# executed command: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/InstCombine/fabs.ll
# .---command stderr
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/InstCombine/fabs.ll:210:15:
 error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: ret float [[FMA]]
# |   ^
# | :125:78: note: scanning from here
# |  %fma = call nnan float @llvm.fma.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :125:78: note: with "FMA" equal to "%fma"
# |  %fma = call nnan float @llvm.fma.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :127:2: note: possible intended match here
# |  ret float %fabsf
# |  ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/test/Transforms/InstCombine/fabs.ll:231:15:
 error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: ret float [[FMULADD]]
# |   ^
# | :137:86: note: scanning from here
# |  %fmuladd = call nnan float @llvm.fmuladd.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :137:86: note: with "FMULADD" equal to "%fmuladd"
# |  %fmuladd = call nnan float @llvm.fmuladd.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :139:2: note: possible intended match here
# |  ret float %fabsf
# |  ^
# | 
# | Input file: 
# | Ch

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread via llvm-branch-commits

github-actions[bot] wrote:


# :window: Windows x64 Test Results

* 129520 tests passed
* 2866 tests skipped
* 2 tests failed

## Failed Tests
(click on a test name to see its output)

### LLVM

LLVM.CodeGen/PowerPC/peephole-mma-phi-liveness.ll

```
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
c:\_work\llvm-project\llvm-project\build\bin\llc.exe -verify-machineinstrs 
-mcpu=ppc -mtriple=powerpc64-ibm-aix < 
C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\PowerPC\peephole-mma-phi-liveness.ll
 | c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe 
C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\PowerPC\peephole-mma-phi-liveness.ll
# executed command: 'c:\_work\llvm-project\llvm-project\build\bin\llc.exe' 
-verify-machineinstrs -mcpu=ppc -mtriple=powerpc64-ibm-aix
# note: command had no output on stdout or stderr
# executed command: 
'c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe' 
'C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\PowerPC\peephole-mma-phi-liveness.ll'
# .---command stderr
# | 
C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\PowerPC\peephole-mma-phi-liveness.ll:22:15:
 error: CHECK-NEXT: is not on the line after the previous match
# | ; CHECK-NEXT: stxv 2, 0(3)
# |   ^
# | :28:2: note: 'next' match was here
# |  stxv 2, 0(3)
# |  ^
# | :25:19: note: previous match ended here
# |  xvmaddadp 0, 1, 1
# |   ^
# | :26:1: note: non-matching line after previous match is here
# |  xvadddp 2, 2, 1
# | ^
# | 
# | Input file: 
# | Check file: 
C:\_work\llvm-project\llvm-project\llvm\test\CodeGen\PowerPC\peephole-mma-phi-liveness.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<
# |  .
# |  .
# |  .
# | 23:  xvmuldp 0, 0, 1 
# | 24:  xvmaddadp 2, 1, 1 
# | 25:  xvmaddadp 0, 1, 1 
# | 26:  xvadddp 2, 2, 1 
# | 27:  xvadddp 0, 0, 1 
# | 28:  stxv 2, 0(3) 
# | next:22  !~~~  error: match on wrong line
# | 29:  stxv 0, 0(3) 
# | 30:  # implicit-def: $acc0 
# | 31:  bc 12, 20, L..BB0_2 
# | 32: # %bb.1: # %bb10 
# | 33:  xvf64gerpp 0, 34, 0 
# |  .
# |  .
# |  .
# | >>
# `-
# error: command failed with exit status: 1

--

```


LLVM.Transforms/InstCombine/fabs.ll

```
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
c:\_work\llvm-project\llvm-project\build\bin\opt.exe 
-mtriple=x86_64-unknown-linux-gnu < 
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\InstCombine\fabs.ll 
-passes=instcombine -S | 
c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe 
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\InstCombine\fabs.ll
# executed command: 'c:\_work\llvm-project\llvm-project\build\bin\opt.exe' 
-mtriple=x86_64-unknown-linux-gnu -passes=instcombine -S
# note: command had no output on stdout or stderr
# executed command: 
'c:\_work\llvm-project\llvm-project\build\bin\filecheck.exe' 
'C:\_work\llvm-project\llvm-project\llvm\test\Transforms\InstCombine\fabs.ll'
# .---command stderr
# | 
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\InstCombine\fabs.ll:210:15:
 error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: ret float [[FMA]]
# |   ^
# | :125:78: note: scanning from here
# |  %fma = call nnan float @llvm.fma.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :125:78: note: with "FMA" equal to "%fma"
# |  %fma = call nnan float @llvm.fma.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :127:2: note: possible intended match here
# |  ret float %fabsf
# |  ^
# | 
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\InstCombine\fabs.ll:231:15:
 error: CHECK-NEXT: expected string not found in input
# | ; CHECK-NEXT: ret float [[FMULADD]]
# |   ^
# | :137:86: note: scanning from here
# |  %fmuladd = call nnan float @llvm.fmuladd.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :137:86: note: with "FMULADD" equal to "%fmuladd"
# |  %fmuladd = call nnan float @llvm.fmuladd.f32(float %x, float %x, float 
1.00e+00)
# | 
 ^
# | :139:2: note: possible intended match here
# |  ret float %fabsf
# |  ^
# | 
# | Input file: 
# | Check file: 
C:\_work\llvm-project\llvm-project\llvm\test\Transforms\InstCombine\fabs.ll
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<
# | .
# | .
# | .
# |   120:  %fabsf = call float @llvm.fabs.f32(float %fma) 
# |   121:  ret float %fabsf 
# |   

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 4cbd9dbb839d6ff0944e58799cd2177c482b34ba Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3c15400d90b48..5fe889df057bf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,29 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2788,6 +2811,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2809,7 +2840,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 4cbd9dbb839d6ff0944e58799cd2177c482b34ba Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3c15400d90b48..5fe889df057bf 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,29 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2788,6 +2811,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2809,7 +2840,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread Yingwei Zheng via llvm-branch-commits

https://github.com/dtcxzyw edited 
https://github.com/llvm/llvm-project/pull/176003
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-15 Thread Yingwei Zheng via llvm-branch-commits

https://github.com/dtcxzyw approved this pull request.

LG

https://github.com/llvm/llvm-project/pull/176003
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 4d6a3911109ece865521de43104e2d7102b41062 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 87a03a558e5ac..b198e5e824f1f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,29 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2771,6 +2794,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2792,7 +2823,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/176003

>From 4d6a3911109ece865521de43104e2d7102b41062 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 40 ++--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 87a03a558e5ac..b198e5e824f1f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,29 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->dropUBImplyingAttrsAndMetadata();
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 static Value *
 simplifyDemandedFPClassMinMax(KnownFPClass &Known, Intrinsic::ID IID,
   const CallInst *CI, FPClassTest DemandedMask,
@@ -2771,6 +2794,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2792,7 +2823,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..9b5274b9e7459 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread Matt Arsenault via llvm-branch-commits


@@ -2056,6 +2056,28 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->setFastMathFlags(InferredFMF);

arsenm wrote:

Missing the attribute drop 

https://github.com/llvm/llvm-project/pull/176003
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-adt

Author: Matt Arsenault (arsenm)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/176003.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
(+35-4) 
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
(+60-5) 


``diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3bbc4a913ada6..3292d3538b4e3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,28 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 FPClassTest DemandedMask,
 KnownFPClass &Known,
@@ -2790,6 +2812,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2811,7 +2841,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..6ec5daa48e125 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PSUB:%.*]] = call nofpclass(nan inf zero nsub

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)


Changes



---
Full diff: https://github.com/llvm/llvm-project/pull/176003.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
(+35-4) 
- (modified) llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
(+60-5) 


``diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3bbc4a913ada6..3292d3538b4e3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,28 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 FPClassTest DemandedMask,
 KnownFPClass &Known,
@@ -2790,6 +2812,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2811,7 +2841,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..6ec5daa48e125 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PSUB:%.*]] = call nofpclass(nan inf ze

[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread Matt Arsenault via llvm-branch-commits

arsenm wrote:

> [!WARNING]
> This pull request is not mergeable via GitHub because a downstack PR is 
> open. Once all requirements are satisfied, merge this PR as a stack  href="https://app.graphite.com/github/pr/llvm/llvm-project/176003?utm_source=stack-comment-downstack-mergeability-warning";
>  >on Graphite.
> https://graphite.dev/docs/merge-pull-requests";>Learn more

* **#176003** https://app.graphite.com/github/pr/llvm/llvm-project/176003?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/> 👈 https://app.graphite.com/github/pr/llvm/llvm-project/176003?utm_source=stack-comment-view-in-graphite";
 target="_blank">(View in Graphite)
* **#175616** https://app.graphite.com/github/pr/llvm/llvm-project/175616?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#175615** https://app.graphite.com/github/pr/llvm/llvm-project/175615?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#175614** https://app.graphite.com/github/pr/llvm/llvm-project/175614?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>: 1 other dependent PR 
([#175999](https://github.com/llvm/llvm-project/pull/175999) https://app.graphite.com/github/pr/llvm/llvm-project/175999?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>)
* **#175613** https://app.graphite.com/github/pr/llvm/llvm-project/175613?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#174853** https://app.graphite.com/github/pr/llvm/llvm-project/174853?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* **#174852** https://app.graphite.com/github/pr/llvm/llvm-project/174852?utm_source=stack-comment-icon";
 target="_blank">https://static.graphite.dev/graphite-32x32-black.png"; alt="Graphite" 
width="10px" height="10px"/>
* `main`




This stack of pull requests is managed by https://graphite.dev?utm-source=stack-comment";>Graphite. Learn 
more about https://stacking.dev/?utm_source=stack-comment";>stacking.


https://github.com/llvm/llvm-project/pull/176003
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm ready_for_review 
https://github.com/llvm/llvm-project/pull/176003
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] InstCombine: Infer fast math flags for sqrt (PR #176003)

2026-01-14 Thread Matt Arsenault via llvm-branch-commits

https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/176003

None

>From 82372b2c36018ae7b2abc9af106e07bbc8bac689 Mon Sep 17 00:00:00 2001
From: Matt Arsenault 
Date: Wed, 14 Jan 2026 18:40:41 +0100
Subject: [PATCH] InstCombine: Infer fast math flags for sqrt

---
 .../InstCombineSimplifyDemanded.cpp   | 39 +--
 .../simplify-demanded-fpclass-sqrt.ll | 65 +--
 2 files changed, 95 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp 
b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3bbc4a913ada6..3292d3538b4e3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2036,9 +2036,9 @@ static Constant *getFPClassConstant(Type *Ty, FPClassTest 
Mask,
 /// Try to set an inferred no-nans or no-infs in \p FMF. \p ValidResults is a
 /// mask of known valid results for the operator (already computed from the
 /// result, and the known operand inputs in \p Known)
-static FastMathFlags
-inferFastMathValueFlags(FastMathFlags FMF, FPClassTest ValidResults,
-ArrayRef Known) {
+static FastMathFlags inferFastMathValueFlags(FastMathFlags FMF,
+ FPClassTest ValidResults,
+ ArrayRef Known) {
   if (!FMF.noNaNs() && (ValidResults & fcNan) == fcNone) {
 if (all_of(Known, [](const KnownFPClass KnownSrc) {
   return KnownSrc.isKnownNeverNaN();
@@ -2056,6 +2056,28 @@ inferFastMathValueFlags(FastMathFlags FMF, FPClassTest 
ValidResults,
   return FMF;
 }
 
+/// Apply epilog fixups to a floating-point intrinsic. See if the result can
+/// fold to a constant, or apply fast math flags.
+static Value *simplifyDemandedFPClassResult(CallInst *FPOp, FastMathFlags FMF,
+FPClassTest DemandedMask,
+KnownFPClass &Known,
+ArrayRef KnownSrcs) {
+  FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+  Constant *SingleVal = getFPClassConstant(FPOp->getType(), ValidResults,
+   /*IsCanonicalizing=*/true);
+  if (SingleVal)
+return SingleVal;
+
+  FastMathFlags InferredFMF =
+  inferFastMathValueFlags(FMF, ValidResults, KnownSrcs);
+  if (InferredFMF != FMF) {
+FPOp->setFastMathFlags(InferredFMF);
+return FPOp;
+  }
+
+  return nullptr;
+}
+
 Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 FPClassTest DemandedMask,
 KnownFPClass &Known,
@@ -2790,6 +2812,14 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
   if (SimplifyDemandedFPClass(I, 0, DemandedSrcMask, KnownSrc, Depth + 1))
 return I;
 
+  // Infer the source cannot be negative if the result cannot be nan.
+  if ((DemandedMask & fcNan) == fcNone)
+KnownSrc.knownNot((fcNegative & ~fcNegZero) | fcNan);
+
+  // Infer the source cannot be +inf if the result is not +nf
+  if ((DemandedMask & fcPosInf) == fcNone)
+KnownSrc.knownNot(fcPosInf);
+
   Type *EltTy = VTy->getScalarType();
   DenormalMode Mode = F.getDenormalMode(EltTy->getFltSemantics());
 
@@ -2811,7 +2841,8 @@ Value 
*InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
 return Copysign;
   }
 
-  return getFPClassConstant(VTy, ValidResults, /*IsCanonicalizing=*/true);
+  return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+   {KnownSrc});
 }
 case Intrinsic::trunc:
 case Intrinsic::floor:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll 
b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
index b09faf0f4c3af..6ec5daa48e125 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-sqrt.ll
@@ -220,7 +220,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_pnorm_sourc
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
 ; CHECK-NEXT:[[ONLY_PNORM:%.*]] = call nofpclass(nan inf zero sub nnorm) 
float @func()
 ; CHECK-NEXT:[[SELECT:%.*]] = select i1 [[COND]], float [[NOT_NAN]], float 
[[ONLY_PNORM]]
-; CHECK-NEXT:[[RESULT:%.*]] = call float @llvm.sqrt.f32(float [[SELECT]])
+; CHECK-NEXT:[[RESULT:%.*]] = call nnan ninf float @llvm.sqrt.f32(float 
[[SELECT]])
 ; CHECK-NEXT:ret float [[RESULT]]
 ;
   %only.pnorm = call nofpclass(nan inf nnorm sub zero) float @func()
@@ -234,7 +234,7 @@ define nofpclass(nan inf zero sub nnorm) float 
@pnorm_result_demands_psub_source
 ; CHECK-SAME: i1 [[COND:%.*]], float nofpcl