[llvm] [AMDGPU] Fold redundant inf/nan checks into frexp instructions (PR #214936)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 8 05:00:58 PDT 2026
================
@@ -18829,6 +18829,131 @@ SDValue SITargetLowering::performClampCombine(SDNode *N,
return getCanonicalConstantFP(DCI.DAG, SDLoc(N), N->getValueType(0), F);
}
+/// Check if a value is a positive or negative infinity constant.
+static bool isInfinityFPConstant(SDValue V) {
+ auto *CFP = dyn_cast<ConstantFPSDNode>(V);
+ return CFP && CFP->getValueAPF().isInfinity();
+}
+
+SDValue
+SITargetLowering::performFrexpSelectCombine(SDNode *N,
+ DAGCombinerInfo &DCI) const {
+ // This optimization only applies when the hardware handles inf/nan correctly.
+ if (Subtarget->hasFractBug())
+ return SDValue();
+
+ SDValue Cond = N->getOperand(0);
+ SDValue TrueVal = N->getOperand(1);
+ SDValue FalseVal = N->getOperand(2);
+
+ // Determine which value is 0 and which might be the frexp result.
+ // Pattern 1: select cond, 0, frexp_result (cond true -> return 0)
+ // Pattern 2: select cond, frexp_result, 0 (cond false -> return 0)
+ // Only check FP zero - frexp returns FP or integer, handle separately.
+ SDValue FrexpVal;
+ bool CondSelectsZero; // If true, condition=true selects zero
+
+ bool TrueIsFPZero = isNullFPConstant(TrueVal);
+ bool FalseIsFPZero = isNullFPConstant(FalseVal);
+ bool TrueIsIntZero = isNullConstant(TrueVal);
+ bool FalseIsIntZero = isNullConstant(FalseVal);
+
+ if (TrueIsFPZero || TrueIsIntZero) {
+ FrexpVal = FalseVal;
+ CondSelectsZero = true;
+ } else if (FalseIsFPZero || FalseIsIntZero) {
+ FrexpVal = TrueVal;
+ CondSelectsZero = false;
+ } else {
+ return SDValue();
+ }
+
+ // Check if FrexpVal comes from amdgcn_frexp_exp or amdgcn_frexp_mant.
+ SDValue FrexpInput;
+ if (!sd_match(FrexpVal, m_IntrinsicWOChain<Intrinsic::amdgcn_frexp_exp>(
+ m_Value(FrexpInput))) &&
+ !sd_match(FrexpVal, m_IntrinsicWOChain<Intrinsic::amdgcn_frexp_mant>(
+ m_Value(FrexpInput))))
+ return SDValue();
----------------
arsenm wrote:
Maybe try matching against ISD::FREXP?
https://github.com/llvm/llvm-project/pull/214936
More information about the llvm-commits
mailing list