[llvm] [DataFlowSanitizer] Properly add ext attributes on arguments as needed. (PR #225443)

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 04:08:21 PDT 2026


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

>From 77e92528322c8856698c2694c832fb03acdadecd Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Tue, 22 Sep 2026 17:39:12 +0200
Subject: [PATCH 1/7] [DataFlowSanitizer] Properly add ext attributes on
 arguments where needed.

---
 .../Instrumentation/DataFlowSanitizer.cpp     | 48 +++++++++++++++++--
 .../DataFlowSanitizer/abilist.ll              |  8 ++--
 .../DataFlowSanitizer/abilist_aggregate.ll    |  8 ++--
 .../DataFlowSanitizer/callback.ll             |  6 +--
 .../instrumented-args-exts.ll                 |  9 ++++
 .../DataFlowSanitizer/origin_abilist.ll       | 12 ++---
 .../DataFlowSanitizer/reaches_function.ll     |  2 +-
 .../DataFlowSanitizer/shadow-args-zext.ll     | 12 ++---
 8 files changed, 76 insertions(+), 29 deletions(-)
 create mode 100644 llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll

diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 866622a2db8fb96..33879efa1d3e65b 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -1107,11 +1107,15 @@ void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
     Value *DataOrigin = getOrigin(Data);
     args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
     CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn, args);
+    CB->addParamAttr(0, Attribute::ZExt);
+    CB->addParamAttr(1, Attribute::ZExt);
+    CB->addParamAttr(3, Attribute::ZExt);
   } else {
     args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
     CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackFn, args);
+    CB->addParamAttr(0, Attribute::ZExt);
+    CB->addParamAttr(2, Attribute::ZExt);
   }
-  CB->addParamAttr(0, Attribute::ZExt);
   CB->setDebugLoc(dbgloc);
 }
 
@@ -1405,9 +1409,13 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
   DFSanMemShadowOriginTransferFn = Mod->getOrInsertFunction(
       "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
 
-  DFSanMemShadowOriginConditionalExchangeFn =
+  {
+    AttributeList AL;
+    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    DFSanMemShadowOriginConditionalExchangeFn =
       Mod->getOrInsertFunction("__dfsan_mem_shadow_origin_conditional_exchange",
-                               DFSanMemShadowOriginConditionalExchangeFnTy);
+                               DFSanMemShadowOriginConditionalExchangeFnTy, AL);
+  }
 
   {
     AttributeList AL;
@@ -1493,6 +1501,7 @@ void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
   {
     AttributeList AL;
     AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
     DFSanConditionalCallbackOriginFn =
         Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
                                  DFSanConditionalCallbackOriginFnTy, AL);
@@ -1500,6 +1509,7 @@ void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
   {
     AttributeList AL;
     AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt);
     DFSanReachesFunctionCallbackFn =
         Mod->getOrInsertFunction("__dfsan_reaches_function_callback",
                                  DFSanReachesFunctionCallbackFnTy, AL);
@@ -1507,6 +1517,8 @@ void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
   {
     AttributeList AL;
     AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
+    AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt);
     DFSanReachesFunctionCallbackOriginFn =
         Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
                                  DFSanReachesFunctionCallbackOriginFnTy, AL);
@@ -3138,6 +3150,22 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
     if (Function *CustomFn = dyn_cast<Function>(CustomF.getCallee())) {
       CustomFn->copyAttributesFrom(&F);
 
+      // Ensure all narrow integer arguments (both original and added
+      // shadow/origin) have an extension attribute on the function
+      // declaration. If none is present, add ZExt as all DFSan args are
+      // unsigned. TODO: Avoid getting here with missing attributes in the
+      // first place (use TLI/emitLibFunc()?).
+      for (unsigned I = 0, E = CustomFn->arg_size(); I < E; ++I) {
+        Type *ParamTy = CustomFn->getFunctionType()->getParamType(I);
+        if (ParamTy->isIntegerTy() && ParamTy->getIntegerBitWidth() <= 32) {
+          if (!CustomFn->hasParamAttribute(I, Attribute::ZExt) &&
+              !CustomFn->hasParamAttribute(I, Attribute::SExt) &&
+              !CustomFn->hasParamAttribute(I, Attribute::NoExt)) {
+            CustomFn->addParamAttr(I, Attribute::ZExt);
+          }
+        }
+      }
+
       // Custom functions returning non-void will write to the return label.
       if (!FT->getReturnType()->isVoidTy()) {
         CustomFn->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
@@ -3164,10 +3192,18 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
     // Adds variable arguments.
     append_range(Args, drop_begin(CB.args(), FT->getNumParams()));
 
+    // Combine CallSite attributes with Function declaration attributes.
+    AttributeList CombinedAttrs = CI->getAttributes();
+    for (unsigned I = 0; I < FT->getNumParams(); ++I) {
+      AttrBuilder AttrB(CI->getContext(), F.getAttributes().getParamAttrs(I));
+      if (AttrB.hasAttributes())
+        CombinedAttrs = CombinedAttrs.addParamAttributes(CI->getContext(), I,
+                                                         AttrB);
+    }
     CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
     CustomCI->setCallingConv(CI->getCallingConv());
     CustomCI->setAttributes(transformFunctionAttributes(
-        CustomFn, CI->getContext(), CI->getAttributes()));
+        CustomFn, CI->getContext(), CombinedAttrs));
 
     // Update the parameter attributes of the custom call instruction to
     // zero extend the shadow parameters. This is required for targets
@@ -3331,10 +3367,12 @@ void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
 
   // If original call returned true, copy Desired to Target.
   // If original call returned false, copy Target to Expected.
-  NextIRB.CreateCall(DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
+  CallInst *CI = NextIRB.CreateCall(
+                     DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
                      {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false),
                       TargetPtr, ExpectedPtr, DesiredPtr,
                       NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
+  CI->addParamAttr(0, Attribute::ZExt);
 }
 
 void DFSanVisitor::visitCallBase(CallBase &CB) {
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll b/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
index 61621ab3a6d7191..d58c541bc6e8c6b 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
@@ -88,8 +88,8 @@ define ptr @g(i32) {
 
 ; CHECK: define linkonce_odr i32 @"dfsw$custom4"(i32 %0, ...)
 
-; CHECK: declare void @__dfsw_custom1(i32, i32, i8, i8)
-; CHECK: declare i32 @__dfsw_custom2(i32, i32, i8, i8, ptr)
+; CHECK: declare void @__dfsw_custom1(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext)
+; CHECK: declare i32 @__dfsw_custom2(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr)
 
-; CHECK: declare void @__dfsw_custom3(i32, i8, ptr, ...)
-; CHECK: declare i32 @__dfsw_custom4(i32, i8, ptr, ptr, ...)
+; CHECK: declare void @__dfsw_custom3(i32 zeroext, i8 zeroext, ptr, ...)
+; CHECK: declare i32 @__dfsw_custom4(i32 zeroext, i8 zeroext, ptr, ptr, ...)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll b/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
index 3cab62b02efc289..8308e38f0b359d6 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
@@ -241,8 +241,8 @@ define void @custom_varg({i32, i1} %a, ...) {
   ret void
 }
 
-; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8, i8, ptr)
-; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8, i8)
-; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8, ptr, ...)
+; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext)
+; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8 zeroext, ptr, ...)
 
-; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8, i8, i8, ptr)
+; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext, i8 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
index a499ec934d9fea5..b4f4f7c67b01690 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
@@ -34,6 +34,6 @@ define i1 @cmp(i8 %a, i8 %b) {
 ; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
 ; CHECK: declare void @__dfsan_cmp_callback(i8 zeroext)
 ; CHECK: declare void @__dfsan_conditional_callback(i8 zeroext)
-; CHECK: declare void @__dfsan_conditional_callback_origin(i8 zeroext, i32)
-; CHECK: declare void @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32, ptr)
-; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8 zeroext, i32, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_conditional_callback_origin(i8 zeroext, i32 zeroext)
+; CHECK: declare void @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32 zeroext, ptr)
+; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8 zeroext, i32 zeroext, ptr, i32 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll b/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
new file mode 100644
index 000000000000000..9e9c1bd0fdbdc15
--- /dev/null
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
@@ -0,0 +1,9 @@
+; Test extensions of arguments to instrumented function.
+;
+; RUN: opt -passes='dfsan' -mtriple=s390x-unknown-linux -S %s | FileCheck %s
+
+define void @fun() {
+  ret void
+}
+
+; CHECK: declare void @__dfsan_mem_shadow_origin_conditional_exchange(i8 zeroext, ptr, ptr, ptr, i64)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll b/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
index 133f3e3854b9d1a..a6f6f717a69fa70 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
@@ -281,14 +281,14 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  call void @__dfso_custom_cb_without_ret(ptr %0, i32 %1, i32 %2, i8 zeroext [[CS]], i8 zeroext [[AS]], i8 zeroext [[BS]], i32 zeroext [[CO]], i32 zeroext [[AO]], i32 zeroext [[BO]])
 ; CHECK-NEXT:  ret void
 
-; CHECK: declare void @__dfso_custom_without_ret(i32, i32, i8, i8, i32, i32)
+; CHECK: declare void @__dfso_custom_without_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, i32 zeroext, i32 zeroext)
 
-; CHECK: declare i32 @__dfso_custom_with_ret(i32, i32, i8, i8, ptr, i32, i32, ptr)
+; CHECK: declare i32 @__dfso_custom_with_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr, i32 zeroext, i32 zeroext, ptr)
 
-; CHECK: declare i32 @__dfso_custom_cb_with_ret(ptr, i32, i32, i8, i8, i8, ptr, i32, i32, i32, ptr)
+; CHECK: declare i32 @__dfso_custom_cb_with_ret(ptr, i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr, i32 zeroext, i32 zeroext, i32 zeroext, ptr)
 
-; CHECK: declare void @__dfso_custom_cb_without_ret(ptr, i32, i32, i8, i8, i8, i32, i32, i32)
+; CHECK: declare void @__dfso_custom_cb_without_ret(ptr, i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i32 zeroext, i32 zeroext, i32 zeroext)
 
-; CHECK: declare void @__dfso_custom_varg_without_ret(i32, i32, i8, i8, ptr, i32, i32, ptr, ...)
+; CHECK: declare void @__dfso_custom_varg_without_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr, i32 zeroext, i32 zeroext, ptr, ...)
 
-; CHECK: declare i32 @__dfso_custom_varg_with_ret(i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...)
+; CHECK: declare i32 @__dfso_custom_varg_with_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr, ptr, i32 zeroext, i32 zeroext, ptr, ptr, ...)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll b/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
index 9e47795e1ba62f9..1917bcc7be08fd1 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
@@ -26,4 +26,4 @@ define void @call() {
   ret void
 }
 
-; CHECK-LABEL: @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32, ptr)
+; CHECK-LABEL: @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
index e338976dca09355..333f1e45fb2df1d 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
@@ -36,17 +36,17 @@ entry:
 
 declare zeroext i16 @dfsan_get_label(i64 signext)
 ; CHECK-LABEL: @"dfsw$dfsan_get_label"
-; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 %0, i8 zeroext %1, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
 
 declare zeroext i16 @k2(i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k2"
-; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 %{{.*}}, i64 %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 declare zeroext i16 @k4(i64 signext, i64 signext, i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k4"
-; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 %{{.*}}, i64 %{{.*}}, i64  %{{.*}}, i64 %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 
-; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8, ptr)
-; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8, i8, ptr)
-; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8, i8, i8, i8, ptr)
+; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8 zeroext, ptr)
+; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr)

>From e61146d7833190838d283e8835b1ff6b282f2668 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <Jonas.Paulsson2 at ibm.com>
Date: Tue, 22 Sep 2026 18:33:01 +0200
Subject: [PATCH 2/7] clang-format

