From 6f26ae980184d61b0c1ff5411eb57f1099f60091 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Mon, 12 Dec 2011 14:13:46 -0800 Subject: [PATCH] Fix bugs with offsetting for varying values with gathers/scatters. Fixes issue #134. --- ctx.cpp | 21 +++++++++++---------- tests/gather-struct-vector.ispc | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 tests/gather-struct-vector.ispc diff --git a/ctx.cpp b/ctx.cpp index 882b294b..041473c6 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -1644,14 +1644,14 @@ FunctionEmitContext::AddElementOffset(llvm::Value *basePtr, int elementNum, // us the offset in bytes to the given element of the structure offset = g->target.StructOffset(st->LLVMType(g->ctx), elementNum); else { - // Otherwise we should have a vector here and the offset is given - // by the element number times the size of the element type of the - // vector. - const VectorType *vt = - dynamic_cast(ptrType->GetBaseType()); - assert(vt != NULL); + // Otherwise we should have a vector or array here and the offset + // is given by the element number times the size of the element + // type of the vector. + const SequentialType *st = + dynamic_cast(ptrType->GetBaseType()); + assert(st != NULL); llvm::Value *size = - g->target.SizeOf(vt->GetElementType()->LLVMType(g->ctx)); + g->target.SizeOf(st->GetElementType()->LLVMType(g->ctx)); llvm::Value *scale = (g->target.is32Bit || g->opt.force32BitAddressing) ? LLVMInt32(elementNum) : LLVMInt64(elementNum); offset = BinaryOperator(llvm::Instruction::Mul, size, scale); @@ -2542,9 +2542,10 @@ FunctionEmitContext::addVaryingOffsetsIfNeeded(llvm::Value *ptr, assert(pt && pt->IsVaryingType()); const Type *baseType = ptrType->GetBaseType(); - assert(dynamic_cast(baseType) != NULL || - dynamic_cast(baseType) != NULL || - dynamic_cast(baseType)); + if (dynamic_cast(baseType) == NULL && + dynamic_cast(baseType) == NULL && + dynamic_cast(baseType) == NULL) + return ptr; if (baseType->IsUniformType()) return ptr; diff --git a/tests/gather-struct-vector.ispc b/tests/gather-struct-vector.ispc new file mode 100644 index 00000000..d0ba704b --- /dev/null +++ b/tests/gather-struct-vector.ispc @@ -0,0 +1,31 @@ + +struct Ray { + float<3> v; +}; + +export uniform int width() { return programCount; } + + +export void f_f(uniform float RET[], uniform float aFOO[]) { + Ray r[programCount]; + for (uniform int i = 0; i < programCount; ++i) { + r[i].v.x = 100*i + programIndex; + r[i].v.y = 200*i + 2*programIndex; + r[i].v.z = 300*i + 3*programIndex; + } + + Ray *rp = &r[programIndex/2]; + RET[programIndex] = rp->v.z; +} + +export void result(uniform float RET[]) { + uniform int d0 = 0; + uniform int d1 = 0; + for (uniform int i = 0; i < programCount; i += 2) { + RET[i] = d0+d1; + d1 += 3; + RET[i+1] = d0+d1; + d0 += 300; + d1 += 3; + } +}