Add type information to pointer arguments.

Unlike LLVM, Subzero does not store the type of value a pointer
references as part of the pointer's type information. So add a type
argument to createGEP(). Also add the type to createStore(), to
enable smaller types to be emulated by larger ones.

Bug swiftshader:11

Change-Id: I08173dd0ba07362d2b27baff4a8fba0ecce093d2
Reviewed-on: https://swiftshader-review.googlesource.com/7392
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index d1dafda..f1d1631 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -459,20 +459,23 @@
 		return V(::builder->Insert(new LoadInst(ptr, "", isVolatile, align)));
 	}
 
-	Value *Nucleus::createStore(Value *value, Value *ptr, bool isVolatile, unsigned int align)
+	Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
 	{
+		assert(ptr->getType()->getContainedType(0) == type);
 		::builder->Insert(new StoreInst(value, ptr, isVolatile, align));
 		return value;
 	}
 
-	Constant *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
+	Constant *Nucleus::createStore(Constant *constant, Value *ptr, Type *type, bool isVolatile, unsigned int align)
 	{
+		assert(ptr->getType()->getContainedType(0) == type);
 		::builder->Insert(new StoreInst(constant, ptr, isVolatile, align));
 		return constant;
 	}
 
-	Value *Nucleus::createGEP(Value *ptr, Value *index)
+	Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
 	{
+		assert(ptr->getType()->getContainedType(0) == type);
 		return V(::builder->CreateGEP(ptr, index));
 	}
 
@@ -6893,17 +6896,17 @@
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, V(Nucleus::createConstantInt(offset))));
+		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset))));
 	}
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
+		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
 	}
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
+		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
 	}
 
 	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp
index f384687..a221db3 100644
--- a/src/Reactor/Nucleus.hpp
+++ b/src/Reactor/Nucleus.hpp
@@ -97,9 +97,9 @@
 
 		// Memory instructions
 		static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0);
-		static Value *createStore(Value *value, Value *ptr, bool isVolatile = false, unsigned int align = 0);
-		static Constant *createStore(Constant *constant, Value *ptr, bool isVolatile = false, unsigned int align = 0);
-		static Value *createGEP(Value *ptr, Value *index);
+		static Value *createStore(Value *value, Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0);
+		static Constant *createStore(Constant *constant, Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0);
+		static Value *createGEP(Value *ptr, Type *type, Value *index);
 
 		// Atomic instructions
 		static Value *createAtomicAdd(Value *ptr, Value *value);
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 2b84a8c..5fbfef7 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -2360,19 +2360,19 @@
 	template<class T>
 	Value *LValue<T>::storeValue(Value *value, unsigned int alignment) const
 	{
-		return Nucleus::createStore(value, address, false, alignment);
+		return Nucleus::createStore(value, address, T::getType(), false, alignment);
 	}
 
 	template<class T>
 	Constant *LValue<T>::storeValue(Constant *constant, unsigned int alignment) const
 	{
-		return Nucleus::createStore(constant, address, false, alignment);
+		return Nucleus::createStore(constant, address, T::getType(), false, alignment);
 	}
 
 	template<class T>
 	Value *LValue<T>::getAddress(Value *index) const
 	{
-		return Nucleus::createGEP(address, index);
+		return Nucleus::createGEP(address, T::getType(), index);
 	}
 
 	template<class T>
@@ -2395,7 +2395,7 @@
 	template<class T>
 	RValue<T> Reference<T>::operator=(RValue<T> rhs) const
 	{
-		Nucleus::createStore(rhs.value, address, false, alignment);
+		Nucleus::createStore(rhs.value, address, T::getType(), false, alignment);
 
 		return rhs;
 	}
@@ -2404,7 +2404,7 @@
 	RValue<T> Reference<T>::operator=(const Reference<T> &ref) const
 	{
 		Value *tmp = Nucleus::createLoad(ref.address, T::getType(), false, ref.alignment);
-		Nucleus::createStore(tmp, address, false, alignment);
+		Nucleus::createStore(tmp, address, T::getType(), false, alignment);
 
 		return RValue<T>(tmp);
 	}
@@ -2692,7 +2692,7 @@
 	template<class T>
 	Reference<T> Pointer<T>::operator[](int index)
 	{
-		Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), (Value*)Nucleus::createConstantInt(index));
+		Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), (Value*)Nucleus::createConstantInt(index));
 
 		return Reference<T>(element, alignment);
 	}
@@ -2700,7 +2700,7 @@
 	template<class T>
 	Reference<T> Pointer<T>::operator[](RValue<Int> index)
 	{
-		Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), index.value);
+		Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value);
 
 		return Reference<T>(element, alignment);
 	}
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index d1fd3e2..bdb00d2 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -474,21 +474,21 @@
 		return V(value);
 	}
 
-	Value *Nucleus::createStore(Value *value, Value *ptr, bool isVolatile, unsigned int align)
+	Value *Nucleus::createStore(Value *value, Value *ptr, Type *type, bool isVolatile, unsigned int align)
 	{
 		auto store = Ice::InstStore::create(::function, value, ptr, align);
 		::basicBlock->appendInst(store);
 		return value;
 	}
 
-	Constant *Nucleus::createStore(Constant *constant, Value *ptr, bool isVolatile, unsigned int align)
+	Constant *Nucleus::createStore(Constant *constant, Value *ptr, Type *type, bool isVolatile, unsigned int align)
 	{
 		auto store = Ice::InstStore::create(::function, constant, ptr, align);
 		::basicBlock->appendInst(store);
 		return constant;
 	}
 
-	Value *Nucleus::createGEP(Value *ptr, Value *index)
+	Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index)
 	{
 		assert(false && "UNIMPLEMENTED"); return nullptr;
 	}
@@ -1144,7 +1144,7 @@
 
 	Type *Byte::getType()
 	{
-		assert(false && "UNIMPLEMENTED"); return nullptr;
+		return T(Ice::IceType_i8);
 	}
 
 	SByte::SByte(Argument<SByte> argument)
@@ -5616,12 +5616,12 @@
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
+		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
 	}
 
 	RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset)
 	{
-		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, offset.value));
+		return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value));
 	}
 
 	RValue<Pointer<Byte>> operator+=(const Pointer<Byte> &lhs, int offset)