[ValueTracking] enhance isKnownNeverInfinity to understand sitofp
authorSanjay Patel <spatel@rotateright.com>
Sun, 27 Sep 2020 12:24:03 +0000 (08:24 -0400)
committerSanjay Patel <spatel@rotateright.com>
Sun, 27 Sep 2020 12:40:31 +0000 (08:40 -0400)
As discussed in D87877, instcombine already has this fold,
but it was missing from the more general ValueTracking logic.

https://alive2.llvm.org/ce/z/PumYZP

llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstSimplify/floating-point-compare.ll

index ac83869..2b8b1ef 100644 (file)
@@ -3523,11 +3523,20 @@ bool llvm::isKnownNeverInfinity(const Value *V, const TargetLibraryInfo *TLI,
       return isKnownNeverInfinity(Inst->getOperand(1), TLI, Depth + 1) &&
              isKnownNeverInfinity(Inst->getOperand(2), TLI, Depth + 1);
     }
-    case Instruction::UIToFP:
-      // If the input type fits into the floating type the result is finite.
-      return ilogb(APFloat::getLargest(
-                 Inst->getType()->getScalarType()->getFltSemantics())) >=
-             (int)Inst->getOperand(0)->getType()->getScalarSizeInBits();
+    case Instruction::SIToFP:
+    case Instruction::UIToFP: {
+      // Get width of largest magnitude integer (remove a bit if signed).
+      // This still works for a signed minimum value because the largest FP
+      // value is scaled by some fraction close to 2.0 (1.0 + 0.xxxx).
+      int IntSize = Inst->getOperand(0)->getType()->getScalarSizeInBits();
+      if (Inst->getOpcode() == Instruction::SIToFP)
+        --IntSize;
+
+      // If the exponent of the largest finite FP value can hold the largest
+      // integer, the result of the cast must be finite.
+      Type *FPTy = Inst->getType()->getScalarType();
+      return ilogb(APFloat::getLargest(FPTy->getFltSemantics())) >= IntSize;
+    }
     default:
       break;
     }
index 0a7c15a..e5184ce 100644 (file)
@@ -1184,14 +1184,12 @@ define i1 @isNotKnownNeverNegativeInfinity_uitofp(i16 %x) {
   ret i1 %r
 }
 
-; largest signed i16 = 2^15 - 1 = 32767
+; largest magnitude signed i16 = 2^15 - 1 = 32767 --> -32768
 ; largest half (max exponent = 15 -> 2^15 * (1 + 1023/1024) = 65504
 
 define i1 @isKnownNeverInfinity_sitofp(i16 %x) {
 ; CHECK-LABEL: @isKnownNeverInfinity_sitofp(
-; CHECK-NEXT:    [[F:%.*]] = sitofp i16 [[X:%.*]] to half
-; CHECK-NEXT:    [[R:%.*]] = fcmp une half [[F]], 0xH7C00
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 true
 ;
   %f = sitofp i16 %x to half
   %r = fcmp une half %f, 0xH7c00
@@ -1213,9 +1211,7 @@ define i1 @isNotKnownNeverInfinity_sitofp(i17 %x) {
 
 define i1 @isKnownNeverNegativeInfinity_sitofp(i16 %x) {
 ; CHECK-LABEL: @isKnownNeverNegativeInfinity_sitofp(
-; CHECK-NEXT:    [[F:%.*]] = sitofp i16 [[X:%.*]] to half
-; CHECK-NEXT:    [[R:%.*]] = fcmp oeq half [[F]], 0xHFC00
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 false
 ;
   %f = sitofp i16 %x to half
   %r = fcmp oeq half %f, 0xHfc00