[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