The code was using exact sizing only, but since what we really need is just to make sure the offsets are in bounds, a minimum bound on the object size is sufficient.
To demonstrate the difference, support computing minimum sizes from obects of scalable vector type.
(isa<AllocaInst>(RHS) || isa<GlobalVariable>(RHS))) {
uint64_t LHSSize, RHSSize;
ObjectSizeOpts Opts;
+ Opts.EvalMode = ObjectSizeOpts::Mode::Min;
Opts.NullIsUnknownSize =
NullPointerIsDefined(cast<AllocaInst>(LHS)->getFunction());
if (getObjectSize(LHS, LHSSize, DL, TLI, Opts) &&
if (!I.getAllocatedType()->isSized())
return unknown();
- if (isa<ScalableVectorType>(I.getAllocatedType()))
+ TypeSize ElemSize = DL.getTypeAllocSize(I.getAllocatedType());
+ if (ElemSize.isScalable() && Options.EvalMode != ObjectSizeOpts::Mode::Min)
return unknown();
-
- APInt Size(IntTyBits, DL.getTypeAllocSize(I.getAllocatedType()));
+ APInt Size(IntTyBits, ElemSize.getKnownMinSize());
if (!I.isArrayAllocation())
return std::make_pair(align(Size, I.getAlign()), Zero);
ret i1 %res
}
+define i1 @scalar_vectors_are_non_empty() {
+; CHECK-LABEL: @scalar_vectors_are_non_empty(
+; CHECK-NEXT: ret i1 true
+;
+ %a = alloca <vscale x 2 x i32>
+ %b = alloca <vscale x 2 x i32>
+ %res = icmp ne <vscale x 2 x i32>* %a, %b
+ ret i1 %res
+}
+
attributes #0 = { null_pointer_is_valid }