Reactor: Fix printing of small integer values.

The printf specifiers expect an int, passing a smaller width integer could lead to weirdness being printed.

Change-Id: I1e75e3fdade270a4bfa55c48efe82ca9f331b2fe
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31272
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 81f8e27..82eefe3 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -4103,6 +4103,27 @@
 		return elements;
 	}
 
+	// toInt returns all the integer values in vals extended to a native width
+	// integer.
+	static std::vector<Value*> toInt(const std::vector<Value*>& vals, bool isSigned)
+	{
+		auto intTy = ::llvm::Type::getIntNTy(*::context, sizeof(int) * 8); // Natural integer width.
+		std::vector<Value*> elements;
+		elements.reserve(vals.size());
+		for (auto v : vals)
+		{
+			if (isSigned)
+			{
+				elements.push_back(V(::builder->CreateSExt(V(v), intTy)));
+			}
+			else
+			{
+				elements.push_back(V(::builder->CreateZExt(V(v), intTy)));
+			}
+		}
+		return elements;
+	}
+
 	// toDouble returns all the float values in vals extended to doubles.
 	static std::vector<Value*> toDouble(const std::vector<Value*>& vals)
 	{
@@ -4116,11 +4137,15 @@
 		return elements;
 	}
 
-	std::vector<Value*> PrintValue::Ty<Byte4>::val(const RValue<Byte4>& v) { return extractAll(v.value, 4); }
-	std::vector<Value*> PrintValue::Ty<Int4>::val(const RValue<Int4>& v) { return extractAll(v.value, 4); }
-	std::vector<Value*> PrintValue::Ty<UInt4>::val(const RValue<UInt4>& v) { return extractAll(v.value, 4); }
-	std::vector<Value*> PrintValue::Ty<Short4>::val(const RValue<Short4>& v) { return extractAll(v.value, 4); }
-	std::vector<Value*> PrintValue::Ty<UShort4>::val(const RValue<UShort4>& v) { return extractAll(v.value, 4); }
+	std::vector<Value*> PrintValue::Ty<Byte4>::val(const RValue<Byte4>& v) { return toInt(extractAll(v.value, 4), false); }
+	std::vector<Value*> PrintValue::Ty<Int>::val(const RValue<Int>& v) { return toInt({v.value}, true); }
+	std::vector<Value*> PrintValue::Ty<Int2>::val(const RValue<Int2>& v) { return toInt(extractAll(v.value, 2), true); }
+	std::vector<Value*> PrintValue::Ty<Int4>::val(const RValue<Int4>& v) { return toInt(extractAll(v.value, 4), true); }
+	std::vector<Value*> PrintValue::Ty<UInt>::val(const RValue<UInt>& v) { return toInt({v.value}, false); }
+	std::vector<Value*> PrintValue::Ty<UInt2>::val(const RValue<UInt2>& v) { return toInt(extractAll(v.value, 2), false); }
+	std::vector<Value*> PrintValue::Ty<UInt4>::val(const RValue<UInt4>& v) { return toInt(extractAll(v.value, 4), false); }
+	std::vector<Value*> PrintValue::Ty<Short4>::val(const RValue<Short4>& v) { return toInt(extractAll(v.value, 4), true); }
+	std::vector<Value*> PrintValue::Ty<UShort4>::val(const RValue<UShort4>& v) { return toInt(extractAll(v.value, 4), false); }
 	std::vector<Value*> PrintValue::Ty<Float>::val(const RValue<Float>& v) { return toDouble({v.value}); }
 	std::vector<Value*> PrintValue::Ty<Float4>::val(const RValue<Float4>& v) { return toDouble(extractAll(v.value, 4)); }
 	std::vector<Value*> PrintValue::Ty<const char*>::val(const char* v) { return {V(::builder->CreateGlobalStringPtr(v))}; }
@@ -4129,7 +4154,7 @@
 	{
 		// LLVM types used below.
 		auto i32Ty = ::llvm::Type::getInt32Ty(*::context);
-		auto intTy = ::llvm::Type::getInt64Ty(*::context); // TODO: Natural int width.
+		auto intTy = ::llvm::Type::getIntNTy(*::context, sizeof(int) * 8); // Natural integer width.
 		auto i8PtrTy = ::llvm::Type::getInt8PtrTy(*::context);
 		auto funcTy = ::llvm::FunctionType::get(i32Ty, {i8PtrTy}, true);
 
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 7aed561..2494b7a 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -3328,7 +3328,12 @@
 	template <> struct PrintValue::Ty<Int>
 	{
 		static constexpr const char* fmt = "%d";
-		static std::vector<Value*> val(const RValue<Int>& v) { return {v.value}; }
+		static std::vector<Value*> val(const RValue<Int>& v);
+	};
+	template <> struct PrintValue::Ty<Int2>
+	{
+		static constexpr const char* fmt = "[%d, %d]";
+		static std::vector<Value*> val(const RValue<Int2>& v);
 	};
 	template <> struct PrintValue::Ty<Int4>
 	{
@@ -3338,7 +3343,12 @@
 	template <> struct PrintValue::Ty<UInt>
 	{
 		static constexpr const char* fmt = "%u";
-		static std::vector<Value*> val(const RValue<UInt>& v) { return {v.value}; }
+		static std::vector<Value*> val(const RValue<UInt>& v);
+	};
+	template <> struct PrintValue::Ty<UInt2>
+	{
+		static constexpr const char* fmt = "[%u, %u]";
+		static std::vector<Value*> val(const RValue<UInt2>& v);
 	};
 	template <> struct PrintValue::Ty<UInt4>
 	{