aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir_opt_algebraic.py13
-rw-r--r--src/compiler/nir/nir_search_helpers.h16
2 files changed, 24 insertions, 5 deletions
diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py
index 79058c06b97..1c7b3597c1f 100644
--- a/src/compiler/nir/nir_opt_algebraic.py
+++ b/src/compiler/nir/nir_opt_algebraic.py
@@ -152,11 +152,7 @@ optimizations = [
(('~fadd@32', ('fmul', a, ('fadd', 1.0, ('fneg', c ) )), ('fmul', b, c )), ('flrp', a, b, c), '!options->lower_flrp32'),
(('~fadd@64', ('fmul', a, ('fadd', 1.0, ('fneg', c ) )), ('fmul', b, c )), ('flrp', a, b, c), '!options->lower_flrp64'),
# These are the same as the previous three rules, but it depends on
- # 1-fsat(x) <=> fsat(1-x):
- #
- # If x >= 0 and x <= 1: fsat(1 - x) == 1 - fsat(x) trivially
- # If x < 0: 1 - fsat(x) => 1 - 0 => 1 and fsat(1 - x) => fsat(> 1) => 1
- # If x > 1: 1 - fsat(x) => 1 - 1 => 0 and fsat(1 - x) => fsat(< 0) => 0
+ # 1-fsat(x) <=> fsat(1-x). See below.
(('~fadd@32', ('fmul', a, ('fsat', ('fadd', 1.0, ('fneg', c )))), ('fmul', b, ('fsat', c))), ('flrp', a, b, ('fsat', c)), '!options->lower_flrp32'),
(('~fadd@64', ('fmul', a, ('fsat', ('fadd', 1.0, ('fneg', c )))), ('fmul', b, ('fsat', c))), ('flrp', a, b, ('fsat', c)), '!options->lower_flrp64'),
@@ -177,6 +173,11 @@ optimizations = [
(('fdot3', ('vec3', a, 0.0, 0.0), b), ('fmul', a, b)),
(('fdot3', ('vec3', a, b, 0.0), c), ('fdot2', ('vec2', a, b), c)),
+ # If x >= 0 and x <= 1: fsat(1 - x) == 1 - fsat(x) trivially
+ # If x < 0: 1 - fsat(x) => 1 - 0 => 1 and fsat(1 - x) => fsat(> 1) => 1
+ # If x > 1: 1 - fsat(x) => 1 - 1 => 0 and fsat(1 - x) => fsat(< 0) => 0
+ (('~fadd', ('fneg(is_used_once)', ('fsat(is_used_once)', 'a(is_not_fmul)')), 1.0), ('fsat', ('fadd', 1.0, ('fneg', a)))),
+
# (a * #b + #c) << #d
# ((a * #b) << #d) + (#c << #d)
# (a * (#b << #d)) + (#c << #d)
@@ -1179,6 +1180,8 @@ late_optimizations = [
(('ior', a, a), a),
(('iand', a, a), a),
+ (('~fadd', ('fneg(is_used_once)', ('fsat(is_used_once)', 'a(is_not_fmul)')), 1.0), ('fsat', ('fadd', 1.0, ('fneg', a)))),
+
(('fdot2', a, b), ('fdot_replicated2', a, b), 'options->fdot_replicates'),
(('fdot3', a, b), ('fdot_replicated3', a, b), 'options->fdot_replicates'),
(('fdot4', a, b), ('fdot_replicated4', a, b), 'options->fdot_replicates'),
diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h
index 9e03c610ece..631c65a8642 100644
--- a/src/compiler/nir/nir_search_helpers.h
+++ b/src/compiler/nir/nir_search_helpers.h
@@ -174,6 +174,22 @@ is_not_const(nir_alu_instr *instr, unsigned src, UNUSED unsigned num_components,
}
static inline bool
+is_not_fmul(nir_alu_instr *instr, unsigned src,
+ UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
+{
+ nir_alu_instr *src_alu =
+ nir_src_as_alu_instr(instr->src[src].src);
+
+ if (src_alu == NULL)
+ return true;
+
+ if (src_alu->op == nir_op_fneg)
+ return is_not_fmul(src_alu, 0, 0, NULL);
+
+ return src_alu->op != nir_op_fmul;
+}
+
+static inline bool
is_used_once(nir_alu_instr *instr)
{
bool zero_if_use = list_empty(&instr->dest.dest.ssa.if_uses);