diff --git a/expr.cpp b/expr.cpp index 65907d94..1f810998 100644 --- a/expr.cpp +++ b/expr.cpp @@ -2811,7 +2811,27 @@ Expr * SelectExpr::Optimize() { if (test == NULL || expr1 == NULL || expr2 == NULL) return NULL; - return this; + + ConstExpr *constTest = dynamic_cast(test); + if (constTest == NULL) + return this; + + // The test is a constant; see if we can resolve to one of the + // expressions.. + bool bv[ISPC_MAX_NVEC]; + int count = constTest->AsBool(bv); + if (count == 1) + // Uniform test value; return the corresponding expression + return (bv[0] == true) ? expr1 : expr2; + else { + // Varying test: see if all of the values are the same; if so, then + // return the corresponding expression + bool first = bv[0]; + for (int i = 0; i < count; ++i) + if (bv[i] != first) + return this; + return (bv[0] == true) ? expr1 : expr2; + } } diff --git a/tests/const-fold-select-1.ispc b/tests/const-fold-select-1.ispc new file mode 100644 index 00000000..08dcb8a5 --- /dev/null +++ b/tests/const-fold-select-1.ispc @@ -0,0 +1,10 @@ + +export uniform int width() { return programCount; } + +export void f_f(uniform float RET[], uniform float aFOO[]) { + RET[programIndex] = (programIndex >= 0) ? 1 : 0; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 1; +} diff --git a/tests/const-fold-select-2.ispc b/tests/const-fold-select-2.ispc new file mode 100644 index 00000000..2db0472a --- /dev/null +++ b/tests/const-fold-select-2.ispc @@ -0,0 +1,10 @@ + +export uniform int width() { return programCount; } + +export void f_f(uniform float RET[], uniform float aFOO[]) { + RET[programIndex] = (programCount < 10000) ? 1 : 0; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 1; +}