Skip to content

Conversation

davemgreen
Copy link
Collaborator

This has recently started causing 'Invalid size request on a scalable vector.'

@llvmbot
Copy link
Member

llvmbot commented Aug 26, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: David Green (davemgreen)

Changes

This has recently started causing 'Invalid size request on a scalable vector.'


Full diff: https://github.com/llvm/llvm-project/pull/155357.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp (+2-1)
  • (added) llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll (+27)
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 50258af5e26c3..70dcf5a2b4b05 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1219,7 +1219,8 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
 
     std::optional<TypeSize> Size = AI->getAllocationSize(AI->getDataLayout());
     // Check that size is known and can be stored in IntptrTy.
-    if (!Size || !ConstantInt::isValueValidForType(IntptrTy, *Size))
+    if (!Size || Size->isScalable() ||
+        !ConstantInt::isValueValidForType(IntptrTy, *Size))
       return;
 
     bool DoPoison = (ID == Intrinsic::lifetime_end);
diff --git a/llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll b/llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll
new file mode 100644
index 0000000000000..6a841f2d399c0
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes='asan<use-after-scope>' -S | FileCheck %s
+
+define void @test() #1 {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CTX_PG:%.*]] = alloca <vscale x 16 x i1>, align 2
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[CTX_PG]])
+; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr inttoptr (i64 17592186044416 to ptr), align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB3:.*]]
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    call void @__asan_report_store8(i64 0) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BB3]]:
+; CHECK-NEXT:    store ptr [[CTX_PG]], ptr null, align 8
+; CHECK-NEXT:    ret void
+;
+entry:
+  %ctx_pg = alloca <vscale x 16 x i1>, align 2
+  call void @llvm.lifetime.start.p0(ptr %ctx_pg)
+  store ptr %ctx_pg, ptr null, align 8
+  ret void
+}
+
+attributes #1 = { sanitize_address }

@llvmbot
Copy link
Member

llvmbot commented Aug 26, 2025

@llvm/pr-subscribers-llvm-transforms

Author: David Green (davemgreen)

Changes

This has recently started causing 'Invalid size request on a scalable vector.'


Full diff: https://github.com/llvm/llvm-project/pull/155357.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp (+2-1)
  • (added) llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll (+27)
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 50258af5e26c3..70dcf5a2b4b05 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1219,7 +1219,8 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {
 
     std::optional<TypeSize> Size = AI->getAllocationSize(AI->getDataLayout());
     // Check that size is known and can be stored in IntptrTy.
-    if (!Size || !ConstantInt::isValueValidForType(IntptrTy, *Size))
+    if (!Size || Size->isScalable() ||
+        !ConstantInt::isValueValidForType(IntptrTy, *Size))
       return;
 
     bool DoPoison = (ID == Intrinsic::lifetime_end);
diff --git a/llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll b/llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll
new file mode 100644
index 0000000000000..6a841f2d399c0
--- /dev/null
+++ b/llvm/test/Instrumentation/AddressSanitizer/asan-scalable-vector.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes='asan<use-after-scope>' -S | FileCheck %s
+
+define void @test() #1 {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CTX_PG:%.*]] = alloca <vscale x 16 x i1>, align 2
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[CTX_PG]])
+; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr inttoptr (i64 17592186044416 to ptr), align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i8 [[TMP0]], 0
+; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB3:.*]]
+; CHECK:       [[BB2]]:
+; CHECK-NEXT:    call void @__asan_report_store8(i64 0) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT:    unreachable
+; CHECK:       [[BB3]]:
+; CHECK-NEXT:    store ptr [[CTX_PG]], ptr null, align 8
+; CHECK-NEXT:    ret void
+;
+entry:
+  %ctx_pg = alloca <vscale x 16 x i1>, align 2
+  call void @llvm.lifetime.start.p0(ptr %ctx_pg)
+  store ptr %ctx_pg, ptr null, align 8
+  ret void
+}
+
+attributes #1 = { sanitize_address }

Copy link
Contributor

@thurstond thurstond left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch!

Nit: the title is ambiguous. "Protect against scalable vectors" could be misinterpreted to mean that scalar vectors will have use-after-scope protection; this patch is actually deliberately not attempting instrumentation for scalable vectors.

@davemgreen davemgreen changed the title [ASan] Protect against scalable vectors in FunctionStackPoisoner. [ASan] Prevent assert from scalable vectors in FunctionStackPoisoner. Aug 26, 2025
@davemgreen
Copy link
Collaborator Author

davemgreen commented Aug 26, 2025

Nit: the title is ambiguous. "Protect against scalable vectors" could be misinterpreted to mean that scalar vectors will have use-after-scope protection; this patch is actually deliberately not attempting instrumentation for scalable vectors.

Good point! I hadn't thought of the two different meanings. I've updated the title. Thanks for the quick review.

@thurstond
Copy link
Contributor

Good point! I hadn't thought of the two different meanings. I've updated the title. Thanks for the quick review.

Thank you!

@@ -1219,7 +1219,8 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> {

std::optional<TypeSize> Size = AI->getAllocationSize(AI->getDataLayout());
// Check that size is known and can be stored in IntptrTy.
if (!Size || !ConstantInt::isValueValidForType(IntptrTy, *Size))
if (!Size || Size->isScalable() ||
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this is better handled in isInterestingAlloca instead, which has its documentation:
Check if we want (and can) handle this alloca.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I believe that scalable vectors are interesting allocas, we just don't handle them here at the moment. There are some tests in llvm/test/Instrumentation/AddressSanitizer/vector-load-store.ll that fail if we don't handle any scalable vectors, as isInterestingAlloca is used in several places.

I could add a TODO maybe?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the other places where isInterestingAlloca is called, does the address sanitizer support those cases with scalable vectors? If not, it's probably safer to disable this entirely and add a TODO to make the address sanitizer to support scalable vectors in general.

Copy link
Contributor

@thurstond thurstond Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regression is specifically for lifetime intrinsics (e.g., as seen in the new test case) - the crash started happening after "[IR] Remove size argument from lifetime intrinsics" (#150248), because now ASan doesn't know the size of the alloca for:

  %ctx_pg = alloca <vscale x 16 x i1>, align 2
  call void @llvm.lifetime.start.p0(ptr %ctx_pg)

(In the past, it could have used the size argument instead of trying to compute it.)

i.e., I think this localized fix is fine, because it is the only place where lifetime intrinsics are handled in ASan.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern is that other places in the AddressSanitizer where isInterestingAlloca returns true also don't support scalable vectors, not just the case that was described in that new test case, i.e. for a case we haven't hit yet. If you can confirm that all other cases where the AddressSanitizer encounters a scalable alloca can be handled correctly, I'm happy with the fix.

This has recently started causing 'Invalid size request on a scalable vector.'
@davemgreen
Copy link
Collaborator Author

This came up again in #155505. That tries to go the isInterestingAlloca route, but is failing some tests because of it. I will push this to get it fixed if htat is OK and if we need to adjust it we always can.

@davemgreen davemgreen merged commit aa5bec0 into llvm:main Aug 27, 2025
7 of 9 checks passed
@davemgreen davemgreen deleted the gh-asan-scalable branch August 27, 2025 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants