[llvm-branch-commits] [llvm] 80e326a - [dfsan] Support passing non-i16 shadow values in TLS mode

Jianzhou Zhao via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Dec 3 18:51:19 PST 2020


Author: Jianzhou Zhao
Date: 2020-12-04T02:45:07Z
New Revision: 80e326a8c4cfae770c10d7bb3d0ae291011bd91f

URL: https://github.com/llvm/llvm-project/commit/80e326a8c4cfae770c10d7bb3d0ae291011bd91f
DIFF: https://github.com/llvm/llvm-project/commit/80e326a8c4cfae770c10d7bb3d0ae291011bd91f.diff

LOG: [dfsan] Support passing non-i16 shadow values in TLS mode

This is a child diff of D92261.

It extended TLS arg/ret to work with aggregate types.

For a function
  t foo(t1 a1, t2 a2, ... tn an)
Its arguments shadow are saved in TLS args like
  a1_s, a2_s, ..., an_s
TLS ret simply includes r_s. By calculating the type size of each shadow
value, we can get their offset.

This is similar to what MSan does. See __msan_retval_tls and __msan_param_tls
from llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp.

Note that this change does not add test cases for overflowed TLS
arg/ret because this is hard to test w/o supporting aggregate shdow
types. We will be adding them after supporting that.

Reviewed-by: morehouse

Differential Revision: https://reviews.llvm.org/D92440

Added: 
    

Modified: 
    compiler-rt/lib/dfsan/dfsan.cpp
    llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
    llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
    llvm/test/Instrumentation/DataFlowSanitizer/call.ll
    llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
    llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll
    llvm/test/Instrumentation/DataFlowSanitizer/load.ll
    llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
    llvm/test/Instrumentation/DataFlowSanitizer/select.ll

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp
index db610857834c..c17bfe0ccb32 100644
--- a/compiler-rt/lib/dfsan/dfsan.cpp
+++ b/compiler-rt/lib/dfsan/dfsan.cpp
@@ -41,8 +41,15 @@ static dfsan_label_info __dfsan_label_info[kNumLabels];
 
 Flags __dfsan::flags_data;
 
-SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_retval_tls;
-SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64];
+// The size of TLS variables. These constants must be kept in sync with the ones
+// in DataFlowSanitizer.cpp.
+static const int kDFsanArgTlsSize = 800;
+static const int kDFsanRetvalTlsSize = 800;
+
+SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64
+    __dfsan_retval_tls[kDFsanRetvalTlsSize / sizeof(u64)];
+SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64
+    __dfsan_arg_tls[kDFsanArgTlsSize / sizeof(u64)];
 
 SANITIZER_INTERFACE_ATTRIBUTE uptr __dfsan_shadow_ptr_mask;
 

diff  --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 9dad9817acea..fc784e72797c 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -106,6 +106,14 @@
 
 using namespace llvm;
 
+// This must be consistent with ShadowWidthBits.
+static const Align kShadowTLSAlignment = Align(2);
+
+// The size of TLS variables. These constants must be kept in sync with the ones
+// in dfsan.cpp.
+static const unsigned kArgTLSSize = 800;
+static const unsigned kRetvalTLSSize = 800;
+
 // External symbol to be used when generating the shadow address for
 // architectures with multiple VMAs. Instead of using a constant integer
 // the runtime will set the external mask based on the VMA range.
@@ -447,7 +455,14 @@ struct DFSanFunction {
     AvoidNewBlocks = F->size() > 1000;
   }
 
-  Value *getArgTLS(unsigned Index, Instruction *Pos);
+  /// Computes the shadow address for a given function argument.
+  ///
+  /// Shadow = ArgTLS+ArgOffset.
+  Value *getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB);
+
+  /// Computes the shadow address for a retval.
+  Value *getRetvalTLS(IRBuilder<> &IRB);
+
   Value *getShadow(Value *V);
   void setShadow(Instruction *I, Value *Shadow);
   Value *combineShadows(Value *V1, Value *V2, Instruction *Pos);
