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)