[PATCH] D19178: Broaden FoldItoFPtoI to try and establish whether the integer value fits into the float type

Carlos Liam via llvm-commits llvm-commits at lists.llvm.org
Tue May 3 07:04:46 PDT 2016


aarzee updated the summary for this revision.
aarzee updated this revision to Diff 55987.
aarzee added a comment.

Made the change suggested by @reames to only consider the mantissa. Scaling and exponent is no longer considered. Should be more easily verifiable.


http://reviews.llvm.org/D19178

Files:
  lib/Transforms/InstCombine/InstCombineCasts.cpp
  test/Transforms/InstCombine/sitofp.ll

Index: test/Transforms/InstCombine/sitofp.ll
===================================================================
--- test/Transforms/InstCombine/sitofp.ll
+++ test/Transforms/InstCombine/sitofp.ll
@@ -182,3 +182,15 @@
  ret i55 %C
 }
 
+; This should fold because even though the bit width of the integer
+; is greater than that of the mantissa, we can establish that the
+; actual value of the integer will fit into the mantissa.
+; CHECK-LABEL: test20
+; CHECK: and
+; CHECK-NEXT: ret i32
+define i32 @test20(i32 %A) nounwind {
+ %B = and i32 %A, 16777215
+ %C = sitofp i32 %B to float
+ %D = fptosi float %C to i32
+ ret i32 %D
+}
Index: lib/Transforms/InstCombine/InstCombineCasts.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -481,13 +481,13 @@
 
   // Test if the trunc is the user of a select which is part of a
   // minimum or maximum operation. If so, don't do any more simplification.
-  // Even simplifying demanded bits can break the canonical form of a 
+  // Even simplifying demanded bits can break the canonical form of a
   // min/max.
   Value *LHS, *RHS;
   if (SelectInst *SI = dyn_cast<SelectInst>(CI.getOperand(0)))
     if (matchSelectPattern(SI, LHS, RHS).Flavor != SPF_UNKNOWN)
       return nullptr;
-  
+
   // See if we can simplify any instructions used by the input whose sole
   // purpose is to compute bits we don't care about.
   if (SimplifyDemandedInstructionBits(CI))
@@ -1133,7 +1133,7 @@
   Type *SrcTy = Src->getType(), *DestTy = CI.getType();
 
   // If we know that the value being extended is positive, we can use a zext
-  // instead. 
+  // instead.
   bool KnownZero, KnownOne;
   ComputeSignBit(Src, KnownZero, KnownOne, 0, &CI);
   if (KnownZero) {
@@ -1418,6 +1418,9 @@
 // This is safe if the intermediate type has enough bits in its mantissa to
 // accurately represent all values of X.  For example, this won't work with
 // i64 -> float -> i64.
+// However, this is also safe if we can establish the most significant set bit
+// of abs(X) fits into the mantissa.
+
 Instruction *InstCombiner::FoldItoFPtoI(Instruction &FI) {
   if (!isa<UIToFPInst>(FI.getOperand(0)) && !isa<SIToFPInst>(FI.getOperand(0)))
     return nullptr;
@@ -1443,7 +1446,31 @@
   int OutputSize = (int)FITy->getScalarSizeInBits() - IsOutputSigned;
   int ActualSize = std::min(InputSize, OutputSize);
 
-  if (ActualSize <= OpITy->getFPMantissaWidth()) {
+  int MantissaWidth = OpITy->getFPMantissaWidth();
+
+  bool safe;
+
+  if (ActualSize <= MantissaWidth) {
+    safe = true;
+    // No need to compute known bits.
+  } else {
+    // Now try and see if the integer value fits into the fp type.
+    // Calculate the most significant possibly set non-sign bit.
+    uint32_t BitWidth = SrcTy->getScalarSizeInBits();
+    APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+    computeKnownBits(SrcI, KnownZero, KnownOne, 0, &FI);
+    int MostSignificantPossiblySetBit = 0;
+    bool PossiblyNegative = IsInputSigned && !KnownZero[BitWidth - 1];
+    for(int i = BitWidth - PossiblyNegative - 1; i != 0; i--) {
+        if (KnownZero[i]) {
+            MostSignificantPossiblySetBit = i + PossiblyNegative;
+            break;
+        }
+    }
+    safe = MantissaWidth > MostSignificantPossiblySetBit;
+  }
+
+  if (safe) {
     if (FITy->getScalarSizeInBits() > SrcTy->getScalarSizeInBits()) {
       if (IsInputSigned && IsOutputSigned)
         return new SExtInst(SrcI, FITy);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19178.55987.patch
Type: text/x-patch
Size: 3550 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160503/a0e33be6/attachment.bin>


More information about the llvm-commits mailing list