From 9df51caba93073eccab1fe506fa43e84719e4b61 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 1 Feb 2016 11:57:33 -0700 Subject: [PATCH] Fix front-end bug: Constant folding of array-of-struct index op. If a constant object was both an array and a structure, and was indexed with a constant, the arrayness was ignored and the wrong subconstant selected. This fixes that. --- Test/baseResults/constFold.frag.out | 36 +++++++++++++++++++++++++ Test/constFold.frag | 12 +++++++++ glslang/MachineIndependent/Constant.cpp | 15 +++++++---- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/Test/baseResults/constFold.frag.out b/Test/baseResults/constFold.frag.out index c03d865d..f5c3e9c5 100644 --- a/Test/baseResults/constFold.frag.out +++ b/Test/baseResults/constFold.frag.out @@ -270,6 +270,14 @@ ERROR: node is still EOpNull! 0:128 76.000000 0:128 59.000000 0:128 88.000000 +0:138 Function Definition: foo4( (global void) +0:138 Function Parameters: +0:140 Sequence +0:140 Sequence +0:140 move second child to first child (temp int) +0:140 'a' (temp int) +0:140 Constant: +0:140 9 (const int) 0:? Linker Objects 0:? 'a' (const int) 0:? 1 (const int) @@ -356,6 +364,16 @@ ERROR: node is still EOpNull! 0:? 13.000000 0:? 14.000000 0:? 15.000000 +0:? 'a0' (const 3-element array of structure{global int i, global float f, global bool b}) +0:? 3 (const int) +0:? 2.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 5.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 9.000000 +0:? false (const bool) Linked fragment stage: @@ -622,6 +640,14 @@ ERROR: node is still EOpNull! 0:128 76.000000 0:128 59.000000 0:128 88.000000 +0:138 Function Definition: foo4( (global void) +0:138 Function Parameters: +0:140 Sequence +0:140 Sequence +0:140 move second child to first child (temp int) +0:140 'a' (temp int) +0:140 Constant: +0:140 9 (const int) 0:? Linker Objects 0:? 'a' (const int) 0:? 1 (const int) @@ -708,4 +734,14 @@ ERROR: node is still EOpNull! 0:? 13.000000 0:? 14.000000 0:? 15.000000 +0:? 'a0' (const 3-element array of structure{global int i, global float f, global bool b}) +0:? 3 (const int) +0:? 2.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 5.000000 +0:? true (const bool) +0:? 1 (const int) +0:? 9.000000 +0:? false (const bool) diff --git a/Test/constFold.frag b/Test/constFold.frag index 81c718c9..97c3b2b6 100644 --- a/Test/constFold.frag +++ b/Test/constFold.frag @@ -127,3 +127,15 @@ void foo3() { mat3x2 r32 = mm2 * mm32; } + +struct cag { + int i; + float f; + bool b; +}; +const cag a0[3] = cag[3](cag(3, 2.0, true), cag(1, 5.0, true), cag(1, 9.0, false)); + +void foo4() +{ + int a = int(a0[2].f); +} \ No newline at end of file diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index a0bb8ded..b4d0695c 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -852,7 +852,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) // // Constant folding of a bracket (array-style) dereference or struct-like dot -// dereference. Can handle any thing except a multi-character swizzle, though +// dereference. Can handle anything except a multi-character swizzle, though // all swizzles may go to foldSwizzle(). // TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc) @@ -861,14 +861,19 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons dereferencedType.getQualifier().storage = EvqConst; TIntermTyped* result = 0; int size = dereferencedType.computeNumComponents(); - + + // arrays, vectors, matrices, all use simple multiplicative math + // while structures need to add up heterogeneous members int start; - if (node->isStruct()) { + if (node->isArray() || ! node->isStruct()) + start = size * index; + else { + // it is a structure + assert(node->isStruct()); start = 0; for (int i = 0; i < index; ++i) start += (*node->getType().getStruct())[i].type->computeNumComponents(); - } else - start = size * index; + } result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc);