[PATCH] [ValueTracking] Allow min/max detection to see through casts.

David Majnemer david.majnemer at gmail.com
Thu May 14 15:38:26 PDT 2015


REPOSITORY
  rL LLVM

================
Comment at: include/llvm/Analysis/ValueTracking.h:294
@@ -279,1 +293,3 @@
+                                         Value *&LHS, Value *&RHS,
+                                         Instruction::CastOps *CastOp=nullptr);
 
----------------
Please clang-format this.

================
Comment at: lib/Analysis/ValueTracking.cpp:3279-3303
@@ +3278,27 @@
+
+static Constant *lookThroughCast(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
+                                 Instruction::CastOps *CastOp) {
+  CastInst *Op1 = dyn_cast<CastInst>(TrueVal);
+  Constant *Op2 = dyn_cast<Constant>(FalseVal);
+  if (!Op1 || !Op2)
+    return nullptr;
+  Value *Castee = Op1->getOperand(0);
+  *CastOp = Op1->getOpcode();
+
+  switch (Op1->getOpcode()) {
+  default: break;
+  case Instruction::SExt:
+    if (CI->isSigned())
+      return ConstantExpr::getTrunc(Op2, Castee->getType());
+    break;
+  case Instruction::ZExt:
+    if (CI->isUnsigned())
+      return ConstantExpr::getTrunc(Op2, Castee->getType());
+    break;
+  case Instruction::Trunc:
+    return ConstantExpr::getIntegerCast(Op2, Castee->getType(),
+                                        ICI->isSigned());
+  }
+  return nullptr;
+}
+
----------------
`TrueVal` and `FalseVal` are not accurate names and the switch/case structure is a little superfluous.  `Castee->getType()` is just `Op1->getSrcTy()`.


I think the following is equivalent:

  static Constant *lookThroughCast(ICmpInst *ICI, Value *V1, Value *V2,
                                   Instruction::CastOps *CastOp) {
    auto *CI = dyn_cast<CastInst>(V1);
    auto *C = dyn_cast<Constant>(V2);
    if (!CI || !C)
      return nullptr;

    *CastOp = CI->getOpcode();

    if ((isa<SExtInst>(CI) && ICI->isSigned()) ||
        (isa<ZExtInst>(CI) && ICI->isUnsigned()))
      return ConstantExpr::getTrunc(C, CI->getSrcTy());

    if (isa<TruncInst>(CI))
      return ConstantExpr::getIntegerCast(C, CI->getSrcTy(), ICI->isSigned());

    return nullptr;
  }

================
Comment at: lib/Analysis/ValueTracking.cpp:3321-3322
@@ +3320,4 @@
+  // Bail out early.
+  if (CI->isEquality())
+    return SPF_UNKNOWN;
+
----------------
I don't think this will compile, `CI` isn't defined.

================
Comment at: lib/Analysis/ValueTracking.cpp:3330
@@ +3329,3 @@
+                                  LHS, RHS);
+    else if (Constant *C = lookThroughCast(ICI, FalseVal, TrueVal, CastOp))
+      return ::matchSelectPattern(Pred, CmpLHS, CmpRHS,
----------------
No need to make this `else if`.

http://reviews.llvm.org/D9748

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the llvm-commits mailing list