summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/ir_constant_expression.cpp
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2018-09-10 22:38:29 -0700
committerMarge Bot <[email protected]>2020-01-23 00:18:57 +0000
commit1d165b0548639df48c406fd6514298309e68aba9 (patch)
tree501b0fb310674a620f635789b1e9a43937322d1f /src/compiler/glsl/ir_constant_expression.cpp
parent20d34c4ebf07c98a40ea43b0cccc95537c176fa9 (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.cpp36
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.