---
 .../Instrumentation/DataFlowSanitizer.cpp     | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 33879efa1d3e65b..42b16b7f8b17312 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -1412,9 +1412,9 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
   {
     AttributeList AL;
     AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    DFSanMemShadowOriginConditionalExchangeFn =
-      Mod->getOrInsertFunction("__dfsan_mem_shadow_origin_conditional_exchange",
-                               DFSanMemShadowOriginConditionalExchangeFnTy, AL);
+    DFSanMemShadowOriginConditionalExchangeFn = Mod->getOrInsertFunction(
+        "__dfsan_mem_shadow_origin_conditional_exchange",
+        DFSanMemShadowOriginConditionalExchangeFnTy, AL);
   }
 
   {
@@ -3197,13 +3197,13 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
     for (unsigned I = 0; I < FT->getNumParams(); ++I) {
       AttrBuilder AttrB(CI->getContext(), F.getAttributes().getParamAttrs(I));
       if (AttrB.hasAttributes())
-        CombinedAttrs = CombinedAttrs.addParamAttributes(CI->getContext(), I,
-                                                         AttrB);
+        CombinedAttrs =
+            CombinedAttrs.addParamAttributes(CI->getContext(), I, AttrB);
     }
     CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
     CustomCI->setCallingConv(CI->getCallingConv());
-    CustomCI->setAttributes(transformFunctionAttributes(
-        CustomFn, CI->getContext(), CombinedAttrs));
+    CustomCI->setAttributes(
+        transformFunctionAttributes(CustomFn, CI->getContext(), CombinedAttrs));
 
     // Update the parameter attributes of the custom call instruction to
     // zero extend the shadow parameters. This is required for targets
@@ -3368,10 +3368,10 @@ void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
   // If original call returned true, copy Desired to Target.
   // If original call returned false, copy Target to Expected.
   CallInst *CI = NextIRB.CreateCall(
-                     DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
-                     {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false),
-                      TargetPtr, ExpectedPtr, DesiredPtr,
-                      NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
+      DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
+      {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
+       ExpectedPtr, DesiredPtr,
+       NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
   CI->addParamAttr(0, Attribute::ZExt);
 }
 

>From 93a7c16ae28907b1dc20e9a3f2386305fe9320f9 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Wed, 23 Sep 2026 10:21:19 +0200
Subject: [PATCH 3/7] Compute attributes with TLI.getExtAttrForI32Param().

---
 llvm/include/llvm/IR/InstrTypes.h             |  6 ++
 .../Instrumentation/DataFlowSanitizer.cpp     | 77 +++++++++++--------
 .../DataFlowSanitizer/abilist.ll              | 18 ++---
 .../DataFlowSanitizer/abilist_aggregate.ll    | 22 +++---
 .../DataFlowSanitizer/array.ll                |  8 +-
 .../DataFlowSanitizer/basic.ll                | 14 ++--
 .../DataFlowSanitizer/callback.ll             | 20 ++---
 .../instrumented-args-exts.ll                 | 33 +++++++-
 .../DataFlowSanitizer/origin_abilist.ll       | 32 ++++----
 .../DataFlowSanitizer/reaches_function.ll     |  2 +-
 .../DataFlowSanitizer/shadow-args-zext.ll     | 37 ++++++---
 .../DataFlowSanitizer/struct.ll               |  4 +-
 12 files changed, 167 insertions(+), 106 deletions(-)

diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 5f7df6a4eb6f8c1..61f5d05240b3a67 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -1589,6 +1589,12 @@ class CallBase : public Instruction {
     Attrs = Attrs.addParamAttributes(getContext(), ArgNo, B);
   }
 
+  /// Adds the attribute to the indicated argument
+  void maybeAddParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
+    assert(ArgNo < arg_size() && "Out of bounds");
+    Attrs = Attrs.maybeAddParamAttribute(getContext(), ArgNo, Kind);
+  }
+
   /// removes the attribute from the list of attributes.
   void removeAttributeAtIndex(unsigned i, Attribute::AttrKind Kind) {
     Attrs = Attrs.removeAttributeAtIndex(getContext(), i, Kind);
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 42b16b7f8b17312..8aa3803ea6be5a7 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -1073,7 +1073,7 @@ void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &I,
   } else {
     CI = IRB.CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
   }
-  CI->addParamAttr(0, Attribute::ZExt);
+  CI->maybeAddParamAttr(0, TLI.getExtAttrForI32Param(/*Signed=*/false));
 }
 
 void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
@@ -1103,18 +1103,20 @@ void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
   CallInst *CB;
   std::vector<Value *> args;
 
+  Attribute::AttrKind ParamExtAttr =
+      TLI.getExtAttrForI32Param(/*Signed=*/false);
   if (DFS.shouldTrackOrigins()) {
     Value *DataOrigin = getOrigin(Data);
     args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
     CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn, args);
-    CB->addParamAttr(0, Attribute::ZExt);
-    CB->addParamAttr(1, Attribute::ZExt);
-    CB->addParamAttr(3, Attribute::ZExt);
+    CB->maybeAddParamAttr(0, ParamExtAttr);
+    CB->maybeAddParamAttr(1, ParamExtAttr);
+    CB->maybeAddParamAttr(3, ParamExtAttr);
   } else {
     args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
     CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackFn, args);
-    CB->addParamAttr(0, Attribute::ZExt);
-    CB->addParamAttr(2, Attribute::ZExt);
+    CB->maybeAddParamAttr(0, ParamExtAttr);
+    CB->maybeAddParamAttr(2, ParamExtAttr);
   }
   CB->setDebugLoc(dbgloc);
 }
@@ -1355,6 +1357,8 @@ DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
 // Initialize DataFlowSanitizer runtime functions and declare them in the module
 void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
   LLVMContext &C = M.getContext();
+  Attribute::AttrKind ParamExtAttr = TargetLibraryInfo::getExtAttrForI32Param(
+      M.getTargetTriple(), /*Signed=*/false);
   {
     AttributeList AL;
     AL = AL.addFnAttribute(C, Attribute::NoUnwind);
@@ -1379,8 +1383,8 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
       "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
     DFSanSetLabelFn =
         Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy, AL);
   }
@@ -1390,15 +1394,15 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
                                                   DFSanVarargWrapperFnTy);
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
     AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
     DFSanChainOriginFn = Mod->getOrInsertFunction("__dfsan_chain_origin",
                                                   DFSanChainOriginFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
     AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
     DFSanChainOriginIfTaintedFn = Mod->getOrInsertFunction(
         "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
@@ -1411,7 +1415,7 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
 
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
     DFSanMemShadowOriginConditionalExchangeFn = Mod->getOrInsertFunction(
         "__dfsan_mem_shadow_origin_conditional_exchange",
         DFSanMemShadowOriginConditionalExchangeFnTy, AL);
@@ -1419,8 +1423,8 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
 
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 3, ParamExtAttr);
     DFSanMaybeStoreOriginFn = Mod->getOrInsertFunction(
         "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
   }
@@ -1472,15 +1476,17 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
 
 // Initializes event callback functions and declare them in the module
 void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
+  Attribute::AttrKind ParamExtAttr = TargetLibraryInfo::getExtAttrForI32Param(
+      M.getTargetTriple(), /*Signed=*/false);
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
     DFSanLoadCallbackFn = Mod->getOrInsertFunction(
         "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
     DFSanStoreCallbackFn = Mod->getOrInsertFunction(
         "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
   }
@@ -1488,37 +1494,37 @@ void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
       "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
     DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback",
                                                   DFSanCmpCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
     DFSanConditionalCallbackFn = Mod->getOrInsertFunction(
         "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
     DFSanConditionalCallbackOriginFn =
         Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
                                  DFSanConditionalCallbackOriginFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 2, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 2, ParamExtAttr);
     DFSanReachesFunctionCallbackFn =
         Mod->getOrInsertFunction("__dfsan_reaches_function_callback",
                                  DFSanReachesFunctionCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.addParamAttribute(M.getContext(), 0, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 1, Attribute::ZExt);
-    AL = AL.addParamAttribute(M.getContext(), 3, Attribute::ZExt);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 3, ParamExtAttr);
     DFSanReachesFunctionCallbackOriginFn =
         Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
                                  DFSanReachesFunctionCallbackOriginFnTy, AL);
@@ -2482,7 +2488,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
     Value *Addr = LI.getPointerOperand();
     CallInst *CI =
         IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
-    CI->addParamAttr(0, Attribute::ZExt);
+    CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
   }
 
   IRBuilder<> IRB(AfterLi->getParent(), AfterLi);
@@ -2740,7 +2746,7 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) {
     Value *Addr = SI.getPointerOperand();
     CallInst *CI =
         IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
-    CI->addParamAttr(0, Attribute::ZExt);
+    CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
   }
 }
 
@@ -2804,7 +2810,8 @@ void DFSanVisitor::visitCmpInst(CmpInst &CI) {
     Value *CombinedShadow = DFSF.getShadow(&CI);
     CallInst *CallI =
         IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
-    CallI->addParamAttr(0, Attribute::ZExt);
+    CallI->maybeAddParamAttr(0,
+                             DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
   }
 }
 
@@ -3111,6 +3118,8 @@ void DFSanVisitor::addOriginArguments(Function &F, CallBase &CB,
 }
 
 bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
+  Attribute::AttrKind ParamExtAttr =
+      DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false);
   IRBuilder<> IRB(&CB);
   switch (DFSF.DFS.getWrapperKind(&F)) {
   case DataFlowSanitizer::WK_Warning:
@@ -3158,10 +3167,11 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
       for (unsigned I = 0, E = CustomFn->arg_size(); I < E; ++I) {
         Type *ParamTy = CustomFn->getFunctionType()->getParamType(I);
         if (ParamTy->isIntegerTy() && ParamTy->getIntegerBitWidth() <= 32) {
-          if (!CustomFn->hasParamAttribute(I, Attribute::ZExt) &&
+          if (ParamExtAttr != Attribute::AttrKind::None &&
+              !CustomFn->hasParamAttribute(I, Attribute::ZExt) &&
               !CustomFn->hasParamAttribute(I, Attribute::SExt) &&
               !CustomFn->hasParamAttribute(I, Attribute::NoExt)) {
-            CustomFn->addParamAttr(I, Attribute::ZExt);
+            CustomFn->addParamAttr(I, ParamExtAttr);
           }
         }
       }
@@ -3212,12 +3222,13 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
       const unsigned ArgNo = ShadowArgStart + N;
       if (CustomCI->getArgOperand(ArgNo)->getType() ==
           DFSF.DFS.PrimitiveShadowTy)
-        CustomCI->addParamAttr(ArgNo, Attribute::ZExt);
+        CustomCI->maybeAddParamAttr(ArgNo, ParamExtAttr);
+
       if (ShouldTrackOrigins) {
         const unsigned OriginArgNo = OriginArgStart + N;
         if (CustomCI->getArgOperand(OriginArgNo)->getType() ==
             DFSF.DFS.OriginTy)
-          CustomCI->addParamAttr(OriginArgNo, Attribute::ZExt);
+          CustomCI->maybeAddParamAttr(OriginArgNo, ParamExtAttr);
       }
     }
 
@@ -3372,7 +3383,7 @@ void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
       {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
        ExpectedPtr, DesiredPtr,
        NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
-  CI->addParamAttr(0, Attribute::ZExt);
+  CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
 }
 
 void DFSanVisitor::visitCallBase(CallBase &CB) {
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll b/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
index d58c541bc6e8c6b..d61d65381837856 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
@@ -33,13 +33,13 @@ define void @f(i32 %x) {
   ; CHECK: %[[LABELVA1:.*]] = alloca [2 x i8]
   ; CHECK: %[[LABELRETURN:.*]] = alloca i8
 
-  ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i8 zeroext 0, i8 zeroext 0)
+  ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i8 0, i8 0)
   call void @custom1(i32 1, i32 2)
 
-  ; CHECK: call i32 @__dfsw_custom2(i32 1, i32 2, i8 zeroext 0, i8 zeroext 0, ptr %[[LABELRETURN]])
+  ; CHECK: call i32 @__dfsw_custom2(i32 1, i32 2, i8 0, i8 0, ptr %[[LABELRETURN]])
   call i32 @custom2(i32 1, i32 2)
 
-  ; CHECK: call void @__dfsw_customcb({{.*}} @cb.dfsan, i8 zeroext 0)
+  ; CHECK: call void @__dfsw_customcb({{.*}} @cb.dfsan, i8 0)
   call void @customcb(ptr @cb)
 
   ; CHECK: %[[LABELVA1_0:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA1]], i32 0, i32 0
@@ -47,13 +47,13 @@ define void @f(i32 %x) {
   ; CHECK: %[[LABELVA1_1:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA1]], i32 0, i32 1
   ; CHECK: store i8 %{{.*}}, ptr %[[LABELVA1_1]]
   ; CHECK: %[[LABELVA1_0A:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA1]], i32 0, i32 0
-  ; CHECK: call void (i32, i8, ptr, ...) @__dfsw_custom3(i32 1, i8 zeroext 0, ptr %[[LABELVA1_0A]], i32 2, i32 %{{.*}})
+  ; CHECK: call void (i32, i8, ptr, ...) @__dfsw_custom3(i32 1, i8 0, ptr %[[LABELVA1_0A]], i32 2, i32 %{{.*}})
 
   call void (i32, ...) @custom3(i32 1, i32 2, i32 %x)
 
   ; CHECK: %[[LABELVA2_0:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA2]], i32 0, i32 0
   ; CHECK: %[[LABELVA2_0A:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA2]], i32 0, i32 0
-  ; CHECK: call i32 (i32, i8, ptr, ptr, ...) @__dfsw_custom4(i32 1, i8 zeroext 0, ptr %[[LABELVA2_0A]], ptr %[[LABELRETURN]], i32 2, i32 3)
+  ; CHECK: call i32 (i32, i8, ptr, ptr, ...) @__dfsw_custom4(i32 1, i8 0, ptr %[[LABELVA2_0A]], ptr %[[LABELRETURN]], i32 2, i32 3)
   call i32 (i32, ...) @custom4(i32 1, i32 2, i32 3)
 
   ret void
@@ -88,8 +88,8 @@ define ptr @g(i32) {
 
 ; CHECK: define linkonce_odr i32 @"dfsw$custom4"(i32 %0, ...)
 
-; CHECK: declare void @__dfsw_custom1(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext)
-; CHECK: declare i32 @__dfsw_custom2(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare void @__dfsw_custom1(i32, i32, i8, i8)
+; CHECK: declare i32 @__dfsw_custom2(i32, i32, i8, i8, ptr)
 
-; CHECK: declare void @__dfsw_custom3(i32 zeroext, i8 zeroext, ptr, ...)
-; CHECK: declare i32 @__dfsw_custom4(i32 zeroext, i8 zeroext, ptr, ptr, ...)
+; CHECK: declare void @__dfsw_custom3(i32, i8, ptr, ...)
+; CHECK: declare i32 @__dfsw_custom4(i32, i8, ptr, ptr, ...)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll b/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
index 8308e38f0b359d6..14d7153e8b2aecc 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
@@ -76,7 +76,7 @@ define {i1, i7} @call_custom_with_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
+  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i8 [[A01]], i8 [[B01]], ptr %labelreturn)
   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -97,7 +97,7 @@ define void @call_custom_without_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]])
