[msan] Fix getOriginForNaryOp.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Thu, 29 Nov 2012 14:44:00 +0000 (14:44 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Thu, 29 Nov 2012 14:44:00 +0000 (14:44 +0000)
The old version failed on a 3-arg instruction with (-1, 0, 0) shadows (it would
pick the 3rd operand origin irrespective of its shadow).

The new version always picks the origin of the rightmost poisoned operand.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168887 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Instrumentation/MemorySanitizer.cpp

index d745a0c47afeb88fa61db0355d191839e7bd60b5..e74ff5c57c3140b66667a2ae5866c10904865e4e 100644 (file)
@@ -842,15 +842,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
   ///
   /// This is a general case of origin propagation. For an Nary operation,
   /// is set to the origin of an argument that is not entirely initialized.
+  /// If there is more than one such arguments, the rightmost of them is picked.
   /// It does not matter which one is picked if all arguments are initialized.
   void setOriginForNaryOp(Instruction &I) {
     if (!ClTrackOrigins) return;
     IRBuilder<> IRB(&I);
     Value *Origin = getOrigin(&I, 0);
     for (unsigned Op = 1, n = I.getNumOperands(); Op < n; ++Op) {
-      Value *S = convertToShadowTyNoVec(getShadow(&I, Op - 1), IRB);
+      Value *S = convertToShadowTyNoVec(getShadow(&I, Op), IRB);
       Origin = IRB.CreateSelect(IRB.CreateICmpNE(S, getCleanShadow(S)),
-                                Origin, getOrigin(&I, Op));
+                                getOrigin(&I, Op), Origin);
     }
     setOrigin(&I, Origin);
   }