diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -2638,12 +2638,6 @@ return false; unsigned NumArgOperands = I.getNumArgOperands(); - if (I.getIntrinsicID() == Intrinsic::abs) { - assert(NumArgOperands == 2); - // The last argument is just a boolean flag. - NumArgOperands = 1; - } - for (unsigned i = 0; i < NumArgOperands; ++i) { Type *Ty = I.getArgOperand(i)->getType(); if (Ty != RetTy) @@ -3236,8 +3230,24 @@ setOriginForNaryOp(I); } + // Instrument abs intrinsic. + // handleUnknownIntrinsic can't handle it because of the last + // is_int_min_poison argument which does not match the result type. + void handleAbsIntrinsic(IntrinsicInst &I) { + assert(I.getType()->isIntOrIntVectorTy()); + assert(I.getArgOperand(0)->getType() == I.getType()); + + // FIXME: Handle is_int_min_poison. + IRBuilder<> IRB(&I); + setShadow(&I, getShadow(&I, 0)); + setOrigin(&I, getOrigin(&I, 0)); + } + void visitIntrinsicInst(IntrinsicInst &I) { switch (I.getIntrinsicID()) { + case Intrinsic::abs: + handleAbsIntrinsic(I); + break; case Intrinsic::lifetime_start: handleLifetimeStart(I); break;