Skip to content

Commit

Permalink
[BoundsChecking] Handle vscale allocas (#90926)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalybuka authored May 3, 2024
1 parent b0eeacb commit 43a38e2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
8 changes: 4 additions & 4 deletions llvm/lib/Analysis/MemoryBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,8 +1138,8 @@ SizeOffsetValue ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
if (!I.getAllocatedType()->isSized())
return ObjectSizeOffsetEvaluator::unknown();

// must be a VLA
assert(I.isArrayAllocation());
// must be a VLA or vscale.
assert(I.isArrayAllocation() || I.getAllocatedType()->isScalableTy());

// If needed, adjust the alloca's operand size to match the pointer indexing
// size. Subsequent math operations expect the types to match.
Expand All @@ -1149,8 +1149,8 @@ SizeOffsetValue ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
assert(ArraySize->getType() == Zero->getType() &&
"Expected zero constant to have pointer index type");

Value *Size = ConstantInt::get(ArraySize->getType(),
DL.getTypeAllocSize(I.getAllocatedType()));
Value *Size = Builder.CreateTypeSize(
ArraySize->getType(), DL.getTypeAllocSize(I.getAllocatedType()));
Size = Builder.CreateMul(Size, ArraySize);
return SizeOffsetValue(Size, Zero);
}
Expand Down
66 changes: 66 additions & 0 deletions llvm/test/Instrumentation/BoundsChecking/simple.ll
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,69 @@ define <vscale x 1 x i32> @load_scalable_vector(i64 %y) nounwind {
%3 = load <vscale x 1 x i32>, ptr %2, align 8
ret <vscale x 1 x i32> %3
}

define void @scalable_alloca(i64 %y) nounwind {
; CHECK-LABEL: @scalable_alloca(
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP1]], 8
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 5
; CHECK-NEXT: [[TMP4:%.*]] = alloca <vscale x 4 x i16>, i32 5, align 8
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP6:%.*]] = mul i64 [[TMP5]], 8
; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], [[TMP6]]
; CHECK-NEXT: [[TMP7:%.*]] = add i64 0, [[DOTIDX]]
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds <vscale x 4 x i16>, ptr [[TMP4]], i64 [[Y]]
; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP10:%.*]] = mul i64 [[TMP9]], 8
; CHECK-NEXT: [[TMP11:%.*]] = sub i64 [[TMP3]], [[TMP7]]
; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP3]], [[TMP7]]
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 [[TMP11]], [[TMP10]]
; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP12]], [[TMP13]]
; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i64 [[TMP7]], 0
; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP15]], [[TMP14]]
; CHECK-NEXT: br i1 [[TMP16]], label [[TRAP:%.*]], label [[TMP17:%.*]]
; CHECK: 17:
; CHECK-NEXT: [[TMP18:%.*]] = load <vscale x 4 x i16>, ptr [[TMP8]], align 4
; CHECK-NEXT: ret void
; CHECK: trap:
; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]]
; CHECK-NEXT: unreachable
;
%1 = alloca <vscale x 4 x i16>, i32 5
%2 = getelementptr inbounds <vscale x 4 x i16>, ptr %1, i64 %y
%3 = load <vscale x 4 x i16>, ptr %2, align 4
ret void
}

define void @scalable_alloca2(i64 %y) nounwind {
; CHECK-LABEL: @scalable_alloca2(
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP1]], 32
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 1
; CHECK-NEXT: [[TMP4:%.*]] = alloca <vscale x 4 x i64>, align 32
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP6:%.*]] = mul i64 [[TMP5]], 32
; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], [[TMP6]]
; CHECK-NEXT: [[TMP7:%.*]] = add i64 0, [[DOTIDX]]
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds <vscale x 4 x i64>, ptr [[TMP4]], i64 [[Y]]
; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.vscale.i64()
; CHECK-NEXT: [[TMP10:%.*]] = mul i64 [[TMP9]], 32
; CHECK-NEXT: [[TMP11:%.*]] = sub i64 [[TMP3]], [[TMP7]]
; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP3]], [[TMP7]]
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 [[TMP11]], [[TMP10]]
; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP12]], [[TMP13]]
; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i64 [[TMP7]], 0
; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP15]], [[TMP14]]
; CHECK-NEXT: br i1 [[TMP16]], label [[TRAP:%.*]], label [[TMP17:%.*]]
; CHECK: 17:
; CHECK-NEXT: [[TMP18:%.*]] = load <vscale x 4 x i64>, ptr [[TMP8]], align 4
; CHECK-NEXT: ret void
; CHECK: trap:
; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]]
; CHECK-NEXT: unreachable
;
%1 = alloca <vscale x 4 x i64>
%2 = getelementptr inbounds <vscale x 4 x i64>, ptr %1, i64 %y
%3 = load <vscale x 4 x i64>, ptr %2, align 4
ret void
}

0 comments on commit 43a38e2

Please sign in to comment.