diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 4884c23f16e12a..b41255f1dbe7c6 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -1600,8 +1600,68 @@ void ConstraintInfo::addFact(CmpInst::Predicate Pred, Value *A, Value *B, DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, std::move(ValuesToRelease)); - if (!R.IsSigned) { - for (Value *V : NewVariables) { + // Add range information from attributes and metadata. + for (auto *V : NewVariables) { + if (V->getType()->getScalarSizeInBits() >= 64) + continue; + std::optional CR; + if (const auto *Arg = dyn_cast(V)) { + CR = Arg->getRange(); + } else if (const auto *CB = dyn_cast(V)) { + CR = CB->getRange(); + } else if (const auto *I = dyn_cast(V)) { + if (auto *Range = I->getMetadata(LLVMContext::MD_range)) + CR = getConstantRangeFromMetadata(*Range); + } + if (CR) { + if (R.IsSigned) { + int64_t MaxVal = CR->getSignedMax().getSExtValue(); + int64_t MinVal = CR->getSignedMin().getSExtValue(); + if (MaxVal != MaxConstraintValue) { + ConstraintTy VarPos( + SmallVector(Value2Index.size() + 1, 0), false, + false, false); + VarPos.Coefficients[0] = MaxVal; + VarPos.Coefficients[Value2Index[V]] = 1; + CSToUse.addVariableRow(VarPos.Coefficients); + DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, + SmallVector()); + } + if (MinVal != MinSignedConstraintValue) { + ConstraintTy VarPos( + SmallVector(Value2Index.size() + 1, 0), false, + false, false); + VarPos.Coefficients[0] = MinVal; + VarPos.Coefficients[Value2Index[V]] = -1; + CSToUse.addVariableRow(VarPos.Coefficients); + DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, + SmallVector()); + } + } else { + uint64_t MaxVal = CR->getUnsignedMax().getZExtValue(); + uint64_t MinVal = CR->getUnsignedMin().getZExtValue(); + if (MaxVal < static_cast(MaxConstraintValue)) { + ConstraintTy VarPos( + SmallVector(Value2Index.size() + 1, 0), false, + false, false); + VarPos.Coefficients[0] = MaxVal; + VarPos.Coefficients[Value2Index[V]] = 1; + CSToUse.addVariableRow(VarPos.Coefficients); + DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, + SmallVector()); + } + MinVal = + std::min(MinVal, static_cast(MaxConstraintValue - 1)); + ConstraintTy VarPos( + SmallVector(Value2Index.size() + 1, 0), false, false, + false); + VarPos.Coefficients[0] = MinVal; + VarPos.Coefficients[Value2Index[V]] = -1; + CSToUse.addVariableRow(VarPos.Coefficients); + DFSInStack.emplace_back(NumIn, NumOut, R.IsSigned, + SmallVector()); + } + } else if (!R.IsSigned) { ConstraintTy VarPos(SmallVector(Value2Index.size() + 1, 0), false, false, false); VarPos.Coefficients[Value2Index[V]] = -1;