[PATCH] D89511: Add alloca size threshold for StackTagging initializer merging.

Evgenii Stepanov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 15 16:26:26 PDT 2020


eugenis created this revision.
eugenis added reviewers: vitalybuka, pcc.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
eugenis requested review of this revision.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89511

Files:
  llvm/lib/Target/AArch64/AArch64StackTagging.cpp
  llvm/test/CodeGen/AArch64/stack-tagging-initializer-merge.ll


Index: llvm/test/CodeGen/AArch64/stack-tagging-initializer-merge.ll
===================================================================
--- llvm/test/CodeGen/AArch64/stack-tagging-initializer-merge.ll
+++ llvm/test/CodeGen/AArch64/stack-tagging-initializer-merge.ll
@@ -306,3 +306,17 @@
 ; CHECK:  call void @llvm.aarch64.stgp(i8* {{.*}}, i64 46360584388608, i64 0)
 ; CHECK:  call void @llvm.aarch64.stgp(i8* {{.*}}, i64 0, i64 3038287259199220266)
 ; CHECK:  ret void
+
+define void @LargeAlloca() sanitize_memtag {
+entry:
+  %x = alloca i32, i32 256, align 16
+  %0 = bitcast i32* %x to i8*
+  call void @llvm.memset.p0i8.i64(i8* nonnull align 16 %0, i8 42, i64 256, i1 false)
+  call void @use(i8* nonnull %0)
+  ret void
+}
+
+; CHECK-LABEL: define void @LargeAlloca(
+; CHECK:  call void @llvm.aarch64.settag(i8* {{.*}}, i64 1024)
+; CHECK:  call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 42, i64 256,
+; CHECK:  ret void
Index: llvm/lib/Target/AArch64/AArch64StackTagging.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64StackTagging.cpp
+++ llvm/lib/Target/AArch64/AArch64StackTagging.cpp
@@ -73,6 +73,10 @@
 static cl::opt<unsigned> ClScanLimit("stack-tagging-merge-init-scan-limit",
                                      cl::init(40), cl::Hidden);
 
+static cl::opt<unsigned>
+    ClMergeInitSizeLimit("stack-tagging-merge-init-size-limit", cl::init(272),
+                         cl::Hidden);
+
 static const Align kTagGranuleSize = Align(16);
 
 namespace {
@@ -434,7 +438,8 @@
   bool LittleEndian =
       Triple(AI->getModule()->getTargetTriple()).isLittleEndian();
   // Current implementation of initializer merging assumes little endianness.
-  if (MergeInit && !F->hasOptNone() && LittleEndian) {
+  if (MergeInit && !F->hasOptNone() && LittleEndian &&
+      Size < ClMergeInitSizeLimit) {
     LLVM_DEBUG(dbgs() << "collecting initializers for " << *AI
                       << ", size = " << Size << "\n");
     InsertBefore = collectInitializers(InsertBefore, Ptr, Size, IB);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D89511.298510.patch
Type: text/x-patch
Size: 2060 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201015/78c79703/attachment.bin>


More information about the llvm-commits mailing list