@@ -456,6 +471,10 @@ struct DFSanFunction {
                     Instruction *Pos);
   void storeShadow(Value *Addr, uint64_t Size, Align Alignment, Value *Shadow,
                    Instruction *Pos);
+
+private:
+  /// Returns the shadow value of an argument A.
+  Value *getShadowForTLSArgument(Argument *A);
 };
 
 class DFSanVisitor : public InstVisitor<DFSanVisitor> {
@@ -816,13 +835,15 @@ bool DataFlowSanitizer::runImpl(Module &M) {
 
   bool Changed = false;
 
-  Type *ArgTLSTy = ArrayType::get(PrimitiveShadowTy, 64);
+  Type *ArgTLSTy = ArrayType::get(Type::getInt64Ty(*Ctx), kArgTLSSize / 8);
   ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
   if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS)) {
     Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
     G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
   }
-  RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", PrimitiveShadowTy);
+  Type *RetvalTLSTy =
+      ArrayType::get(Type::getInt64Ty(*Ctx), kRetvalTLSSize / 8);
+  RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", RetvalTLSTy);
   if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS)) {
     Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
     G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
@@ -1054,10 +1075,48 @@ bool DataFlowSanitizer::runImpl(Module &M) {
          M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize;
 }
 
-Value *DFSanFunction::getArgTLS(unsigned Idx, Instruction *Pos) {
-  IRBuilder<> IRB(Pos);
-  return IRB.CreateConstGEP2_64(ArrayType::get(DFS.PrimitiveShadowTy, 64),
-                                DFS.ArgTLS, 0, Idx);
+Value *DFSanFunction::getArgTLS(unsigned ArgOffset, IRBuilder<> &IRB) {
+  Value *Base = IRB.CreatePointerCast(DFS.ArgTLS, DFS.IntptrTy);
+  if (ArgOffset)
+    Base = IRB.CreateAdd(Base, ConstantInt::get(DFS.IntptrTy, ArgOffset));
+  return IRB.CreateIntToPtr(Base, PointerType::get(DFS.PrimitiveShadowTy, 0),
+                            "_dfsarg");
+}
+
+Value *DFSanFunction::getRetvalTLS(IRBuilder<> &IRB) {
+  return IRB.CreatePointerCast(
+      DFS.RetvalTLS, PointerType::get(DFS.PrimitiveShadowTy, 0), "_dfsret");
+}
+
+Value *DFSanFunction::getShadowForTLSArgument(Argument *A) {
+  unsigned ArgOffset = 0;
+  const DataLayout &DL = F->getParent()->getDataLayout();
+  for (auto &FArg : F->args()) {
+    if (!FArg.getType()->isSized()) {
+      if (A == &FArg)
+        break;
+      continue;
+    }
+
+    unsigned Size = DL.getTypeAllocSize(DFS.PrimitiveShadowTy);
+    if (A != &FArg) {
+      ArgOffset += alignTo(Size, kShadowTLSAlignment);
+      if (ArgOffset > kArgTLSSize)
+        break; // ArgTLS overflows, uses a zero shadow.
+      continue;
+    }
+
+    if (ArgOffset + Size > kArgTLSSize)
+      break; // ArgTLS overflows, uses a zero shadow.
+
+    Instruction *ArgTLSPos = &*F->getEntryBlock().begin();
+    IRBuilder<> IRB(ArgTLSPos);
+    Value *ArgShadowPtr = getArgTLS(ArgOffset, IRB);
+    return IRB.CreateAlignedLoad(DFS.PrimitiveShadowTy, ArgShadowPtr,
+                                 kShadowTLSAlignment);
+  }
+
+  return DFS.ZeroPrimitiveShadow;
 }
 
 Value *DFSanFunction::getShadow(Value *V) {
@@ -1070,13 +1129,7 @@ Value *DFSanFunction::getShadow(Value *V) {
         return DFS.ZeroPrimitiveShadow;
       switch (IA) {
       case DataFlowSanitizer::IA_TLS: {
-        Value *ArgTLSPtr = DFS.ArgTLS;
-        Instruction *ArgTLSPos =
-            DFS.ArgTLS ? &*F->getEntryBlock().begin()
-                       : cast<Instruction>(ArgTLSPtr)->getNextNode();
-        IRBuilder<> IRB(ArgTLSPos);
-        Shadow = IRB.CreateLoad(DFS.PrimitiveShadowTy,
-                                getArgTLS(A->getArgNo(), ArgTLSPos));
+        Shadow = getShadowForTLSArgument(A);
         break;
       }
       case DataFlowSanitizer::IA_Args: {
@@ -1595,7 +1648,13 @@ void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
     case DataFlowSanitizer::IA_TLS: {
       Value *S = DFSF.getShadow(RI.getReturnValue());
       IRBuilder<> IRB(&RI);
-      IRB.CreateStore(S, DFSF.DFS.RetvalTLS);
+      unsigned Size =
+          getDataLayout().getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
+      if (Size <= kRetvalTLSSize) {
+        // If the size overflows, stores nothing. At callsite, oversized return
+        // shadows are set to zero.
+        IRB.CreateAlignedStore(S, DFSF.getRetvalTLS(IRB), kShadowTLSAlignment);
+      }
       break;
     }
     case DataFlowSanitizer::IA_Args: {
@@ -1752,9 +1811,18 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
 
   FunctionType *FT = CB.getFunctionType();
   if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
-    for (unsigned i = 0, n = FT->getNumParams(); i != n; ++i) {
-      IRB.CreateStore(DFSF.getShadow(CB.getArgOperand(i)),
-                      DFSF.getArgTLS(i, &CB));
+    unsigned ArgOffset = 0;
+    const DataLayout &DL = getDataLayout();
+    for (unsigned I = 0, N = FT->getNumParams(); I != N; ++I) {
+      unsigned Size = DL.getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
+      // Stop storing if arguments' size overflows. Inside a function, arguments
+      // after overflow have zero shadow values.
+      if (ArgOffset + Size > kArgTLSSize)
+        break;
+      IRB.CreateAlignedStore(DFSF.getShadow(CB.getArgOperand(I)),
+                             DFSF.getArgTLS(ArgOffset, IRB),
+                             kShadowTLSAlignment);
+      ArgOffset += alignTo(Size, kShadowTLSAlignment);
     }
   }
 
@@ -1775,11 +1843,19 @@ void DFSanVisitor::visitCallBase(CallBase &CB) {
 
     if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
       IRBuilder<> NextIRB(Next);
-      LoadInst *LI =
-          NextIRB.CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.DFS.RetvalTLS);
-      DFSF.SkipInsts.insert(LI);
-      DFSF.setShadow(&CB, LI);
-      DFSF.NonZeroChecks.push_back(LI);
+      const DataLayout &DL = getDataLayout();
+      unsigned Size = DL.getTypeAllocSize(DFSF.DFS.PrimitiveShadowTy);
+      if (Size > kRetvalTLSSize) {
+        // Set overflowed return shadow to be zero.
+        DFSF.setShadow(&CB, DFSF.DFS.ZeroPrimitiveShadow);
+      } else {
+        LoadInst *LI = NextIRB.CreateAlignedLoad(
+            DFSF.DFS.PrimitiveShadowTy, DFSF.getRetvalTLS(NextIRB),
+            kShadowTLSAlignment, "_dfsret");
+        DFSF.SkipInsts.insert(LI);
+        DFSF.setShadow(&CB, LI);
+        DFSF.NonZeroChecks.push_back(LI);
+      }
     }
   }
 

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll b/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
index 3ea78552e4f6..c93d00e2d3e5 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
@@ -4,12 +4,12 @@ target triple = "x86_64-unknown-linux-gnu"
 
 define i8 @add(i8 %a, i8 %b) {
   ; CHECK: @"dfs$add"
-  ; CHECK-DAG: %[[ALABEL:.*]] = load{{.*}}__dfsan_arg_tls, i64 0, i64 0
-  ; CHECK-DAG: %[[BLABEL:.*]] = load{{.*}}__dfsan_arg_tls, i64 0, i64 1
-  ; CHECK: %[[UNION:.*]] = call{{.*}}__dfsan_union(i16 zeroext %[[ALABEL]], i16 zeroext %[[BLABEL]])
-  ; CHECK: %[[ADDLABEL:.*]] = phi i16 [ %[[UNION]], {{.*}} ], [ %[[ALABEL]], {{.*}} ]
+  ; CHECK-DAG: %[[ALABEL:.*]] = load [[SHADOWTYPE:i16]], [[SHADOWTYPE]]* bitcast ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to [[SHADOWTYPE]]*), align [[ALIGN:2]]
+  ; CHECK-DAG: %[[BLABEL:.*]] = load [[SHADOWTYPE]], [[SHADOWTYPE]]* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to [[SHADOWTYPE]]*), align [[ALIGN]]
+  ; CHECK: %[[UNION:.*]] = call zeroext [[SHADOWTYPE]] @__dfsan_union([[SHADOWTYPE]] zeroext %[[ALABEL]], [[SHADOWTYPE]] zeroext %[[BLABEL]])
+  ; CHECK: %[[ADDLABEL:.*]] = phi [[SHADOWTYPE]] [ %[[UNION]], {{.*}} ], [ %[[ALABEL]], {{.*}} ]
   ; CHECK: add i8
-  ; CHECK: store i16 %[[ADDLABEL]], i16* @__dfsan_retval_tls
+  ; CHECK: store [[SHADOWTYPE]] %[[ADDLABEL]], [[SHADOWTYPE]]* bitcast ([100 x i64]* @__dfsan_retval_tls to [[SHADOWTYPE]]*), align [[ALIGN]]
   ; CHECK: ret i8
   %c = add i8 %a, %b
   ret i8 %c

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/call.ll b/llvm/test/Instrumentation/DataFlowSanitizer/call.ll
index 4d9c8e999cf6..feb8ff691058 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/call.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/call.ll
@@ -4,10 +4,10 @@ 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"
 
 ; CHECK-LABEL: @__dfsan_arg_tls
-; CHECK: = external thread_local(initialexec) global [64 x i16]
+; CHECK: = external thread_local(initialexec) global [100 x i64]
 
 ; CHECK-LABEL: @__dfsan_retval_tls
-; CHECK: = external thread_local(initialexec) global i16
+; CHECK: = external thread_local(initialexec) global [100 x i64]
 
 declare i32 @f(i32)
 declare float @llvm.sqrt.f32(float)

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
index 6e7628441808..7194535b4f69 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/callback.ll
@@ -22,7 +22,7 @@ define void @store8(i8* %p, i8 %a) {
 define i1 @cmp(i8 %a, i8 %b) {
   ; CHECK: call void @__dfsan_cmp_callback(i16 %[[l:.*]])
   ; CHECK: %c = icmp ne i8 %a, %b
-  ; CHECK: store i16 %[[l]], i16* @__dfsan_retval_tls
+  ; CHECK: store i16 %[[l]], i16* bitcast ({{.*}}* @__dfsan_retval_tls to i16*)
   
   %c = icmp ne i8 %a, %b
   ret i1 %c

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll b/llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll
index 85f99f5b1828..2a369194d63c 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/fast16labels.ll
@@ -6,11 +6,11 @@ target triple = "x86_64-unknown-linux-gnu"
 
 define i8 @add(i8 %a, i8 %b) {
   ; CHECK-LABEL: define i8 @"dfs$add"
-  ; CHECK-DAG: %[[ALABEL:.*]] = load{{.*}}__dfsan_arg_tls, i64 0, i64 0
-  ; CHECK-DAG: %[[BLABEL:.*]] = load{{.*}}__dfsan_arg_tls, i64 0, i64 1
+  ; CHECK-DAG: %[[ALABEL:.*]] = load [[ST:.*]], [[ST]]* bitcast ([[VT:\[.*\]]]* @__dfsan_arg_tls to [[ST]]*), align [[ALIGN:2]]
+  ; CHECK-DAG: %[[BLABEL:.*]] = load [[ST]], [[ST]]* inttoptr (i64 add (i64 ptrtoint ([[VT]]* @__dfsan_arg_tls to i64), i64 2) to [[ST]]*), align [[ALIGN]]
   ; CHECK: %[[ADDLABEL:.*]] = or i16 %[[ALABEL]], %[[BLABEL]]
   ; CHECK: add i8
-  ; CHECK: store i16 %[[ADDLABEL]], i16* @__dfsan_retval_tls
+  ; CHECK: store [[ST]] %[[ADDLABEL]], [[ST]]* bitcast ([[VT]]* @__dfsan_retval_tls to [[ST]]*), align [[ALIGN]]
   ; CHECK: ret i8
   %c = add i8 %a, %b
   ret i8 %c

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/load.ll b/llvm/test/Instrumentation/DataFlowSanitizer/load.ll
index 9cdf69d11ddb..74f3f8bcee51 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/load.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/load.ll
@@ -170,8 +170,8 @@ define i64 @load64(i64* %p) {
 @X = constant i1 1
 define i1 @load_global() {
   ; NO_COMBINE_PTR_LABEL: @"dfs$load_global"
-  ; NO_COMBINE_PTR_LABEL: store i16 0, i16* @__dfsan_retval_tls, align 2
+  ; NO_COMBINE_PTR_LABEL: store i16 0, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align 2
 
   %a = load i1, i1* @X
   ret i1 %a
-}
\ No newline at end of file
+}

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll b/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
index 08c457f3bfc7..6ef8fef85de1 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/phi.ll
@@ -3,9 +3,9 @@ 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 {i32, i32} @test({i32, i32} %a, i1 %c) {
-  ; CHECK: [[E0:%.*]] = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0), align 2
+  ; CHECK: [[E0:%.*]] = load i16, i16* bitcast ([100 x i64]* @__dfsan_arg_tls to i16*), align [[ALIGN:2]]
   ; CHECK: [[E3:%.*]] = phi i16 [ [[E0]], %T ], [ [[E0]], %F ]
-  ; CHECK: store i16 [[E3]], i16* @__dfsan_retval_tls, align 2
+  ; CHECK: store i16 [[E3]], i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
 
 entry:
   br i1 %c, label %T, label %F

diff  --git a/llvm/test/Instrumentation/DataFlowSanitizer/select.ll b/llvm/test/Instrumentation/DataFlowSanitizer/select.ll
index 275f8282da16..d97fe2d06916 100644
--- a/llvm/test/Instrumentation/DataFlowSanitizer/select.ll
+++ b/llvm/test/Instrumentation/DataFlowSanitizer/select.ll
@@ -4,23 +4,25 @@ 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 @select8(i1 %c, i8 %t, i8 %f) {
-  ; TRACK_CONTROL_FLOW: %1 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 2)
-  ; TRACK_CONTROL_FLOW: %2 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 1)
-  ; TRACK_CONTROL_FLOW: %3 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0)
+  ; TRACK_CONTROL_FLOW: @"dfs$select8"
+  ; TRACK_CONTROL_FLOW: %1 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to i64), i64 4) to i16*), align [[ALIGN:2]]
+  ; TRACK_CONTROL_FLOW: %2 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i16*), align [[ALIGN]]
+  ; TRACK_CONTROL_FLOW: %3 = load i16, i16* bitcast ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i16*), align [[ALIGN]]
   ; TRACK_CONTROL_FLOW: %4 = select i1 %c, i16 %2, i16 %1
   ; TRACK_CONTROL_FLOW: %5 = icmp ne i16 %3, %4
   ; TRACK_CONTROL_FLOW: %7 = call {{.*}} i16 @__dfsan_union(i16 {{.*}} %3, i16 {{.*}} %4)
   ; TRACK_CONTROL_FLOW: %9 = phi i16 [ %7, {{.*}} ], [ %3, {{.*}} ]
   ; TRACK_CONTROL_FLOW: %a = select i1 %c, i8 %t, i8 %f
