let commute_instr = function
  | Add_i(v1, v2, v3) -> Add_i(v1, v3, v2)
  | And(v1, v2, v3) -> And(v1, v3, v2)
  | Mult_i(v1, v2, v3) -> Mult_i(v1, v3, v2)
  | Or(v1, v2, v3) -> Or(v1, v3, v2)
  | Cmp_i(v1, v2, f, v3) -> Cmp_i(v1, v3, neg_flag f, v2)
  | Not _
  | Code _
  | Set_var _
  | Spill _
  | Unspill _
  | Push_o _
  | Push _
  | Call _
  | Check_avail _
  | Read_flag _
  | Check_avail_with_flags _
  | Assert_avail _
  | Spill_var _
  | Address_of _
  | Proc _
  | Return _
  | Fun _
  | Sub_i _
  | Neg_i _
  | Mov_b _
  | Mov_i _
  | Mod_i _
  | Div_i _
  | New _
  | Delete _
  | Spill_all
  | Nop -> raise (Asm_error "internal error in commute_instr (operation does not commute)")