[llvm] [TySan] Fix size type mismatch in instrumentMemInst for 32-bit targets (PR #191601)
Brian Cain via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 10 21:54:36 PDT 2026
https://github.com/androm3da created https://github.com/llvm/llvm-project/pull/191601
The outlined instrumentation path in instrumentMemInst passes Size directly to the __tysan_instrument_mem_inst runtime call, which declares its size parameter as uint64_t (i64). On 32-bit targets, Size is IntptrTy (i32) for allocas and byval arguments, causing an assertion:
Calling a function with a bad signature!
Add CreateZExtOrTrunc to widen Size to U64Ty before the call. This is a no-op on 64-bit targets where IntptrTy is already i64.
>From 9b2804ec8d6a151871c026ed90ab06cfd165afc5 Mon Sep 17 00:00:00 2001
From: Brian Cain <brian.cain at oss.qualcomm.com>
Date: Fri, 10 Apr 2026 21:49:48 -0700
Subject: [PATCH] [TySan] Fix size type mismatch in instrumentMemInst for
32-bit targets
The outlined instrumentation path in instrumentMemInst passes Size
directly to the __tysan_instrument_mem_inst runtime call, which declares
its size parameter as uint64_t (i64). On 32-bit targets, Size is
IntptrTy (i32) for allocas and byval arguments, causing an assertion:
Calling a function with a bad signature!
Add CreateZExtOrTrunc to widen Size to U64Ty before the call. This is
a no-op on 64-bit targets where IntptrTy is already i64.
---
.../Instrumentation/TypeSanitizer.cpp | 5 ++-
.../TypeSanitizer/alloca-32bit.ll | 39 +++++++++++++++++++
2 files changed, 43 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Instrumentation/TypeSanitizer/alloca-32bit.ll
diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 98a8068cac946..cea6e9e316c1d 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -900,9 +900,12 @@ bool TypeSanitizer::instrumentMemInst(Value *V, Instruction *ShadowBase,
if (!Src)
Src = ConstantPointerNull::get(IRB.getPtrTy());
+ // The runtime function expects a uint64_t size parameter. On 32-bit
+ // targets, Size may be IntptrTy (i32), so extend it to match.
+ Value *Size64 = IRB.CreateZExtOrTrunc(Size, U64Ty);
IRB.CreateCall(
TysanIntrumentMemInst,
- {Dest, Src, Size, NeedsMemMove ? IRB.getTrue() : IRB.getFalse()});
+ {Dest, Src, Size64, NeedsMemMove ? IRB.getTrue() : IRB.getFalse()});
return true;
} else {
if (!ShadowBase)
diff --git a/llvm/test/Instrumentation/TypeSanitizer/alloca-32bit.ll b/llvm/test/Instrumentation/TypeSanitizer/alloca-32bit.ll
new file mode 100644
index 0000000000000..2cde3a5b8d677
--- /dev/null
+++ b/llvm/test/Instrumentation/TypeSanitizer/alloca-32bit.ll
@@ -0,0 +1,39 @@
+; Test TySan outlined instrumentation on a 32-bit target.
+; The size argument to __tysan_instrument_mem_inst must be zero-extended
+; from i32 (IntptrTy) to i64 (the runtime function's uint64_t parameter).
+;
+; RUN: opt -passes='tysan' -S %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a:0-n16:32"
+
+declare void @use(ptr)
+
+; Fixed-size alloca: size is a constant i32 that must be zext'd to i64.
+define void @alloca_fixed() sanitize_type {
+; CHECK-LABEL: @alloca_fixed(
+; CHECK: [[X:%.*]] = alloca [10 x i8], align 1
+; CHECK-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 10, i1 false)
+; CHECK-NEXT: call void @use(ptr [[X]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %x = alloca [10 x i8], align 1
+ call void @use(ptr %x)
+ ret void
+}
+
+; Dynamic alloca: size is computed as i32 and must be zext'd to i64.
+define void @alloca_dynamic(i32 %n) sanitize_type {
+; CHECK-LABEL: @alloca_dynamic(
+; CHECK: [[X:%.*]] = alloca i32, i32 [[N:%.*]], align 1
+; CHECK-NEXT: [[SZ:%.*]] = mul i32 [[N]], 4
+; CHECK-NEXT: [[SZ64:%.*]] = zext i32 [[SZ]] to i64
+; CHECK-NEXT: call void @__tysan_instrument_mem_inst(ptr [[X]], ptr null, i64 [[SZ64]], i1 false)
+; CHECK-NEXT: call void @use(ptr [[X]])
+; CHECK-NEXT: ret void
+;
+entry:
+ %x = alloca i32, i32 %n, align 1
+ call void @use(ptr %x)
+ ret void
+}
More information about the llvm-commits
mailing list