[Attributor] Look through (some) casts in AAValueConstantRangeFloating

Casts can be handled natively by the ConstantRange class. We do limit it
to extends for now as we assume an integer type in different locations.
A TODO and a test case with a FIXME was added to remove that restriction
in the future.
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 8b97e3d..f16b9bc 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -6183,6 +6183,12 @@
         return;
       }
 
+    // We handle casts in the updateImpl.
+    // TODO: Allow non integers as well.
+    if (CastInst *CI = dyn_cast<CastInst>(&V))
+      if (CI->getOperand(0)->getType()->isIntegerTy())
+        return;
+
     // Otherwise we give up.
     indicatePessimisticFixpoint();
 
@@ -6212,6 +6218,20 @@
     return T.isValidState();
   }
 
+  bool calculateCastInst(Attributor &A, CastInst *CastI, IntegerRangeState &T,
+                         Instruction *CtxI) {
+    assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
+    // TODO: Allow non integers as well.
+    Value &OpV = *CastI->getOperand(0);
+    assert(OpV.getType()->isIntegerTy() && "Expected integer cast");
+
+    auto &OpAA =
+        A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
+    T.unionAssumed(
+        OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
+    return T.isValidState();
+  }
+
   bool calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
                         Instruction *CtxI) {
     Value *LHS = CmpI->getOperand(0);
@@ -6282,6 +6302,8 @@
         return calculateBinaryOperator(A, BinOp, T, CtxI);
       else if (auto *CmpI = dyn_cast<CmpInst>(I))
         return calculateCmpInst(A, CmpI, T, CtxI);
+      else if (auto *CastI = dyn_cast<CastInst>(I))
+        return calculateCastInst(A, CastI, T, CtxI);
       else {
         // Give up with other instructions.
         // TODO: Add other instructions