Skip to content

Commit 43a38e2

Browse files
authored
[BoundsChecking] Handle vscale allocas (#90926)
1 parent b0eeacb commit 43a38e2

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

llvm/lib/Analysis/MemoryBuiltins.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,8 +1138,8 @@ SizeOffsetValue ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
11381138
if (!I.getAllocatedType()->isSized())
11391139
return ObjectSizeOffsetEvaluator::unknown();
11401140

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

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

1152-
Value *Size = ConstantInt::get(ArraySize->getType(),
1153-
DL.getTypeAllocSize(I.getAllocatedType()));
1152+
Value *Size = Builder.CreateTypeSize(
1153+
ArraySize->getType(), DL.getTypeAllocSize(I.getAllocatedType()));
11541154
Size = Builder.CreateMul(Size, ArraySize);
11551155
return SizeOffsetValue(Size, Zero);
11561156
}

llvm/test/Instrumentation/BoundsChecking/simple.ll

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,69 @@ define <vscale x 1 x i32> @load_scalable_vector(i64 %y) nounwind {
488488
%3 = load <vscale x 1 x i32>, ptr %2, align 8
489489
ret <vscale x 1 x i32> %3
490490
}
491+
492+
define void @scalable_alloca(i64 %y) nounwind {
493+
; CHECK-LABEL: @scalable_alloca(
494+
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
495+
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP1]], 8
496+
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 5
497+
; CHECK-NEXT: [[TMP4:%.*]] = alloca <vscale x 4 x i16>, i32 5, align 8
498+
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
499+
; CHECK-NEXT: [[TMP6:%.*]] = mul i64 [[TMP5]], 8
500+
; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], [[TMP6]]
501+
; CHECK-NEXT: [[TMP7:%.*]] = add i64 0, [[DOTIDX]]
502+
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds <vscale x 4 x i16>, ptr [[TMP4]], i64 [[Y]]
503+
; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.vscale.i64()
504+
; CHECK-NEXT: [[TMP10:%.*]] = mul i64 [[TMP9]], 8
505+
; CHECK-NEXT: [[TMP11:%.*]] = sub i64 [[TMP3]], [[TMP7]]
506+
; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP3]], [[TMP7]]
507+
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 [[TMP11]], [[TMP10]]
508+
; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP12]], [[TMP13]]
509+
; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i64 [[TMP7]], 0
510+
; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP15]], [[TMP14]]
511+
; CHECK-NEXT: br i1 [[TMP16]], label [[TRAP:%.*]], label [[TMP17:%.*]]
512+
; CHECK: 17:
513+
; CHECK-NEXT: [[TMP18:%.*]] = load <vscale x 4 x i16>, ptr [[TMP8]], align 4
514+
; CHECK-NEXT: ret void
515+
; CHECK: trap:
516+
; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]]
517+
; CHECK-NEXT: unreachable
518+
;
519+
%1 = alloca <vscale x 4 x i16>, i32 5
520+
%2 = getelementptr inbounds <vscale x 4 x i16>, ptr %1, i64 %y
521+
%3 = load <vscale x 4 x i16>, ptr %2, align 4
522+
ret void
523+
}
524+
525+
define void @scalable_alloca2(i64 %y) nounwind {
526+
; CHECK-LABEL: @scalable_alloca2(
527+
; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
528+
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP1]], 32
529+
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], 1
530+
; CHECK-NEXT: [[TMP4:%.*]] = alloca <vscale x 4 x i64>, align 32
531+
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
532+
; CHECK-NEXT: [[TMP6:%.*]] = mul i64 [[TMP5]], 32
533+
; CHECK-NEXT: [[DOTIDX:%.*]] = mul i64 [[Y:%.*]], [[TMP6]]
534+
; CHECK-NEXT: [[TMP7:%.*]] = add i64 0, [[DOTIDX]]
535+
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds <vscale x 4 x i64>, ptr [[TMP4]], i64 [[Y]]
536+
; CHECK-NEXT: [[TMP9:%.*]] = call i64 @llvm.vscale.i64()
537+
; CHECK-NEXT: [[TMP10:%.*]] = mul i64 [[TMP9]], 32
538+
; CHECK-NEXT: [[TMP11:%.*]] = sub i64 [[TMP3]], [[TMP7]]
539+
; CHECK-NEXT: [[TMP12:%.*]] = icmp ult i64 [[TMP3]], [[TMP7]]
540+
; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 [[TMP11]], [[TMP10]]
541+
; CHECK-NEXT: [[TMP14:%.*]] = or i1 [[TMP12]], [[TMP13]]
542+
; CHECK-NEXT: [[TMP15:%.*]] = icmp slt i64 [[TMP7]], 0
543+
; CHECK-NEXT: [[TMP16:%.*]] = or i1 [[TMP15]], [[TMP14]]
544+
; CHECK-NEXT: br i1 [[TMP16]], label [[TRAP:%.*]], label [[TMP17:%.*]]
545+
; CHECK: 17:
546+
; CHECK-NEXT: [[TMP18:%.*]] = load <vscale x 4 x i64>, ptr [[TMP8]], align 4
547+
; CHECK-NEXT: ret void
548+
; CHECK: trap:
549+
; CHECK-NEXT: call void @llvm.trap() #[[ATTR6]]
550+
; CHECK-NEXT: unreachable
551+
;
552+
%1 = alloca <vscale x 4 x i64>
553+
%2 = getelementptr inbounds <vscale x 4 x i64>, ptr %1, i64 %y
554+
%3 = load <vscale x 4 x i64>, ptr %2, align 4
555+
ret void
556+
}

0 commit comments

Comments
 (0)