Index: llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -706,9 +706,10 @@ Value *Shadow; Value *Origin; Instruction *OrigIns; + bool After; - ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I) - : Shadow(S), Origin(O), OrigIns(I) {} + ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I, bool A) + : Shadow(S), Origin(O), OrigIns(I), After(A) {} }; SmallVector InstrumentationList; SmallVector StoreList; @@ -900,6 +901,8 @@ Instruction *OrigIns = ShadowData.OrigIns; Value *Shadow = ShadowData.Shadow; Value *Origin = ShadowData.Origin; + if (ShadowData.After) + OrigIns = OrigIns->getNextNode(); materializeOneCheck(OrigIns, Shadow, Origin, InstrumentWithCalls); } DEBUG(dbgs() << "DONE:\n" << F); @@ -1274,7 +1277,8 @@ /// /// This location will be later instrumented with a check that will print a /// UMR warning in runtime if the shadow value is not 0. - void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns) { + void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns, + bool After = false) { assert(Shadow); if (!InsertChecks) return; #ifndef NDEBUG @@ -1283,14 +1287,14 @@ "Can only insert checks for integer and vector shadow types"); #endif InstrumentationList.push_back( - ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns)); + ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns, After)); } /// \brief Remember the place where a shadow check should be inserted. /// /// This location will be later instrumented with a check that will print a /// UMR warning in runtime if the value is not fully defined. - void insertShadowCheck(Value *Val, Instruction *OrigIns) { + void insertShadowCheck(Value *Val, Instruction *OrigIns, bool After = false) { assert(Val); Value *Shadow, *Origin; if (ClCheckConstantShadow) { @@ -1302,7 +1306,7 @@ if (!Shadow) return; Origin = dyn_cast_or_null(getOrigin(Val)); } - insertShadowCheck(Shadow, Origin, OrigIns); + insertShadowCheck(Shadow, Origin, OrigIns, After); } AtomicOrdering addReleaseOrdering(AtomicOrdering a) { @@ -1380,6 +1384,18 @@ setOrigin(&I, getCleanOrigin()); } } + + // Shadow check of the loaded value must follow loads of shadow and origin. + // The first instruction that satisfies this requirement is + // IRB.GetInsertPoint(), but it has not been instrumented yet => may get + // stuff inserted before it, or even disappear without trace. Record the + // location as "after the last instruction of this load's instrumentation". + + // FIXME: implement shadow check for aggregate types and re-enable here and + // in storeOrigin(). + if (PropagateShadow && !I.getType()->isAggregateType()) + insertShadowCheck(&I, &*IRB.GetInsertPoint()->getPrevNode(), + /*After=*/true); } /// \brief Instrument StoreInst