Skip to content

Conversation

@nikic
Copy link
Contributor

@nikic nikic commented Oct 1, 2025

Generate test checks for some dfsan tests with UTC to make them easier to update.

For this purpose I've added a -dfsan-add-global-name-suffix=0 option to avoid the addition of the .dfsan suffix on functions, which allows us to use normal UTC check lines. Otherwise we'd have to use --include-generated-funcs instead, which produces less nice results, as the check lines are not interleaved with the original functions anymore.

@llvmbot
Copy link
Member

llvmbot commented Oct 1, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

Generate test checks for some dfsan tests with UTC to make them easier to update.

For this purpose I've added a -dfsan-add-global-name-suffix=0 option to avoid the addition of the .dfsan suffix on functions, which allows us to use normal UTC check lines. Otherwise we'd have to use --include-generated-funcs instead, which produces less nice results, as the check lines are not interleaved with the original functions anymore.


Patch is 44.30 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/161502.diff

9 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp (+8)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/arith.ll (+54-41)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll (+19-12)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll (+127-37)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/origin_phi.ll (+37-28)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/origin_track_load.ll (+19-20)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/phi.ll (+25-10)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/select.ll (+64-57)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/vector.ll (+54-29)
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 480ff4a8c3cb9..55366ced34cd5 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -261,6 +261,11 @@ static cl::opt<bool> ClIgnorePersonalityRoutine(
              "list, do not create a wrapper for it."),
     cl::Hidden, cl::init(false));
 
+static cl::opt<bool> ClAddGlobalNameSuffix(
+    "dfsan-add-global-name-suffix",
+    cl::desc("Whether to add \\.dfsan suffix to global names"), cl::Hidden,
+    cl::init(true));
+
 static StringRef getGlobalTypeString(const GlobalValue &G) {
   // Types of GlobalVariables are always pointer types.
   Type *GType = G.getValueType();
@@ -1256,6 +1261,9 @@ DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) {
 }
 
 void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
