Convert arrays to pointers in expressions like (a+5)

This was one instance of the C-style array/pointer duality that
was missed the first time around.
This commit is contained in:
Matt Pharr
2011-11-29 17:41:00 -08:00
parent e780662a3f
commit a3641d7691
3 changed files with 69 additions and 18 deletions

View File

@@ -135,6 +135,21 @@ lMaybeIssuePrecisionWarning(const AtomicType *toAtomicType,
///////////////////////////////////////////////////////////////////////////
static Expr *
lArrayToPointer(Expr *expr) {
assert(expr && dynamic_cast<const ArrayType *>(expr->GetType()));
Expr *zero = new ConstExpr(AtomicType::UniformInt32, 0, expr->pos);
Expr *index = new IndexExpr(expr, zero, expr->pos);
Expr *addr = new AddressOfExpr(index, expr->pos);
addr = addr->TypeCheck();
assert(addr != NULL);
addr = addr->Optimize();
assert(addr != NULL);
return addr;
}
static bool
lIsAllIntZeros(Expr *expr) {
const Type *type = expr->GetType();
@@ -1652,6 +1667,16 @@ BinaryExpr::TypeCheck() {
assert(type1 != NULL);
}
// Convert arrays to pointers to their first elements
if (dynamic_cast<const ArrayType *>(type0) != NULL) {
arg0 = lArrayToPointer(arg0);
type0 = arg0->GetType();
}
if (dynamic_cast<const ArrayType *>(type1) != NULL) {
arg1 = lArrayToPointer(arg1);
type1 = arg1->GetType();
}
const PointerType *pt0 = dynamic_cast<const PointerType *>(type0);
const PointerType *pt1 = dynamic_cast<const PointerType *>(type1);
if (pt0 != NULL && pt1 != NULL && op == Sub) {
@@ -5241,24 +5266,18 @@ TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
if (fromArrayType != NULL && toPointerType != NULL) {
// implicit array to pointer to first element
Expr *zero = new ConstExpr(AtomicType::UniformInt32, 0, pos);
Expr *index = new IndexExpr(expr, zero, pos);
Expr *addr = new AddressOfExpr(index, pos);
addr = addr->TypeCheck();
assert(addr != NULL);
addr = addr->Optimize();
assert(addr != NULL);
if (Type::EqualIgnoringConst(addr->GetType(), toPointerType) == false) {
assert(Type::EqualIgnoringConst(addr->GetType()->GetAsVaryingType(),
Expr *arrayAsPtr = lArrayToPointer(expr);
if (Type::EqualIgnoringConst(arrayAsPtr->GetType(), toPointerType) == false) {
assert(Type::EqualIgnoringConst(arrayAsPtr->GetType()->GetAsVaryingType(),
toPointerType) == true);
addr = new TypeCastExpr(toPointerType, addr, false, pos);
addr = addr->TypeCheck();
assert(addr != NULL);
addr = addr->Optimize();
assert(addr != NULL);
arrayAsPtr = new TypeCastExpr(toPointerType, arrayAsPtr, false, pos);
arrayAsPtr = arrayAsPtr->TypeCheck();
assert(arrayAsPtr != NULL);
arrayAsPtr = arrayAsPtr->Optimize();
assert(arrayAsPtr != NULL);
}
assert(Type::EqualIgnoringConst(addr->GetType(), toPointerType));
return addr->GetValue(ctx);
assert(Type::EqualIgnoringConst(arrayAsPtr->GetType(), toPointerType));
return arrayAsPtr->GetValue(ctx);
}
// This also should be caught during typechecking
@@ -5738,8 +5757,8 @@ DereferenceExpr::GetValue(FunctionEmitContext *ctx) const {
return NULL;
Symbol *baseSym = expr->GetBaseSymbol();
assert(baseSym != NULL);
llvm::Value *mask = lMaskForSymbol(baseSym, ctx);
llvm::Value *mask = baseSym ? lMaskForSymbol(baseSym, ctx) :
ctx->GetFullMask();
ctx->SetDebugPos(pos);
return ctx->LoadInst(ptr, mask, type, "deref_load");

View File

@@ -0,0 +1,15 @@
export uniform int width() { return programCount; }
export void f_f(uniform float RET[], uniform float aFOO[]) {
uniform float a[programCount];
for (unsigned int i = 0; i < programCount; ++i)
a[i] = aFOO[i];
RET[programIndex] = *(a + 2);
}
export void result(uniform float RET[]) {
RET[programIndex] = 3;
}

View File

@@ -0,0 +1,17 @@
export uniform int width() { return programCount; }
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
uniform int a[4][4][4];
for (uniform int i = 0; i < 4; ++i)
for (uniform int j = 0; j < 4; ++j)
for (uniform int k = 0; k < 4; ++k)
a[i][j][k] = 100*i+10*j+k;
RET[programIndex] = *(a[2][3] + 1);
}
export void result(uniform float RET[]) {
RET[programIndex] = 231;
}