Skip to content

Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and malloc parameters bound" #117020

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions llvm/include/llvm/IR/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,16 +723,12 @@ class Value {
bool AllowInvariantGroup = false,
function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
nullptr) const;

Value *stripAndAccumulateConstantOffsets(
const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
bool AllowInvariantGroup = false,
function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
nullptr) {
Value *stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset,
bool AllowNonInbounds,
bool AllowInvariantGroup = false) {
return const_cast<Value *>(
static_cast<const Value *>(this)->stripAndAccumulateConstantOffsets(
DL, Offset, AllowNonInbounds, AllowInvariantGroup,
ExternalAnalysis));
DL, Offset, AllowNonInbounds, AllowInvariantGroup));
}

/// This is a wrapper around stripAndAccumulateConstantOffsets with the
Expand Down
108 changes: 4 additions & 104 deletions llvm/lib/Analysis/MemoryBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,69 +673,6 @@ STATISTIC(ObjectVisitorArgument,
STATISTIC(ObjectVisitorLoad,
"Number of load instructions with unsolved size and offset");

static std::optional<APInt>
combinePossibleConstantValues(std::optional<APInt> LHS,
std::optional<APInt> RHS,
ObjectSizeOpts::Mode EvalMode) {
if (!LHS || !RHS)
return std::nullopt;
if (EvalMode == ObjectSizeOpts::Mode::Max)
return LHS->sge(*RHS) ? *LHS : *RHS;
else
return LHS->sle(*RHS) ? *LHS : *RHS;
}

static std::optional<APInt> aggregatePossibleConstantValuesImpl(
const Value *V, ObjectSizeOpts::Mode EvalMode, unsigned recursionDepth) {
constexpr unsigned maxRecursionDepth = 4;
if (recursionDepth == maxRecursionDepth)
return std::nullopt;

if (const auto *CI = dyn_cast<ConstantInt>(V)) {
return CI->getValue();
}

else if (const auto *SI = dyn_cast<SelectInst>(V)) {
return combinePossibleConstantValues(
aggregatePossibleConstantValuesImpl(SI->getTrueValue(), EvalMode,
recursionDepth + 1),
aggregatePossibleConstantValuesImpl(SI->getFalseValue(), EvalMode,
recursionDepth + 1),
EvalMode);
}

else if (const auto *PN = dyn_cast<PHINode>(V)) {
unsigned Count = PN->getNumIncomingValues();
if (Count == 0)
return std::nullopt;
auto Acc = aggregatePossibleConstantValuesImpl(
PN->getIncomingValue(0), EvalMode, recursionDepth + 1);
for (unsigned I = 1; Acc && I < Count; ++I) {
auto Tmp = aggregatePossibleConstantValuesImpl(
PN->getIncomingValue(1), EvalMode, recursionDepth + 1);
Acc = combinePossibleConstantValues(Acc, Tmp, EvalMode);
}
return Acc;
}

return std::nullopt;
}

static std::optional<APInt>
aggregatePossibleConstantValues(const Value *V, ObjectSizeOpts::Mode EvalMode) {
if (auto *CI = dyn_cast<ConstantInt>(V))
return CI->getValue();

if (EvalMode != ObjectSizeOpts::Mode::Min &&
EvalMode != ObjectSizeOpts::Mode::Max)
return std::nullopt;

// Not using computeConstantRange here because we cannot guarantee it's not
// doing optimization based on UB which we want to avoid when expanding
// __builtin_object_size.
return aggregatePossibleConstantValuesImpl(V, EvalMode, 0u);
}

/// Align \p Size according to \p Alignment. If \p Size is greater than
/// getSignedMaxValue(), set it as unknown as we can only represent signed value
/// in OffsetSpan.
Expand Down Expand Up @@ -783,36 +720,11 @@ OffsetSpan ObjectSizeOffsetVisitor::computeImpl(Value *V) {
V = V->stripAndAccumulateConstantOffsets(
DL, Offset, /* AllowNonInbounds */ true, /* AllowInvariantGroup */ true);

// Give it another try with approximated analysis. We don't start with this
// one because stripAndAccumulateConstantOffsets behaves differently wrt.
// overflows if we provide an external Analysis.
if ((Options.EvalMode == ObjectSizeOpts::Mode::Min ||
Options.EvalMode == ObjectSizeOpts::Mode::Max) &&
isa<GEPOperator>(V)) {
// External Analysis used to compute the Min/Max value of individual Offsets
// within a GEP.
ObjectSizeOpts::Mode EvalMode =
Options.EvalMode == ObjectSizeOpts::Mode::Min
? ObjectSizeOpts::Mode::Max
: ObjectSizeOpts::Mode::Min;
auto OffsetRangeAnalysis = [EvalMode](Value &VOffset, APInt &Offset) {
if (auto PossibleOffset =
aggregatePossibleConstantValues(&VOffset, EvalMode)) {
Offset = *PossibleOffset;
return true;
}
return false;
};

V = V->stripAndAccumulateConstantOffsets(
DL, Offset, /* AllowNonInbounds */ true, /* AllowInvariantGroup */ true,
/*ExternalAnalysis=*/OffsetRangeAnalysis);
}

// Later we use the index type size and zero but it will match the type of the
// value that is passed to computeImpl.
IntTyBits = DL.getIndexTypeSizeInBits(V->getType());
Zero = APInt::getZero(IntTyBits);

OffsetSpan ORT = computeValue(V);

bool IndexTypeSizeChanged = InitialIntTyBits != IntTyBits;
Expand Down Expand Up @@ -900,9 +812,8 @@ OffsetSpan ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
return OffsetSpan(Zero, align(Size, I.getAlign()));

Value *ArraySize = I.getArraySize();
if (auto PossibleSize =
aggregatePossibleConstantValues(ArraySize, Options.EvalMode)) {
APInt NumElems = *PossibleSize;
if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
APInt NumElems = C->getValue();
if (!CheckedZextOrTrunc(NumElems))
return ObjectSizeOffsetVisitor::unknown();

Expand All @@ -928,18 +839,7 @@ OffsetSpan ObjectSizeOffsetVisitor::visitArgument(Argument &A) {
}

OffsetSpan ObjectSizeOffsetVisitor::visitCallBase(CallBase &CB) {
auto Mapper = [this](const Value *V) -> const Value * {
if (!V->getType()->isIntegerTy())
return V;

if (auto PossibleBound =
aggregatePossibleConstantValues(V, Options.EvalMode))
return ConstantInt::get(V->getType(), *PossibleBound);

return V;
};

if (std::optional<APInt> Size = getAllocSize(&CB, TLI, Mapper)) {
if (std::optional<APInt> Size = getAllocSize(&CB, TLI)) {
// Very large unsigned value cannot be represented as OffsetSpan.
if (Size->isNegative())
return ObjectSizeOffsetVisitor::unknown();
Expand Down

This file was deleted.

Loading