[PATCH] D123830: [InstCombine] Complete folding of fneg-of-fabs

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 22 08:05:19 PDT 2022


spatel added a comment.

In D123830#3466496 <https://reviews.llvm.org/D123830#3466496>, @Chenbing.Zheng wrote:

> Thanks for spatel's suggestion , that's very useful.

Yes, this looks nicer. See inline for some small improvements.



================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2503
+static Value *foldSelectToFabs(SelectInst &SI, InstCombiner::BuilderTy &Builder,
+                               bool &IsNeg, int Swap) {
+  Value *CondVal = SI.getCondition();
----------------
Swap should be a `bool` parameter, and the caller can use "for (bool Swap : {false, true} )".
Or we can move the FNeg part of the transform into this function and avoid the parameter completely?


================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2506
+  Value *TrueVal = Swap ? SI.getFalseValue() : SI.getTrueValue();
+  Value *FalseVal = Swap ? SI.getTrueValue() : SI.getFalseValue();
+  CmpInst::Predicate Pred;
----------------
If we name this value 'X', then the code would match the comments, so that seems easier to read - see the next comments for a possible reduction.


================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2512-2513
+
+  // Canonicalize select with fcmp to fabs(). -0.0 makes this tricky. We need
+  // fast-math-flags (nsz) or fsub with +0.0 (not fneg) for this to work.
+  // (X <= +/-0.0) ? (0.0 - X) : X --> fabs(X)
----------------
We can move this statement to above the function declaration now. It describes the complete behavior of this function.


================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp:2532-2533
+                  Pred == FCmpInst::FCMP_UGT || Pred == FCmpInst::FCMP_UGE;
+  if (match(TrueVal, m_FNeg(m_Specific(FalseVal))) && SI.hasNoSignedZeros()) {
+    if ((Swap == 0 && IsLTOrLE) || (Swap == 1 && IsGTOrGE))
+      return Builder.CreateUnaryIntrinsic(Intrinsic::fabs, FalseVal, &SI);
----------------
This logic seems more complicated than needed. If we always match the TrueVal as -X, then we can get the swapped predicate and reduce the code to something like this:

```
  if (!match(TrueVal, m_FNeg(m_Specific(FalseVal))) || !SI.hasNoSignedZeros())
    return nullptr;

  if (Swap)
    Pred = FCmpInst::getSwappedPredicate(Pred);

  // With nsz:
  // fold (X <  +/-0.0) ? -X : X or (X <= +/-0.0) ? -X : X to fabs(X)
  // fold (X >  +/-0.0) ? -X : X or (X >= +/-0.0) ? X : -X to -fabs(x)
  bool IsLTOrLE = Pred == FCmpInst::FCMP_OLT || Pred == FCmpInst::FCMP_OLE ||
                  Pred == FCmpInst::FCMP_ULT || Pred == FCmpInst::FCMP_ULE;
  bool IsGTOrGE = Pred == FCmpInst::FCMP_OGT || Pred == FCmpInst::FCMP_OGE ||
                  Pred == FCmpInst::FCMP_UGT || Pred == FCmpInst::FCMP_UGE;

  if (IsLTOrLE)
    return Builder.CreateUnaryIntrinsic(Intrinsic::fabs, FalseVal, &SI);
  if (IsGTOrGE) {
    IsNeg = true;
    return Builder.CreateUnaryIntrinsic(Intrinsic::fabs, FalseVal, &SI);
  }

```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D123830/new/

https://reviews.llvm.org/D123830



More information about the llvm-commits mailing list