correction of overload issues

This commit is contained in:
Ilia Filippov
2014-03-21 12:14:30 +04:00
parent 02d55f24f6
commit 6f44d5b55f
6 changed files with 382 additions and 83 deletions

View File

@@ -2931,23 +2931,26 @@ Function Overloading
--------------------
Functions can be overloaded by parameter type. Given multiple definitions
of a function, ``ispc`` uses the following methods to try to find a match.
If a single match of a given type is found, it is used; if multiple matches
of a given type are found, an error is issued.
of a function, ``ispc`` uses the following model to choose the best function:
each conversion of two types has its cost. ``ispc`` tries to find conversion
with the smallest cost. When ``ispc`` can't find any conversion it means that
this function is not suitable. Then ``ispc`` sums costs for all arguments and
chooses the function with the smallest final cost.
Costs of type conversions placed from small to big:
* All parameter types match exactly.
* All parameter types match exactly, where any reference-type
parameters are considered equivalent to their underlying type.
* Parameters match with only type conversions that don't risk losing any
information (for example, converting an ``int16`` value to an ``int32``
parameter value.)
* Parameters match with only promotions from ``uniform`` to ``varying``
types.
* Parameters match using arbitrary type conversion, without changing
variability from ``uniform`` to ``varying`` (e.g., ``int`` to ``float``,
``float`` to ``int``.)
* Parameters match using arbitrary type conversion, including also changing
variability from ``uniform`` to ``varying`` as needed.
1. Parameter types match exactly.
2. Function parameter type is reference and parameters match when any reference-type parameter are considered equivalent to their underlying type.
3. Function parameter type is const-reference and parameters match when any reference-type parameter are considered equivalent to their underlying type ignoring const attributes.
4. Parameters match exactly, except constant attributes. [NO CONSTANT ATTRIBUTES LATER]
5. Parameters match exactly, except reference attributes. [NO REFERENCES ATTRIBUTES LATER]
6. Parameters match with only type conversions that don't risk losing any information (for example, converting an int16 value to an int32 parameter value.)
7. Parameters match with only promotions from uniform to varying types.
8. Parameters match using arbitrary type conversion, without changing variability from uniform to varying (e.g., int to float, float to int.)
9. Parameters match with widening and promotions from uniform to varying types. (combination of "6" and "7")
10. Parameters match using arbitrary type conversion, including also changing variability from uniform to varying.
* If function parameter type is reference and neither "2" nor "3" aren't suitable, function is not suitable
* If "10" isn't suitable, function is not suitable
Re-establishing The Execution Mask

143
expr.cpp
View File