+  if (!ClAddGlobalNameSuffix)
+    return;
+
   std::string GVName = std::string(GV->getName()), Suffix = ".dfsan";
   GV->setName(GVName + Suffix);
 
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll b/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
index 8c9eb5fa42fc3..2799f57545a97 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
@@ -1,73 +1,86 @@
-; RUN: opt < %s -passes=dfsan -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=dfsan -dfsan-add-global-name-suffix=0 -S | FileCheck %s
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 define i8 @add(i8 %a, i8 %b) {
-  ; CHECK: @add.dfsan
-  ; CHECK-DAG: %[[#ALABEL:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
-  ; CHECK-DAG: %[[#BLABEL:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
-  ; CHECK: %[[#UNION:]] = or i8 %[[#ALABEL]], %[[#BLABEL]]
-  ; CHECK: %c = add i8 %a, %b
-  ; CHECK: store i8 %[[#UNION]], ptr @__dfsan_retval_tls, align [[ALIGN]]
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @add(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = add i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = add i8 %a, %b
   ret i8 %c
 }
 
 define i8 @sub(i8 %a, i8 %b) {
-  ; CHECK: @sub.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = sub i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @sub(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = sub i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = sub i8 %a, %b
   ret i8 %c
 }
 
 define i8 @mul(i8 %a, i8 %b) {
-  ; CHECK: @mul.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = mul i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @mul(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = mul i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = mul i8 %a, %b
   ret i8 %c
 }
 
 define i8 @sdiv(i8 %a, i8 %b) {
-  ; CHECK: @sdiv.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = sdiv i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @sdiv(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = sdiv i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = sdiv i8 %a, %b
   ret i8 %c
 }
 
 define i8 @udiv(i8 %a, i8 %b) {
-  ; CHECK: @udiv.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = udiv i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @udiv(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = udiv i8 %a, %b
   ret i8 %c
 }
 
 define double @fneg(double %a) {
-  ; CHECK: @fneg.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: %c = fneg double %a
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret double %c
+; CHECK-LABEL: define double @fneg(
+; CHECK-SAME: double [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[C:%.*]] = fneg double [[A]]
+; CHECK-NEXT:    store i8 [[TMP1]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret double [[C]]
+;
   %c = fneg double %a
   ret double %c
 }
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll b/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll
index 997681bb8e692..7574346eddbc2 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll
@@ -1,19 +1,26 @@
-; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -S | FileCheck %s
-; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-add-global-name-suffix=0 -S | FileCheck %s
+; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -dfsan-add-global-name-suffix=0 -S | FileCheck %s --check-prefix=CHECK_ORIGIN
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
-; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
 define ptr @gepop(ptr %p, i32 %a, i32 %b, i32 %c) {
-  ; CHECK: @gepop.dfsan
-  ; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align [[ALIGN_O:4]]
-  ; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN_S:2]]
-  ; CHECK: %e = getelementptr [10 x [20 x i32]], ptr %p, i32 %a, i32 %b, i32 %c
-  ; CHECK: store i8 %[[#PS]], ptr @__dfsan_retval_tls, align [[ALIGN_S]]
-  ; CHECK_ORIGIN: store i32 %[[#PO]], ptr @__dfsan_retval_origin_tls, align [[ALIGN_O]]
-
+; CHECK-LABEL: define ptr @gepop(
+; CHECK-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[E:%.*]] = getelementptr [10 x [20 x i32]], ptr [[P]], i32 [[A]], i32 [[B]], i32 [[C]]
+; CHECK-NEXT:    store i8 [[TMP1]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret ptr [[E]]
+;
+; CHECK_ORIGIN-LABEL: define ptr @gepop(
+; CHECK_ORIGIN-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
+; CHECK_ORIGIN-NEXT:    [[TMP1:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
+; CHECK_ORIGIN-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK_ORIGIN-NEXT:    [[E:%.*]] = getelementptr [10 x [20 x i32]], ptr [[P]], i32 [[A]], i32 [[B]], i32 [[C]]
+; CHECK_ORIGIN-NEXT:    store i8 [[TMP2]], ptr @__dfsan_retval_tls, align 2
+; CHECK_ORIGIN-NEXT:    store i32 [[TMP1]], ptr @__dfsan_retval_origin_tls, align 4
+; CHECK_ORIGIN-NEXT:    ret ptr [[E]]
+;
   %e = getelementptr [10 x [20 x i32]], ptr %p, i32 %a, i32 %b, i32 %c
   ret ptr %e
 }
-
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll b/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
index cb9a306eddd83..194a1934e5aad 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
@@ -1,4 +1,5 @@
-; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1  -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -dfsan-add-global-name-suffix=0 -S | FileCheck %s
 ;
 ; %i13 and %i15 have the same key in shadow cache. They should not reuse the same
 ; shadow because their blocks do not dominate each other. Origin tracking
@@ -7,43 +8,129 @@
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
 define void @cached_shadows(double %arg) {
-  ; CHECK: @cached_shadows.dfsan
-  ; CHECK:  [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align
-  ; CHECK:  [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
-  ; CHECK: [[L1:.+]]:
-  ; CHECK:  {{.*}} = phi i8
-  ; CHECK:  {{.*}} = phi i32
-  ; CHECK:  {{.*}} = phi double [ 3.000000e+00
-  ; CHECK:  [[S_L1:%.*]] = phi i8 [ 0, %[[L0:.*]] ], [ [[S_L7:%.*]], %[[L7:.*]] ]
-  ; CHECK:  [[O_L1:%.*]] = phi i32 [ 0, %[[L0]] ], [ [[O_L7:%.*]], %[[L7]] ]
-  ; CHECK:  [[V_L1:%.*]] = phi double [ 4.000000e+00, %[[L0]] ], [ [[V_L7:%.*]], %[[L7]] ]
-  ; CHECK:  br i1 {{%.+}}, label %[[L2:.*]], label %[[L4:.*]]
-  ; CHECK: [[L2]]:
-  ; CHECK:  br i1 {{%.+}}, label %[[L3:.+]], label %[[L7]]
-  ; CHECK: [[L3]]:
-  ; CHECK:  [[S_L3:%.*]] = or i8
-  ; CHECK:  [[AS_NE_L3:%.*]] = icmp ne i8 [[AS]], 0
-  ; CHECK:  [[O_L3:%.*]] = select i1 [[AS_NE_L3]], i32 %{{[0-9]+}}, i32 [[O_L1]]
-  ; CHECK:  [[V_L3:%.*]] = fsub double [[V_L1]], %{{.+}}
-  ; CHECK:  br label %[[L7]]
-  ; CHECK: [[L4]]:
-  ; CHECK:  br i1 %_dfscmp, label %[[L5:.+]], label %[[L6:.+]],
-  ; CHECK: [[L5]]:
-  ; CHECK:  br label %[[L6]]
-  ; CHECK: [[L6]]:
-  ; CHECK:  [[S_L6:%.*]] = or i8
-  ; CHECK:  [[AS_NE_L6:%.*]] = icmp ne i8 [[AS]], 0
-  ; CHECK:  [[O_L6:%.*]] = select i1 [[AS_NE_L6]], i32 [[AO]], i32 [[O_L1]]
-  ; CHECK:  [[V_L6:%.*]] = fadd double [[V_L1]], %{{.+}}
-  ; CHECK:  br label %[[L7]]
-  ; CHECK: [[L7]]:
-  ; CHECK:  [[S_L7]] = phi i8 [ [[S_L3]], %[[L3]] ], [ [[S_L1]], %[[L2]] ], [ [[S_L6]], %[[L6]] ]
-  ; CHECK:  [[O_L7]] = phi i32 [ [[O_L3]], %[[L3]] ], [ [[O_L1]], %[[L2]] ], [ [[O_L6]], %[[L6]] ]
-  ; CHECK:  [[V_L7]] = phi double [ [[V_L3]], %[[L3]] ], [ [[V_L1]], %[[L2]] ], [ [[V_L6]], %[[L6]] ]
-  ; CHECK:  br i1 %{{.+}}, label %[[L1]], label %[[L8:.+]]
-  ; CHECK: [[L8]]:
+; CHECK-LABEL: define void @cached_shadows(
+; CHECK-SAME: double [[ARG:%.*]]) {
+; CHECK-NEXT:  [[BB:.*]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[I:%.*]] = alloca double, align 8
+; CHECK-NEXT:    [[I1:%.*]] = alloca double, align 8
+; CHECK-NEXT:    [[I2:%.*]] = bitcast ptr [[I]] to ptr
+; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[I]] to i64
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i64 [[TMP2]], 87960930222080
+; CHECK-NEXT:    [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
+; CHECK-NEXT:    store i64 0, ptr [[TMP4]], align 1
+; CHECK-NEXT:    store volatile double 1.000000e+00, ptr [[I]], align 8
+; CHECK-NEXT:    [[I3:%.*]] = bitcast ptr [[I1]] to ptr
+; CHECK-NEXT:    [[TMP5:%.*]] = ptrtoint ptr [[I1]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = xor i64 [[TMP5]], 87960930222080
+; CHECK-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
+; CHECK-NEXT:    store i64 0, ptr [[TMP7]], align 1
+; CHECK-NEXT:    store volatile double 2.000000e+00, ptr [[I1]], align 8
+; CHECK-NEXT:    br label %[[BB4:.*]]
+; CHECK:       [[BB4]]:
+; CHECK-NEXT:    [[TMP8:%.*]] = phi i8 [ 0, %[[BB]] ], [ [[TMP76:%.*]], %[[BB16:.*]] ]
+; CHECK-NEXT:    [[TMP9:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP77:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[I5:%.*]] = phi double [ 3.000000e+00, %[[BB]] ], [ [[I17:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[TMP10:%.*]] = phi i8 [ 0, %[[BB]] ], [ [[TMP78:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[TMP11:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP79:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[I6:%.*]] = phi double [ 4.000000e+00, %[[BB]] ], [ [[I18:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[TMP12:%.*]] = ptrtoint ptr [[I1]] to i64
+; CHECK-NEXT:    [[TMP13:%.*]] = xor i64 [[TMP12]], 87960930222080
+; CHECK-NEXT:    [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
+; CHECK-NEXT:    [[TMP15:%.*]] = add i64 [[TMP13]], 17592186044416
+; CHECK-NEXT:    [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr
+; CHECK-NEXT:    [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 8
+; CHECK-NEXT:    [[TMP18:%.*]] = load i64, ptr [[TMP14]], align 1
+; CHECK-NEXT:    [[TMP19:%.*]] = shl i64 [[TMP18]], 32
+; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr i32, ptr [[TMP16]], i64 1
+; CHECK-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 8
+; CHECK-NEXT:    [[TMP22:%.*]] = lshr i64 [[TMP18]], 32
+; CHECK-NEXT:    [[TMP23:%.*]] = or i64 [[TMP18]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = lshr i64 [[TMP23]], 16
+; CHECK-NEXT:    [[TMP25:%.*]] = or i64 [[TMP23]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = lshr i64 [[TMP25]], 8
+; CHECK-NEXT:    [[TMP27:%.*]] = or i64 [[TMP25]], [[TMP26]]
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i8
+; CHECK-NEXT:    [[TMP29:%.*]] = icmp ne i64 [[TMP19]], 0
+; CHECK-NEXT:    [[TMP30:%.*]] = select i1 [[TMP29]], i32 [[TMP17]], i32 [[TMP21]]
+; CHECK-NEXT:    [[I7:%.*]] = load volatile double, ptr [[I1]], align 8
+; CHECK-NEXT:    [[I8:%.*]] = fcmp une double [[I7]], 0.000000e+00
+; CHECK-NEXT:    [[TMP31:%.*]] = ptrtoint ptr [[I1]] to i64
+; CHECK-NEXT:    [[TMP32:%.*]] = xor i64 [[TMP31]], 87960930222080
+; CHECK-NEXT:    [[TMP33:%.*]] = inttoptr i64 [[TMP32]] to ptr
+; CHECK-NEXT:    [[TMP34:%.*]] = add i64 [[TMP32]], 17592186044416
+; CHECK-NEXT:    [[TMP35:%.*]] = inttoptr i64 [[TMP34]] to ptr
+; CHECK-NEXT:    [[TMP36:%.*]] = load i32, ptr [[TMP35]], align 8
+; CHECK-NEXT:    [[TMP37:%.*]] = load i64, ptr [[TMP33]], align 1
+; CHECK-NEXT:    [[TMP38:%.*]] = shl i64 [[TMP37]], 32
+; CHECK-NEXT:    [[TMP39:%.*]] = getelementptr i32, ptr [[TMP35]], i64 1
+; CHECK-NEXT:    [[TMP40:%.*]] = load i32, ptr [[TMP39]], align 8
+; CHECK-NEXT:    [[TMP41:%.*]] = lshr i64 [[TMP37]], 32
+; CHECK-NEXT:    [[TMP42:%.*]] = or i64 [[TMP37]], [[TMP41]]
+; CHECK-NEXT:    [[TMP43:%.*]] = lshr i64 [[TMP42]], 16
+; CHECK-NEXT:    [[TMP44:%.*]] = or i64 [[TMP42]], [[TMP43]]
+; CHECK-NEXT:    [[TMP45:%.*]] = lshr i64 [[TMP44]], 8
+; CHECK-NEXT:    [[TMP46:%.*]] = or i64 [[TMP44]], [[TMP45]]
+; CHECK-NEXT:    [[TMP47:%.*]] = trunc i64 [[TMP46]] to i8
+; CHECK-NEXT:    [[TMP48:%.*]] = icmp ne i64 [[TMP38]], 0
+; CHECK-NEXT:    [[TMP49:%.*]] = select i1 [[TMP48]], i32 [[TMP36]], i32 [[TMP40]]
+; CHECK-NEXT:    [[I9:%.*]] = load volatile double, ptr [[I1]], align 8
+; CHECK-NEXT:    br i1 [[I8]], label %[[BB10:.*]], label %[[BB14:.*]]
+; CHECK:       [[BB10]]:
+; CHECK-NEXT:    [[I11:%.*]] = fcmp une double [[I9]], 0.000000e+00
+; CHECK-NEXT:    br i1 [[I11]], label %[[BB12:.*]], label %[[BB16]]
+; CHECK:       [[BB12]]:
+; CHECK-NEXT:    [[TMP50:%.*]] = or i8 [[TMP10]], [[TMP1]]
+; CHECK-NEXT:    [[TMP51:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP52:%.*]] = select i1 [[TMP51]], i32 [[TMP0]], i32 [[TMP11]]
+; CHECK-NEXT:    [[I13:%.*]] = fsub double [[I6]], [[ARG]]
+; CHECK-NEXT:    br label %[[BB16]]
+; CHECK:       [[BB14]]:
+; CHECK-NEXT:    [[TMP53:%.*]] = ptrtoint ptr [[I]] to i64
+; CHECK-NEXT:    [[TMP54:%.*]] = xor i64 [[TMP53]], 87960930222080
+; CHECK-NEXT:    [[TMP55:%.*]] = inttoptr i64 [[TMP54]] to ptr
+; CHECK-NEXT:    [[TMP56:%.*]] = add i64 [[TMP54]], 17592186044416
+; CHECK-NEXT:    [[TMP57:%.*]] = inttoptr i64 [[TMP56]] to ptr
+; CHECK-NEXT:    [[TMP58:%.*]] = insertelement <8 x i8> poison, i8 [[TMP47]], i32 0
+; CHECK-NEXT:    [[TMP59:%.*]] = insertelement <8 x i8> [[TMP58]], i8 [[TMP47]], i32 1
+; CHECK-NEXT:    [[TMP60:%.*]] = insertelement <8 x i8> [[TMP59]], i8 [[TMP47]], i32 2
+; CHECK-NEXT:    [[TMP61:%.*]] = insertelement <8 x i8> [[TMP60]], i8 [[TMP47]], i32 3
+; CHECK-NEXT:    [[TMP62:%.*]] = insertelement <8 x i8> [[TMP61]], i8 [[TMP47]], i32 4
+; CHECK-NEXT:    [[TMP63:%.*]] = insertelement <8 x i8> [[TMP62]], i8 [[TMP47]], i32 5
+; CHECK-NEXT:    [[TMP64:%.*]] = insertelement <8 x i8> [[TMP63]], i8 [[TMP47]], i32 6
+; CHECK-NEXT:    [[TMP65:%.*]] = insertelement <8 x i8> [[TMP64]], i8 [[TMP47]], i32 7
+; CHECK-NEXT:    [[TMP66:%.*]] = getelementptr <8 x i8>, ptr [[TMP55]], i32 0
+; CHECK-NEXT:    store <8 x i8> [[TMP65]], ptr [[TMP66]], align 1
+; CHECK-NEXT:    [[_DFSCMP:%.*]] = icmp ne i8 [[TMP47]], 0
+; CHECK-NEXT:    br i1 [[_DFSCMP]], label %[[BB67:.*]], label %[[BB72:.*]], !prof [[PROF1:![0-9]+]]
+; CHECK:       [[BB67]]:
+; CHECK-NEXT:    [[TMP68:%.*]] = call i32 @__dfsan_chain_origin(i32 [[TMP49]])
+; CHECK-NEXT:    [[TMP69:%.*]] = zext i32 [[TMP68]] to i64
+; CHECK-NEXT:    [[TMP70:%.*]] = shl i64 [[TMP69]], 32
+; CHECK-NEXT:    [[TMP71:%.*]] = or i64 [[TMP69]], [[TMP70]]
+; CHECK-NEXT:    store i64 [[TMP71]], ptr [[TMP57]], align 8
+; CHECK-NEXT:    br label %[[BB72]]
+; CHECK:       [[BB72]]:
+; CHECK-NEXT:    store volatile double [[I9]], ptr [[I]], align 8
+; CHECK-NEXT:    [[TMP73:%.*]] = or i8 [[TMP10]], [[TMP1]]
+; CHECK-NEXT:    [[TMP74:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP75:%.*]] = select i1 [[TMP74]], i32 [[TMP0]], i32 [[TMP11]]
+; CHECK-NEXT:    [[I15:%.*]] = fadd double [[I6]], [[ARG]]
+; CHECK-NEXT:    br label %[[BB16]]
+; CHECK:       [[BB16]]:
+; CHECK-NEXT:    [[TMP76]] = phi i8 [ [[TMP10]], %[[BB12]] ], [ [[TMP8]], %[[BB10]] ], [ [[TMP10]], %[[BB72]] ]
+; CHECK-NEXT:    [[TMP77]] = phi i32 [ [[TMP11]], %[[BB12]] ], [ [[TMP9]], %[[BB10]] ], [ [[TMP11]], %[[BB72]] ]
+; CHECK-NEXT:    [[I17]] = phi double [ [[I6]], %[[BB12]] ], [ [[I5]], %[[BB10]] ], [ [[I6]], %[[BB72]] ]
+; CHECK-NEXT:    [[TMP78]] = phi i8 [ [[TMP50]], %[[BB12]] ], [ [[TMP10]], %[[BB10]] ], [ [[TMP73]], %[[BB72]] ]
+; CHECK-NEXT:    [[TMP79]] = phi i32 [ [[TMP52]], %[[BB12]] ], [ [[TMP11]], %[[BB10]] ], [ [[TMP75]], %[[BB72]] ]
+; CHECK-NEXT:    [[I18]] = phi double [ [[I13]], %[[BB12]] ], [ [[I6]], %[[BB10]] ], [ [[I15]], %[[BB72]] ]
+; CHECK-NEXT:    [[I19:%.*]] = fcmp olt double [[I17]], 9.900000e+01
+; CHECK-NEXT:    br i1 [[I19]], label %[[BB4]], label %[[BB20:.*]]
+; CHECK:       [[BB20]]:
+; CHECK-NEXT:    ret void
+;
 bb:
   %i = alloca double...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Oct 1, 2025

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

Author: Nikita Popov (nikic)

Changes

Generate test checks for some dfsan tests with UTC to make them easier to update.

For this purpose I've added a -dfsan-add-global-name-suffix=0 option to avoid the addition of the .dfsan suffix on functions, which allows us to use normal UTC check lines. Otherwise we'd have to use --include-generated-funcs instead, which produces less nice results, as the check lines are not interleaved with the original functions anymore.


Patch is 44.30 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/161502.diff

9 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp (+8)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/arith.ll (+54-41)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll (+19-12)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll (+127-37)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/origin_phi.ll (+37-28)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/origin_track_load.ll (+19-20)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/phi.ll (+25-10)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/select.ll (+64-57)
  • (modified) llvm/test/Instrumentation/DataFlowSanitizer/vector.ll (+54-29)
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 480ff4a8c3cb9..55366ced34cd5 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -261,6 +261,11 @@ static cl::opt<bool> ClIgnorePersonalityRoutine(
              "list, do not create a wrapper for it."),
     cl::Hidden, cl::init(false));
 
+static cl::opt<bool> ClAddGlobalNameSuffix(
+    "dfsan-add-global-name-suffix",
+    cl::desc("Whether to add \\.dfsan suffix to global names"), cl::Hidden,
+    cl::init(true));
+
 static StringRef getGlobalTypeString(const GlobalValue &G) {
   // Types of GlobalVariables are always pointer types.
   Type *GType = G.getValueType();
@@ -1256,6 +1261,9 @@ DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) {
 }
 
 void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
+  if (!ClAddGlobalNameSuffix)
+    return;
+
   std::string GVName = std::string(GV->getName()), Suffix = ".dfsan";
   GV->setName(GVName + Suffix);
 
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll b/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
index 8c9eb5fa42fc3..2799f57545a97 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
@@ -1,73 +1,86 @@
-; RUN: opt < %s -passes=dfsan -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=dfsan -dfsan-add-global-name-suffix=0 -S | FileCheck %s
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 define i8 @add(i8 %a, i8 %b) {
-  ; CHECK: @add.dfsan
-  ; CHECK-DAG: %[[#ALABEL:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
-  ; CHECK-DAG: %[[#BLABEL:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
-  ; CHECK: %[[#UNION:]] = or i8 %[[#ALABEL]], %[[#BLABEL]]
-  ; CHECK: %c = add i8 %a, %b
-  ; CHECK: store i8 %[[#UNION]], ptr @__dfsan_retval_tls, align [[ALIGN]]
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @add(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = add i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = add i8 %a, %b
   ret i8 %c
 }
 
 define i8 @sub(i8 %a, i8 %b) {
-  ; CHECK: @sub.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = sub i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @sub(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = sub i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = sub i8 %a, %b
   ret i8 %c
 }
 
 define i8 @mul(i8 %a, i8 %b) {
-  ; CHECK: @mul.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = mul i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @mul(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = mul i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = mul i8 %a, %b
   ret i8 %c
 }
 
 define i8 @sdiv(i8 %a, i8 %b) {
-  ; CHECK: @sdiv.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = sdiv i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @sdiv(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = sdiv i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = sdiv i8 %a, %b
   ret i8 %c
 }
 
 define i8 @udiv(i8 %a, i8 %b) {
-  ; CHECK: @udiv.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: or i8
-  ; CHECK: %c = udiv i8 %a, %b
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret i8 %c
+; CHECK-LABEL: define i8 @udiv(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
+; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
+; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret i8 [[C]]
+;
   %c = udiv i8 %a, %b
   ret i8 %c
 }
 
 define double @fneg(double %a) {
-  ; CHECK: @fneg.dfsan
-  ; CHECK: load{{.*}}__dfsan_arg_tls
-  ; CHECK: %c = fneg double %a
-  ; CHECK: store{{.*}}__dfsan_retval_tls
-  ; CHECK: ret double %c
+; CHECK-LABEL: define double @fneg(
+; CHECK-SAME: double [[A:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[C:%.*]] = fneg double [[A]]
+; CHECK-NEXT:    store i8 [[TMP1]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret double [[C]]
+;
   %c = fneg double %a
   ret double %c
 }
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll b/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll
index 997681bb8e692..7574346eddbc2 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/dont_combine_offset_labels_on_gep.ll
@@ -1,19 +1,26 @@
-; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -S | FileCheck %s
-; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-add-global-name-suffix=0 -S | FileCheck %s
+; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -dfsan-add-global-name-suffix=0 -S | FileCheck %s --check-prefix=CHECK_ORIGIN
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
-; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
 define ptr @gepop(ptr %p, i32 %a, i32 %b, i32 %c) {
-  ; CHECK: @gepop.dfsan
-  ; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align [[ALIGN_O:4]]
-  ; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN_S:2]]
-  ; CHECK: %e = getelementptr [10 x [20 x i32]], ptr %p, i32 %a, i32 %b, i32 %c
-  ; CHECK: store i8 %[[#PS]], ptr @__dfsan_retval_tls, align [[ALIGN_S]]
-  ; CHECK_ORIGIN: store i32 %[[#PO]], ptr @__dfsan_retval_origin_tls, align [[ALIGN_O]]
-
+; CHECK-LABEL: define ptr @gepop(
+; CHECK-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[E:%.*]] = getelementptr [10 x [20 x i32]], ptr [[P]], i32 [[A]], i32 [[B]], i32 [[C]]
+; CHECK-NEXT:    store i8 [[TMP1]], ptr @__dfsan_retval_tls, align 2
+; CHECK-NEXT:    ret ptr [[E]]
+;
+; CHECK_ORIGIN-LABEL: define ptr @gepop(
+; CHECK_ORIGIN-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
+; CHECK_ORIGIN-NEXT:    [[TMP1:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
+; CHECK_ORIGIN-NEXT:    [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK_ORIGIN-NEXT:    [[E:%.*]] = getelementptr [10 x [20 x i32]], ptr [[P]], i32 [[A]], i32 [[B]], i32 [[C]]
+; CHECK_ORIGIN-NEXT:    store i8 [[TMP2]], ptr @__dfsan_retval_tls, align 2
+; CHECK_ORIGIN-NEXT:    store i32 [[TMP1]], ptr @__dfsan_retval_origin_tls, align 4
+; CHECK_ORIGIN-NEXT:    ret ptr [[E]]
+;
   %e = getelementptr [10 x [20 x i32]], ptr %p, i32 %a, i32 %b, i32 %c
   ret ptr %e
 }
-
diff --git a/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll b/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
index cb9a306eddd83..194a1934e5aad 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
@@ -1,4 +1,5 @@
-; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1  -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -dfsan-add-global-name-suffix=0 -S | FileCheck %s
 ;
 ; %i13 and %i15 have the same key in shadow cache. They should not reuse the same
 ; shadow because their blocks do not dominate each other. Origin tracking
@@ -7,43 +8,129 @@
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
 define void @cached_shadows(double %arg) {
-  ; CHECK: @cached_shadows.dfsan
-  ; CHECK:  [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align
-  ; CHECK:  [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
-  ; CHECK: [[L1:.+]]:
-  ; CHECK:  {{.*}} = phi i8
-  ; CHECK:  {{.*}} = phi i32
-  ; CHECK:  {{.*}} = phi double [ 3.000000e+00
-  ; CHECK:  [[S_L1:%.*]] = phi i8 [ 0, %[[L0:.*]] ], [ [[S_L7:%.*]], %[[L7:.*]] ]
-  ; CHECK:  [[O_L1:%.*]] = phi i32 [ 0, %[[L0]] ], [ [[O_L7:%.*]], %[[L7]] ]
-  ; CHECK:  [[V_L1:%.*]] = phi double [ 4.000000e+00, %[[L0]] ], [ [[V_L7:%.*]], %[[L7]] ]
-  ; CHECK:  br i1 {{%.+}}, label %[[L2:.*]], label %[[L4:.*]]
-  ; CHECK: [[L2]]:
-  ; CHECK:  br i1 {{%.+}}, label %[[L3:.+]], label %[[L7]]
-  ; CHECK: [[L3]]:
-  ; CHECK:  [[S_L3:%.*]] = or i8
-  ; CHECK:  [[AS_NE_L3:%.*]] = icmp ne i8 [[AS]], 0
-  ; CHECK:  [[O_L3:%.*]] = select i1 [[AS_NE_L3]], i32 %{{[0-9]+}}, i32 [[O_L1]]
-  ; CHECK:  [[V_L3:%.*]] = fsub double [[V_L1]], %{{.+}}
-  ; CHECK:  br label %[[L7]]
-  ; CHECK: [[L4]]:
-  ; CHECK:  br i1 %_dfscmp, label %[[L5:.+]], label %[[L6:.+]],
-  ; CHECK: [[L5]]:
-  ; CHECK:  br label %[[L6]]
-  ; CHECK: [[L6]]:
-  ; CHECK:  [[S_L6:%.*]] = or i8
-  ; CHECK:  [[AS_NE_L6:%.*]] = icmp ne i8 [[AS]], 0
-  ; CHECK:  [[O_L6:%.*]] = select i1 [[AS_NE_L6]], i32 [[AO]], i32 [[O_L1]]
-  ; CHECK:  [[V_L6:%.*]] = fadd double [[V_L1]], %{{.+}}
-  ; CHECK:  br label %[[L7]]
-  ; CHECK: [[L7]]:
-  ; CHECK:  [[S_L7]] = phi i8 [ [[S_L3]], %[[L3]] ], [ [[S_L1]], %[[L2]] ], [ [[S_L6]], %[[L6]] ]
-  ; CHECK:  [[O_L7]] = phi i32 [ [[O_L3]], %[[L3]] ], [ [[O_L1]], %[[L2]] ], [ [[O_L6]], %[[L6]] ]
-  ; CHECK:  [[V_L7]] = phi double [ [[V_L3]], %[[L3]] ], [ [[V_L1]], %[[L2]] ], [ [[V_L6]], %[[L6]] ]
-  ; CHECK:  br i1 %{{.+}}, label %[[L1]], label %[[L8:.+]]
-  ; CHECK: [[L8]]:
+; CHECK-LABEL: define void @cached_shadows(
+; CHECK-SAME: double [[ARG:%.*]]) {
+; CHECK-NEXT:  [[BB:.*]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
+; CHECK-NEXT:    [[I:%.*]] = alloca double, align 8
+; CHECK-NEXT:    [[I1:%.*]] = alloca double, align 8
+; CHECK-NEXT:    [[I2:%.*]] = bitcast ptr [[I]] to ptr
+; CHECK-NEXT:    [[TMP2:%.*]] = ptrtoint ptr [[I]] to i64
+; CHECK-NEXT:    [[TMP3:%.*]] = xor i64 [[TMP2]], 87960930222080
+; CHECK-NEXT:    [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
+; CHECK-NEXT:    store i64 0, ptr [[TMP4]], align 1
+; CHECK-NEXT:    store volatile double 1.000000e+00, ptr [[I]], align 8
+; CHECK-NEXT:    [[I3:%.*]] = bitcast ptr [[I1]] to ptr
+; CHECK-NEXT:    [[TMP5:%.*]] = ptrtoint ptr [[I1]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = xor i64 [[TMP5]], 87960930222080
+; CHECK-NEXT:    [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
+; CHECK-NEXT:    store i64 0, ptr [[TMP7]], align 1
+; CHECK-NEXT:    store volatile double 2.000000e+00, ptr [[I1]], align 8
+; CHECK-NEXT:    br label %[[BB4:.*]]
+; CHECK:       [[BB4]]:
+; CHECK-NEXT:    [[TMP8:%.*]] = phi i8 [ 0, %[[BB]] ], [ [[TMP76:%.*]], %[[BB16:.*]] ]
+; CHECK-NEXT:    [[TMP9:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP77:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[I5:%.*]] = phi double [ 3.000000e+00, %[[BB]] ], [ [[I17:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[TMP10:%.*]] = phi i8 [ 0, %[[BB]] ], [ [[TMP78:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[TMP11:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP79:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[I6:%.*]] = phi double [ 4.000000e+00, %[[BB]] ], [ [[I18:%.*]], %[[BB16]] ]
+; CHECK-NEXT:    [[TMP12:%.*]] = ptrtoint ptr [[I1]] to i64
+; CHECK-NEXT:    [[TMP13:%.*]] = xor i64 [[TMP12]], 87960930222080
+; CHECK-NEXT:    [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
+; CHECK-NEXT:    [[TMP15:%.*]] = add i64 [[TMP13]], 17592186044416
+; CHECK-NEXT:    [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr
+; CHECK-NEXT:    [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 8
+; CHECK-NEXT:    [[TMP18:%.*]] = load i64, ptr [[TMP14]], align 1
+; CHECK-NEXT:    [[TMP19:%.*]] = shl i64 [[TMP18]], 32
+; CHECK-NEXT:    [[TMP20:%.*]] = getelementptr i32, ptr [[TMP16]], i64 1
+; CHECK-NEXT:    [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 8
+; CHECK-NEXT:    [[TMP22:%.*]] = lshr i64 [[TMP18]], 32
+; CHECK-NEXT:    [[TMP23:%.*]] = or i64 [[TMP18]], [[TMP22]]
+; CHECK-NEXT:    [[TMP24:%.*]] = lshr i64 [[TMP23]], 16
+; CHECK-NEXT:    [[TMP25:%.*]] = or i64 [[TMP23]], [[TMP24]]
+; CHECK-NEXT:    [[TMP26:%.*]] = lshr i64 [[TMP25]], 8
+; CHECK-NEXT:    [[TMP27:%.*]] = or i64 [[TMP25]], [[TMP26]]
+; CHECK-NEXT:    [[TMP28:%.*]] = trunc i64 [[TMP27]] to i8
+; CHECK-NEXT:    [[TMP29:%.*]] = icmp ne i64 [[TMP19]], 0
+; CHECK-NEXT:    [[TMP30:%.*]] = select i1 [[TMP29]], i32 [[TMP17]], i32 [[TMP21]]
+; CHECK-NEXT:    [[I7:%.*]] = load volatile double, ptr [[I1]], align 8
+; CHECK-NEXT:    [[I8:%.*]] = fcmp une double [[I7]], 0.000000e+00
+; CHECK-NEXT:    [[TMP31:%.*]] = ptrtoint ptr [[I1]] to i64
+; CHECK-NEXT:    [[TMP32:%.*]] = xor i64 [[TMP31]], 87960930222080
+; CHECK-NEXT:    [[TMP33:%.*]] = inttoptr i64 [[TMP32]] to ptr
+; CHECK-NEXT:    [[TMP34:%.*]] = add i64 [[TMP32]], 17592186044416
+; CHECK-NEXT:    [[TMP35:%.*]] = inttoptr i64 [[TMP34]] to ptr
+; CHECK-NEXT:    [[TMP36:%.*]] = load i32, ptr [[TMP35]], align 8
+; CHECK-NEXT:    [[TMP37:%.*]] = load i64, ptr [[TMP33]], align 1
+; CHECK-NEXT:    [[TMP38:%.*]] = shl i64 [[TMP37]], 32
+; CHECK-NEXT:    [[TMP39:%.*]] = getelementptr i32, ptr [[TMP35]], i64 1
+; CHECK-NEXT:    [[TMP40:%.*]] = load i32, ptr [[TMP39]], align 8
+; CHECK-NEXT:    [[TMP41:%.*]] = lshr i64 [[TMP37]], 32
+; CHECK-NEXT:    [[TMP42:%.*]] = or i64 [[TMP37]], [[TMP41]]
+; CHECK-NEXT:    [[TMP43:%.*]] = lshr i64 [[TMP42]], 16
+; CHECK-NEXT:    [[TMP44:%.*]] = or i64 [[TMP42]], [[TMP43]]
+; CHECK-NEXT:    [[TMP45:%.*]] = lshr i64 [[TMP44]], 8
+; CHECK-NEXT:    [[TMP46:%.*]] = or i64 [[TMP44]], [[TMP45]]
+; CHECK-NEXT:    [[TMP47:%.*]] = trunc i64 [[TMP46]] to i8
+; CHECK-NEXT:    [[TMP48:%.*]] = icmp ne i64 [[TMP38]], 0
+; CHECK-NEXT:    [[TMP49:%.*]] = select i1 [[TMP48]], i32 [[TMP36]], i32 [[TMP40]]
+; CHECK-NEXT:    [[I9:%.*]] = load volatile double, ptr [[I1]], align 8
+; CHECK-NEXT:    br i1 [[I8]], label %[[BB10:.*]], label %[[BB14:.*]]
+; CHECK:       [[BB10]]:
+; CHECK-NEXT:    [[I11:%.*]] = fcmp une double [[I9]], 0.000000e+00
+; CHECK-NEXT:    br i1 [[I11]], label %[[BB12:.*]], label %[[BB16]]
+; CHECK:       [[BB12]]:
+; CHECK-NEXT:    [[TMP50:%.*]] = or i8 [[TMP10]], [[TMP1]]
+; CHECK-NEXT:    [[TMP51:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP52:%.*]] = select i1 [[TMP51]], i32 [[TMP0]], i32 [[TMP11]]
+; CHECK-NEXT:    [[I13:%.*]] = fsub double [[I6]], [[ARG]]
+; CHECK-NEXT:    br label %[[BB16]]
+; CHECK:       [[BB14]]:
+; CHECK-NEXT:    [[TMP53:%.*]] = ptrtoint ptr [[I]] to i64
+; CHECK-NEXT:    [[TMP54:%.*]] = xor i64 [[TMP53]], 87960930222080
+; CHECK-NEXT:    [[TMP55:%.*]] = inttoptr i64 [[TMP54]] to ptr
+; CHECK-NEXT:    [[TMP56:%.*]] = add i64 [[TMP54]], 17592186044416
+; CHECK-NEXT:    [[TMP57:%.*]] = inttoptr i64 [[TMP56]] to ptr
+; CHECK-NEXT:    [[TMP58:%.*]] = insertelement <8 x i8> poison, i8 [[TMP47]], i32 0
+; CHECK-NEXT:    [[TMP59:%.*]] = insertelement <8 x i8> [[TMP58]], i8 [[TMP47]], i32 1
+; CHECK-NEXT:    [[TMP60:%.*]] = insertelement <8 x i8> [[TMP59]], i8 [[TMP47]], i32 2
+; CHECK-NEXT:    [[TMP61:%.*]] = insertelement <8 x i8> [[TMP60]], i8 [[TMP47]], i32 3
+; CHECK-NEXT:    [[TMP62:%.*]] = insertelement <8 x i8> [[TMP61]], i8 [[TMP47]], i32 4
+; CHECK-NEXT:    [[TMP63:%.*]] = insertelement <8 x i8> [[TMP62]], i8 [[TMP47]], i32 5
+; CHECK-NEXT:    [[TMP64:%.*]] = insertelement <8 x i8> [[TMP63]], i8 [[TMP47]], i32 6
+; CHECK-NEXT:    [[TMP65:%.*]] = insertelement <8 x i8> [[TMP64]], i8 [[TMP47]], i32 7
+; CHECK-NEXT:    [[TMP66:%.*]] = getelementptr <8 x i8>, ptr [[TMP55]], i32 0
+; CHECK-NEXT:    store <8 x i8> [[TMP65]], ptr [[TMP66]], align 1
+; CHECK-NEXT:    [[_DFSCMP:%.*]] = icmp ne i8 [[TMP47]], 0
+; CHECK-NEXT:    br i1 [[_DFSCMP]], label %[[BB67:.*]], label %[[BB72:.*]], !prof [[PROF1:![0-9]+]]
+; CHECK:       [[BB67]]:
+; CHECK-NEXT:    [[TMP68:%.*]] = call i32 @__dfsan_chain_origin(i32 [[TMP49]])
+; CHECK-NEXT:    [[TMP69:%.*]] = zext i32 [[TMP68]] to i64
+; CHECK-NEXT:    [[TMP70:%.*]] = shl i64 [[TMP69]], 32
+; CHECK-NEXT:    [[TMP71:%.*]] = or i64 [[TMP69]], [[TMP70]]
+; CHECK-NEXT:    store i64 [[TMP71]], ptr [[TMP57]], align 8
+; CHECK-NEXT:    br label %[[BB72]]
+; CHECK:       [[BB72]]:
+; CHECK-NEXT:    store volatile double [[I9]], ptr [[I]], align 8
+; CHECK-NEXT:    [[TMP73:%.*]] = or i8 [[TMP10]], [[TMP1]]
+; CHECK-NEXT:    [[TMP74:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP75:%.*]] = select i1 [[TMP74]], i32 [[TMP0]], i32 [[TMP11]]
+; CHECK-NEXT:    [[I15:%.*]] = fadd double [[I6]], [[ARG]]
+; CHECK-NEXT:    br label %[[BB16]]
+; CHECK:       [[BB16]]:
+; CHECK-NEXT:    [[TMP76]] = phi i8 [ [[TMP10]], %[[BB12]] ], [ [[TMP8]], %[[BB10]] ], [ [[TMP10]], %[[BB72]] ]
+; CHECK-NEXT:    [[TMP77]] = phi i32 [ [[TMP11]], %[[BB12]] ], [ [[TMP9]], %[[BB10]] ], [ [[TMP11]], %[[BB72]] ]
+; CHECK-NEXT:    [[I17]] = phi double [ [[I6]], %[[BB12]] ], [ [[I5]], %[[BB10]] ], [ [[I6]], %[[BB72]] ]
+; CHECK-NEXT:    [[TMP78]] = phi i8 [ [[TMP50]], %[[BB12]] ], [ [[TMP10]], %[[BB10]] ], [ [[TMP73]], %[[BB72]] ]
+; CHECK-NEXT:    [[TMP79]] = phi i32 [ [[TMP52]], %[[BB12]] ], [ [[TMP11]], %[[BB10]] ], [ [[TMP75]], %[[BB72]] ]
+; CHECK-NEXT:    [[I18]] = phi double [ [[I13]], %[[BB12]] ], [ [[I6]], %[[BB10]] ], [ [[I15]], %[[BB72]] ]
+; CHECK-NEXT:    [[I19:%.*]] = fcmp olt double [[I17]], 9.900000e+01
+; CHECK-NEXT:    br i1 [[I19]], label %[[BB4]], label %[[BB20:.*]]
+; CHECK:       [[BB20]]:
+; CHECK-NEXT:    ret void
+;
 bb:
   %i = alloca double...
[truncated]

target triple = "x86_64-unknown-linux-gnu"

; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could retain these using --check-globals, but this doesn't really seem relevant for the individual tests.

@nikic nikic force-pushed the dfsan-tests-2 branch 2 times, most recently from 54cf258 to b779d4c Compare October 6, 2025 13:22
Generate test checks for some dfsan tests with UTC to make them
easier to update.

For this purpose I've added a `-dfsan-add-global-name-suffix=0`
option to avoid the addition of the `.dfsan` suffix on functions,
which allows us to use normal UTC check lines. Otherwise we'd
have to use `--include-generated-funcs` instead, which produces
less nice results, as the check lines are not interleaved with
the original functions anymore.
@nikic
Copy link
Contributor Author

nikic commented Oct 6, 2025

I've changed a few more tests to be generated. For now I'm leaving along tests where multiple configurations are tested and that leads to significant increase in check line size.

@nikic nikic merged commit a0ed47d into llvm:main Oct 7, 2025
9 checks passed
@nikic nikic deleted the dfsan-tests-2 branch October 7, 2025 07:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants