+static bool
+get_induction_and_limit_vars(nir_ssa_scalar cond,
+ nir_ssa_scalar *ind,
+ nir_ssa_scalar *limit,
+ bool *limit_rhs,
+ loop_info_state *state)
+{
+ nir_ssa_scalar rhs, lhs;
+ lhs = nir_ssa_scalar_chase_alu_src(cond, 0);
+ rhs = nir_ssa_scalar_chase_alu_src(cond, 1);
+
+ if (get_loop_var(lhs.def, state)->type == basic_induction) {
+ *ind = lhs;
+ *limit = rhs;
+ *limit_rhs = true;
+ return true;
+ } else if (get_loop_var(rhs.def, state)->type == basic_induction) {
+ *ind = rhs;
+ *limit = lhs;
+ *limit_rhs = false;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool
+try_find_trip_count_vars_in_iand(nir_ssa_scalar *cond,
+ nir_ssa_scalar *ind,
+ nir_ssa_scalar *limit,
+ bool *limit_rhs,
+ loop_info_state *state)
+{
+ const nir_op alu_op = nir_ssa_scalar_alu_op(*cond);
+ assert(alu_op == nir_op_ieq || alu_op == nir_op_inot);
+
+ nir_ssa_scalar iand = nir_ssa_scalar_chase_alu_src(*cond, 0);
+
+ if (alu_op == nir_op_ieq) {
+ nir_ssa_scalar zero = nir_ssa_scalar_chase_alu_src(*cond, 1);
+
+ if (!nir_ssa_scalar_is_alu(iand) || !nir_ssa_scalar_is_const(zero)) {
+ /* Maybe we had it the wrong way, flip things around */
+ nir_ssa_scalar tmp = zero;
+ zero = iand;
+ iand = tmp;
+
+ /* If we still didn't find what we need then return */
+ if (!nir_ssa_scalar_is_const(zero))
+ return false;
+ }
+
+ /* If the loop is not breaking on (x && y) == 0 then return */
+ if (nir_ssa_scalar_as_uint(zero) != 0)
+ return false;
+ }
+
+ if (!nir_ssa_scalar_is_alu(iand))
+ return false;
+
+ if (nir_ssa_scalar_alu_op(iand) != nir_op_iand)
+ return false;
+
+ /* Check if iand src is a terminator condition and try get induction var
+ * and trip limit var.
+ */
+ bool found_induction_var = false;
+ for (unsigned i = 0; i < 2; i++) {
+ nir_ssa_scalar src = nir_ssa_scalar_chase_alu_src(iand, i);
+ if (is_supported_terminator_condition(src) &&
+ get_induction_and_limit_vars(src, ind, limit, limit_rhs, state)) {
+ *cond = src;
+ found_induction_var = true;
+
+ /* If we've found one with a constant limit, stop. */
+ if (nir_ssa_scalar_is_const(*limit))
+ return true;
+ }
+ }
+
+ return found_induction_var;
+}
+