Skip to content

Commit 188a7d6

Browse files
committed
Add alloca size threshold for StackTagging initializer merging.
Summary: Initializer merging generates pretty inefficient code for large allocas that also happens to trigger an exponential algorithm somewhere in Machine Instruction Scheduler. See https://bugs.llvm.org/show_bug.cgi?id=47867. This change adds an upper limit for the alloca size. The default limit is selected such that worst case size of memtag-generated code is similar to non-memtag (but because of the ISA quirks, this case is realized at the different value of alloca size, ex. memset inlining triggers at sizes below 512, but stack tagging instructions are 2x shorter, so limit is approx. 256). We could try harder to emit more compact code with initializer merging, but that would only affect large, sparsely initialized allocas, and those are doing fine already. Reviewers: vitalybuka, pcc Subscribers: llvm-commits
1 parent c76968d commit 188a7d6

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

llvm/lib/Target/AArch64/AArch64StackTagging.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ static cl::opt<bool>
7373
static cl::opt<unsigned> ClScanLimit("stack-tagging-merge-init-scan-limit",
7474
cl::init(40), cl::Hidden);
7575

76+
static cl::opt<unsigned>
77+
ClMergeInitSizeLimit("stack-tagging-merge-init-size-limit", cl::init(272),
78+
cl::Hidden);
79+
7680
static const Align kTagGranuleSize = Align(16);
7781

7882
namespace {
@@ -434,7 +438,8 @@ void AArch64StackTagging::tagAlloca(AllocaInst *AI, Instruction *InsertBefore,
434438
bool LittleEndian =
435439
Triple(AI->getModule()->getTargetTriple()).isLittleEndian();
436440
// Current implementation of initializer merging assumes little endianness.
437-
if (MergeInit && !F->hasOptNone() && LittleEndian) {
441+
if (MergeInit && !F->hasOptNone() && LittleEndian &&
442+
Size < ClMergeInitSizeLimit) {
438443
LLVM_DEBUG(dbgs() << "collecting initializers for " << *AI
439444
<< ", size = " << Size << "\n");
440445
InsertBefore = collectInitializers(InsertBefore, Ptr, Size, IB);

llvm/test/CodeGen/AArch64/stack-tagging-initializer-merge.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,17 @@ entry:
306306
; CHECK: call void @llvm.aarch64.stgp(i8* {{.*}}, i64 46360584388608, i64 0)
307307
; CHECK: call void @llvm.aarch64.stgp(i8* {{.*}}, i64 0, i64 3038287259199220266)
308308
; CHECK: ret void
309+
310+
define void @LargeAlloca() sanitize_memtag {
311+
entry:
312+
%x = alloca i32, i32 256, align 16
313+
%0 = bitcast i32* %x to i8*
314+
call void @llvm.memset.p0i8.i64(i8* nonnull align 16 %0, i8 42, i64 256, i1 false)
315+
call void @use(i8* nonnull %0)
316+
ret void
317+
}
318+
319+
; CHECK-LABEL: define void @LargeAlloca(
320+
; CHECK: call void @llvm.aarch64.settag(i8* {{.*}}, i64 1024)
321+
; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 42, i64 256,
322+
; CHECK: ret void

0 commit comments

Comments
 (0)