Support unsigned array indices. Change-Id: I4136781005cbd0551461adecdd94d8e3cc8688d0 Reviewed-on: https://swiftshader-review.googlesource.com/8570 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 480ac6b..e6b4b94 100644 --- a/src/Reactor/LLVMReactor.cpp +++ b/src/Reactor/LLVMReactor.cpp
@@ -451,8 +451,13 @@ return value; } - Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index) + Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex) { + if(unsignedIndex && sizeof(void*) == 8) + { + index = createZExt(index, Long::getType()); + } + assert(ptr->getType()->getContainedType(0) == type); return V(::builder->CreateGEP(ptr, index)); } @@ -6282,17 +6287,17 @@ RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, int offset) { - return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset)))); + return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), V(Nucleus::createConstantInt(offset)), false)); } RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset) { - return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value)); + return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false)); } RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset) { - return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value)); + return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true)); } RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp index 196ca76..831ed40 100644 --- a/src/Reactor/Nucleus.hpp +++ b/src/Reactor/Nucleus.hpp
@@ -96,7 +96,7 @@ // Memory instructions static Value *createLoad(Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0); static Value *createStore(Value *value, Value *ptr, Type *type, bool isVolatile = false, unsigned int align = 0); - static Value *createGEP(Value *ptr, Type *type, Value *index); + static Value *createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex); // Atomic instructions static Value *createAtomicAdd(Value *ptr, Value *value);
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp index 859e98f..74a3f6c 100644 --- a/src/Reactor/Reactor.hpp +++ b/src/Reactor/Reactor.hpp
@@ -90,7 +90,7 @@ Value *loadValue(unsigned int alignment = 0) const; Value *storeValue(Value *value, unsigned int alignment = 0) const; - Value *getAddress(Value *index) const; + Value *getAddress(Value *index, bool unsignedIndex) const; }; template<class T> @@ -2120,7 +2120,9 @@ Reference<T> operator*(); Reference<T> operator[](int index); + Reference<T> operator[](unsigned int index); Reference<T> operator[](RValue<Int> index); + Reference<T> operator[](RValue<UInt> index); static Type *getType(); @@ -2149,7 +2151,9 @@ Array(int size = S); Reference<T> operator[](int index); + Reference<T> operator[](unsigned int index); Reference<T> operator[](RValue<Int> index); + Reference<T> operator[](RValue<UInt> index); }; // RValue<Array<T>> operator++(Array<T> &val, int); // Post-increment @@ -2245,9 +2249,9 @@ } template<class T> - Value *LValue<T>::getAddress(Value *index) const + Value *LValue<T>::getAddress(Value *index, bool unsignedIndex) const { - return Nucleus::createGEP(address, T::getType(), index); + return Nucleus::createGEP(address, T::getType(), index, unsignedIndex); } template<class T> @@ -2536,7 +2540,15 @@ template<class T> Reference<T> Pointer<T>::operator[](int index) { - Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index)); + Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), false); + + return Reference<T>(element, alignment); + } + + template<class T> + Reference<T> Pointer<T>::operator[](unsigned int index) + { + Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), Nucleus::createConstantInt(index), true); return Reference<T>(element, alignment); } @@ -2544,7 +2556,15 @@ template<class T> Reference<T> Pointer<T>::operator[](RValue<Int> index) { - Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value); + Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, false); + + return Reference<T>(element, alignment); + } + + template<class T> + Reference<T> Pointer<T>::operator[](RValue<UInt> index) + { + Value *element = Nucleus::createGEP(LValue<Pointer<T>>::loadValue(), T::getType(), index.value, true); return Reference<T>(element, alignment); } @@ -2563,7 +2583,15 @@ template<class T, int S> Reference<T> Array<T, S>::operator[](int index) { - Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index)); + Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index), false); + + return Reference<T>(element); + } + + template<class T, int S> + Reference<T> Array<T, S>::operator[](unsigned int index) + { + Value *element = LValue<T>::getAddress(Nucleus::createConstantInt(index), true); return Reference<T>(element); } @@ -2571,7 +2599,15 @@ template<class T, int S> Reference<T> Array<T, S>::operator[](RValue<Int> index) { - Value *element = LValue<T>::getAddress(index.value); + Value *element = LValue<T>::getAddress(index.value, false); + + return Reference<T>(element); + } + + template<class T, int S> + Reference<T> Array<T, S>::operator[](RValue<UInt> index) + { + Value *element = LValue<T>::getAddress(index.value, true); return Reference<T>(element); }
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp index 7ba4e50..9cd6fb8 100644 --- a/src/Reactor/SubzeroReactor.cpp +++ b/src/Reactor/SubzeroReactor.cpp
@@ -804,7 +804,7 @@ return value; } - Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index) + Value *Nucleus::createGEP(Value *ptr, Type *type, Value *index, bool unsignedIndex) { assert(index->getType() == Ice::IceType_i32); @@ -827,7 +827,14 @@ if(sizeof(void*) == 8) { - index = createSExt(index, T(Ice::IceType_i64)); + if(unsignedIndex) + { + index = createZExt(index, T(Ice::IceType_i64)); + } + else + { + index = createSExt(index, T(Ice::IceType_i64)); + } } return createAdd(ptr, index); @@ -6272,12 +6279,12 @@ RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<Int> offset) { - return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value)); + return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, false)); } RValue<Pointer<Byte>> operator+(RValue<Pointer<Byte>> lhs, RValue<UInt> offset) { - return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value)); + return RValue<Pointer<Byte>>(Nucleus::createGEP(lhs.value, Byte::getType(), offset.value, true)); } RValue<Pointer<Byte>> operator+=(Pointer<Byte> &lhs, int offset)