[llvm] [TypeSanitizer] Properly add ext attributes on arguments where needed. (PR #224366)

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 01:14:31 PDT 2026


https://github.com/JonPsson1 updated https://github.com/llvm/llvm-project/pull/224366

>From b2f33d4d13e75e4d59fe7bf4bc3c9bc79e9c8c62 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <Jonas.Paulsson2 at ibm.com>
Date: Thu, 17 Sep 2026 18:57:36 +0200
Subject: [PATCH 1/8] [TypeSanitizer] Properly add ext attributes on arguments
 where needed.

---
 .../Instrumentation/TypeSanitizer.cpp         | 26 ++++++++++++-------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index cea6e9e316c1d6..951860a614f3ef 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -152,19 +152,24 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
   AttributeList Attr;
   Attr = Attr.addFnAttribute(M.getContext(), Attribute::NoUnwind);
   // Initialize the callbacks.
-  TysanCheck =
-      M.getOrInsertFunction(kTysanCheckName, Attr, IRB.getVoidTy(),
-                            IRB.getPtrTy(), // Pointer to data to be read.
-                            OrdTy,          // Size of the data in bytes.
-                            IRB.getPtrTy(), // Pointer to type descriptor.
-                            OrdTy           // Flags.
-      );
+  TysanCheck = M.getOrInsertFunction(
+      kTysanCheckName,
+      Attr.addParamAttribute(M.getContext(), 1, Attribute::ZExt)
+          .addParamAttribute(M.getContext(), 3, Attribute::NoExt),
+      IRB.getVoidTy(),
+      IRB.getPtrTy(), // Pointer to data to be read.
+      OrdTy,          // Size of the data in bytes.
+      IRB.getPtrTy(), // Pointer to type descriptor.
+      OrdTy           // Flags.
+  );
 
   TysanCtorFunction =
       M.getOrInsertFunction(kTysanModuleCtorName, Attr, IRB.getVoidTy());
 
   TysanIntrumentMemInst = M.getOrInsertFunction(
-      "__tysan_instrument_mem_inst", Attr, IRB.getVoidTy(),
+      "__tysan_instrument_mem_inst",
+      Attr.addParamAttribute(M.getContext(), 3, Attribute::ZExt),
+      IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer of data to be written to
       IRB.getPtrTy(), // Pointer of data to write
       U64Ty,          // Size of the data in bytes
@@ -172,7 +177,10 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
   );
 
   TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
-      "__tysan_instrument_with_shadow_update", Attr, IRB.getVoidTy(),
+      "__tysan_instrument_with_shadow_update",
+      Attr.addParamAttribute(M.getContext(), 2, Attribute::ZExt)
+          .addParamAttribute(M.getContext(), 4, Attribute::NoExt),
+      IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer to data to be read
       IRB.getPtrTy(), // Pointer to type descriptor
       BoolType,       // Do we need to type check this

>From 53f1f7c3c7c45a957fb4d217e0321939f8cb90df Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Fri, 18 Sep 2026 12:25:02 +0200
Subject: [PATCH 2/8] Use getExtAttrForI32Param(), add test.

---
 llvm/include/llvm/IR/Attributes.h              |  9 +++++++++
 .../Instrumentation/TypeSanitizer.cpp          | 18 +++++++++++-------
 .../TypeSanitizer/instrumented-args-exts.ll    | 11 +++++++++++
 3 files changed, 31 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll

diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index d9ab56cdcc1f65..870fcd4bc594a9 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -721,6 +721,15 @@ class AttributeList {
     return addAttributesAtIndex(C, ArgNo + FirstArgIndex, B);
   }
 
+  /// Add an argument attribute to the list. Returns a new list because
+  /// attribute lists are immutable.
+  [[nodiscard]] AttributeList
+  addParamExtAttribute(LLVMContext &C, unsigned ArgNo,
+                       Attribute::AttrKind Kind) const {
+    if (Kind != Attribute::AttrKind::None)
+      return addParamAttribute(C, ArgNo, Kind);
+  }
+
   /// Remove the specified attribute at the specified index from this
   /// attribute list. Returns a new list because attribute lists are immutable.
   [[nodiscard]] LLVM_ABI AttributeList removeAttributeAtIndex(
diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 951860a614f3ef..2cb666b0ad0961 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -144,18 +144,22 @@ TypeSanitizer::TypeSanitizer(Module &M)
 }
 
 void TypeSanitizer::initializeCallbacks(Module &M) {
-  IRBuilder<> IRB(M.getContext());
+  LLVMContext &C = M.getContext();
+  IRBuilder<> IRB(C);
   OrdTy = IRB.getInt32Ty();
   U64Ty = IRB.getInt64Ty();
   Type *BoolType = IRB.getInt1Ty();
 
   AttributeList Attr;
-  Attr = Attr.addFnAttribute(M.getContext(), Attribute::NoUnwind);
+  Attr = Attr.addFnAttribute(C, Attribute::NoUnwind);
+  Attribute::AttrKind ZExtAttr =
+    TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/false);
+
   // Initialize the callbacks.
   TysanCheck = M.getOrInsertFunction(
       kTysanCheckName,
-      Attr.addParamAttribute(M.getContext(), 1, Attribute::ZExt)
-          .addParamAttribute(M.getContext(), 3, Attribute::NoExt),
+      Attr.addParamExtAttribute(C, 1, ZExtAttr)
+          .addParamExtAttribute(C, 3, Attribute::NoExt),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer to data to be read.
       OrdTy,          // Size of the data in bytes.
@@ -168,7 +172,7 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanIntrumentMemInst = M.getOrInsertFunction(
       "__tysan_instrument_mem_inst",
-      Attr.addParamAttribute(M.getContext(), 3, Attribute::ZExt),
+      Attr.addParamExtAttribute(C, 3, ZExtAttr),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer of data to be written to
       IRB.getPtrTy(), // Pointer of data to write
@@ -178,8 +182,8 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
       "__tysan_instrument_with_shadow_update",
-      Attr.addParamAttribute(M.getContext(), 2, Attribute::ZExt)
-          .addParamAttribute(M.getContext(), 4, Attribute::NoExt),
+      Attr.addParamExtAttribute(C, 2, ZExtAttr)
+          .addParamExtAttribute(C, 4, Attribute::NoExt),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer to data to be read
       IRB.getPtrTy(), // Pointer to type descriptor
diff --git a/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll b/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll
new file mode 100644
index 00000000000000..ba3dc271d1ec01
--- /dev/null
+++ b/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll
@@ -0,0 +1,11 @@
+; Test extensions of arguments to instrumented functions.
+;
+; RUN: opt -passes='tysan' -mtriple=s390x-unknown-linux -S %s | FileCheck %s
+
+define void @fun() {
+  ret void
+}
+
+; CHECK: declare void @__tysan_check(ptr, i32 zeroext, ptr, i32 noext)
+; CHECK: declare void @__tysan_instrument_mem_inst(ptr, ptr, i64, i1 zeroext)
+; CHECK: declare void @__tysan_instrument_with_shadow_update(ptr, ptr, i1 zeroext, i64, i32 noext)

>From ce439f574c19bbb65b42b16b1c6c7fcba7c32cbf Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Fri, 18 Sep 2026 12:56:49 +0200
Subject: [PATCH 3/8] Fixes.

---
 llvm/include/llvm/IR/Attributes.h                  |  5 +++--
 .../Transforms/Instrumentation/TypeSanitizer.cpp   | 14 ++++++++------
 .../TypeSanitizer/instrumented-args-exts.ll        |  4 ++--
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 870fcd4bc594a9..7ff7def7525fa2 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -724,10 +724,11 @@ class AttributeList {
   /// Add an argument attribute to the list. Returns a new list because
   /// attribute lists are immutable.
   [[nodiscard]] AttributeList
-  addParamExtAttribute(LLVMContext &C, unsigned ArgNo,
-                       Attribute::AttrKind Kind) const {
+  maybeAddParamAttribute(LLVMContext &C, unsigned ArgNo,
+                         Attribute::AttrKind Kind) const {
     if (Kind != Attribute::AttrKind::None)
       return addParamAttribute(C, ArgNo, Kind);
+    return *this;
   }
 
   /// Remove the specified attribute at the specified index from this
diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 2cb666b0ad0961..5ce14d7410c36d 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -152,14 +152,16 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   AttributeList Attr;
   Attr = Attr.addFnAttribute(C, Attribute::NoUnwind);
+  Attribute::AttrKind SExtAttr =
+    TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/true);
   Attribute::AttrKind ZExtAttr =
     TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/false);
 
-  // Initialize the callbacks.
+  // Initialize the callbacks.  TODO: use TLI/emitLibFunc() for these functions.
   TysanCheck = M.getOrInsertFunction(
       kTysanCheckName,
-      Attr.addParamExtAttribute(C, 1, ZExtAttr)
-          .addParamExtAttribute(C, 3, Attribute::NoExt),
+      Attr.maybeAddParamAttribute(C, 1, SExtAttr)
+          .maybeAddParamAttribute(C, 3, SExtAttr),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer to data to be read.
       OrdTy,          // Size of the data in bytes.
@@ -172,7 +174,7 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanIntrumentMemInst = M.getOrInsertFunction(
       "__tysan_instrument_mem_inst",
-      Attr.addParamExtAttribute(C, 3, ZExtAttr),
+      Attr.maybeAddParamAttribute(C, 3, ZExtAttr),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer of data to be written to
       IRB.getPtrTy(), // Pointer of data to write
@@ -182,8 +184,8 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
       "__tysan_instrument_with_shadow_update",
-      Attr.addParamExtAttribute(C, 2, ZExtAttr)
-          .addParamExtAttribute(C, 4, Attribute::NoExt),
+      Attr.maybeAddParamAttribute(C, 2, ZExtAttr)
+          .maybeAddParamAttribute(C, 4, SExtAttr),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer to data to be read
       IRB.getPtrTy(), // Pointer to type descriptor
diff --git a/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll b/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll
index ba3dc271d1ec01..94e799889d90fb 100644
--- a/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll
+++ b/llvm/test/Instrumentation/TypeSanitizer/instrumented-args-exts.ll
@@ -6,6 +6,6 @@ define void @fun() {
   ret void
 }
 
-; CHECK: declare void @__tysan_check(ptr, i32 zeroext, ptr, i32 noext)
+; CHECK: declare void @__tysan_check(ptr, i32 signext, ptr, i32 signext)
 ; CHECK: declare void @__tysan_instrument_mem_inst(ptr, ptr, i64, i1 zeroext)
-; CHECK: declare void @__tysan_instrument_with_shadow_update(ptr, ptr, i1 zeroext, i64, i32 noext)
+; CHECK: declare void @__tysan_instrument_with_shadow_update(ptr, ptr, i1 zeroext, i64, i32 signext)

>From 3a97cad1462650a0cc46f9c956821c3b9d6a5dcd Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <Jonas.Paulsson2 at ibm.com>
Date: Fri, 18 Sep 2026 13:16:48 +0200
Subject: [PATCH 4/8] clang-format

---
 .../Instrumentation/TypeSanitizer.cpp         | 49 +++++++++----------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 5ce14d7410c36d..355edc9193f432 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -153,46 +153,45 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
   AttributeList Attr;
   Attr = Attr.addFnAttribute(C, Attribute::NoUnwind);
   Attribute::AttrKind SExtAttr =
-    TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/true);
+      TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/true);
   Attribute::AttrKind ZExtAttr =
-    TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/false);
+      TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/false);
 
   // Initialize the callbacks.  TODO: use TLI/emitLibFunc() for these functions.
-  TysanCheck = M.getOrInsertFunction(
-      kTysanCheckName,
-      Attr.maybeAddParamAttribute(C, 1, SExtAttr)
-          .maybeAddParamAttribute(C, 3, SExtAttr),
-      IRB.getVoidTy(),
-      IRB.getPtrTy(), // Pointer to data to be read.
-      OrdTy,          // Size of the data in bytes.
-      IRB.getPtrTy(), // Pointer to type descriptor.
-      OrdTy           // Flags.
-  );
+  TysanCheck =
+      M.getOrInsertFunction(kTysanCheckName,
+                            Attr.maybeAddParamAttribute(C, 1, SExtAttr)
+                                .maybeAddParamAttribute(C, 3, SExtAttr),
+                            IRB.getVoidTy(),
+                            IRB.getPtrTy(), // Pointer to data to be read.
+                            OrdTy,          // Size of the data in bytes.
+                            IRB.getPtrTy(), // Pointer to type descriptor.
+                            OrdTy           // Flags.
+      );
 
   TysanCtorFunction =
       M.getOrInsertFunction(kTysanModuleCtorName, Attr, IRB.getVoidTy());
 
   TysanIntrumentMemInst = M.getOrInsertFunction(
       "__tysan_instrument_mem_inst",
-      Attr.maybeAddParamAttribute(C, 3, ZExtAttr),
-      IRB.getVoidTy(),
+      Attr.maybeAddParamAttribute(C, 3, ZExtAttr), IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer of data to be written to
       IRB.getPtrTy(), // Pointer of data to write
       U64Ty,          // Size of the data in bytes
       BoolType        // Do we need to call memmove
   );
 
-  TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
-      "__tysan_instrument_with_shadow_update",
-      Attr.maybeAddParamAttribute(C, 2, ZExtAttr)
-          .maybeAddParamAttribute(C, 4, SExtAttr),
-      IRB.getVoidTy(),
-      IRB.getPtrTy(), // Pointer to data to be read
-      IRB.getPtrTy(), // Pointer to type descriptor
-      BoolType,       // Do we need to type check this
-      U64Ty,          // Size of data we access in bytes
-      OrdTy           // Flags
-  );
+  TysanInstrumentWithShadowUpdate =
+      M.getOrInsertFunction("__tysan_instrument_with_shadow_update",
+                            Attr.maybeAddParamAttribute(C, 2, ZExtAttr)
+                                .maybeAddParamAttribute(C, 4, SExtAttr),
+                            IRB.getVoidTy(),
+                            IRB.getPtrTy(), // Pointer to data to be read
+                            IRB.getPtrTy(), // Pointer to type descriptor
+                            BoolType,       // Do we need to type check this
+                            U64Ty,          // Size of data we access in bytes
+                            OrdTy           // Flags
+      );
 
   TysanSetShadowType = M.getOrInsertFunction(
       "__tysan_set_shadow_type", Attr, IRB.getVoidTy(),

>From 4a08ac18797f42042d87d773b614785dd9b09ce0 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Sun, 20 Sep 2026 10:33:15 +0200
Subject: [PATCH 5/8] Hardcode zeroext for bool.

---
 .../Instrumentation/TypeSanitizer.cpp         | 26 +++++++++----------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 355edc9193f432..7a95daeb8e271d 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -154,8 +154,6 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
   Attr = Attr.addFnAttribute(C, Attribute::NoUnwind);
   Attribute::AttrKind SExtAttr =
       TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/true);