-  ; TRACK_CONTROL_FLOW: store i16 %9, i16* @__dfsan_retval_tls
+  ; TRACK_CONTROL_FLOW: store i16 %9, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
   ; TRACK_CONTROL_FLOW: ret i8 %a
   
-  ; NO_TRACK_CONTROL_FLOW: %1 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 2)
-  ; NO_TRACK_CONTROL_FLOW: %2 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 1)
-  ; NO_TRACK_CONTROL_FLOW: %3 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0)
+  ; NO_TRACK_CONTROL_FLOW: @"dfs$select8"
+  ; NO_TRACK_CONTROL_FLOW: %1 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to i64), i64 4) to i16*), align [[ALIGN:2]]
+  ; NO_TRACK_CONTROL_FLOW: %2 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i16*), align [[ALIGN]]
+  ; NO_TRACK_CONTROL_FLOW: %3 = load i16, i16* bitcast ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i16*), align [[ALIGN]]
   ; NO_TRACK_CONTROL_FLOW: %4 = select i1 %c, i16 %2, i16 %1
   ; NO_TRACK_CONTROL_FLOW: %a = select i1 %c, i8 %t, i8 %f
-  ; NO_TRACK_CONTROL_FLOW: store i16 %4, i16* @__dfsan_retval_tls
+  ; NO_TRACK_CONTROL_FLOW: store i16 %4, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
   ; NO_TRACK_CONTROL_FLOW: ret i8 %a
 
   %a = select i1 %c, i8 %t, i8 %f