@@ -8091,23 +8091,6 @@ lGetOverloadCandidateMessage(const std::vector<Symbol *> &funcs,
}
static bool
lIsMatchToNonConstReference(const Type *callType, const Type *funcArgType) {
return (CastType<ReferenceType>(funcArgType) &&
(funcArgType->IsConstType() == false) &&
Type::Equal(callType, funcArgType->GetReferenceTarget()));
}
static bool
lIsMatchToNonConstReferenceUnifToVarying(const Type *callType,
const Type *funcArgType) {
return (CastType<ReferenceType>(funcArgType) &&
(funcArgType->IsConstType() == false) &&
Type::Equal(callType->GetAsVaryingType(),
funcArgType->GetReferenceTarget()));
}
/** Helper function used for function overload resolution: returns true if
converting the argument to the call type only requires a type
conversion that won't lose information. Otherwise return false.
@@ -8154,31 +8137,6 @@ lIsMatchWithTypeWidening(const Type *callType, const Type *funcArgType) {
}
/** Helper function used for function overload resolution: returns true if
the call argument type and the function argument type match if we only
do a uniform -> varying type conversion but otherwise have exactly the
same type.
*/
static bool
lIsMatchWithUniformToVarying(const Type *callType, const Type *funcArgType) {
return (callType->IsUniformType() &&
funcArgType->IsVaryingType() &&
Type::EqualIgnoringConst(callType->GetAsVaryingType(), funcArgType));
}
/** Helper function used for function overload resolution: returns true if
we can type convert from the call argument type to the function
argument type, but without doing a uniform -> varying conversion.
*/
static bool
lIsMatchWithTypeConvSameVariability(const Type *callType,
const Type *funcArgType) {
return (CanConvertTypes(callType, funcArgType) &&
(callType->GetVariability() == funcArgType->GetVariability()));
}
/* Returns the set of function overloads that are potential matches, given
argCount values being passed as arguments to the function call.
*/
@@ -8249,11 +8207,12 @@ FunctionSymbolExpr::computeOverloadCost(const FunctionType *ftype,
if (Type::Equal(callType, fargType))
// Perfect match: no cost
// Step "1" from documentation
costSum += 0;
else if (argCouldBeNULL && (*argCouldBeNULL)[i] &&
lArgIsPointerType(fargType))
// Passing NULL to a pointer-typed parameter is also a no-cost
// operation
// Passing NULL to a pointer-typed parameter is also a no-cost operation
// Step "1" from documentation
costSum += 0;
else {
// If the argument is a compile-time constant, we'd like to
@@ -8261,32 +8220,82 @@ FunctionSymbolExpr::computeOverloadCost(const FunctionType *ftype,
// cost if it wasn't--so scale up the cost when this isn't the
// case..
if (argIsConstant == NULL || (*argIsConstant)[i] == false)
costScale *= 128;
costScale *= 512;
// For convenience, normalize to non-const types (except for
// references, where const-ness matters). For all other types,
// we're passing by value anyway, so const doesn't matter.
const Type *callTypeNC = callType, *fargTypeNC = fargType;
if (CastType<ReferenceType>(callType) == NULL)
callTypeNC = callType->GetAsNonConstType();
if (CastType<ReferenceType>(fargType) == NULL)
fargTypeNC = fargType->GetAsNonConstType();
if (Type::Equal(callTypeNC, fargTypeNC))
// Exact match (after dealing with references, above)
costSum += 1 * costScale;
// note: orig fargType for the next two...
else if (lIsMatchToNonConstReference(callTypeNC, fargType))
if (CastType<ReferenceType>(fargType)) {
// Here we completely handle the case where fargType is reference.
if (callType->IsConstType() && !fargType->IsConstType()) {
// It is forbidden to pass const object to non-const reference (cvf -> vfr)
return -1;
}
if (!callType->IsConstType() && fargType->IsConstType()) {
// It is possible to pass (vf -> cvfr)
// but it is worse than (vf -> vfr) or (cvf -> cvfr)
// Step "3" from documentation
costSum += 2 * costScale;
}
if (!Type::Equal(callType->GetReferenceTarget()->GetAsNonConstType(),
fargType->GetReferenceTarget()->GetAsNonConstType())) {
// Types under references must be equal completely.
// vd -> vfr or vd -> cvfr are forbidden. (Although clang allows vd -> cvfr case.)
return -1;
}
// penalty for equal types under reference (vf -> vfr is worse than vf -> vf)
// Step "2" from documentation
costSum += 2 * costScale;
else if (lIsMatchToNonConstReferenceUnifToVarying(callTypeNC, fargType))
costSum += 4 * costScale;
else if (lIsMatchWithTypeWidening(callTypeNC, fargTypeNC))
continue;
}
const Type *callTypeNP = callType;
if (CastType<ReferenceType>(callType)) {
callTypeNP = callType->GetReferenceTarget();
// we can treat vfr as vf for callType with some penalty
// Step "5" from documentation
costSum += 2 * costScale;
}
// Now we deal with references, so we can normalize to non-const types
// because we're passing by value anyway, so const doesn't matter.
const Type *callTypeNC = callTypeNP, *fargTypeNC = fargType;
callTypeNC = callTypeNP->GetAsNonConstType();
fargTypeNC = fargType->GetAsNonConstType();
// Now we forget about constants and references!
if (Type::Equal(callTypeNC, fargTypeNC)) {
// The best case: vf -> vf.
// Step "4" from documentation
costSum += 1 * costScale;
continue;
}
if (lIsMatchWithTypeWidening(callTypeNC, fargTypeNC)) {
// A little bit worse case: vf -> vd.
// Step "6" from documentation
costSum += 8 * costScale;
else if (lIsMatchWithUniformToVarying(callTypeNC, fargTypeNC))
costSum += 16 * costScale;
else if (lIsMatchWithTypeConvSameVariability(callTypeNC, fargTypeNC))
costSum += 32 * costScale;
else if (CanConvertTypes(callTypeNC, fargTypeNC))
continue;
}
if (fargType->IsVaryingType() && callType->IsUniformType()) {
// Here we deal with brodcasting uniform to varying.
// callType - varying and fargType - uniform is forbidden.
if (Type::Equal(callTypeNC->GetAsVaryingType(), fargTypeNC)) {
// uf -> vf is better than uf -> ui or uf -> ud
// Step "7" from documentation
costSum += 16 * costScale;
continue;
}
if (lIsMatchWithTypeWidening(callTypeNC->GetAsVaryingType(), fargTypeNC)) {
// uf -> vd is better than uf -> vi (128 < 128 + 64)
// but worse than uf -> ui (128 > 64)
// Step "9" from documentation
costSum += 128 * costScale;
continue;
}
// 128 + 64 is the max. uf -> vi is the worst case.
// Step "10" from documentation
costSum += 128 * costScale;
}
if (CanConvertTypes(callTypeNC, fargTypeNC))
// two cases: the worst is 128 + 64: uf -> vi and
// the only 64: (64 < 128) uf -> ui worse than uf -> vd
// Step "8" from documentation
costSum += 64 * costScale;
else
// Failure--no type conversion possible...

93
tests/ref-overloads.ispc Normal file
View File

@@ -0,0 +1,93 @@
/////////////////////////VARYING
//int A011(varying float f){return 0;} int A011(varying float& f){return 1;} int A011(varying const float& f){return 2;}
//int A011(varying double f){return 3;} int A011(varying int f){return 4;} int A011(uniform float f){return 5;}
//int A011(uniform float& f){return 6;} int A011(uniform const float& f){return 7;} int A011(uniform double f){return 8;} int A011(uniform int f){return 9;}
int A013(varying const float& f){return 2;} int A013(varying double f){return 3;} int A013(varying int f){return 4;}
int A013(uniform float f){return 5;} int A013(uniform float& f){return 6;} int A013(uniform const float& f){return 7;}
int A013(uniform double f){return 8;} int A013(uniform int f){return 9;}
int A014(varying double f){return 3;} int A014(varying int f){return 4;}
int A014(uniform float f){return 5;} int A014(uniform float& f){return 6;} int A014(uniform const float& f){return 7;}
int A014(uniform double f){return 8;} int A014(uniform int f){return 9;}
int A015(varying int f){return 4;} int A015(uniform float f){return 5;}
int A015(uniform float& f){return 6;} int A015(uniform const float& f){return 7;}
int A015(uniform double f){return 8;} int A015(uniform int f){return 9;}
int A032(varying float& f){return 1;} int A032(varying double f){return 3;} int A032(varying int f){return 4;}
int A032(uniform float f){return 5;} int A032(uniform float& f){return 6;} int A032(uniform const float& f){return 7;}
int A032(uniform double f){return 8;} int A032(uniform int f){return 9;}
int A033(varying int f){return 4;}
int A033(uniform float f){return 5;} int A033(uniform float& f){return 6;} int A033(uniform const float& f){return 7;}
int A033(uniform double f){return 8;} int A033(uniform int f){return 9;}
/////////////////////////UNIFORM
int A051(varying float f){return 0;} int A051(varying float& f){return 1;} int A051(varying const float& f){return 2;}
int A051(varying double f){return 3;} int A051(varying int f){return 4;}
int A051(uniform const float& f){return 7;} int A051(uniform double f){return 8;} int A051(uniform int f){return 9;}
int A052(varying float f){return 0;} int A052(varying float& f){return 1;} int A052(varying const float& f){return 2;}
int A052(varying double f){return 3;} int A052(varying int f){return 4;}
int A052(uniform double f){return 8;} int A052(uniform int f){return 9;}
int A053(varying float f){return 0;} int A053(varying float& f){return 1;} int A053(varying const float& f){return 2;}
int A053(varying double f){return 3;} int A053(varying int f){return 4;} int A053(uniform int f){return 9;}
int A054(varying float& f){return 1;} int A054(varying const float& f){return 2;}
int A054(varying double f){return 3;} int A054(varying int f){return 4;} int A054(uniform int f){return 9;}
int A055(varying float& f){return 1;} int A055(varying const float& f){return 2;}
int A055(varying double f){return 3;} int A055(varying int f){return 4;}
int A056(varying float& f){return 1;} int A056(varying const float& f){return 2;} int A056(varying int f){return 4;}
export uniform int width() { return programCount; }
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
varying float vf = 5;
varying const float vcf = 5;
varying float& vfr = vf;
varying const float& vcfr = vf;
uniform float uf = 5;
uniform const float ucf = 5;
uniform float& ufr = uf;
uniform const float& ucfr = uf;
if (A013(vf) != 2) {RET[programIndex] = 1; return;}
if (A014(vf) != 3) {RET[programIndex] = 2; return;}
if (A015(vf) != 4) {RET[programIndex] = 3; return;}
if (A013(vfr) != 2) {RET[programIndex] = 4; return;}
if (A014(vfr) != 3) {RET[programIndex] = 5; return;}
if (A015(vfr) != 4) {RET[programIndex] = 6; return;}
if (A032(vcf) != 3) {RET[programIndex] = 7; return;}
if (A033(vcf) != 4) {RET[programIndex] = 8; return;}
if (A032(vcfr) != 3) {RET[programIndex] = 9; return;}
if (A033(vcfr) != 4) {RET[programIndex] = 10; return;}
if (A051(uf) != 7) {RET[programIndex] = 11; return;}
if (A052(uf) != 8) {RET[programIndex] = 12; return;}
if (A053(uf) != 0) {RET[programIndex] = 13; return;}
if (A054(uf) != 9) {RET[programIndex] = 14; return;}
if (A055(uf) != 3) {RET[programIndex] = 15; return;}
if (A056(uf) != 4) {RET[programIndex] = 16; return;}
if (A051(ufr) != 7) {RET[programIndex] = 17; return;}
if (A052(ufr) != 8) {RET[programIndex] = 18; return;}
if (A053(ufr) != 0) {RET[programIndex] = 19; return;}
if (A054(ufr) != 9) {RET[programIndex] = 20; return;}
if (A055(ufr) != 3) {RET[programIndex] = 21; return;}
if (A056(ufr) != 4) {RET[programIndex] = 22; return;}
RET[programIndex] = 0;
}
export void result(uniform float RET[]) { RET[programIndex] = 0; }

41
tests/ref-overloads1.ispc Normal file
View File

@@ -0,0 +1,41 @@
void A1(float f) {}
void A2(float& f) {}
void A3(const float& f) {}
void A4(double f) {}
void A5(int f) {}
void A6(uniform float f) {}
void A7(uniform float& f) {}
void A8(uniform const float& f){}
void A9(uniform double f) {}
void A0(uniform int f) {}
export uniform int width() { return programCount; }
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
varying float vf = 5;
varying const float vcf = 5;
varying float& vfr = vf;
varying const float& vcfr = vf;
uniform float uf = 5;
uniform const float ucf = 5;
uniform float& ufr = uf;
uniform const float& ucfr = uf;
A1(vf); A1(vcf); A1(vfr); A1(vcfr); A1(uf); A1(ucf); A1(ufr); A1(ucfr);
A2(vf); A2(vfr);
A3(vf); A3(vcf); A3(vfr); A3(vcfr);
A4(vf); A4(vcf); A4(vfr); A4(vcfr); A4(uf); A4(ucf); A4(ufr); A4(ucfr);
A5(vf); A5(vcf); A5(vfr); A5(vcfr); A5(uf); A5(ucf); A5(ufr); A5(ucfr);
A6(uf); A6(ucf); A6(ufr); A6(ucfr);
A7(uf); A7(ufr);
A8(uf); A8(ucf); A8(ufr); A8(ucfr);
A9(uf); A9(ucf); A9(ufr); A9(ucfr);
A0(uf); A0(ucf); A0(ufr); A0(ucfr);
RET[programIndex] = 1;
}
export void result(uniform float RET[]) { RET[programIndex] = 1; }

54
tests/ref-overloads2.ispc Normal file
View File

@@ -0,0 +1,54 @@
void A01(varying float f){} void A01(varying float& f){} void A01(varying const float& f){} void A01(varying double f){} void A01(varying int f){}
void A02(varying float& f){} void A02(varying const float& f){} void A02(varying double f){} void A02(varying int f){}
void A03(varying float f){} void A03(varying const float& f){} void A03(varying double f){} void A03(varying int f){}
void A04(varying float f){} void A04(varying float& f){} void A04(varying double f){} void A04(varying int f){}
void A05(varying float f){} void A05(varying float& f){} void A05(varying const float& f){} void A05(varying int f){}
void A06(varying float f){} void A06(varying float& f){} void A06(varying const float& f){} void A06(varying double f){}
void A07(varying float f){} void A07(varying float& f){} void A07(varying const float& f){} void A07(varying double f){} void A07(varying int f){}
void A08(varying float f){} void A08(varying float& f){} void A08(varying const float& f){} void A08(varying double f){} void A08(varying int f){}
void A09(varying float f){} void A09(varying float& f){} void A09(varying const float& f){} void A09(varying double f){} void A09(varying int f){}
void A10(varying float f){} void A10(varying float& f){} void A10(varying const float& f){} void A10(varying double f){} void A10(varying int f){}
void A11(varying float f){} void A11(varying float& f){} void A11(varying const float& f){} void A11(varying double f){} void A11(varying int f){}
void A01(uniform float f){} void A01(uniform float& f){} void A01(uniform const float& f){} void A01(uniform double f){} void A01(uniform int f){}
void A02(uniform float f){} void A02(uniform float& f){} void A02(uniform const float& f){} void A02(uniform double f){} void A02(uniform int f){}
void A03(uniform float f){} void A03(uniform float& f){} void A03(uniform const float& f){} void A03(uniform double f){} void A03(uniform int f){}
void A04(uniform float f){} void A04(uniform float& f){} void A04(uniform const float& f){} void A04(uniform double f){} void A04(uniform int f){}
void A05(uniform float f){} void A05(uniform float& f){} void A05(uniform const float& f){} void A05(uniform double f){} void A05(uniform int f){}
void A06(uniform float f){} void A06(uniform float& f){} void A06(uniform const float& f){} void A06(uniform double f){} void A06(uniform int f){}
void A07(uniform float& f){} void A07(uniform const float& f){} void A07(uniform double f){} void A07(uniform int f){}
void A08(uniform float f){} void A08(uniform const float& f){} void A08(uniform double f){} void A08(uniform int f){}
void A09(uniform float f){} void A09(uniform float& f){} void A09(uniform double f){} void A09(uniform int f){}
void A10(uniform float f){} void A10(uniform float& f){} void A10(uniform const float& f){} void A10(uniform int f){}
void A11(uniform float f){} void A11(uniform float& f){} void A11(uniform const float& f){} void A11(uniform double f){}
export uniform int width() { return programCount; }
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
varying float vf = 5;
varying const float vcf = 5;
varying float& vfr = vf;
varying const float& vcfr = vf;
uniform float uf = 5;
uniform const float ucf = 5;
uniform float& ufr = uf;
uniform const float& ucfr = uf;
A01(vf); A01(vcf); A01(vfr); A01(vcfr); A01(uf); A01(ucf); A01(ufr); A01(ucfr);
A02(vf); A02(vcf); A02(vfr); A02(vcfr); A02(uf); A02(ucf); A02(ufr); A02(ucfr);
A03(vf); A03(vcf); A03(vfr); A03(vcfr); A03(uf); A03(ucf); A03(ufr); A03(ucfr);
A04(vf); A04(vcf); A04(vfr); A04(vcfr); A04(uf); A04(ucf); A04(ufr); A04(ucfr);
A05(vf); A05(vcf); A05(vfr); A05(vcfr); A05(uf); A05(ucf); A05(ufr); A05(ucfr);
A06(vf); A06(vcf); A06(vfr); A06(vcfr); A06(uf); A06(ucf); A06(ufr); A06(ucfr);
A07(vf); A07(vcf); A07(vfr); A07(vcfr); A07(uf); A07(ucf); A07(ufr); A07(ucfr);
A08(vf); A08(vcf); A08(vfr); A08(vcfr); A08(uf); A08(ucf); A08(ufr); A08(ucfr);
A09(vf); A09(vcf); A09(vfr); A09(vcfr); A09(uf); A09(ucf); A09(ufr); A09(ucfr);
A10(vf); A10(vcf); A10(vfr); A10(vcfr); A10(uf); A10(ucf); A10(ufr); A10(ucfr);
RET[programIndex] = 1;
}
export void result(uniform float RET[]) { RET[programIndex] = 1; }

99
tests/ref-overloads3.ispc Normal file
View File

@@ -0,0 +1,99 @@
int A01(varying float f){return 0;} int A01(varying float& f){return 1;} int A01(varying const float& f){return 2;} int A01(varying double f){return 3;} int A01(varying int f){return 4;}
int A02(varying float& f){return 1;} int A02(varying const float& f){return 2;} int A02(varying double f){return 3;} int A02(varying int f){return 4;}
int A03(varying float f){return 0;} int A03(varying const float& f){return 2;} int A03(varying double f){return 3;} int A03(varying int f){return 4;}
int A04(varying float f){return 0;} int A04(varying float& f){return 1;} int A04(varying double f){return 3;} int A04(varying int f){return 4;}
int A07(varying float f){return 0;} int A07(varying float& f){return 1;} int A07(varying const float& f){return 2;} int A07(varying double f){return 3;} int A07(varying int f){return 4;}
int A08(varying float f){return 0;} int A08(varying float& f){return 1;} int A08(varying const float& f){return 2;} int A08(varying double f){return 3;} int A08(varying int f){return 4;}
int A09(varying float f){return 0;} int A09(varying float& f){return 1;} int A09(varying const float& f){return 2;} int A09(varying double f){return 3;} int A09(varying int f){return 4;}
int A01(uniform float f){return 5;} int A01(uniform float& f){return 6;} int A01(uniform const float& f){return 7;} int A01(uniform double f){return 8;} int A01(uniform int f){return 9;}
int A02(uniform float f){return 5;} int A02(uniform float& f){return 6;} int A02(uniform const float& f){return 7;} int A02(uniform double f){return 8;} int A02(uniform int f){return 9;}
int A03(uniform float f){return 5;} int A03(uniform float& f){return 6;} int A03(uniform const float& f){return 7;} int A03(uniform double f){return 8;} int A03(uniform int f){return 9;}
int A04(uniform float f){return 5;} int A04(uniform float& f){return 6;} int A04(uniform const float& f){return 7;} int A04(uniform double f){return 8;} int A04(uniform int f){return 9;}
int A07(uniform float& f){return 6;} int A07(uniform const float& f){return 7;} int A07(uniform double f){return 8;} int A07(uniform int f){return 9;}
int A08(uniform float f){return 5;} int A08(uniform const float& f){return 7;} int A08(uniform double f){return 8;} int A08(uniform int f){return 9;}
int A09(uniform float f){return 5;} int A09(uniform float& f){return 6;} int A09(uniform double f){return 8;} int A09(uniform int f){return 9;}
export uniform int width() { return programCount; }
export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) {
varying float vf = 5;
varying const float vcf = 5;
varying float& vfr = vf;
varying const float& vcfr = vf;
uniform float uf = 5;
uniform const float ucf = 5;
uniform float& ufr = uf;
uniform const float& ucfr = uf;
if (A01(vf) != 0) {RET[programIndex] = 1; return;}
if (A01(vcf) != 0) {RET[programIndex] = 2; return;}
if (A01(vfr) != 1) {RET[programIndex] = 3; return;}
if (A01(vcfr)!= 2) {RET[programIndex] = 4; return;}
if (A01(uf) != 5) {RET[programIndex] = 5; return;}
if (A01(ucf) != 5) {RET[programIndex] = 6; return;}
if (A01(ufr) != 6) {RET[programIndex] = 7; return;}
if (A01(ucfr)!= 7) {RET[programIndex] = 8; return;}
if (A02(vf) != 1) {RET[programIndex] = 9; return;}
if (A02(vcf) != 2) {RET[programIndex] = 10; return;}
if (A02(vfr) != 1) {RET[programIndex] = 11; return;}
if (A02(vcfr)!= 2) {RET[programIndex] = 12; return;}
if (A02(uf) != 5) {RET[programIndex] = 13; return;}
if (A02(ucf) != 5) {RET[programIndex] = 14; return;}
if (A02(ufr) != 6) {RET[programIndex] = 15; return;}
if (A02(ucfr)!= 7) {RET[programIndex] = 16; return;}
if (A03(vf) != 0) {RET[programIndex] = 17; return;}
if (A03(vcf) != 0) {RET[programIndex] = 18; return;}
if (A03(vfr) != 0) {RET[programIndex] = 19; return;}
if (A03(vcfr)!= 2) {RET[programIndex] = 20; return;}
if (A03(uf) != 5) {RET[programIndex] = 21; return;}
if (A03(ucf) != 5) {RET[programIndex] = 22; return;}
if (A03(ufr) != 6) {RET[programIndex] = 23; return;}
if (A03(ucfr)!= 7) {RET[programIndex] = 24; return;}
if (A04(vf) != 0) {RET[programIndex] = 25; return;}
if (A04(vcf) != 0) {RET[programIndex] = 26; return;}
if (A04(vfr) != 1) {RET[programIndex] = 27; return;}
if (A04(vcfr)!= 0) {RET[programIndex] = 28; return;}
if (A04(uf) != 5) {RET[programIndex] = 29; return;}
if (A04(ucf) != 5) {RET[programIndex] = 30; return;}
if (A04(ufr) != 6) {RET[programIndex] = 31; return;}
if (A04(ucfr)!= 7) {RET[programIndex] = 32; return;}
if (A07(vf) != 0) {RET[programIndex] = 33; return;}
if (A07(vcf) != 0) {RET[programIndex] = 34; return;}
if (A07(vfr) != 1) {RET[programIndex] = 35; return;}
if (A07(vcfr)!= 2) {RET[programIndex] = 36; return;}
if (A07(uf) != 6) {RET[programIndex] = 37; return;}
if (A07(ucf) != 7) {RET[programIndex] = 38; return;}
if (A07(ufr) != 6) {RET[programIndex] = 39; return;}
if (A07(ucfr)!= 7) {RET[programIndex] = 40; return;}
if (A08(vf) != 0) {RET[programIndex] = 41; return;}
if (A08(vcf) != 0) {RET[programIndex] = 42; return;}
if (A08(vfr) != 1) {RET[programIndex] = 43; return;}
if (A08(vcfr)!= 2) {RET[programIndex] = 44; return;}
if (A08(uf) != 5) {RET[programIndex] = 45; return;}
if (A08(ucf) != 5) {RET[programIndex] = 46; return;}
if (A08(ufr) != 5) {RET[programIndex] = 47; return;}
if (A08(ucfr)!= 7) {RET[programIndex] = 48; return;}
if (A09(vf) != 0) {RET[programIndex] = 49; return;}
if (A09(vcf) != 0) {RET[programIndex] = 50; return;}
if (A09(vfr) != 1) {RET[programIndex] = 51; return;}
if (A09(vcfr)!= 2) {RET[programIndex] = 52; return;}
if (A09(uf) != 5) {RET[programIndex] = 53; return;}
if (A09(ucf) != 5) {RET[programIndex] = 54; return;}
if (A09(ufr) != 6) {RET[programIndex] = 55; return;}
if (A09(ucfr)!= 5) {RET[programIndex] = 56; return;}
RET[programIndex] = 0;
}
export void result(uniform float RET[]) { RET[programIndex] = 0; }