glsl: Fix constant expression handling for <, >, <=, >= on vectors.

ir_binop_less, ir_binop_greater, ir_binop_lequal, and ir_binop_gequal
are defined to work on vectors as well as scalars, as long as the two
operands have the same type.

This is evident from both ir_validate.cpp and our use of these opcodes
in the GLSL lessThan, greaterThan, lessThanEqual, greaterThanEqual
built-in functions.

Found by code inspection.  Not known to fix any bugs.  Presumably, our
tests for the built-in comparison functions must pass because C.E.
handling is done on the ir_call of "greaterThan" rather than the inlined
opcode.  The C.E. handling of the built-in function calls is correct.

NOTE: This is a candidate for the 7.9 branch.
This commit is contained in:
Kenneth Graunke 2010-11-17 10:40:28 -08:00
parent fb7ae06f59
commit e16c9d5d03

View file

@ -581,63 +581,75 @@ ir_expression::constant_expression_value()
break;
case ir_binop_less:
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
break;
default:
assert(0);
assert(op[0]->type == op[1]->type);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] < op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] < op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] < op[1]->value.f[0];
break;
default:
assert(0);
}
}
break;
case ir_binop_greater:
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] > op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] > op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] > op[1]->value.f[0];
break;
default:
assert(0);
assert(op[0]->type == op[1]->type);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[c] = op[0]->value.u[c] > op[1]->value.u[c];
break;
case GLSL_TYPE_INT:
data.b[c] = op[0]->value.i[c] > op[1]->value.i[c];
break;
case GLSL_TYPE_FLOAT:
data.b[c] = op[0]->value.f[c] > op[1]->value.f[c];
break;
default:
assert(0);
}
}
break;
case ir_binop_lequal:
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
break;
default:
assert(0);
assert(op[0]->type == op[1]->type);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] <= op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] <= op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] <= op[1]->value.f[0];
break;
default:
assert(0);
}
}
break;
case ir_binop_gequal:
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
break;
default:
assert(0);
assert(op[0]->type == op[1]->type);
for (unsigned c = 0; c < op[0]->type->components(); c++) {
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
data.b[0] = op[0]->value.u[0] >= op[1]->value.u[0];
break;
case GLSL_TYPE_INT:
data.b[0] = op[0]->value.i[0] >= op[1]->value.i[0];
break;
case GLSL_TYPE_FLOAT:
data.b[0] = op[0]->value.f[0] >= op[1]->value.f[0];
break;
default:
assert(0);
}
}
break;
case ir_binop_equal: