From 1d165b0548639df48c406fd6514298309e68aba9 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Mon, 10 Sep 2018 22:38:29 -0700 Subject: glsl: Add new expressions for INTEL_shader_integer_functions2 v2: Re-write iadd64_saturate and isub64_saturate to avoid undefined overflow behavior. Also fix copy-and-paste bug in isub64_saturate. Suggested by Caio. v3: Avoid signed integer overflow for abs_sub(0, INT_MIN). Noticed by Caio. v4: Alternate fix for signed integer overflow for abs_sub(0, INT_MIN). I tried the previous methon in a small test program with -ftrapv, and it failed. Reviewed-by: Caio Marcelo de Oliveira Filho Part-of: --- src/compiler/glsl/ir_constant_expression.cpp | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/compiler/glsl/ir_constant_expression.cpp') diff --git a/src/compiler/glsl/ir_constant_expression.cpp b/src/compiler/glsl/ir_constant_expression.cpp index 5b1b5aa8eff..d7f0abe8304 100644 --- a/src/compiler/glsl/ir_constant_expression.cpp +++ b/src/compiler/glsl/ir_constant_expression.cpp @@ -416,6 +416,42 @@ unpack_half_1x16(uint16_t u) return _mesa_half_to_float(u); } +static int32_t +iadd_saturate(int32_t a, int32_t b) +{ + return CLAMP(int64_t(a) + int64_t(b), INT32_MIN, INT32_MAX); +} + +static int64_t +iadd64_saturate(int64_t a, int64_t b) +{ + if (a < 0 && b < INT64_MIN - a) + return INT64_MIN; + + if (a > 0 && b > INT64_MAX - a) + return INT64_MAX; + + return a + b; +} + +static int32_t +isub_saturate(int32_t a, int32_t b) +{ + return CLAMP(int64_t(a) - int64_t(b), INT32_MIN, INT32_MAX); +} + +static int64_t +isub64_saturate(int64_t a, int64_t b) +{ + if (b > 0 && a < INT64_MIN + b) + return INT64_MIN; + + if (b < 0 && a > INT64_MAX + b) + return INT64_MAX; + + return a - b; +} + /** * Get the constant that is ultimately referenced by an r-value, in a constant * expression evaluation context. -- cgit v1.2.3