+  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i8 [[A01]], i8 [[B01]])
 
   call void @custom_without_ret({i32, i1} %a, [2 x i7] %b)
   ret void
@@ -117,7 +117,7 @@ define void @call_custom_varg({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
   ; CHECK: store i8 [[B01]], ptr [[V0]], align 1
   ; CHECK: [[V:%.*]] = getelementptr inbounds nuw [1 x i8], ptr %labelva, i32 0, i32 0
-  ; CHECK: call void ({ i32, i1 }, i8, ptr, ...) @__dfsw_custom_varg({ i32, i1 } %a, i8 zeroext [[A01]], ptr [[V]], [2 x i7] %b)
+  ; CHECK: call void ({ i32, i1 }, i8, ptr, ...) @__dfsw_custom_varg({ i32, i1 } %a, i8 [[A01]], ptr [[V]], [2 x i7] %b)
 
   call void ({i32, i1}, ...) @custom_varg({i32, i1} %a, [2 x i7] %b)
   ret void
@@ -134,7 +134,7 @@ define {i1, i7} @call_custom_cb({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i8 zeroext 0, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
+  ; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i8 0, i8 [[A01]], i8 [[B01]], ptr %labelreturn)
   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -189,7 +189,7 @@ define ptr @ret_custom() {
 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr %0, { i32, i1 } %1, [2 x i7] %2, i8 zeroext [[CB]], i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
+; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr %0, { i32, i1 } %1, [2 x i7] %2, i8 [[CB]], i8 [[A01]], i8 [[B01]], ptr %labelreturn)
 ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
 ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
 ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -206,7 +206,7 @@ define {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
+  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i8 [[A01]], i8 [[B01]], ptr %labelreturn)
   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -229,7 +229,7 @@ define void @custom_without_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]])
+  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i8 [[A01]], i8 [[B01]])
   ; CHECK: ret
   ret void
 }
@@ -241,8 +241,8 @@ define void @custom_varg({i32, i1} %a, ...) {
   ret void
 }
 
-; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext, ptr)
-; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext)
-; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8 zeroext, ptr, ...)
+; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8, i8, ptr)
+; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8, i8)
+; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8, ptr, ...)
 
-; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8, i8, i8, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/array.ll b/llvm/test/Instrumentation/DataFlowSanitizer/array.ll
index 14468c18ca201b2..1214bf627c1c40d 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/array.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/array.ll
@@ -78,7 +78,7 @@ define [1 x i1] @load_array1(ptr %p) {
 
   ; EVENT_CALLBACKS: @load_array1.dfsan
   ; EVENT_CALLBACKS: [[L:%.*]] = or i8
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[L]], ptr {{.*}})
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[L]], ptr {{.*}})
 
   ; FAST: @load_array1.dfsan
   ; FAST: [[P:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
@@ -104,7 +104,7 @@ define [2 x i1] @load_array2(ptr %p) {
   ; EVENT_CALLBACKS: @load_array2.dfsan
   ; EVENT_CALLBACKS: [[O1:%.*]] = or i8
   ; EVENT_CALLBACKS: [[O2:%.*]] = or i8 [[O1]]
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[O2]], ptr {{.*}})
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[O2]], ptr {{.*}})
 
   ; FAST: @load_array2.dfsan
   ; FAST: [[P:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
@@ -131,7 +131,7 @@ define [4 x i1] @load_array4(ptr %p) {
   ; EVENT_CALLBACKS: [[O1:%.*]] = or i32 [[O0]]
   ; EVENT_CALLBACKS: [[O2:%.*]] = trunc i32 [[O1]] to i8
   ; EVENT_CALLBACKS: [[O3:%.*]] = or i8 [[O2]]
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[O3]], ptr {{.*}})
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[O3]], ptr {{.*}})
 
   ; FAST: @load_array4.dfsan
   ; FAST: [[T:%.*]] = trunc i32 {{.*}} to i8
@@ -193,7 +193,7 @@ define void @store_zero_array(ptr %p) {
 define void @store_array2([2 x i1] %a, ptr %p) {
   ; EVENT_CALLBACKS: @store_array2.dfsan
   ; EVENT_CALLBACKS: [[E12:%.*]] = or i8
-  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 zeroext [[E12]], ptr %p)
+  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 [[E12]], ptr %p)
 
   ; FAST: @store_array2.dfsan
   ; FAST: [[S:%.*]] = load [2 x i8], ptr @__dfsan_arg_tls, align [[ALIGN:2]]
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll b/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
index fa8c9267bba5991..3ccf0b5f70ad66c 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
@@ -27,10 +27,10 @@ define void @store(ptr %p) {
   ret void
 }
 
-; CHECK: declare void @__dfsan_load_callback(i8 zeroext, ptr)
-; CHECK: declare void @__dfsan_store_callback(i8 zeroext, ptr)
+; CHECK: declare void @__dfsan_load_callback(i8, ptr)
+; CHECK: declare void @__dfsan_store_callback(i8, ptr)
 ; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
-; CHECK: declare void @__dfsan_cmp_callback(i8 zeroext)
+; CHECK: declare void @__dfsan_cmp_callback(i8)
 
 ; CHECK: ; Function Attrs: nounwind memory(read)
 ; CHECK-NEXT: declare zeroext i8 @__dfsan_union_load(ptr, i64)
@@ -39,10 +39,10 @@ define void @store(ptr %p) {
 ; CHECK-NEXT: declare zeroext i64 @__dfsan_load_label_and_origin(ptr, i64)
 
 ; CHECK: declare void @__dfsan_unimplemented(ptr)
-; CHECK: declare void @__dfsan_set_label(i8 zeroext, i32 zeroext, ptr, i64)
+; CHECK: declare void @__dfsan_set_label(i8, i32, ptr, i64)
 ; CHECK: declare void @__dfsan_nonzero_label()
 ; CHECK: declare void @__dfsan_vararg_wrapper(ptr)
-; CHECK: declare zeroext i32 @__dfsan_chain_origin(i32 zeroext)
-; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8 zeroext, i32 zeroext)
+; CHECK: declare zeroext i32 @__dfsan_chain_origin(i32)
+; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8, i32)
 ; CHECK: declare void @__dfsan_mem_origin_transfer(ptr, ptr, i64)
-; CHECK: declare void @__dfsan_maybe_store_origin(i8 zeroext, ptr, i64, i32 zeroext)
+; CHECK: declare void @__dfsan_maybe_store_origin(i8, ptr, i64, i32)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
index b4f4f7c67b01690..0eeb57bda81b3c0 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
@@ -3,7 +3,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 target triple = "x86_64-unknown-linux-gnu"
 
 define i8 @load8(ptr %p) {
-  ; CHECK: call void @__dfsan_load_callback(i8 zeroext %[[LABEL:.*]], ptr %p)
+  ; CHECK: call void @__dfsan_load_callback(i8 %[[LABEL:.*]], ptr %p)
   ; CHECK: %a = load i8, ptr %p
   ; CHECK: store i8 %[[LABEL]], ptr @__dfsan_retval_tls
 
@@ -13,7 +13,7 @@ define i8 @load8(ptr %p) {
 
 define void @store8(ptr %p, i8 %a) {
   ; CHECK: store i8 %[[LABEL:.*]], ptr %{{.*}}
-  ; CHECK: call void @__dfsan_store_callback(i8 zeroext %[[LABEL]], ptr %p)
+  ; CHECK: call void @__dfsan_store_callback(i8 %[[LABEL]], ptr %p)
   ; CHECK: store i8 %a, ptr %p
 
   store i8 %a, ptr %p
@@ -21,7 +21,7 @@ define void @store8(ptr %p, i8 %a) {
 }
 
 define i1 @cmp(i8 %a, i8 %b) {
-  ; CHECK: call void @__dfsan_cmp_callback(i8 zeroext %[[CMPLABEL:.*]])
+  ; CHECK: call void @__dfsan_cmp_callback(i8 %[[CMPLABEL:.*]])
   ; CHECK: %c = icmp ne i8 %a, %b
   ; CHECK: store i8 %[[CMPLABEL]], ptr @__dfsan_retval_tls
 
@@ -29,11 +29,11 @@ define i1 @cmp(i8 %a, i8 %b) {
   ret i1 %c
 }
 
-; CHECK: declare void @__dfsan_load_callback(i8 zeroext, ptr)
-; CHECK: declare void @__dfsan_store_callback(i8 zeroext, ptr)
+; CHECK: declare void @__dfsan_load_callback(i8, ptr)
+; CHECK: declare void @__dfsan_store_callback(i8, ptr)
 ; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
-; CHECK: declare void @__dfsan_cmp_callback(i8 zeroext)
-; CHECK: declare void @__dfsan_conditional_callback(i8 zeroext)
-; CHECK: declare void @__dfsan_conditional_callback_origin(i8 zeroext, i32 zeroext)
-; CHECK: declare void @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32 zeroext, ptr)
-; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8 zeroext, i32 zeroext, ptr, i32 zeroext, ptr)
+; CHECK: declare void @__dfsan_cmp_callback(i8)
+; CHECK: declare void @__dfsan_conditional_callback(i8)
+; CHECK: declare void @__dfsan_conditional_callback_origin(i8, i32)
+; CHECK: declare void @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8, i32, ptr, i32, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll b/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
index 9e9c1bd0fdbdc15..abe7eb3c4801d0f 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
@@ -1,9 +1,36 @@
-; Test extensions of arguments to instrumented function.
+; Test extensions of arguments to instrumented functions.
 ;
-; RUN: opt -passes='dfsan' -mtriple=s390x-unknown-linux -S %s | FileCheck %s
+; RUN: opt -passes='dfsan' -mtriple=x86_64-unknown-linux-gnu -S %s | FileCheck %s
+; RUN: opt -passes='dfsan' -mtriple=s390x-unknown-linux -S %s | FileCheck %s --check-prefix=SYSTEMZ
 
 define void @fun() {
   ret void
 }
 
-; CHECK: declare void @__dfsan_mem_shadow_origin_conditional_exchange(i8 zeroext, ptr, ptr, ptr, i64)
+
+; CHECK: declare void @__dfsan_load_callback(i8, ptr)
+; CHECK: declare void @__dfsan_store_callback(i8, ptr)
+; CHECK: declare void @__dfsan_cmp_callback(i8)
+; CHECK: declare void @__dfsan_conditional_callback(i8)
+; CHECK: declare void @__dfsan_conditional_callback_origin(i8, i32)
+; CHECK: declare void @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8, i32, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_set_label(i8, i32, ptr, i64)
+; CHECK: declare zeroext i32 @__dfsan_chain_origin(i32)
+; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8, i32)
+; CHECK: declare void @__dfsan_mem_shadow_origin_conditional_exchange(i8, ptr, ptr, ptr, i64)
+; CHECK: declare void @__dfsan_maybe_store_origin(i8, ptr, i64, i32)
+
+; SYSTEMZ: declare void @__dfsan_load_callback(i8 zeroext, ptr)
+; SYSTEMZ: declare void @__dfsan_store_callback(i8 zeroext, ptr)
+; SYSTEMZ: declare void @__dfsan_cmp_callback(i8 zeroext)
+; SYSTEMZ: declare void @__dfsan_conditional_callback(i8 zeroext)
+; SYSTEMZ: declare void @__dfsan_conditional_callback_origin(i8 zeroext, i32 zeroext)
+; SYSTEMZ: declare void @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32 zeroext, ptr)
+; SYSTEMZ: declare void @__dfsan_reaches_function_callback_origin(i8 zeroext, i32 zeroext, ptr, i32 zeroext, ptr)
+; SYSTEMZ: declare void @__dfsan_set_label(i8 zeroext, i32 zeroext, ptr, i64)
+; SYSTEMZ: declare zeroext i32 @__dfsan_chain_origin(i32 zeroext)
+; SYSTEMZ: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8 zeroext, i32 zeroext)
+; SYSTEMZ: declare void @__dfsan_mem_shadow_origin_conditional_exchange(i8 zeroext, ptr, ptr, ptr, i64)
+; SYSTEMZ: declare void @__dfsan_maybe_store_origin(i8 zeroext, ptr, i64, i32 zeroext)
+
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll b/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
index a6f6f717a69fa70..c7319b5697cf7f8 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
@@ -116,7 +116,7 @@ define void @call_custom_without_ret(i32 %a, i32 %b) {
   ; CHECK: [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: call void @__dfso_custom_without_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], i32 zeroext [[AO]], i32 zeroext [[BO]])
+  ; CHECK: call void @__dfso_custom_without_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], i32 [[AO]], i32 [[BO]])
   ; CHECK-NEXT: ret void
 
   call void @custom_without_ret(i32 %a, i32 %b)
@@ -131,7 +131,7 @@ define i32 @call_custom_with_ret(i32 %a, i32 %b) {
   ; CHECK: %labelreturn = alloca i8, align 1
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: {{.*}} = call i32 @__dfso_custom_with_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 zeroext [[AO]], i32 zeroext [[BO]], ptr %originreturn)
+  ; CHECK: {{.*}} = call i32 @__dfso_custom_with_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr %originreturn)
   ; CHECK: [[RS:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RO:%.*]] = load i32, ptr %originreturn, align 4
   ; CHECK: store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -155,7 +155,7 @@ define void @call_custom_varg_without_ret(i32 %a, i32 %b) {
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
   ; CHECK: store i32 [[AO]], ptr [[VO0]], align 4
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
-  ; CHECK: call void (i32, i32, i8, i8, ptr, i32, i32, ptr, ...) @__dfso_custom_varg_without_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr [[VS0]], i32 zeroext [[AO]], i32 zeroext [[BO]], ptr [[VO0]], i32 %a)
+  ; CHECK: call void (i32, i32, i8, i8, ptr, i32, i32, ptr, ...) @__dfso_custom_varg_without_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], ptr [[VS0]], i32 [[AO]], i32 [[BO]], ptr [[VO0]], i32 %a)
   ; CHECK-NEXT: ret void
 
   call void (i32, i32, ...) @custom_varg_without_ret(i32 %a, i32 %b, i32 %a)
@@ -178,7 +178,7 @@ define i32 @call_custom_varg_with_ret(i32 %a, i32 %b) {
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
   ; CHECK: store i32 [[BO]], ptr [[VO0]], align 4
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
-  ; CHECK: {{.*}} = call i32 (i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...) @__dfso_custom_varg_with_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr [[VS0]], ptr %labelreturn, i32 zeroext [[AO]], i32 zeroext [[BO]], ptr [[VO0]], ptr %originreturn, i32 %b)
+  ; CHECK: {{.*}} = call i32 (i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...) @__dfso_custom_varg_with_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], ptr [[VS0]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr [[VO0]], ptr %originreturn, i32 %b)
   ; CHECK: [[RS:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RO:%.*]] = load i32, ptr %originreturn, align 4
   ; CHECK: store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -196,7 +196,7 @@ define i32 @call_custom_cb_with_ret(i32 %a, i32 %b) {
   ; CHECK: %labelreturn = alloca i8, align 1
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: {{.*}} = call i32 @__dfso_custom_cb_with_ret(ptr @cb_with_ret.dfsan, i32 %a, i32 %b, i8 zeroext 0, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 zeroext 0, i32 zeroext [[AO]], i32 zeroext [[BO]], ptr %originreturn)
+  ; CHECK: {{.*}} = call i32 @__dfso_custom_cb_with_ret(ptr @cb_with_ret.dfsan, i32 %a, i32 %b, i8 0, i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 0, i32 [[AO]], i32 [[BO]], ptr %originreturn)
   ; CHECK: [[RS:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RO:%.*]] = load i32, ptr %originreturn, align 4
   ; CHECK: store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -212,7 +212,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
   ; CHECK: [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: call void @__dfso_custom_cb_without_ret(ptr @cb_without_ret.dfsan, i32 %a, i32 %b, i8 zeroext 0, i8 zeroext [[AS]], i8 zeroext [[BS]], i32 zeroext 0, i32 zeroext [[AO]], i32 zeroext [[BO]])
+  ; CHECK: call void @__dfso_custom_cb_without_ret(ptr @cb_without_ret.dfsan, i32 %a, i32 %b, i8 0, i8 [[AS]], i8 [[BS]], i32 0, i32 [[AO]], i32 [[BO]])
   ; CHECK-NEXT: ret void
 
   call void @custom_cb_without_ret(ptr @cb_without_ret, i32 %a, i32 %b)
@@ -230,7 +230,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  [[AO:%.*]]  = load i32, ptr @__dfsan_arg_origin_tls, align 4
 ; CHECK-NEXT:  [[BS:%.*]]  = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[AS:%.*]]  = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  call void @__dfso_custom_without_ret(i32 %0, i32 %1, i8 zeroext [[AS]], i8 zeroext [[BS]], i32 zeroext [[AO]], i32 zeroext [[BO]])
+; CHECK-NEXT:  call void @__dfso_custom_without_ret(i32 %0, i32 %1, i8 [[AS]], i8 [[BS]], i32 [[AO]], i32 [[BO]])
 ; CHECK-NEXT:  ret void
 
 ; CHECK: define linkonce_odr i32 @"dfso$custom_with_ret"(i32 %0, i32 %1)
@@ -240,7 +240,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  %labelreturn = alloca i8, align 1
 ; CHECK-NEXT:  [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_with_ret(i32 %0, i32 %1, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 zeroext [[AO]], i32 zeroext [[BO]], ptr %originreturn)
+; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_with_ret(i32 %0, i32 %1, i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr %originreturn)
 ; CHECK-NEXT:  [[RS:%.*]] = load i8, ptr %labelreturn, align 1
 ; CHECK-NEXT:  [[RO:%.*]] = load i32, ptr %originreturn, align 4
 ; CHECK-NEXT:  store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -264,7 +264,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 4), align 2
 ; CHECK-NEXT:  [[AS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[CS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_cb_with_ret(ptr %0, i32 %1, i32 %2, i8 zeroext [[CS]], i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 zeroext [[CO]], i32 zeroext [[AO]], i32 zeroext [[BO]], ptr %originreturn)
+; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_cb_with_ret(ptr %0, i32 %1, i32 %2, i8 [[CS]], i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 [[CO]], i32 [[AO]], i32 [[BO]], ptr %originreturn)
 ; CHECK-NEXT:  [[RS:%.*]] = load i8, ptr %labelreturn, align 1
 ; CHECK-NEXT:  [[RO:%.*]] = load i32, ptr %originreturn, align 4
 ; CHECK-NEXT:  store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -278,17 +278,17 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 4), align 2
 ; CHECK-NEXT:  [[AS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[CS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  call void @__dfso_custom_cb_without_ret(ptr %0, i32 %1, i32 %2, i8 zeroext [[CS]], i8 zeroext [[AS]], i8 zeroext [[BS]], i32 zeroext [[CO]], i32 zeroext [[AO]], i32 zeroext [[BO]])
+; CHECK-NEXT:  call void @__dfso_custom_cb_without_ret(ptr %0, i32 %1, i32 %2, i8 [[CS]], i8 [[AS]], i8 [[BS]], i32 [[CO]], i32 [[AO]], i32 [[BO]])
 ; CHECK-NEXT:  ret void
 
-; CHECK: declare void @__dfso_custom_without_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, i32 zeroext, i32 zeroext)
+; CHECK: declare void @__dfso_custom_without_ret(i32, i32, i8, i8, i32, i32)
 
-; CHECK: declare i32 @__dfso_custom_with_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr, i32 zeroext, i32 zeroext, ptr)
+; CHECK: declare i32 @__dfso_custom_with_ret(i32, i32, i8, i8, ptr, i32, i32, ptr)
 
-; CHECK: declare i32 @__dfso_custom_cb_with_ret(ptr, i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr, i32 zeroext, i32 zeroext, i32 zeroext, ptr)
+; CHECK: declare i32 @__dfso_custom_cb_with_ret(ptr, i32, i32, i8, i8, i8, ptr, i32, i32, i32, ptr)
 
-; CHECK: declare void @__dfso_custom_cb_without_ret(ptr, i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i32 zeroext, i32 zeroext, i32 zeroext)
+; CHECK: declare void @__dfso_custom_cb_without_ret(ptr, i32, i32, i8, i8, i8, i32, i32, i32)
 
-; CHECK: declare void @__dfso_custom_varg_without_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr, i32 zeroext, i32 zeroext, ptr, ...)
+; CHECK: declare void @__dfso_custom_varg_without_ret(i32, i32, i8, i8, ptr, i32, i32, ptr, ...)
 
-; CHECK: declare i32 @__dfso_custom_varg_with_ret(i32 zeroext, i32 zeroext, i8 zeroext, i8 zeroext, ptr, ptr, i32 zeroext, i32 zeroext, ptr, ptr, ...)
+; CHECK: declare i32 @__dfso_custom_varg_with_ret(i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll b/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
index 1917bcc7be08fd1..654696833a67102 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
@@ -26,4 +26,4 @@ define void @call() {
   ret void
 }
 
-; CHECK-LABEL: @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32 zeroext, ptr)
+; CHECK-LABEL: @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
index 333f1e45fb2df1d..78e8d84675e3940 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
@@ -1,12 +1,16 @@
 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -passes=dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt | FileCheck %s
+; RUN: opt -mtriple=s390x-unknown-linux < %s -passes=dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt \
+; RUN:   | FileCheck %s --check-prefix=SYSTEMZ
 
-; REQUIRES: x86-registered-target
+; REQUIRES: x86-registered-target, systemz-registered-target
 
 ; Test that the custom abi marks shadow parameters as zero extended.
 
 define i32 @m() {
   ; CHECK-LABEL: @m.dfsan
-  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i8 zeroext 0, ptr %{{.*}})
+  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i8 0, ptr %{{.*}})
+  ; SYSTEMZ-LABEL: @m.dfsan
+  ; SYSTEMZ: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i8 zeroext 0, ptr %{{.*}})
 
 entry:
   %call = call zeroext i16 @dfsan_get_label(i64 signext 56)
@@ -16,7 +20,9 @@ entry:
 
 define i32 @k() {
   ; CHECK-LABEL: @k.dfsan
-  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
+  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i8 {{.*}}, i8 {{.*}}, ptr %{{.*}})
+  ; SYSTEMZ-LABEL: @k.dfsan
+  ; SYSTEMZ: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
 
 entry:
   %call = call zeroext i16 @k2(i64 signext 56, i64 signext 67)
@@ -26,7 +32,9 @@ entry:
 
 define i32 @k3() {
   ; CHECK-LABEL: @k3.dfsan
-  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
+  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i8 {{.*}}, i8 {{.*}}, i8 {{.*}}, i8 {{.*}}, ptr %{{.*}})
+  ; SYSTEMZ-LABEL: @k3.dfsan
+  ; SYSTEMZ: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
 
 entry:
   %call = call zeroext i16 @k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89)
@@ -36,17 +44,26 @@ entry:
 
 declare zeroext i16 @dfsan_get_label(i64 signext)
 ; CHECK-LABEL: @"dfsw$dfsan_get_label"
-; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 %1, ptr %{{.*}})
+; SYSTEMZ-LABEL: @"dfsw$dfsan_get_label"
+; SYSTEMZ: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
 
 declare zeroext i16 @k2(i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k2"
-; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, ptr %{{.*}})
+; SYSTEMZ-LABEL: @"dfsw$k2"
+; SYSTEMZ: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 declare zeroext i16 @k4(i64 signext, i64 signext, i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k4"
-; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, ptr %{{.*}})
+; SYSTEMZ-LABEL: @"dfsw$k4"
+; SYSTEMZ: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 
-; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8 zeroext, ptr)
-; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8 zeroext, i8 zeroext, ptr)
-; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8, ptr)
+; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8, i8, ptr)
+; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8, i8, i8, i8, ptr)
+; SYSTEMZ: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8 zeroext, ptr)
+; SYSTEMZ: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8 zeroext, i8 zeroext, ptr)
+; SYSTEMZ: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll b/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
index 9b4a35005a14210..7ac0af121d64e04 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
@@ -130,7 +130,7 @@ define {i1, i1} @load_struct(ptr %p) {
   ; EVENT_CALLBACKS: [[OL0:%.*]] = or i8
   ; EVENT_CALLBACKS: [[OL1:%.*]] = or i8 [[OL0]],
   ; EVENT_CALLBACKS: [[S0:%.*]] = insertvalue { i8, i8 } undef, i8 [[OL1]], 0
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[OL1]]
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[OL1]]
 
   %s = load {i1, i1}, ptr %p
   ret {i1, i1} %s
@@ -149,7 +149,7 @@ define void @store_struct(ptr %p, {i1, i1} %s) {
 
   ; EVENT_CALLBACKS: @store_struct.dfsan
   ; EVENT_CALLBACKS: [[OL:%.*]] = or i8
-  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 zeroext [[OL]]
+  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 [[OL]]
 
   ; COMBINE_STORE_PTR: @store_struct.dfsan
   ; COMBINE_STORE_PTR: [[PL:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]

>From 81e71759bf6be0e0f49300edc37d6b5eed499d12 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <Jonas.Paulsson2 at ibm.com>
Date: Mon, 28 Sep 2026 11:24:14 +0200
Subject: [PATCH 4/7] Handle i8 extensions with a new getExtAttrForI8Param()
 hook.

---
 .../include/llvm/Analysis/TargetLibraryInfo.h |  6 ++
 .../Instrumentation/DataFlowSanitizer.cpp     | 95 +++++++++++--------
 .../DataFlowSanitizer/abilist.ll              | 18 ++--
 .../DataFlowSanitizer/abilist_aggregate.ll    | 22 ++---
 .../DataFlowSanitizer/array.ll                |  8 +-
 .../DataFlowSanitizer/basic.ll                | 12 +--
 .../DataFlowSanitizer/callback.ll             | 20 ++--
 .../instrumented-args-exts.ll                 | 22 ++---
 .../DataFlowSanitizer/origin_abilist.ll       | 32 +++----
 .../DataFlowSanitizer/reaches_function.ll     |  2 +-
 .../DataFlowSanitizer/shadow-args-zext.ll     | 37 ++------
 .../DataFlowSanitizer/struct.ll               |  4 +-
 12 files changed, 139 insertions(+), 139 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 19c251f592608a7..b006cceb4290861 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -523,6 +523,12 @@ class TargetLibraryInfo {
     return ShouldZExtBoolParam ? Attribute::ZExt : Attribute::None;
   }
 
+  static Attribute::AttrKind getExtAttrForI8Param(bool Signed = true) {
+    // Return the extension attributes here even though nothing special is
+    // done in case any target needs something different in the future.
+    return Signed ? Attribute::SExt : Attribute::ZExt;
+  }
+
   static Attribute::AttrKind getExtAttrForI32Param(const Triple &T,
                                                    bool Signed = true) {
     bool ShouldExtI32Param, ShouldExtI32Return;
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 8aa3803ea6be5a7..bb654db6d1bb0f5 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -1070,10 +1070,11 @@ void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &I,
     Value *CondOrigin = getOrigin(Condition);
     CI = IRB.CreateCall(DFS.DFSanConditionalCallbackOriginFn,
                         {CondShadow, CondOrigin});
+    CI->maybeAddParamAttr(1, TLI.getExtAttrForI32Param(/*Signed=*/false));
   } else {
     CI = IRB.CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
   }
-  CI->maybeAddParamAttr(0, TLI.getExtAttrForI32Param(/*Signed=*/false));
+  CI->maybeAddParamAttr(0, TLI.getExtAttrForI8Param(/*Signed=*/false));
 }
 
 void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
@@ -1103,21 +1104,20 @@ void DFSanFunction::addReachesFunctionCallbacksIfEnabled(IRBuilder<> &IRB,
   CallInst *CB;
   std::vector<Value *> args;
 
-  Attribute::AttrKind ParamExtAttr =
+  Attribute::AttrKind I32ParamExtAttr =
       TLI.getExtAttrForI32Param(/*Signed=*/false);
   if (DFS.shouldTrackOrigins()) {
     Value *DataOrigin = getOrigin(Data);
     args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
     CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn, args);
-    CB->maybeAddParamAttr(0, ParamExtAttr);
-    CB->maybeAddParamAttr(1, ParamExtAttr);
-    CB->maybeAddParamAttr(3, ParamExtAttr);
+    CB->maybeAddParamAttr(1, I32ParamExtAttr);
+    CB->maybeAddParamAttr(3, I32ParamExtAttr);
   } else {
     args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
     CB = IRB.CreateCall(DFS.DFSanReachesFunctionCallbackFn, args);
-    CB->maybeAddParamAttr(0, ParamExtAttr);
-    CB->maybeAddParamAttr(2, ParamExtAttr);
+    CB->maybeAddParamAttr(2, I32ParamExtAttr);
   }
+  CB->maybeAddParamAttr(0, TLI.getExtAttrForI8Param(/*Signed=*/false));
   CB->setDebugLoc(dbgloc);
 }
 
@@ -1357,8 +1357,11 @@ DataFlowSanitizer::buildWrapperFunction(Function *F, StringRef NewFName,
 // Initialize DataFlowSanitizer runtime functions and declare them in the module
 void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
   LLVMContext &C = M.getContext();
-  Attribute::AttrKind ParamExtAttr = TargetLibraryInfo::getExtAttrForI32Param(
-      M.getTargetTriple(), /*Signed=*/false);
+  Attribute::AttrKind I8ParamExtAttr =
+      TargetLibraryInfo::getExtAttrForI8Param(/*Signed=*/false);
+  Attribute::AttrKind I32ParamExtAttr =
+      TargetLibraryInfo::getExtAttrForI32Param(M.getTargetTriple(),
+                                               /*Signed=*/false);
   {
     AttributeList AL;
     AL = AL.addFnAttribute(C, Attribute::NoUnwind);
@@ -1383,8 +1386,8 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
       "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, I32ParamExtAttr);
     DFSanSetLabelFn =
         Mod->getOrInsertFunction("__dfsan_set_label", DFSanSetLabelFnTy, AL);
   }
@@ -1394,15 +1397,15 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
                                                   DFSanVarargWrapperFnTy);
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I32ParamExtAttr);
     AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
     DFSanChainOriginFn = Mod->getOrInsertFunction("__dfsan_chain_origin",
                                                   DFSanChainOriginFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, I32ParamExtAttr);
     AL = AL.addRetAttribute(M.getContext(), Attribute::ZExt);
     DFSanChainOriginIfTaintedFn = Mod->getOrInsertFunction(
         "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
@@ -1415,7 +1418,7 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
 
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
     DFSanMemShadowOriginConditionalExchangeFn = Mod->getOrInsertFunction(
         "__dfsan_mem_shadow_origin_conditional_exchange",
         DFSanMemShadowOriginConditionalExchangeFnTy, AL);
@@ -1423,8 +1426,8 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
 
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 3, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 3, I32ParamExtAttr);
     DFSanMaybeStoreOriginFn = Mod->getOrInsertFunction(
         "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
   }
@@ -1476,17 +1479,20 @@ void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) {
 
 // Initializes event callback functions and declare them in the module
 void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
-  Attribute::AttrKind ParamExtAttr = TargetLibraryInfo::getExtAttrForI32Param(
-      M.getTargetTriple(), /*Signed=*/false);
+  Attribute::AttrKind I8ParamExtAttr =
+      TargetLibraryInfo::getExtAttrForI8Param(/*Signed=*/false);
+  Attribute::AttrKind I32ParamExtAttr =
+      TargetLibraryInfo::getExtAttrForI32Param(M.getTargetTriple(),
+                                               /*Signed=*/false);
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
     DFSanLoadCallbackFn = Mod->getOrInsertFunction(
         "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
     DFSanStoreCallbackFn = Mod->getOrInsertFunction(
         "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
   }
@@ -1494,37 +1500,37 @@ void DataFlowSanitizer::initializeCallbackFunctions(Module &M) {
       "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
     DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback",
                                                   DFSanCmpCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
     DFSanConditionalCallbackFn = Mod->getOrInsertFunction(
         "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, I32ParamExtAttr);
     DFSanConditionalCallbackOriginFn =
         Mod->getOrInsertFunction("__dfsan_conditional_callback_origin",
                                  DFSanConditionalCallbackOriginFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 2, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 2, I32ParamExtAttr);
     DFSanReachesFunctionCallbackFn =
         Mod->getOrInsertFunction("__dfsan_reaches_function_callback",
                                  DFSanReachesFunctionCallbackFnTy, AL);
   }
   {
     AttributeList AL;
-    AL = AL.maybeAddParamAttribute(M.getContext(), 0, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 1, ParamExtAttr);
-    AL = AL.maybeAddParamAttribute(M.getContext(), 3, ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 0, I8ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 1, I32ParamExtAttr);
+    AL = AL.maybeAddParamAttribute(M.getContext(), 3, I32ParamExtAttr);
     DFSanReachesFunctionCallbackOriginFn =
         Mod->getOrInsertFunction("__dfsan_reaches_function_callback_origin",
                                  DFSanReachesFunctionCallbackOriginFnTy, AL);
@@ -2488,7 +2494,7 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) {
     Value *Addr = LI.getPointerOperand();
     CallInst *CI =
         IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
-    CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
+    CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI8Param(/*Signed=*/false));
   }
 
   IRBuilder<> IRB(AfterLi->getParent(), AfterLi);
@@ -2746,7 +2752,7 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) {
     Value *Addr = SI.getPointerOperand();
     CallInst *CI =
         IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
-    CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
+    CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI8Param(/*Signed=*/false));
   }
 }
 
@@ -2811,7 +2817,7 @@ void DFSanVisitor::visitCmpInst(CmpInst &CI) {
     CallInst *CallI =
         IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
     CallI->maybeAddParamAttr(0,
-                             DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
+                             DFSF.TLI.getExtAttrForI8Param(/*Signed=*/false));
   }
 }
 
@@ -3118,7 +3124,9 @@ void DFSanVisitor::addOriginArguments(Function &F, CallBase &CB,
 }
 
 bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
-  Attribute::AttrKind ParamExtAttr =
+  Attribute::AttrKind I8ParamExtAttr =
+      DFSF.TLI.getExtAttrForI8Param(/*Signed=*/false);
+  Attribute::AttrKind I32ParamExtAttr =
       DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false);
   IRBuilder<> IRB(&CB);
   switch (DFSF.DFS.getWrapperKind(&F)) {
@@ -3161,17 +3169,20 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
 
       // Ensure all narrow integer arguments (both original and added
       // shadow/origin) have an extension attribute on the function
-      // declaration. If none is present, add ZExt as all DFSan args are
-      // unsigned. TODO: Avoid getting here with missing attributes in the
-      // first place (use TLI/emitLibFunc()?).
+      // declaration. If none is present, add the right attribute for zero
+      // extend as all DFSan args are unsigned. TODO: Avoid getting here with
+      // missing attributes in the first place (use TLI/emitLibFunc()?).
       for (unsigned I = 0, E = CustomFn->arg_size(); I < E; ++I) {
         Type *ParamTy = CustomFn->getFunctionType()->getParamType(I);
         if (ParamTy->isIntegerTy() && ParamTy->getIntegerBitWidth() <= 32) {
-          if (ParamExtAttr != Attribute::AttrKind::None &&
+          Attribute::AttrKind IntArgAttr = ParamTy->getIntegerBitWidth() == 8
+                                               ? I8ParamExtAttr
+                                               : I32ParamExtAttr;
+          if (IntArgAttr != Attribute::AttrKind::None &&
               !CustomFn->hasParamAttribute(I, Attribute::ZExt) &&
               !CustomFn->hasParamAttribute(I, Attribute::SExt) &&
               !CustomFn->hasParamAttribute(I, Attribute::NoExt)) {
-            CustomFn->addParamAttr(I, ParamExtAttr);
+            CustomFn->addParamAttr(I, IntArgAttr);
           }
         }
       }
@@ -3222,13 +3233,13 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
       const unsigned ArgNo = ShadowArgStart + N;
       if (CustomCI->getArgOperand(ArgNo)->getType() ==
           DFSF.DFS.PrimitiveShadowTy)
-        CustomCI->maybeAddParamAttr(ArgNo, ParamExtAttr);
+        CustomCI->maybeAddParamAttr(ArgNo, I8ParamExtAttr);
 
       if (ShouldTrackOrigins) {
         const unsigned OriginArgNo = OriginArgStart + N;
         if (CustomCI->getArgOperand(OriginArgNo)->getType() ==
             DFSF.DFS.OriginTy)
-          CustomCI->maybeAddParamAttr(OriginArgNo, ParamExtAttr);
+          CustomCI->maybeAddParamAttr(OriginArgNo, I32ParamExtAttr);
       }
     }
 
@@ -3383,7 +3394,7 @@ void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
       {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
        ExpectedPtr, DesiredPtr,
        NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
-  CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false));
+  CI->maybeAddParamAttr(0, DFSF.TLI.getExtAttrForI8Param(/*Signed=*/false));
 }
 
 void DFSanVisitor::visitCallBase(CallBase &CB) {
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll b/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
index d61d65381837856..579f8051a67d008 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/abilist.ll
@@ -33,13 +33,13 @@ define void @f(i32 %x) {
   ; CHECK: %[[LABELVA1:.*]] = alloca [2 x i8]
   ; CHECK: %[[LABELRETURN:.*]] = alloca i8
 
-  ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i8 0, i8 0)
+  ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i8 zeroext 0, i8 zeroext 0)
   call void @custom1(i32 1, i32 2)
 
-  ; CHECK: call i32 @__dfsw_custom2(i32 1, i32 2, i8 0, i8 0, ptr %[[LABELRETURN]])
+  ; CHECK: call i32 @__dfsw_custom2(i32 1, i32 2, i8 zeroext 0, i8 zeroext 0, ptr %[[LABELRETURN]])
   call i32 @custom2(i32 1, i32 2)
 
-  ; CHECK: call void @__dfsw_customcb({{.*}} @cb.dfsan, i8 0)
+  ; CHECK: call void @__dfsw_customcb({{.*}} @cb.dfsan, i8 zeroext 0)
   call void @customcb(ptr @cb)
 
   ; CHECK: %[[LABELVA1_0:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA1]], i32 0, i32 0
@@ -47,13 +47,13 @@ define void @f(i32 %x) {
   ; CHECK: %[[LABELVA1_1:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA1]], i32 0, i32 1
   ; CHECK: store i8 %{{.*}}, ptr %[[LABELVA1_1]]
   ; CHECK: %[[LABELVA1_0A:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA1]], i32 0, i32 0
-  ; CHECK: call void (i32, i8, ptr, ...) @__dfsw_custom3(i32 1, i8 0, ptr %[[LABELVA1_0A]], i32 2, i32 %{{.*}})
+  ; CHECK: call void (i32, i8, ptr, ...) @__dfsw_custom3(i32 1, i8 zeroext 0, ptr %[[LABELVA1_0A]], i32 2, i32 %{{.*}})
 
   call void (i32, ...) @custom3(i32 1, i32 2, i32 %x)
 
   ; CHECK: %[[LABELVA2_0:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA2]], i32 0, i32 0
   ; CHECK: %[[LABELVA2_0A:.*]] = getelementptr inbounds nuw [2 x i8], ptr %[[LABELVA2]], i32 0, i32 0
-  ; CHECK: call i32 (i32, i8, ptr, ptr, ...) @__dfsw_custom4(i32 1, i8 0, ptr %[[LABELVA2_0A]], ptr %[[LABELRETURN]], i32 2, i32 3)
+  ; CHECK: call i32 (i32, i8, ptr, ptr, ...) @__dfsw_custom4(i32 1, i8 zeroext 0, ptr %[[LABELVA2_0A]], ptr %[[LABELRETURN]], i32 2, i32 3)
   call i32 (i32, ...) @custom4(i32 1, i32 2, i32 3)
 
   ret void
@@ -88,8 +88,8 @@ define ptr @g(i32) {
 
 ; CHECK: define linkonce_odr i32 @"dfsw$custom4"(i32 %0, ...)
 
-; CHECK: declare void @__dfsw_custom1(i32, i32, i8, i8)
-; CHECK: declare i32 @__dfsw_custom2(i32, i32, i8, i8, ptr)
+; CHECK: declare void @__dfsw_custom1(i32, i32, i8 zeroext, i8 zeroext)
+; CHECK: declare i32 @__dfsw_custom2(i32, i32, i8 zeroext, i8 zeroext, ptr)
 
-; CHECK: declare void @__dfsw_custom3(i32, i8, ptr, ...)
-; CHECK: declare i32 @__dfsw_custom4(i32, i8, ptr, ptr, ...)
+; CHECK: declare void @__dfsw_custom3(i32, i8 zeroext, ptr, ...)
+; CHECK: declare i32 @__dfsw_custom4(i32, i8 zeroext, ptr, ptr, ...)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll b/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
index 14d7153e8b2aecc..8308e38f0b359d6 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/abilist_aggregate.ll
@@ -76,7 +76,7 @@ define {i1, i7} @call_custom_with_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i8 [[A01]], i8 [[B01]], ptr %labelreturn)
+  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -97,7 +97,7 @@ define void @call_custom_without_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i8 [[A01]], i8 [[B01]])
+  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]])
 
   call void @custom_without_ret({i32, i1} %a, [2 x i7] %b)
   ret void
@@ -117,7 +117,7 @@ define void @call_custom_varg({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
   ; CHECK: store i8 [[B01]], ptr [[V0]], align 1
   ; CHECK: [[V:%.*]] = getelementptr inbounds nuw [1 x i8], ptr %labelva, i32 0, i32 0
-  ; CHECK: call void ({ i32, i1 }, i8, ptr, ...) @__dfsw_custom_varg({ i32, i1 } %a, i8 [[A01]], ptr [[V]], [2 x i7] %b)
+  ; CHECK: call void ({ i32, i1 }, i8, ptr, ...) @__dfsw_custom_varg({ i32, i1 } %a, i8 zeroext [[A01]], ptr [[V]], [2 x i7] %b)
 
   call void ({i32, i1}, ...) @custom_varg({i32, i1} %a, [2 x i7] %b)
   ret void
@@ -134,7 +134,7 @@ define {i1, i7} @call_custom_cb({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i8 0, i8 [[A01]], i8 [[B01]], ptr %labelreturn)
+  ; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i8 zeroext 0, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -189,7 +189,7 @@ define ptr @ret_custom() {
 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr %0, { i32, i1 } %1, [2 x i7] %2, i8 [[CB]], i8 [[A01]], i8 [[B01]], ptr %labelreturn)
+; CHECK: [[R:%.*]]  = call { i1, i7 } @__dfsw_custom_cb(ptr %0, { i32, i1 } %1, [2 x i7] %2, i8 zeroext [[CB]], i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
 ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
 ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
 ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -206,7 +206,7 @@ define {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i8 [[A01]], i8 [[B01]], ptr %labelreturn)
+  ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)
   ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0
   ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1
@@ -229,7 +229,7 @@ define void @custom_without_ret({i32, i1} %a, [2 x i7] %b) {
   ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0
   ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1
   ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]
-  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i8 [[A01]], i8 [[B01]])
+  ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]])
   ; CHECK: ret
   ret void
 }
@@ -241,8 +241,8 @@ define void @custom_varg({i32, i1} %a, ...) {
   ret void
 }
 
-; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8, i8, ptr)
-; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8, i8)
-; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8, ptr, ...)
+; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext)
+; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8 zeroext, ptr, ...)
 
-; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8, i8, i8, ptr)
+; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8 zeroext, i8 zeroext, i8 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/array.ll b/llvm/test/Instrumentation/DataFlowSanitizer/array.ll
index 1214bf627c1c40d..14468c18ca201b2 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/array.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/array.ll
@@ -78,7 +78,7 @@ define [1 x i1] @load_array1(ptr %p) {
 
   ; EVENT_CALLBACKS: @load_array1.dfsan
   ; EVENT_CALLBACKS: [[L:%.*]] = or i8
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[L]], ptr {{.*}})
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[L]], ptr {{.*}})
 
   ; FAST: @load_array1.dfsan
   ; FAST: [[P:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
@@ -104,7 +104,7 @@ define [2 x i1] @load_array2(ptr %p) {
   ; EVENT_CALLBACKS: @load_array2.dfsan
   ; EVENT_CALLBACKS: [[O1:%.*]] = or i8
   ; EVENT_CALLBACKS: [[O2:%.*]] = or i8 [[O1]]
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[O2]], ptr {{.*}})
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[O2]], ptr {{.*}})
 
   ; FAST: @load_array2.dfsan
   ; FAST: [[P:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
@@ -131,7 +131,7 @@ define [4 x i1] @load_array4(ptr %p) {
   ; EVENT_CALLBACKS: [[O1:%.*]] = or i32 [[O0]]
   ; EVENT_CALLBACKS: [[O2:%.*]] = trunc i32 [[O1]] to i8
   ; EVENT_CALLBACKS: [[O3:%.*]] = or i8 [[O2]]
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[O3]], ptr {{.*}})
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[O3]], ptr {{.*}})
 
   ; FAST: @load_array4.dfsan
   ; FAST: [[T:%.*]] = trunc i32 {{.*}} to i8
@@ -193,7 +193,7 @@ define void @store_zero_array(ptr %p) {
 define void @store_array2([2 x i1] %a, ptr %p) {
   ; EVENT_CALLBACKS: @store_array2.dfsan
   ; EVENT_CALLBACKS: [[E12:%.*]] = or i8
-  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 [[E12]], ptr %p)
+  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 zeroext [[E12]], ptr %p)
 
   ; FAST: @store_array2.dfsan
   ; FAST: [[S:%.*]] = load [2 x i8], ptr @__dfsan_arg_tls, align [[ALIGN:2]]
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll b/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
index 3ccf0b5f70ad66c..ff12b4b80644ad7 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/basic.ll
@@ -27,10 +27,10 @@ define void @store(ptr %p) {
   ret void
 }
 
-; CHECK: declare void @__dfsan_load_callback(i8, ptr)
-; CHECK: declare void @__dfsan_store_callback(i8, ptr)
+; CHECK: declare void @__dfsan_load_callback(i8 zeroext, ptr)
+; CHECK: declare void @__dfsan_store_callback(i8 zeroext, ptr)
 ; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
-; CHECK: declare void @__dfsan_cmp_callback(i8)
+; CHECK: declare void @__dfsan_cmp_callback(i8 zeroext)
 
 ; CHECK: ; Function Attrs: nounwind memory(read)
 ; CHECK-NEXT: declare zeroext i8 @__dfsan_union_load(ptr, i64)
@@ -39,10 +39,10 @@ define void @store(ptr %p) {
 ; CHECK-NEXT: declare zeroext i64 @__dfsan_load_label_and_origin(ptr, i64)
 
 ; CHECK: declare void @__dfsan_unimplemented(ptr)
-; CHECK: declare void @__dfsan_set_label(i8, i32, ptr, i64)
+; CHECK: declare void @__dfsan_set_label(i8 zeroext, i32, ptr, i64)
 ; CHECK: declare void @__dfsan_nonzero_label()
 ; CHECK: declare void @__dfsan_vararg_wrapper(ptr)
 ; CHECK: declare zeroext i32 @__dfsan_chain_origin(i32)
-; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8, i32)
+; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8 zeroext, i32)
 ; CHECK: declare void @__dfsan_mem_origin_transfer(ptr, ptr, i64)
-; CHECK: declare void @__dfsan_maybe_store_origin(i8, ptr, i64, i32)
+; CHECK: declare void @__dfsan_maybe_store_origin(i8 zeroext, ptr, i64, i32)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
index 0eeb57bda81b3c0..a499ec934d9fea5 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
@@ -3,7 +3,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 target triple = "x86_64-unknown-linux-gnu"
 
 define i8 @load8(ptr %p) {
-  ; CHECK: call void @__dfsan_load_callback(i8 %[[LABEL:.*]], ptr %p)
+  ; CHECK: call void @__dfsan_load_callback(i8 zeroext %[[LABEL:.*]], ptr %p)
   ; CHECK: %a = load i8, ptr %p
   ; CHECK: store i8 %[[LABEL]], ptr @__dfsan_retval_tls
 
@@ -13,7 +13,7 @@ define i8 @load8(ptr %p) {
 
 define void @store8(ptr %p, i8 %a) {
   ; CHECK: store i8 %[[LABEL:.*]], ptr %{{.*}}
-  ; CHECK: call void @__dfsan_store_callback(i8 %[[LABEL]], ptr %p)
+  ; CHECK: call void @__dfsan_store_callback(i8 zeroext %[[LABEL]], ptr %p)
   ; CHECK: store i8 %a, ptr %p
 
   store i8 %a, ptr %p
@@ -21,7 +21,7 @@ define void @store8(ptr %p, i8 %a) {
 }
 
 define i1 @cmp(i8 %a, i8 %b) {
-  ; CHECK: call void @__dfsan_cmp_callback(i8 %[[CMPLABEL:.*]])
+  ; CHECK: call void @__dfsan_cmp_callback(i8 zeroext %[[CMPLABEL:.*]])
   ; CHECK: %c = icmp ne i8 %a, %b
   ; CHECK: store i8 %[[CMPLABEL]], ptr @__dfsan_retval_tls
 
@@ -29,11 +29,11 @@ define i1 @cmp(i8 %a, i8 %b) {
   ret i1 %c
 }
 
-; CHECK: declare void @__dfsan_load_callback(i8, ptr)
-; CHECK: declare void @__dfsan_store_callback(i8, ptr)
+; CHECK: declare void @__dfsan_load_callback(i8 zeroext, ptr)
+; CHECK: declare void @__dfsan_store_callback(i8 zeroext, ptr)
 ; CHECK: declare void @__dfsan_mem_transfer_callback(ptr, i64)
-; CHECK: declare void @__dfsan_cmp_callback(i8)
-; CHECK: declare void @__dfsan_conditional_callback(i8)
-; CHECK: declare void @__dfsan_conditional_callback_origin(i8, i32)
-; CHECK: declare void @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
-; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8, i32, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_cmp_callback(i8 zeroext)
+; CHECK: declare void @__dfsan_conditional_callback(i8 zeroext)
+; CHECK: declare void @__dfsan_conditional_callback_origin(i8 zeroext, i32)
+; CHECK: declare void @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8 zeroext, i32, ptr, i32, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll b/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
index abe7eb3c4801d0f..1bbeb584f51f8f8 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/instrumented-args-exts.ll
@@ -8,18 +8,18 @@ define void @fun() {
 }
 
 
-; CHECK: declare void @__dfsan_load_callback(i8, ptr)
-; CHECK: declare void @__dfsan_store_callback(i8, ptr)
-; CHECK: declare void @__dfsan_cmp_callback(i8)
-; CHECK: declare void @__dfsan_conditional_callback(i8)
-; CHECK: declare void @__dfsan_conditional_callback_origin(i8, i32)
-; CHECK: declare void @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
-; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8, i32, ptr, i32, ptr)
-; CHECK: declare void @__dfsan_set_label(i8, i32, ptr, i64)
+; CHECK: declare void @__dfsan_load_callback(i8 zeroext, ptr)
+; CHECK: declare void @__dfsan_store_callback(i8 zeroext, ptr)
+; CHECK: declare void @__dfsan_cmp_callback(i8 zeroext)
+; CHECK: declare void @__dfsan_conditional_callback(i8 zeroext)
+; CHECK: declare void @__dfsan_conditional_callback_origin(i8 zeroext, i32)
+; CHECK: declare void @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_reaches_function_callback_origin(i8 zeroext, i32, ptr, i32, ptr)
+; CHECK: declare void @__dfsan_set_label(i8 zeroext, i32, ptr, i64)
 ; CHECK: declare zeroext i32 @__dfsan_chain_origin(i32)
-; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8, i32)
-; CHECK: declare void @__dfsan_mem_shadow_origin_conditional_exchange(i8, ptr, ptr, ptr, i64)
-; CHECK: declare void @__dfsan_maybe_store_origin(i8, ptr, i64, i32)
+; CHECK: declare zeroext i32 @__dfsan_chain_origin_if_tainted(i8 zeroext, i32)
+; CHECK: declare void @__dfsan_mem_shadow_origin_conditional_exchange(i8 zeroext, ptr, ptr, ptr, i64)
+; CHECK: declare void @__dfsan_maybe_store_origin(i8 zeroext, ptr, i64, i32)
 
 ; SYSTEMZ: declare void @__dfsan_load_callback(i8 zeroext, ptr)
 ; SYSTEMZ: declare void @__dfsan_store_callback(i8 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll b/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
index c7319b5697cf7f8..816a4155c3b808c 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/origin_abilist.ll
@@ -116,7 +116,7 @@ define void @call_custom_without_ret(i32 %a, i32 %b) {
   ; CHECK: [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: call void @__dfso_custom_without_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], i32 [[AO]], i32 [[BO]])
+  ; CHECK: call void @__dfso_custom_without_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], i32 [[AO]], i32 [[BO]])
   ; CHECK-NEXT: ret void
 
   call void @custom_without_ret(i32 %a, i32 %b)
@@ -131,7 +131,7 @@ define i32 @call_custom_with_ret(i32 %a, i32 %b) {
   ; CHECK: %labelreturn = alloca i8, align 1
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: {{.*}} = call i32 @__dfso_custom_with_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr %originreturn)
+  ; CHECK: {{.*}} = call i32 @__dfso_custom_with_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr %originreturn)
   ; CHECK: [[RS:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RO:%.*]] = load i32, ptr %originreturn, align 4
   ; CHECK: store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -155,7 +155,7 @@ define void @call_custom_varg_without_ret(i32 %a, i32 %b) {
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
   ; CHECK: store i32 [[AO]], ptr [[VO0]], align 4
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
-  ; CHECK: call void (i32, i32, i8, i8, ptr, i32, i32, ptr, ...) @__dfso_custom_varg_without_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], ptr [[VS0]], i32 [[AO]], i32 [[BO]], ptr [[VO0]], i32 %a)
+  ; CHECK: call void (i32, i32, i8, i8, ptr, i32, i32, ptr, ...) @__dfso_custom_varg_without_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr [[VS0]], i32 [[AO]], i32 [[BO]], ptr [[VO0]], i32 %a)
   ; CHECK-NEXT: ret void
 
   call void (i32, i32, ...) @custom_varg_without_ret(i32 %a, i32 %b, i32 %a)
@@ -178,7 +178,7 @@ define i32 @call_custom_varg_with_ret(i32 %a, i32 %b) {
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
   ; CHECK: store i32 [[BO]], ptr [[VO0]], align 4
   ; CHECK: [[VO0:%.*]] = getelementptr inbounds nuw [1 x i32], ptr %originva, i32 0, i32 0
-  ; CHECK: {{.*}} = call i32 (i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...) @__dfso_custom_varg_with_ret(i32 %a, i32 %b, i8 [[AS]], i8 [[BS]], ptr [[VS0]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr [[VO0]], ptr %originreturn, i32 %b)
+  ; CHECK: {{.*}} = call i32 (i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...) @__dfso_custom_varg_with_ret(i32 %a, i32 %b, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr [[VS0]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr [[VO0]], ptr %originreturn, i32 %b)
   ; CHECK: [[RS:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RO:%.*]] = load i32, ptr %originreturn, align 4
   ; CHECK: store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -196,7 +196,7 @@ define i32 @call_custom_cb_with_ret(i32 %a, i32 %b) {
   ; CHECK: %labelreturn = alloca i8, align 1
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: {{.*}} = call i32 @__dfso_custom_cb_with_ret(ptr @cb_with_ret.dfsan, i32 %a, i32 %b, i8 0, i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 0, i32 [[AO]], i32 [[BO]], ptr %originreturn)
+  ; CHECK: {{.*}} = call i32 @__dfso_custom_cb_with_ret(ptr @cb_with_ret.dfsan, i32 %a, i32 %b, i8 zeroext 0, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 0, i32 [[AO]], i32 [[BO]], ptr %originreturn)
   ; CHECK: [[RS:%.*]] = load i8, ptr %labelreturn, align 1
   ; CHECK: [[RO:%.*]] = load i32, ptr %originreturn, align 4
   ; CHECK: store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -212,7 +212,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
   ; CHECK: [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
   ; CHECK: [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
   ; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-  ; CHECK: call void @__dfso_custom_cb_without_ret(ptr @cb_without_ret.dfsan, i32 %a, i32 %b, i8 0, i8 [[AS]], i8 [[BS]], i32 0, i32 [[AO]], i32 [[BO]])
+  ; CHECK: call void @__dfso_custom_cb_without_ret(ptr @cb_without_ret.dfsan, i32 %a, i32 %b, i8 zeroext 0, i8 zeroext [[AS]], i8 zeroext [[BS]], i32 0, i32 [[AO]], i32 [[BO]])
   ; CHECK-NEXT: ret void
 
   call void @custom_cb_without_ret(ptr @cb_without_ret, i32 %a, i32 %b)
@@ -230,7 +230,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  [[AO:%.*]]  = load i32, ptr @__dfsan_arg_origin_tls, align 4
 ; CHECK-NEXT:  [[BS:%.*]]  = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[AS:%.*]]  = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  call void @__dfso_custom_without_ret(i32 %0, i32 %1, i8 [[AS]], i8 [[BS]], i32 [[AO]], i32 [[BO]])
+; CHECK-NEXT:  call void @__dfso_custom_without_ret(i32 %0, i32 %1, i8 zeroext [[AS]], i8 zeroext [[BS]], i32 [[AO]], i32 [[BO]])
 ; CHECK-NEXT:  ret void
 
 ; CHECK: define linkonce_odr i32 @"dfso$custom_with_ret"(i32 %0, i32 %1)
@@ -240,7 +240,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  %labelreturn = alloca i8, align 1
 ; CHECK-NEXT:  [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_with_ret(i32 %0, i32 %1, i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr %originreturn)
+; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_with_ret(i32 %0, i32 %1, i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 [[AO]], i32 [[BO]], ptr %originreturn)
 ; CHECK-NEXT:  [[RS:%.*]] = load i8, ptr %labelreturn, align 1
 ; CHECK-NEXT:  [[RO:%.*]] = load i32, ptr %originreturn, align 4
 ; CHECK-NEXT:  store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -264,7 +264,7 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 4), align 2
 ; CHECK-NEXT:  [[AS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[CS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_cb_with_ret(ptr %0, i32 %1, i32 %2, i8 [[CS]], i8 [[AS]], i8 [[BS]], ptr %labelreturn, i32 [[CO]], i32 [[AO]], i32 [[BO]], ptr %originreturn)
+; CHECK-NEXT:  [[R:%.*]] = call i32 @__dfso_custom_cb_with_ret(ptr %0, i32 %1, i32 %2, i8 zeroext [[CS]], i8 zeroext [[AS]], i8 zeroext [[BS]], ptr %labelreturn, i32 [[CO]], i32 [[AO]], i32 [[BO]], ptr %originreturn)
 ; CHECK-NEXT:  [[RS:%.*]] = load i8, ptr %labelreturn, align 1
 ; CHECK-NEXT:  [[RO:%.*]] = load i32, ptr %originreturn, align 4
 ; CHECK-NEXT:  store i8 [[RS]], ptr @__dfsan_retval_tls, align 2
@@ -278,17 +278,17 @@ define void @call_custom_cb_without_ret(i32 %a, i32 %b) {
 ; CHECK-NEXT:  [[BS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 4), align 2
 ; CHECK-NEXT:  [[AS:%.*]] = load i8, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align 2
 ; CHECK-NEXT:  [[CS:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
-; CHECK-NEXT:  call void @__dfso_custom_cb_without_ret(ptr %0, i32 %1, i32 %2, i8 [[CS]], i8 [[AS]], i8 [[BS]], i32 [[CO]], i32 [[AO]], i32 [[BO]])
+; CHECK-NEXT:  call void @__dfso_custom_cb_without_ret(ptr %0, i32 %1, i32 %2, i8 zeroext [[CS]], i8 zeroext [[AS]], i8 zeroext [[BS]], i32 [[CO]], i32 [[AO]], i32 [[BO]])
 ; CHECK-NEXT:  ret void
 
-; CHECK: declare void @__dfso_custom_without_ret(i32, i32, i8, i8, i32, i32)
+; CHECK: declare void @__dfso_custom_without_ret(i32, i32, i8 zeroext, i8 zeroext, i32, i32)
 
-; CHECK: declare i32 @__dfso_custom_with_ret(i32, i32, i8, i8, ptr, i32, i32, ptr)
+; CHECK: declare i32 @__dfso_custom_with_ret(i32, i32, i8 zeroext, i8 zeroext, ptr, i32, i32, ptr)
 
-; CHECK: declare i32 @__dfso_custom_cb_with_ret(ptr, i32, i32, i8, i8, i8, ptr, i32, i32, i32, ptr)
+; CHECK: declare i32 @__dfso_custom_cb_with_ret(ptr, i32, i32, i8 zeroext, i8 zeroext, i8 zeroext, ptr, i32, i32, i32, ptr)
 
-; CHECK: declare void @__dfso_custom_cb_without_ret(ptr, i32, i32, i8, i8, i8, i32, i32, i32)
+; CHECK: declare void @__dfso_custom_cb_without_ret(ptr, i32, i32, i8 zeroext, i8 zeroext, i8 zeroext, i32, i32, i32)
 
-; CHECK: declare void @__dfso_custom_varg_without_ret(i32, i32, i8, i8, ptr, i32, i32, ptr, ...)
+; CHECK: declare void @__dfso_custom_varg_without_ret(i32, i32, i8 zeroext, i8 zeroext, ptr, i32, i32, ptr, ...)
 
-; CHECK: declare i32 @__dfso_custom_varg_with_ret(i32, i32, i8, i8, ptr, ptr, i32, i32, ptr, ptr, ...)
+; CHECK: declare i32 @__dfso_custom_varg_with_ret(i32, i32, i8 zeroext, i8 zeroext, ptr, ptr, i32, i32, ptr, ptr, ...)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll b/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
index 654696833a67102..9e47795e1ba62f9 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/reaches_function.ll
@@ -26,4 +26,4 @@ define void @call() {
   ret void
 }
 
-; CHECK-LABEL: @__dfsan_reaches_function_callback(i8, ptr, i32, ptr)
+; CHECK-LABEL: @__dfsan_reaches_function_callback(i8 zeroext, ptr, i32, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
index 78e8d84675e3940..333f1e45fb2df1d 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
@@ -1,16 +1,12 @@
 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -passes=dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt | FileCheck %s
-; RUN: opt -mtriple=s390x-unknown-linux < %s -passes=dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt \
-; RUN:   | FileCheck %s --check-prefix=SYSTEMZ
 
-; REQUIRES: x86-registered-target, systemz-registered-target
+; REQUIRES: x86-registered-target
 
 ; Test that the custom abi marks shadow parameters as zero extended.
 
 define i32 @m() {
   ; CHECK-LABEL: @m.dfsan
-  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i8 0, ptr %{{.*}})
-  ; SYSTEMZ-LABEL: @m.dfsan
-  ; SYSTEMZ: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i8 zeroext 0, ptr %{{.*}})
+  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i8 zeroext 0, ptr %{{.*}})
 
 entry:
   %call = call zeroext i16 @dfsan_get_label(i64 signext 56)
@@ -20,9 +16,7 @@ entry:
 
 define i32 @k() {
   ; CHECK-LABEL: @k.dfsan
-  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i8 {{.*}}, i8 {{.*}}, ptr %{{.*}})
-  ; SYSTEMZ-LABEL: @k.dfsan
-  ; SYSTEMZ: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
+  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
 
 entry:
   %call = call zeroext i16 @k2(i64 signext 56, i64 signext 67)
@@ -32,9 +26,7 @@ entry:
 
 define i32 @k3() {
   ; CHECK-LABEL: @k3.dfsan
-  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i8 {{.*}}, i8 {{.*}}, i8 {{.*}}, i8 {{.*}}, ptr %{{.*}})
-  ; SYSTEMZ-LABEL: @k3.dfsan
-  ; SYSTEMZ: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
+  ; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, i8 zeroext {{.*}}, ptr %{{.*}})
 
 entry:
   %call = call zeroext i16 @k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89)
@@ -44,26 +36,17 @@ entry:
 
 declare zeroext i16 @dfsan_get_label(i64 signext)
 ; CHECK-LABEL: @"dfsw$dfsan_get_label"
-; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 %1, ptr %{{.*}})
-; SYSTEMZ-LABEL: @"dfsw$dfsan_get_label"
-; SYSTEMZ: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
 
 declare zeroext i16 @k2(i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k2"
-; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, ptr %{{.*}})
-; SYSTEMZ-LABEL: @"dfsw$k2"
-; SYSTEMZ: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 declare zeroext i16 @k4(i64 signext, i64 signext, i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k4"
-; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, i8 %{{.*}}, ptr %{{.*}})
-; SYSTEMZ-LABEL: @"dfsw$k4"
-; SYSTEMZ: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 
-; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8, ptr)
-; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8, i8, ptr)
-; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8, i8, i8, i8, ptr)
-; SYSTEMZ: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8 zeroext, ptr)
-; SYSTEMZ: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8 zeroext, i8 zeroext, ptr)
-; SYSTEMZ: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8 zeroext, ptr)
+; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i8 zeroext, i8 zeroext, ptr)
+; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, ptr)
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll b/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
index 7ac0af121d64e04..9b4a35005a14210 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/struct.ll
@@ -130,7 +130,7 @@ define {i1, i1} @load_struct(ptr %p) {
   ; EVENT_CALLBACKS: [[OL0:%.*]] = or i8
   ; EVENT_CALLBACKS: [[OL1:%.*]] = or i8 [[OL0]],
   ; EVENT_CALLBACKS: [[S0:%.*]] = insertvalue { i8, i8 } undef, i8 [[OL1]], 0
-  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 [[OL1]]
+  ; EVENT_CALLBACKS: call void @__dfsan_load_callback(i8 zeroext [[OL1]]
 
   %s = load {i1, i1}, ptr %p
   ret {i1, i1} %s
@@ -149,7 +149,7 @@ define void @store_struct(ptr %p, {i1, i1} %s) {
 
   ; EVENT_CALLBACKS: @store_struct.dfsan
   ; EVENT_CALLBACKS: [[OL:%.*]] = or i8
-  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 [[OL]]
+  ; EVENT_CALLBACKS: call void @__dfsan_store_callback(i8 zeroext [[OL]]
 
   ; COMBINE_STORE_PTR: @store_struct.dfsan
   ; COMBINE_STORE_PTR: [[PL:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]

>From b8d4054f64ca721510a636ab6f0ff6b4d099c768 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Wed, 30 Sep 2026 19:39:37 +0200
Subject: [PATCH 5/7] Reworked.

---
 .../Instrumentation/DataFlowSanitizer.cpp     | 118 ++++++++----------
 .../DataFlowSanitizer/shadow-args-zext.ll     |   6 +-
 2 files changed, 56 insertions(+), 68 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index bb654db6d1bb0f5..213bed4ed9a32dc 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -370,9 +370,11 @@ class DFSanABIList {
 /// useful for updating calls of the old function to the new type.
 struct TransformedFunction {
   TransformedFunction(FunctionType *OriginalType, FunctionType *TransformedType,
-                      const std::vector<unsigned> &ArgumentIndexMapping)
+                      const std::vector<unsigned> &ArgumentIndexMapping,
+                      AttributeList &NewParamAttrs)
       : OriginalType(OriginalType), TransformedType(TransformedType),
-        ArgumentIndexMapping(ArgumentIndexMapping) {}
+        ArgumentIndexMapping(ArgumentIndexMapping),
+        NewParamAttrs(NewParamAttrs) {}
 
   // Disallow copies.
   TransformedFunction(const TransformedFunction &) = delete;
@@ -394,6 +396,10 @@ struct TransformedFunction {
   /// from F to F' made the first argument of F into the third argument of F',
   /// then ArgumentIndexMapping[0] will equal 2.
   std::vector<unsigned> ArgumentIndexMapping;
+
+  /// The (extension) attributes that new Shadow and Origin parameters in
+  /// TransformedType should have.
+  AttributeList NewParamAttrs;
 };
 
 /// Given function attributes from a call site for the original function,
@@ -538,7 +544,8 @@ class DataFlowSanitizer {
   bool isInstrumented(const Function *F);
   bool isInstrumented(const GlobalAlias *GA);
   bool isForceZeroLabels(const Function *F);
-  TransformedFunction getCustomFunctionType(FunctionType *T);
+  TransformedFunction getCustomFunctionType(FunctionType *T,
+                                            TargetLibraryInfo &TLI);
   WrapperKind getWrapperKind(Function *F);
   void addGlobalNameSuffix(GlobalValue *GV);
   void buildExternWeakCheckIfNeeded(IRBuilder<> &IRB, Function *F);
@@ -890,8 +897,15 @@ DataFlowSanitizer::DataFlowSanitizer(
   CombineTaintLookupTableNames.insert_range(ClCombineTaintLookupTables);
 }
 
-TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
+TransformedFunction
+DataFlowSanitizer::getCustomFunctionType(FunctionType *T,
+                                         TargetLibraryInfo &TLI) {
   SmallVector<Type *, 4> ArgTypes;
+  AttributeList NewParamAttrs;
+  Attribute::AttrKind ShadowParamExtAttr =
+      TLI.getExtAttrForI8Param(/*Signed=*/false);
+  Attribute::AttrKind OriginParamExtAttr =
+      TLI.getExtAttrForI32Param(/*Signed=*/false);
 
   // Some parameters of the custom function being constructed are
   // parameters of T.  Record the mapping from parameters of T to
@@ -903,8 +917,12 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
     ArgumentIndexMapping.push_back(ArgTypes.size());
     ArgTypes.push_back(ParamType);
   }
-  for (unsigned I = 0, E = T->getNumParams(); I != E; ++I)
+  for (unsigned I = 0, E = T->getNumParams(); I != E; ++I) {
+    if (ShadowParamExtAttr != Attribute::AttrKind::None)
+      NewParamAttrs = NewParamAttrs.addParamAttribute(*Ctx, ArgTypes.size(),
+                                                      ShadowParamExtAttr);
     ArgTypes.push_back(PrimitiveShadowTy);
+  }
   if (T->isVarArg())
     ArgTypes.push_back(PrimitiveShadowPtrTy);
   Type *RetType = T->getReturnType();
@@ -912,8 +930,12 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
     ArgTypes.push_back(PrimitiveShadowPtrTy);
 
   if (shouldTrackOrigins()) {
-    for (unsigned I = 0, E = T->getNumParams(); I != E; ++I)
+    for (unsigned I = 0, E = T->getNumParams(); I != E; ++I) {
+      if (OriginParamExtAttr != Attribute::AttrKind::None)
+        NewParamAttrs = NewParamAttrs.addParamAttribute(*Ctx, ArgTypes.size(),
+                                                        OriginParamExtAttr);
       ArgTypes.push_back(OriginTy);
+    }
     if (T->isVarArg())
       ArgTypes.push_back(OriginPtrTy);
     if (!RetType->isVoidTy())
@@ -922,7 +944,7 @@ TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *T) {
 
   return TransformedFunction(
       T, FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg()),
-      ArgumentIndexMapping);
+      ArgumentIndexMapping, NewParamAttrs);
 }
 
 bool DataFlowSanitizer::isZeroShadow(Value *V) {
@@ -3124,10 +3146,6 @@ void DFSanVisitor::addOriginArguments(Function &F, CallBase &CB,
 }
 
 bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
-  Attribute::AttrKind I8ParamExtAttr =
-      DFSF.TLI.getExtAttrForI8Param(/*Signed=*/false);
-  Attribute::AttrKind I32ParamExtAttr =
-      DFSF.TLI.getExtAttrForI32Param(/*Signed=*/false);
   IRBuilder<> IRB(&CB);
   switch (DFSF.DFS.getWrapperKind(&F)) {
   case DataFlowSanitizer::WK_Warning:
@@ -3159,37 +3177,27 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
 
     const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
     FunctionType *FT = F.getFunctionType();
-    TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
+    TransformedFunction CustomFnTy =
+        DFSF.DFS.getCustomFunctionType(FT, DFSF.TLI);
     std::string CustomFName = ShouldTrackOrigins ? "__dfso_" : "__dfsw_";
     CustomFName += F.getName();
-    FunctionCallee CustomF = DFSF.DFS.Mod->getOrInsertFunction(
-        CustomFName, CustomFn.TransformedType);
-    if (Function *CustomFn = dyn_cast<Function>(CustomF.getCallee())) {
-      CustomFn->copyAttributesFrom(&F);
-
-      // Ensure all narrow integer arguments (both original and added
-      // shadow/origin) have an extension attribute on the function
-      // declaration. If none is present, add the right attribute for zero
-      // extend as all DFSan args are unsigned. TODO: Avoid getting here with
-      // missing attributes in the first place (use TLI/emitLibFunc()?).
-      for (unsigned I = 0, E = CustomFn->arg_size(); I < E; ++I) {
-        Type *ParamTy = CustomFn->getFunctionType()->getParamType(I);
-        if (ParamTy->isIntegerTy() && ParamTy->getIntegerBitWidth() <= 32) {
-          Attribute::AttrKind IntArgAttr = ParamTy->getIntegerBitWidth() == 8
-                                               ? I8ParamExtAttr
-                                               : I32ParamExtAttr;
-          if (IntArgAttr != Attribute::AttrKind::None &&
-              !CustomFn->hasParamAttribute(I, Attribute::ZExt) &&
-              !CustomFn->hasParamAttribute(I, Attribute::SExt) &&
-              !CustomFn->hasParamAttribute(I, Attribute::NoExt)) {
-            CustomFn->addParamAttr(I, IntArgAttr);
-          }
-        }
-      }
+    FunctionCallee CustomFunCallee = DFSF.DFS.Mod->getOrInsertFunction(
+        CustomFName, CustomFnTy.TransformedType);
+    if (Function *CustomFun = dyn_cast<Function>(CustomFunCallee.getCallee())) {
+      // Strange things may occur here: F may have two i64 arguments while
+      // getOrInsertFunction() returns a preexisting Function with those
+      // (first) two args as i8:s. Make sure the extensions of those i8:s
+      // survive copyAttributesFrom() and also add the extensions for the new
+      // parameters.
+      AttributeList CustomAL = CustomFun->getAttributes();
+      CustomFun->copyAttributesFrom(&F);
+      CustomFun->setAttributes(AttributeList::get(
+          CI->getContext(),
+          {CustomFun->getAttributes(), CustomAL, CustomFnTy.NewParamAttrs}));
 
       // Custom functions returning non-void will write to the return label.
       if (!FT->getReturnType()->isVoidTy()) {
-        CustomFn->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
+        CustomFun->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
       }
     }
 
@@ -3213,35 +3221,15 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
     // Adds variable arguments.
     append_range(Args, drop_begin(CB.args(), FT->getNumParams()));
 
-    // Combine CallSite attributes with Function declaration attributes.
-    AttributeList CombinedAttrs = CI->getAttributes();
-    for (unsigned I = 0; I < FT->getNumParams(); ++I) {
-      AttrBuilder AttrB(CI->getContext(), F.getAttributes().getParamAttrs(I));
-      if (AttrB.hasAttributes())
-        CombinedAttrs =
-            CombinedAttrs.addParamAttributes(CI->getContext(), I, AttrB);
-    }
-    CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
+    CallInst *CustomCI = IRB.CreateCall(CustomFunCallee, Args);
     CustomCI->setCallingConv(CI->getCallingConv());
-    CustomCI->setAttributes(
-        transformFunctionAttributes(CustomFn, CI->getContext(), CombinedAttrs));
-
-    // Update the parameter attributes of the custom call instruction to
-    // zero extend the shadow parameters. This is required for targets
-    // which consider PrimitiveShadowTy an illegal type.
-    for (unsigned N = 0; N < FT->getNumParams(); N++) {
-      const unsigned ArgNo = ShadowArgStart + N;
-      if (CustomCI->getArgOperand(ArgNo)->getType() ==
-          DFSF.DFS.PrimitiveShadowTy)
-        CustomCI->maybeAddParamAttr(ArgNo, I8ParamExtAttr);
-
-      if (ShouldTrackOrigins) {
-        const unsigned OriginArgNo = OriginArgStart + N;
-        if (CustomCI->getArgOperand(OriginArgNo)->getType() ==
-            DFSF.DFS.OriginTy)
-          CustomCI->maybeAddParamAttr(OriginArgNo, I32ParamExtAttr);
-      }
-    }
+    // Add attributes to the parameters from the original call and Function
+    // and as well those needed for the new parameters.
+    CustomCI->setAttributes(AttributeList::get(
+        CI->getContext(),
+        {transformFunctionAttributes(CustomFnTy, CI->getContext(),
+                                     CI->getAttributes()),
+         F.getAttributes(), CustomFnTy.NewParamAttrs}));
 
     // Loads the return value shadow and origin.
     if (!FT->getReturnType()->isVoidTy()) {
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
index 333f1e45fb2df1d..2929983c7c8882d 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll
@@ -36,15 +36,15 @@ entry:
 
 declare zeroext i16 @dfsan_get_label(i64 signext)
 ; CHECK-LABEL: @"dfsw$dfsan_get_label"
-; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
+; CHECK: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext %0, i8 zeroext %1, ptr %{{.*}})
 
 declare zeroext i16 @k2(i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k2"
-; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 declare zeroext i16 @k4(i64 signext, i64 signext, i64 signext, i64 signext)
 ; CHECK-LABEL: @"dfsw$k4"
-; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
+; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i64 signext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, i8 zeroext %{{.*}}, ptr %{{.*}})
 
 
 ; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i8 zeroext, ptr)

>From ed5b1b15737e04204de97e47153e679073455452 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Thu, 1 Oct 2026 10:35:39 +0200
Subject: [PATCH 6/7] Use maybeAddParamAttribute() in two places.

---
 .../Transforms/Instrumentation/DataFlowSanitizer.cpp   | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 213bed4ed9a32dc..b47a858e5900f26 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -918,9 +918,8 @@ DataFlowSanitizer::getCustomFunctionType(FunctionType *T,
     ArgTypes.push_back(ParamType);
   }
   for (unsigned I = 0, E = T->getNumParams(); I != E; ++I) {
-    if (ShadowParamExtAttr != Attribute::AttrKind::None)
-      NewParamAttrs = NewParamAttrs.addParamAttribute(*Ctx, ArgTypes.size(),
-                                                      ShadowParamExtAttr);
+    NewParamAttrs = NewParamAttrs.maybeAddParamAttribute(*Ctx, ArgTypes.size(),
+                                                         ShadowParamExtAttr);
     ArgTypes.push_back(PrimitiveShadowTy);
   }
   if (T->isVarArg())
@@ -931,9 +930,8 @@ DataFlowSanitizer::getCustomFunctionType(FunctionType *T,
 
   if (shouldTrackOrigins()) {
     for (unsigned I = 0, E = T->getNumParams(); I != E; ++I) {
-      if (OriginParamExtAttr != Attribute::AttrKind::None)
-        NewParamAttrs = NewParamAttrs.addParamAttribute(*Ctx, ArgTypes.size(),
-                                                        OriginParamExtAttr);
+      NewParamAttrs = NewParamAttrs.maybeAddParamAttribute(
+          *Ctx, ArgTypes.size(), OriginParamExtAttr);
       ArgTypes.push_back(OriginTy);
     }
     if (T->isVarArg())

>From 5626d18e8ea4ea2e5ef551efe1fd506316efcaa1 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <paulson1 at linux.ibm.com>
Date: Thu, 1 Oct 2026 13:07:28 +0200
Subject: [PATCH 7/7] Remove unused variables.

---
 llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index b47a858e5900f26..492383b72c63b31 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -3208,11 +3208,9 @@ bool DFSanVisitor::visitWrappedCallBase(Function &F, CallBase &CB) {
     }
 
     // Adds shadow arguments.
-    const unsigned ShadowArgStart = Args.size();
     addShadowArguments(F, CB, Args, IRB);
 
     // Adds origin arguments.
-    const unsigned OriginArgStart = Args.size();
     if (ShouldTrackOrigins)
       addOriginArguments(F, CB, Args, IRB);
 



More information about the llvm-commits mailing list