diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/nir/nir_opt_algebraic.py | 5 | ||||
-rw-r--r-- | src/compiler/nir/nir_search_helpers.h | 19 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index bdf432be09d..c488b2c4fb9 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -375,6 +375,9 @@ optimizations = [ (('fsat', ('b2f', a)), ('b2f', a)), (('fsat', a), ('fmin', ('fmax', a, 0.0), 1.0), 'options->lower_fsat'), (('fsat', ('fsat', a)), ('fsat', a)), + (('fsat', ('fneg(is_used_once)', ('fadd(is_used_once)', a, b))), ('fsat', ('fadd', ('fneg', a), ('fneg', b))), '!options->lower_negate && !options->lower_fsat'), + (('fsat', ('fneg(is_used_once)', ('fmul(is_used_once)', a, b))), ('fsat', ('fmul', ('fneg', a), b)), '!options->lower_negate && !options->lower_fsat'), + (('fsat', ('fabs(is_used_once)', ('fmul(is_used_once)', a, b))), ('fsat', ('fmul', ('fabs', a), ('fabs', b))), '!options->lower_fsat'), (('fmin', ('fmax', ('fmin', ('fmax', a, b), c), b), c), ('fmin', ('fmax', a, b), c)), (('imin', ('imax', ('imin', ('imax', a, b), c), b), c), ('imin', ('imax', a, b), c)), (('umin', ('umax', ('umin', ('umax', a, b), c), b), c), ('umin', ('umax', a, b), c)), @@ -698,7 +701,7 @@ optimizations.extend([ (('iabs', ('isub', 0, a)), ('iabs', a)), # Propagate negation up multiplication chains - (('fmul', ('fneg', a), b), ('fneg', ('fmul', a, b))), + (('fmul(is_used_by_non_fsat)', ('fneg', a), b), ('fneg', ('fmul', a, b))), (('imul', ('ineg', a), b), ('ineg', ('imul', a, b))), # Propagate constants up multiplication chains diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h index 1624508993d..91d638a488f 100644 --- a/src/compiler/nir/nir_search_helpers.h +++ b/src/compiler/nir/nir_search_helpers.h @@ -193,4 +193,23 @@ is_not_used_by_if(nir_alu_instr *instr) return list_empty(&instr->dest.dest.ssa.if_uses); } +static inline bool +is_used_by_non_fsat(nir_alu_instr *instr) +{ + nir_foreach_use(src, &instr->dest.dest.ssa) { + const nir_instr *const user_instr = src->parent_instr; + + if (user_instr->type != nir_instr_type_alu) + return true; + + const nir_alu_instr *const user_alu = nir_instr_as_alu(user_instr); + + assert(instr != user_alu); + if (user_alu->op != nir_op_fsat) + return true; + } + + return false; +} + #endif /* _NIR_SEARCH_ */ |