diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 6daee7a3b6e81..0b63c2059268c 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -4008,6 +4008,10 @@ struct MemorySanitizerVisitor : public InstVisitor { /// shadow[out] = /// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType] /// + /// CAUTION: this assumes that the intrinsic will handle arbitrary + /// bit-patterns (for example, if the intrinsic accepts floats for + /// var1, we require that it doesn't care if inputs are NaNs). + /// /// For example, this can be applied to the Arm NEON vector table intrinsics /// (tbl{1,2,3,4}). /// @@ -4022,7 +4026,11 @@ struct MemorySanitizerVisitor : public InstVisitor { // Don't use getNumOperands() because it includes the callee for (unsigned int i = 0; i < I.arg_size() - trailingVerbatimArgs; i++) { Value *Shadow = getShadow(&I, i); - ShadowArgs.push_back(Shadow); + + // Shadows are integer-ish types but some intrinsics require a + // different (e.g., floating-point) type. + ShadowArgs.push_back( + IRB.CreateBitCast(Shadow, I.getArgOperand(i)->getType())); } for (unsigned int i = I.arg_size() - trailingVerbatimArgs; i < I.arg_size(); @@ -4043,7 +4051,7 @@ struct MemorySanitizerVisitor : public InstVisitor { CombinedShadow = IRB.CreateOr(Shadow, CombinedShadow, "_msprop"); } - setShadow(&I, CombinedShadow); + setShadow(&I, IRB.CreateBitCast(CombinedShadow, getShadowTy(&I))); setOriginForNaryOp(I); }