diff --git a/compiler-rt/lib/dfsan/dfsan.cpp b/compiler-rt/lib/dfsan/dfsan.cpp index db610857834c06..c17bfe0ccb3229 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 9dad9817acea5b..fc784e72797ca6 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 { @@ -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(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(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(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 3ea78552e4f64b..c93d00e2d3e589 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 4d9c8e999cf6f8..feb8ff69105816 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 6e762844180877..7194535b4f6971 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 85f99f5b1828e4..2a369194d63cc1 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 9cdf69d11ddb9e..74f3f8bcee5188 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 08c457f3bfc7b9..6ef8fef85de11b 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 275f8282da1627..d97fe2d0691632 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