diff options
author | Ian Romanick <[email protected]> | 2018-09-10 22:38:29 -0700 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-01-23 00:18:57 +0000 |
commit | 1d165b0548639df48c406fd6514298309e68aba9 (patch) | |
tree | 501b0fb310674a620f635789b1e9a43937322d1f /src/compiler/glsl/ir_constant_expression.cpp | |
parent | 20d34c4ebf07c98a40ea43b0cccc95537c176fa9 (diff) |
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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/767>
Diffstat (limited to 'src/compiler/glsl/ir_constant_expression.cpp')
-rw-r--r-- | src/compiler/glsl/ir_constant_expression.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
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. |