std::vector<uint16_t> uses;
 };
 
+struct CmpInfo {
+   aco_opcode ordered;
+   aco_opcode unordered;
+   aco_opcode ordered_swapped;
+   aco_opcode unordered_swapped;
+   aco_opcode inverse;
+   aco_opcode f32;
+   unsigned size;
+};
+
+ALWAYS_INLINE bool get_cmp_info(aco_opcode op, CmpInfo *info);
+
 bool can_swap_operands(aco_ptr<Instruction>& instr)
 {
    if (instr->operands[0].isConstant() ||
    case aco_opcode::v_min_i32:
    case aco_opcode::v_max_u32:
    case aco_opcode::v_min_u32:
-   case aco_opcode::v_cmp_eq_f16:
-   case aco_opcode::v_cmp_eq_f32:
-   case aco_opcode::v_cmp_lg_f16:
-   case aco_opcode::v_cmp_lg_f32:
+   case aco_opcode::v_max_i16:
+   case aco_opcode::v_min_i16:
+   case aco_opcode::v_max_u16:
+   case aco_opcode::v_min_u16:
+   case aco_opcode::v_max_i16_e64:
+   case aco_opcode::v_min_i16_e64:
+   case aco_opcode::v_max_u16_e64:
+   case aco_opcode::v_min_u16_e64:
       return true;
    case aco_opcode::v_sub_f16:
       instr->opcode = aco_opcode::v_subrev_f16;
    case aco_opcode::v_sub_f32:
       instr->opcode = aco_opcode::v_subrev_f32;
       return true;
-   case aco_opcode::v_cmp_lt_f16:
-      instr->opcode = aco_opcode::v_cmp_gt_f16;
-      return true;
-   case aco_opcode::v_cmp_lt_f32:
-      instr->opcode = aco_opcode::v_cmp_gt_f32;
-      return true;
-   case aco_opcode::v_cmp_ge_f16:
-      instr->opcode = aco_opcode::v_cmp_le_f16;
+   case aco_opcode::v_sub_co_u32:
+      instr->opcode = aco_opcode::v_subrev_co_u32;
       return true;
-   case aco_opcode::v_cmp_ge_f32:
-      instr->opcode = aco_opcode::v_cmp_le_f32;
+   case aco_opcode::v_sub_u16:
+      instr->opcode = aco_opcode::v_subrev_u16;
       return true;
-   case aco_opcode::v_cmp_lt_i32:
-      instr->opcode = aco_opcode::v_cmp_gt_i32;
+   case aco_opcode::v_sub_u32:
+      instr->opcode = aco_opcode::v_subrev_u32;
       return true;
-   default:
+   default: {
+      CmpInfo info;
+      get_cmp_info(instr->opcode, &info);
+      if (info.ordered == instr->opcode) {
+         instr->opcode = info.ordered_swapped;
+         return true;
+      }
+      if (info.unordered == instr->opcode) {
+         instr->opcode = info.unordered_swapped;
+         return true;
+      }
       return false;
    }
+   }
 }
 
 bool can_use_VOP3(opt_ctx& ctx, const aco_ptr<Instruction>& instr)
    }
 }
 
-struct CmpInfo {
-   aco_opcode ordered;
-   aco_opcode unordered;
-   aco_opcode inverse;
-   aco_opcode f32;
-   unsigned size;
-};
-
 ALWAYS_INLINE bool get_cmp_info(aco_opcode op, CmpInfo *info)
 {
    info->ordered = aco_opcode::num_opcodes;
    info->unordered = aco_opcode::num_opcodes;
+   info->ordered_swapped = aco_opcode::num_opcodes;
+   info->unordered_swapped = aco_opcode::num_opcodes;
    switch (op) {
-   #define CMP2(ord, unord, sz) \
+   #define CMP2(ord, unord, ord_swap, unord_swap, sz) \
    case aco_opcode::v_cmp_##ord##_f##sz:\
    case aco_opcode::v_cmp_n##unord##_f##sz:\
       info->ordered = aco_opcode::v_cmp_##ord##_f##sz;\
       info->unordered = aco_opcode::v_cmp_n##unord##_f##sz;\
+      info->ordered_swapped = aco_opcode::v_cmp_##ord_swap##_f##sz;\
+      info->unordered_swapped = aco_opcode::v_cmp_n##unord_swap##_f##sz;\
       info->inverse = op == aco_opcode::v_cmp_n##unord##_f##sz ? aco_opcode::v_cmp_##unord##_f##sz : aco_opcode::v_cmp_n##ord##_f##sz;\
       info->f32 = op == aco_opcode::v_cmp_##ord##_f##sz ? aco_opcode::v_cmp_##ord##_f32 : aco_opcode::v_cmp_n##unord##_f32;\
       info->size = sz;\
       return true;
-   #define CMP(ord, unord) \
-   CMP2(ord, unord, 16)\
-   CMP2(ord, unord, 32)\
-   CMP2(ord, unord, 64)
-   CMP(lt, /*n*/ge)
-   CMP(eq, /*n*/lg)
-   CMP(le, /*n*/gt)
-   CMP(gt, /*n*/le)
-   CMP(lg, /*n*/eq)
-   CMP(ge, /*n*/lt)
+   #define CMP(ord, unord, ord_swap, unord_swap) \
+   CMP2(ord, unord, ord_swap, unord_swap, 16)\
+   CMP2(ord, unord, ord_swap, unord_swap, 32)\
+   CMP2(ord, unord, ord_swap, unord_swap, 64)
+   CMP(lt, /*n*/ge, gt, /*n*/le)
+   CMP(eq, /*n*/lg, eq, /*n*/lg)
+   CMP(le, /*n*/gt, ge, /*n*/lt)
+   CMP(gt, /*n*/le, lt, /*n*/le)
+   CMP(lg, /*n*/eq, lg, /*n*/eq)
+   CMP(ge, /*n*/lt, le, /*n*/gt)
    #undef CMP
    #undef CMP2
    #define ORD_TEST(sz) \