Mark Reactor routine parameters 'noundef'

Code built with the -fsanitize-memory-param-retval flag will cause
MemorySanitizer instrumentation to check function parameters before the
call, and omit updating their 'shadow' in the __msan_param_tls[] thread-
local arrays. This allows callees to assume parameters are always
initialized, but they must not check the shadow since it contains stale
data, which can lead to false positive errors.

Previously we worked around this by calling __msan_unpoison_param() to
clear the shadow in RoutineT<> calls. This can lead to false negatives
for builds without -fsanitize-memory-param-retval, and also didn't
address the issue for routine calls through a raw function pointer
instead of RoutineT<>::operator().

This change instead marks parameters as `NoUndef` for LLVM >= 13. It
assumes that if such a recent version of LLVM is being used and
detection of uninitialized parameters is desired, projects will be
compiled with -fsanitize-memory-param-retval.

Where this is not the case we're subject to the same false negatives as
before, but builds that use the integrated LLVM 10 copy regain coverage,
and this approach also works for raw function pointer calls.

Bug: b/229724343
Change-Id: I80438b9a6328c346b74c7d652661898e301777bc
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/65228
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Commit-Queue: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/LLVMJIT.cpp b/src/Reactor/LLVMJIT.cpp
index 9590820..b15987a 100644
--- a/src/Reactor/LLVMJIT.cpp
+++ b/src/Reactor/LLVMJIT.cpp
@@ -169,7 +169,7 @@
 			"-x86-asm-syntax=intel",  // Use Intel syntax rather than the default AT&T
 #endif
 #if LLVM_VERSION_MAJOR <= 12
-			"-warn-stack-size=524288"  // Warn when a function uses more than 512 KiB of stack memory
+			"-warn-stack-size=524288",  // Warn when a function uses more than 512 KiB of stack memory
 #endif
 		};
 
@@ -922,7 +922,7 @@
 
 	if(__has_feature(memory_sanitizer) && msanInstrumentation)
 	{
-		llvm::MemorySanitizerOptions msanOpts;
+		llvm::MemorySanitizerOptions msanOpts(0 /* TrackOrigins */, false /* Recover */, false /* Kernel */, true /* EagerChecks */);
 		pm.addPass(llvm::ModuleMemorySanitizerPass(msanOpts));
 		pm.addPass(llvm::createModuleToFunctionPassAdaptor(llvm::MemorySanitizerPass(msanOpts)));
 	}
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index c958c8b..d72e405 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -517,6 +517,16 @@
 	if(__has_feature(memory_sanitizer))
 	{
 		func->addFnAttr(llvm::Attribute::SanitizeMemory);
+
+		// Assume that when using recent versions of LLVM, MemorySanitizer enabled builds
+		// use -fsanitize-memory-param-retval, which makes the caller not update the shadow
+		// of function parameters. NoUndef skips generating checks for uninitialized values.
+#if LLVM_VERSION_MAJOR >= 13
+		for(unsigned int i = 0; i < params.size(); i++)
+		{
+			func->addParamAttr(i, llvm::Attribute::NoUndef);
+		}
+#endif
 	}
 
 	func->addFnAttr("warn-stack-size", "524288");  // Warn when a function uses more than 512 KiB of stack memory
diff --git a/src/Reactor/Routine.hpp b/src/Reactor/Routine.hpp
index f9994ab..14fa116 100644
--- a/src/Reactor/Routine.hpp
+++ b/src/Reactor/Routine.hpp
@@ -15,16 +15,6 @@
 #ifndef rr_Routine_hpp
 #define rr_Routine_hpp
 
-// A Clang extension to determine compiler features.
-// We use it to detect Sanitizer builds (e.g. -fsanitize=memory).
-#ifndef __has_feature
-#	define __has_feature(x) 0
-#endif
-
-#if __has_feature(memory_sanitizer)
-#	include "sanitizer/msan_interface.h"
-#endif
-
 #include <memory>
 
 namespace rr {
@@ -67,11 +57,6 @@
 	template<typename... Args>
 	Return operator()(Args... args) const
 	{
-#if __has_feature(memory_sanitizer)
-		// TODO(b/228253151): Fix support for detecting uninitialized parameters.
-		__msan_unpoison_param(sizeof...(args));
-#endif
-
 		return function(args...);
 	}