[llvm] [AMDGPU] Fold redundant inf/nan checks into frexp instructions (PR #214936)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 8 03:01:14 PDT 2026
================
@@ -18829,6 +18829,145 @@ SDValue SITargetLowering::performClampCombine(SDNode *N,
return getCanonicalConstantFP(DCI.DAG, SDLoc(N), N->getValueType(0), F);
}
+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)
+ SDValue FrexpVal;
+ bool CondSelectsZero; // If true, condition=true selects zero
+
+ auto isZero = [](SDValue V) {
+ if (auto *C = dyn_cast<ConstantSDNode>(V))
+ return C->isZero();
+ if (auto *C = dyn_cast<ConstantFPSDNode>(V))
+ return C->isZero();
+ return false;
+ };
+
+ if (isZero(TrueVal)) {
+ FrexpVal = FalseVal;
+ CondSelectsZero = true;
+ } else if (isZero(FalseVal)) {
+ FrexpVal = TrueVal;
+ CondSelectsZero = false;
+ } else {
+ return SDValue();
+ }
+
+ // Check if FrexpVal comes from amdgcn_frexp_exp or amdgcn_frexp_mant.
+ if (FrexpVal.getOpcode() != ISD::INTRINSIC_WO_CHAIN)
+ return SDValue();
+
+ unsigned IID = FrexpVal.getConstantOperandVal(0);
+ if (IID != Intrinsic::amdgcn_frexp_exp && IID != Intrinsic::amdgcn_frexp_mant)
+ return SDValue();
+
+ SDValue FrexpInput = FrexpVal.getOperand(1);
+
+ // Helper to strip fabs/fneg/fcopysign from a value.
+ auto peekFPSignOps = [](SDValue Val) {
----------------
addmisol wrote:
I have moved it to llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h, so both files can use it.
https://github.com/llvm/llvm-project/pull/214936
More information about the llvm-commits
mailing list