Index: lib/Analysis/LazyValueInfo.cpp =================================================================== --- lib/Analysis/LazyValueInfo.cpp +++ lib/Analysis/LazyValueInfo.cpp @@ -1003,23 +1003,27 @@ bool LazyValueInfoCache::solveBlockValueCast(LVILatticeVal &BBLV, Instruction *BBI, BasicBlock *BB) { - // Figure out the range of the LHS. If that fails, bail. - if (!hasBlockValue(BBI->getOperand(0), BB)) { + // Figure out the range of the LHS. If that fails, we still apply the + // transfer rule on the full set since we may be able to locally infer + // interesting facts. + if (!hasBlockValue(BBI->getOperand(0), BB)) if (pushBlockValue(std::make_pair(BB, BBI->getOperand(0)))) + // More work to do before applying this transfer rule return false; - BBLV.markOverdefined(); - return true; - } - LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB); - intersectAssumeBlockValueConstantRange(BBI->getOperand(0), LHSVal, BBI); - if (!LHSVal.isConstantRange()) { - BBLV.markOverdefined(); - return true; + const unsigned OperandBitWidth = + BBI->getOperand(0)->getType()->getPrimitiveSizeInBits(); + + ConstantRange LHSRange = ConstantRange(OperandBitWidth); + if (hasBlockValue(BBI->getOperand(0), BB)) { + LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB); + intersectAssumeBlockValueConstantRange(BBI->getOperand(0), LHSVal, BBI); + if (LHSVal.isConstantRange()) + LHSRange = LHSVal.getConstantRange(); } - ConstantRange LHSRange = LHSVal.getConstantRange(); - IntegerType *ResultTy = cast(BBI->getType()); + const unsigned ResultBitWidth = + cast(BBI->getType())->getBitWidth(); // NOTE: We're currently limited by the set of operations that ConstantRange // can evaluate symbolically. Enhancing that set will allows us to analyze @@ -1027,13 +1031,13 @@ LVILatticeVal Result; switch (BBI->getOpcode()) { case Instruction::Trunc: - Result.markConstantRange(LHSRange.truncate(ResultTy->getBitWidth())); + Result.markConstantRange(LHSRange.truncate(ResultBitWidth)); break; case Instruction::SExt: - Result.markConstantRange(LHSRange.signExtend(ResultTy->getBitWidth())); + Result.markConstantRange(LHSRange.signExtend(ResultBitWidth)); break; case Instruction::ZExt: - Result.markConstantRange(LHSRange.zeroExtend(ResultTy->getBitWidth())); + Result.markConstantRange(LHSRange.zeroExtend(ResultBitWidth)); break; case Instruction::BitCast: Result.markConstantRange(LHSRange); Index: test/Transforms/CorrelatedValuePropagation/basic.ll =================================================================== --- test/Transforms/CorrelatedValuePropagation/basic.ll +++ test/Transforms/CorrelatedValuePropagation/basic.ll @@ -392,3 +392,39 @@ out: ret i1 false } + +define i1 @zext_unknown(i8 %a) { +; CHECK-LABEL: @zext_unknown +; CHECK: ret i1 true +entry: + %a32 = zext i8 %a to i32 + %cmp = icmp sle i32 %a32, 256 + br label %exit +exit: + ret i1 %cmp +} + +define i1 @trunc_unknown(i32 %a) { +; CHECK-LABEL: @trunc_unknown +; CHECK: ret i1 true +entry: + %a8 = trunc i32 %a to i8 + %a32 = sext i8 %a8 to i32 + %cmp = icmp sle i32 %a32, 128 + br label %exit +exit: + ret i1 %cmp +} + +; TODO: missed optimization +; Make sure we exercise non-integer inputs to unary operators (i.e. crash check) +define i1 @bitcast_unknown(float %a) { +; CHECK-LABEL: @bitcast_unknown +; CHECK: ret i1 %cmp +entry: + %a32 = bitcast float %a to i32 + %cmp = icmp sle i32 %a32, 128 + br label %exit +exit: + ret i1 %cmp +}