Skip to content

llvm.objectsize cannot compute a trivial bound #64796

@bevin-hansson

Description

@bevin-hansson

The following example results in a return value of 0, but it should be possible to figure out that there's at minimum 10 bytes left in the object:

int cond;

long long bos() {
    char arr[20];
    void *p = cond ? &arr[0] : &arr[10];
    return __builtin_object_size(p, 2);
}

See Godbolt: https://godbolt.org/z/vhfWv69Tv

Looking at ObjectSizeOffsetVisitor shows two things that seem odd.

The first is that it will give up on visiting instructions that have already been visited:

  if (Instruction *I = dyn_cast<Instruction>(V)) {
    // If we have already seen this instruction, bail out. Cycles can happen in
    // unreachable code after constant propagation.
    if (!SeenInsts.insert(I).second)
      return unknown();

    return visit(*I);
  }

So it won't end up visiting the alloca again, and just considers it to have unknown size on the second visit.

Even without this, the analysis still fails. If MustSucceed is false, it resorts to finding an exact size instead of a reasonable conservative estimate:

  // Unless we have to fold this to something, try to be as accurate as
  // possible.
  if (MustSucceed)
    EvalOptions.EvalMode =
        MaxVal ? ObjectSizeOpts::Mode::Max : ObjectSizeOpts::Mode::Min;
  else
    EvalOptions.EvalMode = ObjectSizeOpts::Mode::ExactSizeFromOffset;

But the result then is that it cannot find an exact size (because it doesn't know if it's 10 or 20), so it produces the most conservative estimate 0 instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    llvmUmbrella label for LLVM issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions