Skip to content

Commit c3b80ad

Browse files
committed
Fix StackSafetyAnalysis crash with scalable vector types.
Summary: Treat scalable allocas as if they have storage size of 0, and scalable-typed memory accesses as if their range is unlimited. This is not a proper support of scalable vector types in the analysis - we can do better, but not today. Reviewers: vitalybuka Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D73394
1 parent 8e3f59b commit c3b80ad

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

llvm/lib/Analysis/StackSafetyAnalysis.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@ raw_ostream &operator<<(raw_ostream &OS, const ParamInfo &P) {
131131
/// size can not be statically determined.
132132
uint64_t getStaticAllocaAllocationSize(const AllocaInst *AI) {
133133
const DataLayout &DL = AI->getModule()->getDataLayout();
134-
uint64_t Size = DL.getTypeAllocSize(AI->getAllocatedType());
134+
TypeSize TS = DL.getTypeAllocSize(AI->getAllocatedType());
135+
if (TS.isScalable())
136+
return 0;
137+
uint64_t Size = TS.getFixedSize();
135138
if (AI->isArrayAllocation()) {
136139
auto C = dyn_cast<ConstantInt>(AI->getArraySize());
137140
if (!C)
@@ -211,7 +214,9 @@ class StackSafetyLocalAnalysis {
211214

212215
ConstantRange offsetFromAlloca(Value *Addr, const Value *AllocaPtr);
213216
ConstantRange getAccessRange(Value *Addr, const Value *AllocaPtr,
214-
uint64_t AccessSize);
217+
ConstantRange SizeRange);
218+
ConstantRange getAccessRange(Value *Addr, const Value *AllocaPtr,
219+
TypeSize Size);
215220
ConstantRange getMemIntrinsicAccessRange(const MemIntrinsic *MI, const Use &U,
216221
const Value *AllocaPtr);
217222

@@ -244,9 +249,9 @@ StackSafetyLocalAnalysis::offsetFromAlloca(Value *Addr,
244249
return Offset;
245250
}
246251

247-
ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr,
248-
const Value *AllocaPtr,
249-
uint64_t AccessSize) {
252+
ConstantRange
253+
StackSafetyLocalAnalysis::getAccessRange(Value *Addr, const Value *AllocaPtr,
254+
ConstantRange SizeRange) {
250255
if (!SE.isSCEVable(Addr->getType()))
251256
return UnknownRange;
252257

@@ -255,12 +260,20 @@ ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr,
255260

256261
ConstantRange AccessStartRange =
257262
SE.getUnsignedRange(Expr).zextOrTrunc(PointerSize);
258-
ConstantRange SizeRange = getRange(0, AccessSize);
259263
ConstantRange AccessRange = AccessStartRange.add(SizeRange);
260264
assert(!AccessRange.isEmptySet());
261265
return AccessRange;
262266
}
263267

268+
ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr,
269+
const Value *AllocaPtr,
270+
TypeSize Size) {
271+
ConstantRange SizeRange = Size.isScalable()
272+
? ConstantRange::getFull(PointerSize)
273+
: getRange(0, Size.getFixedSize());
274+
return getAccessRange(Addr, AllocaPtr, SizeRange);
275+
}
276+
264277
ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
265278
const MemIntrinsic *MI, const Use &U, const Value *AllocaPtr) {
266279
if (auto MTI = dyn_cast<MemTransferInst>(MI)) {
@@ -274,7 +287,8 @@ ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
274287
// Non-constant size => unsafe. FIXME: try SCEV getRange.
275288
if (!Len)
276289
return UnknownRange;
277-
ConstantRange AccessRange = getAccessRange(U, AllocaPtr, Len->getZExtValue());
290+
ConstantRange AccessRange =
291+
getAccessRange(U, AllocaPtr, getRange(0, Len->getZExtValue()));
278292
return AccessRange;
279293
}
280294

llvm/test/Analysis/StackSafetyAnalysis/local.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,22 @@ if.then:
349349
if.end:
350350
ret void
351351
}
352+
353+
; FIXME: scalable allocas are considered to be of size zero, and scalable accesses to be full-range.
354+
; This effectively disables safety analysis for scalable allocations.
355+
define void @Scalable(<vscale x 4 x i32>* %p, <vscale x 4 x i32>* %unused, <vscale x 4 x i32> %v) {
356+
; CHECK-LABEL: @Scalable dso_preemptable{{$}}
357+
; CHECK-NEXT: args uses:
358+
; CHECK-NEXT: p[]: full-set
359+
; CHECK-NEXT: unused[]: empty-set
360+
; CHECK-NEXT: v[]: full-set
361+
; CHECK-NEXT: allocas uses:
362+
; CHECK-NEXT: x[0]: [0,1){{$}}
363+
; CHECK-NOT: ]:
364+
entry:
365+
%x = alloca <vscale x 4 x i32>, align 4
366+
%x1 = bitcast <vscale x 4 x i32>* %x to i8*
367+
store i8 0, i8* %x1, align 1
368+
store <vscale x 4 x i32> %v, <vscale x 4 x i32>* %p, align 4
369+
ret void
370+
}

0 commit comments

Comments
 (0)