[llvm] f669755 - [Float2Int] Extract calcRange() method (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 31 07:13:21 PDT 2022


Author: Nikita Popov
Date: 2022-03-31T16:13:13+02:00
New Revision: f66975555fec57e55f3d72d06d8bc83472cd2c1e

URL: https://github.com/llvm/llvm-project/commit/f66975555fec57e55f3d72d06d8bc83472cd2c1e
DIFF: https://github.com/llvm/llvm-project/commit/f66975555fec57e55f3d72d06d8bc83472cd2c1e.diff

LOG: [Float2Int] Extract calcRange() method (NFC)

This avoids the awkward "Abort" flag, because we can simply
early-return instead.

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/Scalar/Float2Int.h
    llvm/lib/Transforms/Scalar/Float2Int.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/llvm/include/llvm/Transforms/Scalar/Float2Int.h
index d53c1f471bfe1..9def40ed880d4 100644
--- a/llvm/include/llvm/Transforms/Scalar/Float2Int.h
+++ b/llvm/include/llvm/Transforms/Scalar/Float2Int.h
@@ -41,6 +41,7 @@ class Float2IntPass : public PassInfoMixin<Float2IntPass> {
   ConstantRange badRange();
   ConstantRange unknownRange();
   ConstantRange validateRange(ConstantRange R);
+  ConstantRange calcRange(Instruction *I);
   void walkBackwards();
   void walkForwards();
   bool validateAndTransform();

diff  --git a/llvm/lib/Transforms/Scalar/Float2Int.cpp b/llvm/lib/Transforms/Scalar/Float2Int.cpp
index 4b6ff27e15974..bf87311143289 100644
--- a/llvm/lib/Transforms/Scalar/Float2Int.cpp
+++ b/llvm/lib/Transforms/Scalar/Float2Int.cpp
@@ -235,116 +235,114 @@ void Float2IntPass::walkBackwards() {
   }
 }
 
-// Walk forwards down the list of seen instructions, so we visit defs before
-// uses.
-void Float2IntPass::walkForwards() {
-  for (auto &It : reverse(SeenInsts)) {
-    if (It.second != unknownRange())
-      continue;
+// Calculate result range from operand ranges
+ConstantRange Float2IntPass::calcRange(Instruction *I) {
+  std::function<ConstantRange(ArrayRef<ConstantRange>)> Op;
+  switch (I->getOpcode()) {
+    // FIXME: Handle select and phi nodes.
+  default:
+  case Instruction::UIToFP:
+  case Instruction::SIToFP:
+    llvm_unreachable("Should have been handled in walkForwards!");
 
-    Instruction *I = It.first;
-    std::function<ConstantRange(ArrayRef<ConstantRange>)> Op;
-    switch (I->getOpcode()) {
-      // FIXME: Handle select and phi nodes.
-    default:
-    case Instruction::UIToFP:
-    case Instruction::SIToFP:
-      llvm_unreachable("Should have been handled in walkForwards!");
+  case Instruction::FNeg:
+    Op = [](ArrayRef<ConstantRange> Ops) {
+      assert(Ops.size() == 1 && "FNeg is a unary operator!");
+      unsigned Size = Ops[0].getBitWidth();
+      auto Zero = ConstantRange(APInt::getZero(Size));
+      return Zero.sub(Ops[0]);
+    };
+    break;
 
-    case Instruction::FNeg:
-      Op = [](ArrayRef<ConstantRange> Ops) {
-        assert(Ops.size() == 1 && "FNeg is a unary operator!");
-        unsigned Size = Ops[0].getBitWidth();
-        auto Zero = ConstantRange(APInt::getZero(Size));
-        return Zero.sub(Ops[0]);
-      };
-      break;
+  case Instruction::FAdd:
+  case Instruction::FSub:
+  case Instruction::FMul:
+    Op = [I](ArrayRef<ConstantRange> Ops) {
+      assert(Ops.size() == 2 && "its a binary operator!");
+      auto BinOp = (Instruction::BinaryOps) I->getOpcode();
+      return Ops[0].binaryOp(BinOp, Ops[1]);
+    };
+    break;
 
-    case Instruction::FAdd:
-    case Instruction::FSub:
-    case Instruction::FMul:
-      Op = [I](ArrayRef<ConstantRange> Ops) {
-        assert(Ops.size() == 2 && "its a binary operator!");
-        auto BinOp = (Instruction::BinaryOps) I->getOpcode();
-        return Ops[0].binaryOp(BinOp, Ops[1]);
-      };
-      break;
+  //
+  // Root-only instructions - we'll only see these if they're the
+  //                          first node in a walk.
+  //
+  case Instruction::FPToUI:
+  case Instruction::FPToSI:
+    Op = [I](ArrayRef<ConstantRange> Ops) {
+      assert(Ops.size() == 1 && "FPTo[US]I is a unary operator!");
+      // Note: We're ignoring the casts output size here as that's what the
+      // caller expects.
+      auto CastOp = (Instruction::CastOps)I->getOpcode();
+      return Ops[0].castOp(CastOp, MaxIntegerBW+1);
+    };
+    break;
 
-    //
-    // Root-only instructions - we'll only see these if they're the
-    //                          first node in a walk.
-    //
-    case Instruction::FPToUI:
-    case Instruction::FPToSI:
-      Op = [I](ArrayRef<ConstantRange> Ops) {
-        assert(Ops.size() == 1 && "FPTo[US]I is a unary operator!");
-        // Note: We're ignoring the casts output size here as that's what the
-        // caller expects.
-        auto CastOp = (Instruction::CastOps)I->getOpcode();
-        return Ops[0].castOp(CastOp, MaxIntegerBW+1);
-      };
-      break;
+  case Instruction::FCmp:
+    Op = [](ArrayRef<ConstantRange> Ops) {
+      assert(Ops.size() == 2 && "FCmp is a binary operator!");
+      return Ops[0].unionWith(Ops[1]);
+    };
+    break;
+  }
 
-    case Instruction::FCmp:
-      Op = [](ArrayRef<ConstantRange> Ops) {
-        assert(Ops.size() == 2 && "FCmp is a binary operator!");
-        return Ops[0].unionWith(Ops[1]);
-      };
-      break;
+  SmallVector<ConstantRange, 4> OpRanges;
+  for (Value *O : I->operands()) {
+    if (Instruction *OI = dyn_cast<Instruction>(O)) {
+      assert(SeenInsts.find(OI) != SeenInsts.end() &&
+             "def not seen before use!");
+      OpRanges.push_back(SeenInsts.find(OI)->second);
+    } else if (ConstantFP *CF = dyn_cast<ConstantFP>(O)) {
+      // Work out if the floating point number can be losslessly represented
+      // as an integer.
+      // APFloat::convertToInteger(&Exact) purports to do what we want, but
+      // the exactness can be too precise. For example, negative zero can
+      // never be exactly converted to an integer.
+      //
+      // Instead, we ask APFloat to round itself to an integral value - this
+      // preserves sign-of-zero - then compare the result with the original.
+      //
+      const APFloat &F = CF->getValueAPF();
+
+      // First, weed out obviously incorrect values. Non-finite numbers
+      // can't be represented and neither can negative zero, unless
+      // we're in fast math mode.
+      if (!F.isFinite() ||
+          (F.isZero() && F.isNegative() && isa<FPMathOperator>(I) &&
+           !I->hasNoSignedZeros()))
+        return badRange();
+
+      APFloat NewF = F;
+      auto Res = NewF.roundToIntegral(APFloat::rmNearestTiesToEven);
+      if (Res != APFloat::opOK || NewF != F)
+        return badRange();
+
+      // OK, it's representable. Now get it.
+      APSInt Int(MaxIntegerBW+1, false);
+      bool Exact;
+      CF->getValueAPF().convertToInteger(Int,
+                                         APFloat::rmNearestTiesToEven,
+                                         &Exact);
+      OpRanges.push_back(ConstantRange(Int));
+    } else {
+      llvm_unreachable("Should have already marked this as badRange!");
     }
+  }
 
-    bool Abort = false;
-    SmallVector<ConstantRange,4> OpRanges;
-    for (Value *O : I->operands()) {
-      if (Instruction *OI = dyn_cast<Instruction>(O)) {
-        assert(SeenInsts.find(OI) != SeenInsts.end() &&
-               "def not seen before use!");
-        OpRanges.push_back(SeenInsts.find(OI)->second);
-      } else if (ConstantFP *CF = dyn_cast<ConstantFP>(O)) {
-        // Work out if the floating point number can be losslessly represented
-        // as an integer.
-        // APFloat::convertToInteger(&Exact) purports to do what we want, but
-        // the exactness can be too precise. For example, negative zero can
-        // never be exactly converted to an integer.
-        //
-        // Instead, we ask APFloat to round itself to an integral value - this
-        // preserves sign-of-zero - then compare the result with the original.
-        //
-        const APFloat &F = CF->getValueAPF();
-
-        // First, weed out obviously incorrect values. Non-finite numbers
-        // can't be represented and neither can negative zero, unless
-        // we're in fast math mode.
-        if (!F.isFinite() ||
-            (F.isZero() && F.isNegative() && isa<FPMathOperator>(I) &&
-             !I->hasNoSignedZeros())) {
-          seen(I, badRange());
-          Abort = true;
-          break;
-        }
+  // Reduce the operands' ranges to a single range.
+  return Op(OpRanges);
+}
 
-        APFloat NewF = F;
-        auto Res = NewF.roundToIntegral(APFloat::rmNearestTiesToEven);
-        if (Res != APFloat::opOK || NewF != F) {
-          seen(I, badRange());
-          Abort = true;
-          break;
-        }
-        // OK, it's representable. Now get it.
-        APSInt Int(MaxIntegerBW+1, false);
-        bool Exact;
-        CF->getValueAPF().convertToInteger(Int,
-                                           APFloat::rmNearestTiesToEven,
-                                           &Exact);
-        OpRanges.push_back(ConstantRange(Int));
-      } else {
-        llvm_unreachable("Should have already marked this as badRange!");
-      }
-    }
+// Walk forwards down the list of seen instructions, so we visit defs before
+// uses.
+void Float2IntPass::walkForwards() {
+  for (auto &It : reverse(SeenInsts)) {
+    if (It.second != unknownRange())
+      continue;
 
-    // Reduce the operands' ranges to a single range and return.
-    if (!Abort)
-      seen(I, Op(OpRanges));
+    Instruction *I = It.first;
+    seen(I, calcRange(I));
   }
 }
 


        


More information about the llvm-commits mailing list