@@ -28,19 +30,21 @@ define i8 @select8(i1 %c, i8 %t, i8 %f) {
 }
 
 define i8 @select8e(i1 %c, i8 %tf) {
-  ; TRACK_CONTROL_FLOW: %1 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 1)
-  ; TRACK_CONTROL_FLOW: %2 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0)
+  ; TRACK_CONTROL_FLOW: @"dfs$select8e"
+  ; TRACK_CONTROL_FLOW: %1 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i16*), align [[ALIGN]]
+  ; TRACK_CONTROL_FLOW: %2 = load i16, i16* bitcast ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i16*), align [[ALIGN]]
   ; TRACK_CONTROL_FLOW: %3 = icmp ne i16 %2, %1
   ; TRACK_CONTROL_FLOW: %5 = call {{.*}} i16 @__dfsan_union(i16 {{.*}} %2, i16 {{.*}} %1)
   ; TRACK_CONTROL_FLOW: %7 = phi i16 [ %5, {{.*}} ], [ %2, {{.*}} ]
   ; TRACK_CONTROL_FLOW: %a = select i1 %c, i8 %tf, i8 %tf
-  ; TRACK_CONTROL_FLOW: store i16 %7, i16* @__dfsan_retval_tls
+  ; TRACK_CONTROL_FLOW: store i16 %7, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
   ; TRACK_CONTROL_FLOW: ret i8 %a
   
-  ; NO_TRACK_CONTROL_FLOW: %1 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 1)
-  ; NO_TRACK_CONTROL_FLOW: %2 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0)
+  ; NO_TRACK_CONTROL_FLOW: @"dfs$select8e"
+  ; NO_TRACK_CONTROL_FLOW: %1 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i16*), align [[ALIGN]]
+  ; NO_TRACK_CONTROL_FLOW: %2 = load i16, i16* bitcast ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i16*), align [[ALIGN]]
   ; NO_TRACK_CONTROL_FLOW: %a = select i1 %c, i8 %tf, i8 %tf
-  ; NO_TRACK_CONTROL_FLOW: store i16 %1, i16* @__dfsan_retval_tls
+  ; NO_TRACK_CONTROL_FLOW: store i16 %1, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
   ; NO_TRACK_CONTROL_FLOW: ret i8 %a
 
   %a = select i1 %c, i8 %tf, i8 %tf
@@ -48,9 +52,10 @@ define i8 @select8e(i1 %c, i8 %tf) {
 }
 
 define <4 x i8> @select8v(<4 x i1> %c, <4 x i8> %t, <4 x i8> %f) {
-  ; TRACK_CONTROL_FLOW: %1 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 2)
-  ; TRACK_CONTROL_FLOW: %2 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 1)
-  ; TRACK_CONTROL_FLOW: %3 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0)
+  ; TRACK_CONTROL_FLOW: @"dfs$select8v"
+  ; TRACK_CONTROL_FLOW: %1 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to i64), i64 4) to i16*), align [[ALIGN:2]]
+  ; TRACK_CONTROL_FLOW: %2 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i16*), align [[ALIGN]]
+  ; TRACK_CONTROL_FLOW: %3 = load i16, i16* bitcast ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i16*), align [[ALIGN]]
   ; TRACK_CONTROL_FLOW: %4 = icmp ne i16 %2, %1
   ; TRACK_CONTROL_FLOW: %6 = call {{.*}} i16 @__dfsan_union(i16 {{.*}} %2, i16 zeroext %1)
   ; TRACK_CONTROL_FLOW: %8 = phi i16 [ %6, {{.*}} ], [ %2, {{.*}} ]
@@ -58,17 +63,18 @@ define <4 x i8> @select8v(<4 x i1> %c, <4 x i8> %t, <4 x i8> %f) {
   ; TRACK_CONTROL_FLOW: %11 = call {{.*}} i16 @__dfsan_union(i16 {{.*}} %3, i16 zeroext %8)
   ; TRACK_CONTROL_FLOW: %13 = phi i16 [ %11, {{.*}} ], [ %3, {{.*}} ]
   ; TRACK_CONTROL_FLOW: %a = select <4 x i1> %c, <4 x i8> %t, <4 x i8> %f
-  ; TRACK_CONTROL_FLOW: store i16 %13, i16* @__dfsan_retval_tls
+  ; TRACK_CONTROL_FLOW: store i16 %13, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
   ; TRACK_CONTROL_FLOW: ret <4 x i8> %a
 
-  ; NO_TRACK_CONTROL_FLOW: %1 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 2)
-  ; NO_TRACK_CONTROL_FLOW: %2 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 1)
-  ; NO_TRACK_CONTROL_FLOW: %3 = load i16, i16* getelementptr inbounds ([64 x i16], [64 x i16]* @__dfsan_arg_tls, i64 0, i64 0)
+  ; NO_TRACK_CONTROL_FLOW: @"dfs$select8v"
+  ; NO_TRACK_CONTROL_FLOW: %1 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE:\[100 x i64\]]]* @__dfsan_arg_tls to i64), i64 4) to i16*), align [[ALIGN:2]]
+  ; NO_TRACK_CONTROL_FLOW: %2 = load i16, i16* inttoptr (i64 add (i64 ptrtoint ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i64), i64 2) to i16*), align [[ALIGN]]
+  ; NO_TRACK_CONTROL_FLOW: %3 = load i16, i16* bitcast ([[ARGTLSTYPE]]* @__dfsan_arg_tls to i16*), align [[ALIGN]]
   ; NO_TRACK_CONTROL_FLOW: %4 = icmp ne i16 %2, %1
   ; NO_TRACK_CONTROL_FLOW: %6 = call {{.*}} i16 @__dfsan_union(i16 {{.*}} %2, i16 {{.*}} %1)
   ; NO_TRACK_CONTROL_FLOW: %8 = phi i16 [ %6, {{.*}} ], [ %2, {{.*}} ]
   ; NO_TRACK_CONTROL_FLOW: %a = select <4 x i1> %c, <4 x i8> %t, <4 x i8> %f
-  ; NO_TRACK_CONTROL_FLOW: store i16 %8, i16* @__dfsan_retval_tls
+  ; NO_TRACK_CONTROL_FLOW: store i16 %8, i16* bitcast ([100 x i64]* @__dfsan_retval_tls to i16*), align [[ALIGN]]
   ; NO_TRACK_CONTROL_FLOW: ret <4 x i8> %a
 
   %a = select <4 x i1> %c, <4 x i8> %t, <4 x i8> %f


        


More information about the llvm-branch-commits mailing list