Commit ac27c516 by Thomas Lively

Subzero: Elide checks of known valid accesses of locals

parent 34e88480
...@@ -41,15 +41,15 @@ const llvm::NaClBitcodeRecord::RecordVector RzContents = ...@@ -41,15 +41,15 @@ const llvm::NaClBitcodeRecord::RecordVector RzContents =
// In order to instrument the code correctly, the .pexe must not have had its // In order to instrument the code correctly, the .pexe must not have had its
// symbols stripped. // symbols stripped.
using string_map = std::unordered_map<std::string, std::string>; using StringMap = std::unordered_map<std::string, std::string>;
using string_set = std::unordered_set<std::string>; using StringSet = std::unordered_set<std::string>;
// TODO(tlively): Handle all allocation functions // TODO(tlively): Handle all allocation functions
const string_map FuncSubstitutions = {{"malloc", "__asan_malloc"}, const StringMap FuncSubstitutions = {{"malloc", "__asan_malloc"},
{"free", "__asan_free"}, {"free", "__asan_free"},
{"calloc", "__asan_calloc"}, {"calloc", "__asan_calloc"},
{"__asan_dummy_calloc", "__asan_calloc"}, {"__asan_dummy_calloc", "__asan_calloc"},
{"realloc", "__asan_realloc"}}; {"realloc", "__asan_realloc"}};
const string_set FuncBlackList = {"_Balloc"}; const StringSet FuncBlackList = {"_Balloc"};
llvm::NaClBitcodeRecord::RecordVector sizeToByteVec(SizeT Size) { llvm::NaClBitcodeRecord::RecordVector sizeToByteVec(SizeT Size) {
llvm::NaClBitcodeRecord::RecordVector SizeContents; llvm::NaClBitcodeRecord::RecordVector SizeContents;
...@@ -62,6 +62,7 @@ llvm::NaClBitcodeRecord::RecordVector sizeToByteVec(SizeT Size) { ...@@ -62,6 +62,7 @@ llvm::NaClBitcodeRecord::RecordVector sizeToByteVec(SizeT Size) {
} // end of anonymous namespace } // end of anonymous namespace
ICE_TLS_DEFINE_FIELD(VarSizeMap *, ASanInstrumentation, LocalVars);
ICE_TLS_DEFINE_FIELD(std::vector<InstCall *> *, ASanInstrumentation, ICE_TLS_DEFINE_FIELD(std::vector<InstCall *> *, ASanInstrumentation,
LocalDtors); LocalDtors);
...@@ -157,8 +158,10 @@ std::string ASanInstrumentation::nextRzName() { ...@@ -157,8 +158,10 @@ std::string ASanInstrumentation::nextRzName() {
// Check for an alloca signaling the presence of local variables and add a // Check for an alloca signaling the presence of local variables and add a
// redzone if it is found // redzone if it is found
void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) { void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) {
if (ICE_TLS_GET_FIELD(LocalDtors) == nullptr) if (ICE_TLS_GET_FIELD(LocalDtors) == nullptr) {
ICE_TLS_SET_FIELD(LocalDtors, new std::vector<InstCall *>()); ICE_TLS_SET_FIELD(LocalDtors, new std::vector<InstCall *>());
ICE_TLS_SET_FIELD(LocalVars, new VarSizeMap());
}
Cfg *Func = Context.getNode()->getCfg(); Cfg *Func = Context.getNode()->getCfg();
bool HasLocals = false; bool HasLocals = false;
LoweringContext C; LoweringContext C;
...@@ -179,6 +182,7 @@ void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) { ...@@ -179,6 +182,7 @@ void ASanInstrumentation::instrumentFuncStart(LoweringContext &Context) {
// create the new alloca that includes a redzone // create the new alloca that includes a redzone
SizeT VarSize = VarSizeOp->getValue(); SizeT VarSize = VarSizeOp->getValue();
Variable *Dest = Cur->getDest(); Variable *Dest = Cur->getDest();
ICE_TLS_GET_FIELD(LocalVars)->insert({Dest, VarSize});
SizeT RzPadding = RzSize + Utils::OffsetToAlignment(VarSize, RzSize); SizeT RzPadding = RzSize + Utils::OffsetToAlignment(VarSize, RzSize);
auto *ByteCount = auto *ByteCount =
ConstantInteger32::create(Ctx, IceType_i32, VarSize + RzPadding); ConstantInteger32::create(Ctx, IceType_i32, VarSize + RzPadding);
...@@ -286,10 +290,13 @@ void ASanInstrumentation::instrumentStore(LoweringContext &Context, ...@@ -286,10 +290,13 @@ void ASanInstrumentation::instrumentStore(LoweringContext &Context,
typeWidthInBytes(Instr->getData()->getType()), Func); typeWidthInBytes(Instr->getData()->getType()), Func);
} }
// TODO(tlively): Take size of access into account as well
void ASanInstrumentation::instrumentAccess(LoweringContext &Context, void ASanInstrumentation::instrumentAccess(LoweringContext &Context,
Operand *Op, SizeT Size, Operand *Op, SizeT Size,
Constant *CheckFunc) { Constant *CheckFunc) {
VarSizeMap::iterator LocalSize = ICE_TLS_GET_FIELD(LocalVars)->find(Op);
if (LocalSize != ICE_TLS_GET_FIELD(LocalVars)->end() &&
LocalSize->second >= Size)
return;
constexpr SizeT NumArgs = 2; constexpr SizeT NumArgs = 2;
constexpr Variable *Void = nullptr; constexpr Variable *Void = nullptr;
constexpr bool NoTailCall = false; constexpr bool NoTailCall = false;
...@@ -342,6 +349,7 @@ void ASanInstrumentation::instrumentStart(Cfg *Func) { ...@@ -342,6 +349,7 @@ void ASanInstrumentation::instrumentStart(Cfg *Func) {
// TODO(tlively): make this more efficient with swap idiom // TODO(tlively): make this more efficient with swap idiom
void ASanInstrumentation::finishFunc(Cfg *) { void ASanInstrumentation::finishFunc(Cfg *) {
ICE_TLS_GET_FIELD(LocalVars)->clear();
ICE_TLS_GET_FIELD(LocalDtors)->clear(); ICE_TLS_GET_FIELD(LocalDtors)->clear();
} }
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
namespace Ice { namespace Ice {
using VarSizeMap = std::unordered_map<Operand *, SizeT>;
class ASanInstrumentation : public Instrumentation { class ASanInstrumentation : public Instrumentation {
ASanInstrumentation() = delete; ASanInstrumentation() = delete;
ASanInstrumentation(const ASanInstrumentation &) = delete; ASanInstrumentation(const ASanInstrumentation &) = delete;
...@@ -32,6 +34,7 @@ class ASanInstrumentation : public Instrumentation { ...@@ -32,6 +34,7 @@ class ASanInstrumentation : public Instrumentation {
public: public:
ASanInstrumentation(GlobalContext *Ctx) : Instrumentation(Ctx), RzNum(0) { ASanInstrumentation(GlobalContext *Ctx) : Instrumentation(Ctx), RzNum(0) {
ICE_TLS_INIT_FIELD(LocalVars);
ICE_TLS_INIT_FIELD(LocalDtors); ICE_TLS_INIT_FIELD(LocalDtors);
} }
void instrumentGlobals(VariableDeclarationList &Globals) override; void instrumentGlobals(VariableDeclarationList &Globals) override;
...@@ -48,6 +51,7 @@ private: ...@@ -48,6 +51,7 @@ private:
Constant *AccessFunc); Constant *AccessFunc);
void instrumentStart(Cfg *Func) override; void instrumentStart(Cfg *Func) override;
void finishFunc(Cfg *Func) override; void finishFunc(Cfg *Func) override;
ICE_TLS_DECLARE_FIELD(VarSizeMap *, LocalVars);
ICE_TLS_DECLARE_FIELD(std::vector<InstCall *> *, LocalDtors); ICE_TLS_DECLARE_FIELD(std::vector<InstCall *> *, LocalDtors);
std::atomic<uint32_t> RzNum; std::atomic<uint32_t> RzNum;
bool DidProcessGlobals = false; bool DidProcessGlobals = false;
......
; Test that direct loads and stores of local variables are not checked.
; REQUIRES: allow_dump
; RUN: %p2i -i %s --args -verbose=inst -threads=0 -fsanitize-address \
; RUN: | FileCheck --check-prefix=DUMP %s
define internal void @foo() {
%ptr8 = alloca i8, i32 1, align 4
%ptr16 = alloca i8, i32 2, align 4
%ptr32 = alloca i8, i32 4, align 4
%ptr64 = alloca i8, i32 8, align 4
%ptr128 = alloca i8, i32 16, align 4
%target8 = bitcast i8* %ptr8 to i8*
%target16 = bitcast i8* %ptr16 to i16*
%target32 = bitcast i8* %ptr32 to i32*
%target64 = bitcast i8* %ptr64 to i64*
%target128 = bitcast i8* %ptr128 to <4 x i32>*
; unchecked loads
%loaded8 = load i8, i8* %target8, align 1
%loaded16 = load i16, i16* %target16, align 1
%loaded32 = load i32, i32* %target32, align 1
%loaded64 = load i64, i64* %target64, align 1
%loaded128 = load <4 x i32>, <4 x i32>* %target128, align 4
; unchecked stores
store i8 %loaded8, i8* %target8, align 1
store i16 %loaded16, i16* %target16, align 1
store i32 %loaded32, i32* %target32, align 1
store i64 %loaded64, i64* %target64, align 1
store <4 x i32> %loaded128, <4 x i32>* %target128, align 4
%addr8 = ptrtoint i8* %ptr8 to i32
%addr16 = ptrtoint i8* %ptr16 to i32
%addr32 = ptrtoint i8* %ptr32 to i32
%addr64 = ptrtoint i8* %ptr64 to i32
%addr128 = ptrtoint i8* %ptr128 to i32
%off8 = add i32 %addr8, -1
%off16 = add i32 %addr16, -1
%off32 = add i32 %addr32, -1
%off64 = add i32 %addr64, -1
%off128 = add i32 %addr128, -1
%offtarget8 = inttoptr i32 %off8 to i8*
%offtarget16 = inttoptr i32 %off16 to i16*
%offtarget32 = inttoptr i32 %off32 to i32*
%offtarget64 = inttoptr i32 %off64 to i64*
%offtarget128 = inttoptr i32 %off128 to <4 x i32>*
; checked loads
%offloaded8 = load i8, i8* %offtarget8, align 1
%offloaded16 = load i16, i16* %offtarget16, align 1
%offloaded32 = load i32, i32* %offtarget32, align 1
%offloaded64 = load i64, i64* %offtarget64, align 1
%offloaded128 = load <4 x i32>, <4 x i32>* %offtarget128, align 4
; checked stores
store i8 %offloaded8, i8* %offtarget8, align 1
store i16 %offloaded16, i16* %offtarget16, align 1
store i32 %offloaded32, i32* %offtarget32, align 1
store i64 %offloaded64, i64* %offtarget64, align 1
store <4 x i32> %offloaded128, <4 x i32>* %offtarget128, align 4
ret void
}
; DUMP-LABEL: ================ Instrumented CFG ================
; DUMP-NEXT: define internal void @foo() {
; Unchecked loads and stores
; DUMP: %loaded8 = load i8, i8* %ptr8, align 1
; DUMP-NEXT: %loaded16 = load i16, i16* %ptr16, align 1
; DUMP-NEXT: %loaded32 = load i32, i32* %ptr32, align 1
; DUMP-NEXT: %loaded64 = load i64, i64* %ptr64, align 1
; DUMP-NEXT: %loaded128 = load <4 x i32>, <4 x i32>* %ptr128, align 4
; DUMP-NEXT: store i8 %loaded8, i8* %ptr8, align 1
; DUMP-NEXT: store i16 %loaded16, i16* %ptr16, align 1
; DUMP-NEXT: store i32 %loaded32, i32* %ptr32, align 1
; DUMP-NEXT: store i64 %loaded64, i64* %ptr64, align 1
; DUMP-NEXT: store <4 x i32> %loaded128, <4 x i32>* %ptr128, align 4
; Checked loads and stores
; DUMP: call void @__asan_check_load(i32 %off8, i32 1)
; DUMP-NEXT: %offloaded8 = load i8, i8* %off8, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %off16, i32 2)
; DUMP-NEXT: %offloaded16 = load i16, i16* %off16, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %off32, i32 4)
; DUMP-NEXT: %offloaded32 = load i32, i32* %off32, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %off64, i32 8)
; DUMP-NEXT: %offloaded64 = load i64, i64* %off64, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %off128, i32 16)
; DUMP-NEXT: %offloaded128 = load <4 x i32>, <4 x i32>* %off128, align 4
; DUMP-NEXT: call void @__asan_check_store(i32 %off8, i32 1)
; DUMP-NEXT: store i8 %offloaded8, i8* %off8, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %off16, i32 2)
; DUMP-NEXT: store i16 %offloaded16, i16* %off16, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %off32, i32 4)
; DUMP-NEXT: store i32 %offloaded32, i32* %off32, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %off64, i32 8)
; DUMP-NEXT: store i64 %offloaded64, i64* %off64, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %off128, i32 16)
; DUMP-NEXT: store <4 x i32> %offloaded128, <4 x i32>* %off128, align 4
...@@ -20,12 +20,13 @@ ...@@ -20,12 +20,13 @@
@srcGlobal128 = internal global [16 x i8] c"DATADATADATADATA" @srcGlobal128 = internal global [16 x i8] c"DATADATADATADATA"
; A function with a local variable that does the loads ; A function with a local variable that does the loads
define internal void @doLoads() { define internal void @doLoads(i32 %arg8, i32 %arg16, i32 %arg32, i32 %arg64,
%srcLocal8 = alloca i8, i32 1, align 4 i32 %arg128) {
%srcLocal16 = alloca i8, i32 2, align 4 %srcLocal8 = inttoptr i32 %arg8 to i8*
%srcLocal32 = alloca i8, i32 4, align 4 %srcLocal16 = inttoptr i32 %arg16 to i16*
%srcLocal64 = alloca i8, i32 8, align 4 %srcLocal32 = inttoptr i32 %arg32 to i32*
%srcLocal128 = alloca i8, i32 16, align 4 %srcLocal64 = inttoptr i32 %arg64 to i64*
%srcLocal128 = inttoptr i32 %arg128 to <4 x i32>*
%ptrConst8 = bitcast [1 x i8]* @srcConst8 to i8* %ptrConst8 = bitcast [1 x i8]* @srcConst8 to i8*
%ptrConst16 = bitcast [2 x i8]* @srcConst16 to i16* %ptrConst16 = bitcast [2 x i8]* @srcConst16 to i16*
...@@ -39,12 +40,6 @@ define internal void @doLoads() { ...@@ -39,12 +40,6 @@ define internal void @doLoads() {
%ptrGlobal64 = bitcast [8 x i8]* @srcGlobal64 to i64* %ptrGlobal64 = bitcast [8 x i8]* @srcGlobal64 to i64*
%ptrGlobal128 = bitcast [16 x i8]* @srcGlobal128 to <4 x i32>* %ptrGlobal128 = bitcast [16 x i8]* @srcGlobal128 to <4 x i32>*
%ptrLocal8 = bitcast i8* %srcLocal8 to i8*
%ptrLocal16 = bitcast i8* %srcLocal16 to i16*
%ptrLocal32 = bitcast i8* %srcLocal32 to i32*
%ptrLocal64 = bitcast i8* %srcLocal64 to i64*
%ptrLocal128 = bitcast i8* %srcLocal128 to <4 x i32>*
%dest1 = load i8, i8* %ptrConst8, align 1 %dest1 = load i8, i8* %ptrConst8, align 1
%dest2 = load i16, i16* %ptrConst16, align 1 %dest2 = load i16, i16* %ptrConst16, align 1
%dest3 = load i32, i32* %ptrConst32, align 1 %dest3 = load i32, i32* %ptrConst32, align 1
...@@ -57,19 +52,19 @@ define internal void @doLoads() { ...@@ -57,19 +52,19 @@ define internal void @doLoads() {
%dest9 = load i64, i64* %ptrGlobal64, align 1 %dest9 = load i64, i64* %ptrGlobal64, align 1
%dest10 = load <4 x i32>, <4 x i32>* %ptrGlobal128, align 4 %dest10 = load <4 x i32>, <4 x i32>* %ptrGlobal128, align 4
%dest11 = load i8, i8* %ptrLocal8, align 1 %dest11 = load i8, i8* %srcLocal8, align 1
%dest12 = load i16, i16* %ptrLocal16, align 1 %dest12 = load i16, i16* %srcLocal16, align 1
%dest13 = load i32, i32* %ptrLocal32, align 1 %dest13 = load i32, i32* %srcLocal32, align 1
%dest14 = load i64, i64* %ptrLocal64, align 1 %dest14 = load i64, i64* %srcLocal64, align 1
%dest15 = load <4 x i32>, <4 x i32>* %ptrLocal128, align 4 %dest15 = load <4 x i32>, <4 x i32>* %srcLocal128, align 4
ret void ret void
} }
; DUMP-LABEL: ================ Instrumented CFG ================ ; DUMP-LABEL: ================ Instrumented CFG ================
; DUMP-NEXT: define internal void @doLoads() { ; DUMP-NEXT: define internal void @doLoads(
; DUMP-NEXT: __0: ; DUMP-NEXT: __0:
; DUMP: call void @__asan_check_load(i32 @srcConst8, i32 1) ; DUMP-NEXT: call void @__asan_check_load(i32 @srcConst8, i32 1)
; DUMP-NEXT: %dest1 = load i8, i8* @srcConst8, align 1 ; DUMP-NEXT: %dest1 = load i8, i8* @srcConst8, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 @srcConst16, i32 2) ; DUMP-NEXT: call void @__asan_check_load(i32 @srcConst16, i32 2)
; DUMP-NEXT: %dest2 = load i16, i16* @srcConst16, align 1 ; DUMP-NEXT: %dest2 = load i16, i16* @srcConst16, align 1
...@@ -89,15 +84,15 @@ define internal void @doLoads() { ...@@ -89,15 +84,15 @@ define internal void @doLoads() {
; DUMP-NEXT: %dest9 = load i64, i64* @srcGlobal64, align 1 ; DUMP-NEXT: %dest9 = load i64, i64* @srcGlobal64, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 @srcGlobal128, i32 16) ; DUMP-NEXT: call void @__asan_check_load(i32 @srcGlobal128, i32 16)
; DUMP-NEXT: %dest10 = load <4 x i32>, <4 x i32>* @srcGlobal128, align 4 ; DUMP-NEXT: %dest10 = load <4 x i32>, <4 x i32>* @srcGlobal128, align 4
; DUMP-NEXT: call void @__asan_check_load(i32 %srcLocal8, i32 1) ; DUMP-NEXT: call void @__asan_check_load(i32 %arg8, i32 1)
; DUMP-NEXT: %dest11 = load i8, i8* %srcLocal8, align 1 ; DUMP-NEXT: %dest11 = load i8, i8* %arg8, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %srcLocal16, i32 2) ; DUMP-NEXT: call void @__asan_check_load(i32 %arg16, i32 2)
; DUMP-NEXT: %dest12 = load i16, i16* %srcLocal16, align 1 ; DUMP-NEXT: %dest12 = load i16, i16* %arg16, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %srcLocal32, i32 4) ; DUMP-NEXT: call void @__asan_check_load(i32 %arg32, i32 4)
; DUMP-NEXT: %dest13 = load i32, i32* %srcLocal32, align 1 ; DUMP-NEXT: %dest13 = load i32, i32* %arg32, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %srcLocal64, i32 8) ; DUMP-NEXT: call void @__asan_check_load(i32 %arg64, i32 8)
; DUMP-NEXT: %dest14 = load i64, i64* %srcLocal64, align 1 ; DUMP-NEXT: %dest14 = load i64, i64* %arg64, align 1
; DUMP-NEXT: call void @__asan_check_load(i32 %srcLocal128, i32 16) ; DUMP-NEXT: call void @__asan_check_load(i32 %arg128, i32 16)
; DUMP-NEXT: %dest15 = load <4 x i32>, <4 x i32>* %srcLocal128, align 4 ; DUMP-NEXT: %dest15 = load <4 x i32>, <4 x i32>* %arg128, align 4
; DUMP: ret void ; DUMP: ret void
; DUMP-NEXT: } ; DUMP-NEXT: }
...@@ -13,12 +13,13 @@ ...@@ -13,12 +13,13 @@
@destGlobal128 = internal global [16 x i8] zeroinitializer @destGlobal128 = internal global [16 x i8] zeroinitializer
; A function with a local variable that does the stores ; A function with a local variable that does the stores
define internal void @doStores(<4 x i32> %vecSrc) { define internal void @doStores(<4 x i32> %vecSrc, i32 %arg8, i32 %arg16,
%destLocal8 = alloca i8, i32 1, align 4 i32 %arg32, i32 %arg64, i32 %arg128) {
%destLocal16 = alloca i8, i32 2, align 4 %destLocal8 = inttoptr i32 %arg8 to i8*
%destLocal32 = alloca i8, i32 4, align 4 %destLocal16 = inttoptr i32 %arg16 to i16*
%destLocal64 = alloca i8, i32 8, align 4 %destLocal32 = inttoptr i32 %arg32 to i32*
%destLocal128 = alloca i8, i32 16, align 4 %destLocal64 = inttoptr i32 %arg64 to i64*
%destLocal128 = inttoptr i32 %arg128 to <4 x i32>*
%ptrGlobal8 = bitcast [1 x i8]* @destGlobal8 to i8* %ptrGlobal8 = bitcast [1 x i8]* @destGlobal8 to i8*
%ptrGlobal16 = bitcast [2 x i8]* @destGlobal16 to i16* %ptrGlobal16 = bitcast [2 x i8]* @destGlobal16 to i16*
...@@ -26,31 +27,25 @@ define internal void @doStores(<4 x i32> %vecSrc) { ...@@ -26,31 +27,25 @@ define internal void @doStores(<4 x i32> %vecSrc) {
%ptrGlobal64 = bitcast [8 x i8]* @destGlobal64 to i64* %ptrGlobal64 = bitcast [8 x i8]* @destGlobal64 to i64*
%ptrGlobal128 = bitcast [16 x i8]* @destGlobal128 to <4 x i32>* %ptrGlobal128 = bitcast [16 x i8]* @destGlobal128 to <4 x i32>*
%ptrLocal8 = bitcast i8* %destLocal8 to i8*
%ptrLocal16 = bitcast i8* %destLocal16 to i16*
%ptrLocal32 = bitcast i8* %destLocal32 to i32*
%ptrLocal64 = bitcast i8* %destLocal64 to i64*
%ptrLocal128 = bitcast i8* %destLocal128 to <4 x i32>*
store i8 42, i8* %ptrGlobal8, align 1 store i8 42, i8* %ptrGlobal8, align 1
store i16 42, i16* %ptrGlobal16, align 1 store i16 42, i16* %ptrGlobal16, align 1
store i32 42, i32* %ptrGlobal32, align 1 store i32 42, i32* %ptrGlobal32, align 1
store i64 42, i64* %ptrGlobal64, align 1 store i64 42, i64* %ptrGlobal64, align 1
store <4 x i32> %vecSrc, <4 x i32>* %ptrGlobal128, align 4 store <4 x i32> %vecSrc, <4 x i32>* %ptrGlobal128, align 4
store i8 42, i8* %ptrLocal8, align 1 store i8 42, i8* %destLocal8, align 1
store i16 42, i16* %ptrLocal16, align 1 store i16 42, i16* %destLocal16, align 1
store i32 42, i32* %ptrLocal32, align 1 store i32 42, i32* %destLocal32, align 1
store i64 42, i64* %ptrLocal64, align 1 store i64 42, i64* %destLocal64, align 1
store <4 x i32> %vecSrc, <4 x i32>* %ptrLocal128, align 4 store <4 x i32> %vecSrc, <4 x i32>* %destLocal128, align 4
ret void ret void
} }
; DUMP-LABEL: ================ Instrumented CFG ================ ; DUMP-LABEL: ================ Instrumented CFG ================
; DUMP-NEXT: define internal void @doStores(<4 x i32> %vecSrc) { ; DUMP-NEXT: define internal void @doStores(
; DUMP-NEXT: __0: ; DUMP-NEXT: __0:
; DUMP: call void @__asan_check_store(i32 @destGlobal8, i32 1) ; DUMP-NEXT: call void @__asan_check_store(i32 @destGlobal8, i32 1)
; DUMP-NEXT: store i8 42, i8* @destGlobal8, align 1 ; DUMP-NEXT: store i8 42, i8* @destGlobal8, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 @destGlobal16, i32 2) ; DUMP-NEXT: call void @__asan_check_store(i32 @destGlobal16, i32 2)
; DUMP-NEXT: store i16 42, i16* @destGlobal16, align 1 ; DUMP-NEXT: store i16 42, i16* @destGlobal16, align 1
...@@ -60,15 +55,15 @@ define internal void @doStores(<4 x i32> %vecSrc) { ...@@ -60,15 +55,15 @@ define internal void @doStores(<4 x i32> %vecSrc) {
; DUMP-NEXT: store i64 42, i64* @destGlobal64, align 1 ; DUMP-NEXT: store i64 42, i64* @destGlobal64, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 @destGlobal128, i32 16) ; DUMP-NEXT: call void @__asan_check_store(i32 @destGlobal128, i32 16)
; DUMP-NEXT: store <4 x i32> %vecSrc, <4 x i32>* @destGlobal128, align 4 ; DUMP-NEXT: store <4 x i32> %vecSrc, <4 x i32>* @destGlobal128, align 4
; DUMP-NEXT: call void @__asan_check_store(i32 %destLocal8, i32 1) ; DUMP-NEXT: call void @__asan_check_store(i32 %arg8, i32 1)
; DUMP-NEXT: store i8 42, i8* %destLocal8, align 1 ; DUMP-NEXT: store i8 42, i8* %arg8, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %destLocal16, i32 2) ; DUMP-NEXT: call void @__asan_check_store(i32 %arg16, i32 2)
; DUMP-NEXT: store i16 42, i16* %destLocal16, align 1 ; DUMP-NEXT: store i16 42, i16* %arg16, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %destLocal32, i32 4) ; DUMP-NEXT: call void @__asan_check_store(i32 %arg32, i32 4)
; DUMP-NEXT: store i32 42, i32* %destLocal32, align 1 ; DUMP-NEXT: store i32 42, i32* %arg32, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %destLocal64, i32 8) ; DUMP-NEXT: call void @__asan_check_store(i32 %arg64, i32 8)
; DUMP-NEXT: store i64 42, i64* %destLocal64, align 1 ; DUMP-NEXT: store i64 42, i64* %arg64, align 1
; DUMP-NEXT: call void @__asan_check_store(i32 %destLocal128, i32 16) ; DUMP-NEXT: call void @__asan_check_store(i32 %arg128, i32 16)
; DUMP-NEXT: store <4 x i32> %vecSrc, <4 x i32>* %destLocal128, align 4 ; DUMP-NEXT: store <4 x i32> %vecSrc, <4 x i32>* %arg128, align 4
; DUMP: ret void ; DUMP: ret void
; DUMP-NEXT: } ; DUMP-NEXT: }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment