+#include "util/u_math.h"
+
+static bool debug;
+
+static void
+dump_from(struct vc4_compile *c, struct qinst *inst)
+{
+ if (!debug)
+ return;
+
+ fprintf(stderr, "optimizing: ");
+ qir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+}
+
+static void
+dump_to(struct vc4_compile *c, struct qinst *inst)
+{
+ if (!debug)
+ return;
+
+ fprintf(stderr, "to: ");
+ qir_dump_inst(c, inst);
+ fprintf(stderr, "\n");
+}
+
+static bool
+is_constant_value(struct vc4_compile *c, struct qreg reg,
+ uint32_t val)
+{
+ if (reg.file == QFILE_UNIF &&
+ !reg.pack &&
+ c->uniform_contents[reg.index] == QUNIFORM_CONSTANT &&
+ c->uniform_data[reg.index] == val) {
+ return true;
+ }
+
+ if (reg.file == QFILE_SMALL_IMM && reg.index == val)
+ return true;
+
+ return false;
+}
+
+static bool
+is_zero(struct vc4_compile *c, struct qreg reg)
+{
+ reg = qir_follow_movs(c, reg);
+ return is_constant_value(c, reg, 0);
+}
+
+static bool
+is_1f(struct vc4_compile *c, struct qreg reg)
+{
+ reg = qir_follow_movs(c, reg);
+ return is_constant_value(c, reg, fui(1.0));
+}
+
+static void
+replace_with_mov(struct vc4_compile *c, struct qinst *inst, struct qreg arg)
+{
+ dump_from(c, inst);
+
+ inst->src[0] = arg;
+ if (qir_has_implicit_tex_uniform(inst))
+ inst->src[1] = inst->src[qir_get_tex_uniform_src(inst)];
+
+ if (qir_is_mul(inst))
+ inst->op = QOP_MMOV;
+ else if (qir_is_float_input(inst))
+ inst->op = QOP_FMOV;
+ else
+ inst->op = QOP_MOV;
+ dump_to(c, inst);
+}
+
+static bool
+replace_x_0_with_x(struct vc4_compile *c,
+ struct qinst *inst,
+ int arg)
+{
+ if (!is_zero(c, inst->src[arg]))
+ return false;
+ replace_with_mov(c, inst, inst->src[1 - arg]);
+ return true;
+}
+
+static bool
+replace_x_0_with_0(struct vc4_compile *c,
+ struct qinst *inst,
+ int arg)
+{
+ if (!is_zero(c, inst->src[arg]))
+ return false;
+ replace_with_mov(c, inst, inst->src[arg]);
+ return true;
+}
+
+static bool
+fmul_replace_one(struct vc4_compile *c,
+ struct qinst *inst,
+ int arg)
+{
+ if (!is_1f(c, inst->src[arg]))
+ return false;
+ replace_with_mov(c, inst, inst->src[1 - arg]);
+ return true;
+}