v2: Set in alphabetic order Change to use the new IS_CONSTANT macro Add a function for creating a minmax_range from two constants Use the function to improve the resolution of abs's range. --- src/glsl/opt_minmax.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/src/glsl/opt_minmax.cpp b/src/glsl/opt_minmax.cpp index 8fee0aa..04ae0c0 100644 --- a/src/glsl/opt_minmax.cpp +++ b/src/glsl/opt_minmax.cpp @@ -213,6 +213,21 @@ larger_constant(ir_constant *a, ir_constant *b) return a; } +/* Makes a minmax_range from the two constants + * The smaller of them is set as low, and the larger as high. + * If the comparison between the two is mixed the two will be combined + * in larger_constant and smaller_constant to yield a correct result. + */ +static minmax_range +make_range_from_constants(ir_constant *a, ir_constant *b) +{ + assert(a != NULL); + assert(b != NULL); + + return minmax_range(smaller_constant(a, b), + larger_constant(a, b)); +} + /* Combines two ranges by doing an element-wise min() / max() depending on the * operation. */ @@ -282,6 +297,19 @@ get_range(ir_rvalue *rval) if (expr) { switch (expr->operation) { + case ir_unop_abs: + r0 = get_range(expr->operands[0]); + + if (r0.high && r0.low) + return make_range_from_constants( + abs(r0.high)->constant_expression_value(), + abs(r0.low)->constant_expression_value()); + + if (IS_CONSTANT(r0.low, >, 0.0f)) + return minmax_range(r0.low, NULL); + + return minmax_range(new(mem_ctx) ir_constant(0.0f), NULL); + case ir_unop_exp: case ir_unop_exp2: case ir_unop_sqrt: -- 2.2.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev