[llvm] [InstCombine] InstCombine should fold frexp of select to select of frexp (PR #121227)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 6 21:50:20 PST 2025


================
@@ -4043,6 +4044,57 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) {
   return nullptr;
 }
 
+static Value *foldFrexpOfSelect(ExtractValueInst &EV, IntrinsicInst *FrexpCall,
+                                SelectInst *SelectInst,
+                                InstCombiner::BuilderTy &Builder) {
+  // Helper to fold frexp of select to select of frexp.
+  Value *Cond = SelectInst->getCondition();
+  Value *TrueVal = SelectInst->getTrueValue();
+  Value *FalseVal = SelectInst->getFalseValue();
+
+  const APFloat *ConstVal = nullptr;
+  Value *VarOp = nullptr;
+  bool ConstIsTrue = false;
+
+  if (match(TrueVal, m_APFloat(ConstVal))) {
+    VarOp = FalseVal;
+    ConstIsTrue = true;
+  } else if (match(FalseVal, m_APFloat(ConstVal))) {
+    VarOp = TrueVal;
+    ConstIsTrue = false;
+  } else {
+    return nullptr;
+  }
+
+  Builder.SetInsertPoint(&EV);
+
+  CallInst *NewFrexp =
+      Builder.CreateCall(FrexpCall->getCalledFunction(), {VarOp}, "frexp");
+  NewFrexp->copyIRFlags(FrexpCall);
+
+  Value *NewEV = Builder.CreateExtractValue(NewFrexp, 0, "mantissa");
+
+  int Exp;
+  APFloat Mantissa = frexp(*ConstVal, Exp, APFloat::rmNearestTiesToEven);
+
+  Constant *ConstantMantissa;
+  if (auto *VecTy = dyn_cast<VectorType>(TrueVal->getType())) {
+    SmallVector<Constant *, 4> Elems(
+        VecTy->getElementCount().getFixedValue(),
+        ConstantFP::get(VecTy->getElementType(), Mantissa));
+    ConstantMantissa = ConstantVector::get(Elems);
+  } else {
+    ConstantMantissa = ConstantFP::get(TrueVal->getType(), Mantissa);
+  }
+
+  Value *NewSel = Builder.CreateSelect(
+      Cond, ConstIsTrue ? ConstantMantissa : NewEV,
+      ConstIsTrue ? NewEV : ConstantMantissa, "select.frexp");
+  if (auto *NewSelInst = dyn_cast<Instruction>(NewSel))
+    NewSelInst->copyFastMathFlags(SelectInst);
----------------
dtcxzyw wrote:

```suggestion
  Value *NewSel = Builder.CreateSelectFMF(
      Cond, ConstIsTrue ? ConstantMantissa : NewEV,
      ConstIsTrue ? NewEV : ConstantMantissa, &SelectInst, "select.frexp");
```
It is simpler to use `CreateSelectFMF`. Please rebase on the top of https://github.com/llvm/llvm-project/pull/121657.


https://github.com/llvm/llvm-project/pull/121227


More information about the llvm-commits mailing list