-  Attribute::AttrKind ZExtAttr =
-      TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/false);
 
   // Initialize the callbacks.  TODO: use TLI/emitLibFunc() for these functions.
   TysanCheck =
@@ -174,24 +172,24 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanIntrumentMemInst = M.getOrInsertFunction(
       "__tysan_instrument_mem_inst",
-      Attr.maybeAddParamAttribute(C, 3, ZExtAttr), IRB.getVoidTy(),
+      Attr.addParamAttribute(C, 3, Attribute::AttrKind::ZExt), IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer of data to be written to
       IRB.getPtrTy(), // Pointer of data to write
       U64Ty,          // Size of the data in bytes
       BoolType        // Do we need to call memmove
   );
 
-  TysanInstrumentWithShadowUpdate =
-      M.getOrInsertFunction("__tysan_instrument_with_shadow_update",
-                            Attr.maybeAddParamAttribute(C, 2, ZExtAttr)
-                                .maybeAddParamAttribute(C, 4, SExtAttr),
-                            IRB.getVoidTy(),
-                            IRB.getPtrTy(), // Pointer to data to be read
-                            IRB.getPtrTy(), // Pointer to type descriptor
-                            BoolType,       // Do we need to type check this
-                            U64Ty,          // Size of data we access in bytes
-                            OrdTy           // Flags
-      );
+  TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
+      "__tysan_instrument_with_shadow_update",
+      Attr.addParamAttribute(C, 2, Attribute::AttrKind::ZExt)
+          .maybeAddParamAttribute(C, 4, SExtAttr),
+      IRB.getVoidTy(),
+      IRB.getPtrTy(), // Pointer to data to be read
+      IRB.getPtrTy(), // Pointer to type descriptor
+      BoolType,       // Do we need to type check this
+      U64Ty,          // Size of data we access in bytes
+      OrdTy           // Flags
+  );
 
   TysanSetShadowType = M.getOrInsertFunction(
       "__tysan_set_shadow_type", Attr, IRB.getVoidTy(),

>From f094d5dd849962306cce46f3688a9675dcdfcaa1 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Mon, 21 Sep 2026 10:03:16 +0200
Subject: [PATCH 6/8] Add getExtAttrForBoolParam().

---
 llvm/include/llvm/Analysis/TargetLibraryInfo.h | 18 ++++++++++++++++++
 .../Instrumentation/TypeSanitizer.cpp          |  6 ++++--
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index abbf2db6e27cb2..4cd1fa1b4082fb 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -464,6 +464,18 @@ class TargetLibraryInfo {
     return Impl->CustomNames.find(F)->second;
   }
 
+  static void initBoolExtensionsForTriple(bool &ShouldZExtBoolParam,
+                                          bool &ShouldZExtBoolReturn,
+                                          const Triple &T) {
+    ShouldZExtBoolParam = ShouldZExtBoolReturn = false;
+
+    if (T.isPPC64() || T.getArch() == Triple::sparcv9 ||
+        T.getArch() == Triple::systemz || T.isLoongArch() ||
+        T.isMIPS() || T.isRISCV64()) {
+      ShouldZExtBoolParam = ShouldZExtBoolReturn = true;
+    }
+  }
+
   static void initExtensionsForTriple(bool &ShouldExtI32Param,
                                       bool &ShouldExtI32Return,
                                       bool &ShouldSignExtI32Param,
@@ -506,6 +518,12 @@ class TargetLibraryInfo {
   }
 
 public:
+  static Attribute::AttrKind getExtAttrForBoolParam(const Triple &T) {
+    bool ShouldZExtBoolParam, ShouldZExtBoolReturn;
+    initBoolExtensionsForTriple(ShouldZExtBoolParam, ShouldZExtBoolReturn, T);
+    return ShouldZExtBoolParam ? Attribute::ZExt : Attribute::None;
+  }
+
   static Attribute::AttrKind getExtAttrForI32Param(const Triple &T,
                                                    bool Signed = true) {
     bool ShouldExtI32Param, ShouldExtI32Return;
diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 7a95daeb8e271d..2a13d38b43e986 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -154,6 +154,8 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
   Attr = Attr.addFnAttribute(C, Attribute::NoUnwind);
   Attribute::AttrKind SExtAttr =
       TargetLibraryInfo::getExtAttrForI32Param(TargetTriple, /*Signed=*/true);
+  Attribute::AttrKind BoolExtAttr =
+      TargetLibraryInfo::getExtAttrForBoolParam(TargetTriple);
 
   // Initialize the callbacks.  TODO: use TLI/emitLibFunc() for these functions.
   TysanCheck =
@@ -172,7 +174,7 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanIntrumentMemInst = M.getOrInsertFunction(
       "__tysan_instrument_mem_inst",
-      Attr.addParamAttribute(C, 3, Attribute::AttrKind::ZExt), IRB.getVoidTy(),
+      Attr.maybeAddParamAttribute(C, 3, BoolExtAttr), IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer of data to be written to
       IRB.getPtrTy(), // Pointer of data to write
       U64Ty,          // Size of the data in bytes
@@ -181,7 +183,7 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
 
   TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
       "__tysan_instrument_with_shadow_update",
-      Attr.addParamAttribute(C, 2, Attribute::AttrKind::ZExt)
+      Attr.maybeAddParamAttribute(C, 2, BoolExtAttr)
           .maybeAddParamAttribute(C, 4, SExtAttr),
       IRB.getVoidTy(),
       IRB.getPtrTy(), // Pointer to data to be read

>From dfca49335fc9b9518825fb34b35631fa94ef15b0 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <Jonas.Paulsson2 at ibm.com>
Date: Mon, 21 Sep 2026 10:20:11 +0200
Subject: [PATCH 7/8] clang-format

---
 .../include/llvm/Analysis/TargetLibraryInfo.h |  4 ++--
 .../Instrumentation/TypeSanitizer.cpp         | 22 +++++++++----------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 4cd1fa1b4082fb..e4def3cea77134 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -470,8 +470,8 @@ class TargetLibraryInfo {
     ShouldZExtBoolParam = ShouldZExtBoolReturn = false;
 
     if (T.isPPC64() || T.getArch() == Triple::sparcv9 ||
-        T.getArch() == Triple::systemz || T.isLoongArch() ||
-        T.isMIPS() || T.isRISCV64()) {
+        T.getArch() == Triple::systemz || T.isLoongArch() || T.isMIPS() ||
+        T.isRISCV64()) {
       ShouldZExtBoolParam = ShouldZExtBoolReturn = true;
     }
   }
diff --git a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
index 2a13d38b43e986..c6436617d69e6f 100644
--- a/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/TypeSanitizer.cpp
@@ -181,17 +181,17 @@ void TypeSanitizer::initializeCallbacks(Module &M) {
       BoolType        // Do we need to call memmove
   );
 
-  TysanInstrumentWithShadowUpdate = M.getOrInsertFunction(
-      "__tysan_instrument_with_shadow_update",
-      Attr.maybeAddParamAttribute(C, 2, BoolExtAttr)
-          .maybeAddParamAttribute(C, 4, SExtAttr),
-      IRB.getVoidTy(),
-      IRB.getPtrTy(), // Pointer to data to be read
-      IRB.getPtrTy(), // Pointer to type descriptor
-      BoolType,       // Do we need to type check this
-      U64Ty,          // Size of data we access in bytes
-      OrdTy           // Flags
-  );
+  TysanInstrumentWithShadowUpdate =
+      M.getOrInsertFunction("__tysan_instrument_with_shadow_update",
+                            Attr.maybeAddParamAttribute(C, 2, BoolExtAttr)
+                                .maybeAddParamAttribute(C, 4, SExtAttr),
+                            IRB.getVoidTy(),
+                            IRB.getPtrTy(), // Pointer to data to be read
+                            IRB.getPtrTy(), // Pointer to type descriptor
+                            BoolType,       // Do we need to type check this
+                            U64Ty,          // Size of data we access in bytes
+                            OrdTy           // Flags
+      );
 
   TysanSetShadowType = M.getOrInsertFunction(
       "__tysan_set_shadow_type", Attr, IRB.getVoidTy(),

>From 442a7c77e7066cbd7e93ece9455c463ebbada116 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Tue, 22 Sep 2026 09:55:04 +0200
Subject: [PATCH 8/8] updated per review.

---
 llvm/include/llvm/Analysis/TargetLibraryInfo.h | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index e4def3cea77134..19c251f592608a 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -469,10 +469,9 @@ class TargetLibraryInfo {
                                           const Triple &T) {
     ShouldZExtBoolParam = ShouldZExtBoolReturn = false;
 
-    if (T.isPPC64() || T.getArch() == Triple::sparcv9 ||
-        T.getArch() == Triple::systemz || T.isLoongArch() || T.isMIPS() ||
-        T.isRISCV64()) {
-      ShouldZExtBoolParam = ShouldZExtBoolReturn = true;
+    if (!T.isAArch64() && !T.isOSDarwin()) {
+      ShouldZExtBoolParam = true;
+      ShouldZExtBoolReturn = true;
     }
   }
 



More information about the llvm-commits mailing list