You are an expert Lean4 and formal verification agent proving a Lean4 theorem. Your output **must** strictly adhere to the specified format.

### Input Information
You will receive the following components, relevant to the target theorem:
* <all_available_defs>: Definitions available from imported modules (either from the current Lean repository or from Mathlib)
* <all_available_lemmas>: Lemmas/theorems available that may assist the proof.
* <local_ctx>...</local_ctx>: The local file context (imports, namespaces, definitions, comments, etc.) from the top of the file up to—but not including—the target theorem or any previously defined local lemmas/theorems.
* <target_theorem>...</target_theorem>: The target theorem statement, ending with `:=`.

**Notes**
1. Definitions include their full bodies, but for definitions whose bodies contain proofs, the proof parts are replaced by `admit` (i.e., admit /- proof elided -/), while the rest of the definition is kept unchanged; lemmas include only their statements.
2. You may freely reference any definition or lemma contained in these tags without redefining them.
3. The tags for available definitions and lemmas (all_available_defs, all_available_lemmas) may be omitted if empty.

### Output Format & Requirements
Your output MUST contain a complete, syntactically correct Lean 4 proof for the target theorem.

**Strict Output Structure:**
<reasoning> 
...
</reasoning> 

<lean4_invented_lemmas>
-- each lemma is a full Lean 4 declaration with a complete proof
...
</lean4_invented_lemmas>

<lean4_proof>
-- Lean 4 proof body of the target theorem
...
</lean4_proof>

**Requirements:**
1. <reasoning> and <lean4_invented_lemmas> are OPTIONAL. Include them only if they aid proof construction.
2. <lean4_proof> MUST contain only the proof body (tactics/terms), starting by "by", NOT the theorem declaration.
3. <lean4_invented_lemmas> (if present) MUST contain syntactically correct lemma declarations that type checks AND complete proof bodies. Defining a lemma using `axiom` is NOT allowed.
4. <reasoning> contains high-level proof planning.
5. If you create a lemma under <lean4_invented_lemmas> whose name is namespaced (e.g., X.Y.Z), you MUST always refer to it using its fully qualified name. Do NOT rely on shortened names. For example, write rw [X.Y.Z], not rw [Z] for invented lemmas.
6. All Lean 4 code MUST be syntactically correct. No `sorry`, `admit`, or non-Lean text. Comments allowed using `--` or `/- ... -/`.
7. Follow the tags and structure EXACTLY. No extra text before, between, or after the sections.
8. Do NOT wrap invented lemmas in a `mutual` block unless they have genuine mutual recursion. Declare each lemma independently.

### Examples are provided here (example input are under "User Prompt", and example assistant response are under "Agent Response"):
Example 1 ------------------- 
User Prompt:
<all_available_defs>
structure BitVec (w : Nat) where
  /-- Construct a `BitVec w` from a number less than `2^w`.
  O(1), because we use `Fin` as the internal representation of a bitvector. -/
  ofFin ::

  /-- Interpret a bitvector as a number less than `2^w`.
  O(1), because we use `Fin` as the internal representation of a bitvector. -/
  toFin : Fin (hPow 2 w)
</all_available_defs>

<all_available_lemmas>
theorem List.getElem_append_left{α : Type u_1} {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.length) : (l₁ ++ l₂)[i] = l₁[i]
theorem getElem_eq_testBit_toNat (x : BitVec w) (i : Nat) (h : i < w) :
  x[i] = x.toNat.testBit i := rfl
@[simp, grind =] theorem toNat_cons (b : Bool) (x : BitVec w) :
    (cons b x).toNat = (b.toNat <<< w) ||| x.toNat
@[simp, grind =] theorem getLsbD_of_ge (x : BitVec w) (i : Nat) (ge : w ≤ i) : getLsbD x i = false
theorem testBit_toNat (x : BitVec w) : x.toNat.testBit i = x.getLsbD i
</all_available_lemmas>

<local_ctx>
import Mathlib.Computability.NFA
import Mathlib.Data.FinEnum
import Mathlib.Data.Rel
import Mathlib.Data.Vector.Basic
import Blase.AutoStructs.ForLean

open Set
open Mathlib
open SetRel

-- this is better because card is defeq to n
instance (α : Type) : Inter (Language α) := ⟨Set.inter⟩
instance (α : Type) : Union (Language α) := ⟨Set.union⟩

/--
The set of `n`-tuples of bit vectors of an arbitrary width.
-/
structure BitVecs (n : Nat) where
  w : Nat
  bvs : List.Vector (BitVec w) n

def BitVecs.cast (bvs : BitVecs n) (h : n = n') : BitVecs n' :=
  { w := bvs.w, bvs := h ▸ bvs.bvs }

abbrev BitVecs.empty : BitVecs n := ⟨0, List.Vector.replicate n .nil⟩
abbrev BitVecs.singleton {w : Nat} (bv : BitVec w) : BitVecs 1 := ⟨w, bv ::ᵥ .nil⟩
abbrev BitVecs.pair {w : Nat} (bv1 bv2 : BitVec w) : BitVecs 2 := ⟨w, bv1 ::ᵥ bv2 ::ᵥ .nil⟩

/--
The set of `n`-tuples of bit vectors of an arbitrary width, encoded as a list of
bit vectors of width `n`. The width of the encoded bit vectors is the length of
the list.
-/
abbrev BitVecs' (n : Nat) := List (BitVec n)

@[simps]
def dec (bvs' : BitVecs' n) : BitVecs n where
  w := bvs'.length
  bvs := List.Vector.ofFn fun k => BitVec.ofFn fun i => bvs'[i].getLsbD k

@[simp]
</local_ctx>

<target_theorem>
lemma dec_snoc n (bvs' : BitVecs' n) (a : BitVec n) :
  dec (bvs' ++ [a]) =
    { w := bvs'.length + 1
      bvs := List.Vector.ofFn fun k =>
        BitVec.cons (a.getLsbD k) ((dec bvs').bvs.get k) } :=
</target_theorem>

Agent Response:
<reasoning> 
The goal is to understand what `dec` does after appending one more bitvector `a` to `bvs'`. By definition, `dec` builds a width `= length` and a vector of bitvectors whose `i`-th bit at position `k` is `bvs'[i].getLsbD k`. So for `bvs' ++ [a]`, we expect the width to increase by 1 and each resulting bitvector to be `BitVec.cons` of the new bit coming from `a`.

First, I use `ext` twice: once on the record to focus on the `bvs` field, and once on the resulting bitvector. This reduces everything to a pointwise statement:
for fixed `k` and `i` with `i < bvs'.length + 1`,
the bit `(bvs' ++ [a])[i].getLsbD k` should match the bit at index `i` of `BitVec.cons (a.getLsbD k) ((dec bvs').bvs.get k)`.

At this point I need a clean description of indexing into `BitVec.cons`: if we have `x : BitVec n`, then `(cons b x)[i]` should give `b` at the new “last” index `n` and `x[i]` otherwise. That motivates an auxiliary lemma `getElem_cons` expressing exactly this behavior, proved via the `testBit`/`toNat` characterization and a case split on `i < n`, `i = n`, `i > n`.

Using `getElem_cons`, the RHS becomes an `if` on whether `i = bvs'.length`. So I split into cases:
- If `i = bvs'.length`, then `(bvs' ++ [a])[i]` is the appended `a`, so both sides reduce to `a.getLsbD k`.
- If `i ≠ bvs'.length`, the bound `i < bvs'.length + 1` forces `i < bvs'.length`. Then `(bvs' ++ [a])[i] = bvs'[i]` by `List.getElem_append_left`, and the RHS takes the “else” branch and likewise gives the bit from `bvs'[i]`. In both subcases, `simp` (plus the definition of `dec`) finishes.

So the whole proof is: `ext` to bit level, unfold `dec` with `simp_all`, rewrite with `getElem_cons`, split on the boundary index `i = length bvs'`, and in the “< length” branch use `List.getElem_append_left` and bounds to line up both sides.
</reasoning> 

<lean4_invented_lemmas>
@[grind =]
theorem getElem_cons {b : Bool} {n} {x : BitVec n} {i : Nat} (h : i < n + 1) :
    (cons b x)[i] = if h : i = n then b else x[i] := by
  simp only [BitVec.getElem_eq_testBit_toNat, BitVec.toNat_cons, Nat.testBit_or]
  rw [Nat.testBit_shiftLeft]
  rcases Nat.lt_trichotomy i n with i_lt_n | i_eq_n | n_lt_i
  · have p1 : ¬(n ≤ i) := by omega
    have p2 : i ≠ n := by omega
    simp [p1, p2]
  · simp only [i_eq_n, ge_iff_le, Nat.le_refl, decide_true, Nat.sub_self, Nat.testBit_zero,
    Bool.true_and, BitVec.testBit_toNat, BitVec.getLsbD_of_ge, Bool.or_false]
    cases b <;> trivial
  · have p1 : i ≠ n := by omega
    have p2 : i - n ≠ 0 := by omega
    simp [p1, p2, Nat.testBit_bool_toNat]
</lean4_invented_lemmas>

<lean4_proof>
by
  ext k i hi <;> simp_all
  rw [getElem_cons]
  split
  next heq => simp_all
  next h =>
    have hlt : i < List.length bvs' := by simp at hi; omega
    rw [List.getElem_append_left hlt]
    simp
</lean4_proof>

### Your task:
<all_available_defs>
Array in Init.Prelude
Nat in Init.Prelude
BEq in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Repr in Init.Data.Repr
Std.HashMap in Std.Data.HashMap.Basic
Std.HashSet in Std.Data.HashSet.Basic
BitVec in Init.Prelude
FinEnum.toList in Mathlib.Data.FinEnum
List in Init.Prelude
List.Nodup in Init.Data.List.Basic
Subtype in Init.Prelude
Set in Mathlib.Data.Set.Defs
LawfulBEq in Init.Core
Function.Injective2 in Mathlib.Logic.Function.Basic

structure CNFA (n : Nat) where
  m : RawCNFA (BitVec n)
  wf : m.WF

instance RawCNFA.statesFinset (m : RawCNFA A) : Fintype m.states := (Finset.range m.stateMax).fintypeCoeSort

abbrev State := Nat

def Std.HashSet.toSet [BEq α] [Hashable α] (m : HashSet α) : Set α := { x | x ∈ m }

axiom hashMap_missing : ∀ {P : Prop}, P

BitVec.append in Init.Data.BitVec.Basic

def icmp_equality_test_commute_icmp1_after := [llvm|
{
^0(%arg23 : i64, %arg24 : i64, %arg25 : i64):
  %0 = llvm.icmp "eq" %arg24, %arg23 : i64
  "llvm.return"(%0) : (i1) -> ()
}
]

Function.LeftInverse in Init.Data.Function

def alive_InstCombineShift__279_src :=
[sllvm| {
^bb0(%X : i64, %C : i64):
  %v1 = llvm.lshr %X, %C : i64
  %v2 = llvm.shl %v1, %C : i64
  llvm.return %v2 : i64
}]

def add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.add %arg4, %0 : i32
  %3 = llvm.or %2, %arg5 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_4_after := [llvm|
{
^0(%arg62 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg62, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def slt_or_not_max_logical_before := [llvm|
{
^0(%arg60 : i8, %arg61 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "slt" %arg60, %arg61 : i8
  %3 = llvm.icmp "ne" %arg60, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def bools2_logical_commute0_and1_after := [llvm|
{
^0(%arg61 : i1, %arg62 : i1, %arg63 : i1):
  %0 = "llvm.select"(%arg63, %arg61, %arg62) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def select_add_before := [llvm|
{
^0(%arg15 : i1, %arg16 : i64, %arg17 : i64):
  %0 = llvm.add %arg16, %arg17 : i64
  %1 = "llvm.select"(%arg15, %0, %arg16) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def getEqRhs (eq : Expr) : MetaM Expr := do
  check eq
  let eq ← whnf <| ← inferType eq
  let some (_ty, _lhs, rhs) := eq.eq? | throwError m!"unable to infer RHS for equality {eq}"
  let rhs ← instantiateMVars rhs
  rhs.ensureHasNoMVars
  return rhs

def nonexact_ashr_ne_noexactlog_before := [llvm|
{
^0(%arg133 : i8):
  %0 = llvm.mlir.constant(-90 : i8) : i8
  %1 = llvm.mlir.constant(-30 : i8) : i8
  %2 = llvm.ashr %0, %arg133 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

instance : DialectToExpr LLVM where
  toExprM := .const ``Id [0]
  toExprDialect := .const ``LLVM []

def test5_after := [llvm|
{
^0(%arg2 : i7):
  %0 = llvm.mlir.constant(-24 : i7) : i7
  %1 = llvm.and %arg2, %0 : i7
  "llvm.return"(%1) : (i7) -> ()
}
]

def add_of_mul_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8, %arg6 : i8):
  %0 = llvm.mul %arg4, %arg5 overflow<nsw> : i8
  %1 = llvm.mul %arg4, %arg6 overflow<nsw> : i8
  %2 = llvm.add %0, %1 overflow<nsw> : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

instance : MLIR.AST.TransformExpr (Handshake) 0 where
  mkExpr := mkExpr

def xor_or_xor_common_op_commute5_after := [llvm|
{
^0(%arg68 : i32, %arg69 : i32, %arg70 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg68, %0 : i32
  %2 = llvm.and %arg69, %1 : i32
  %3 = llvm.xor %2, %arg70 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

instance : Inhabited (
          {lets : Lets d Γstart .pure Γ} →
          State d lets →
          {ts : RegionSignature d.Ty} →
          (rs : HVector (fun t => Com d t.1 .impure t.2) ts) →
          { rs' : HVector (fun t => Com d t.1 .impure t.2) ts // HVector.denote rs =
            HVector.denote rs' }) where
  default := fun _s _ts rs => ⟨rs, rfl⟩

def sra  {Γ : Ctxt _} (e₁ e₂: Ctxt.Var Γ .bv) : Expr RV64 Γ .pure [.bv]  :=
  Expr.mk
    (op := Op.sll)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := HVector.nil)

def udiv_exact_eq_1_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.udiv exact %arg10, %arg11 : i8
  %2 = llvm.icmp "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def t1_before := [llvm|
{
^0(%arg31 : i8):
  %0 = llvm.mlir.constant(31 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(32 : i8) : i8
  %3 = llvm.mlir.constant(-32 : i8) : i8
  %4 = llvm.and %arg31, %0 : i8
  %5 = llvm.icmp "eq" %4, %1 : i8
  %6 = llvm.add %arg31, %2 : i8
  %7 = llvm.and %6, %3 : i8
  %8 = "llvm.select"(%5, %arg31, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%8) : (i8) -> ()
}
]

def visitADD_Neg1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (-1) : i64
      %0 = llvm.and  %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      llvm.return %x : i64
  }]

def sge_smin1_before := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.icmp "slt" %arg79, %arg80 : i32
  %1 = "llvm.select"(%0, %arg79, %arg80) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "sge" %1, %arg79 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def masked_or_allones_before := [llvm|
{
^0(%arg127 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(39 : i32) : i32
  %2 = llvm.and %arg127, %0 : i32
  %3 = llvm.icmp "eq" %2, %0 : i32
  %4 = llvm.and %arg127, %1 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.or %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def llvm_const_lower_riscv_li8 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM8, rhs:= liRiscv8,
   correct := by admit /- proof elided -/

def PR42691_7_before := [llvm|
{
^0(%arg331 : i32):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.icmp "uge" %arg331, %0 : i32
  %3 = llvm.icmp "eq" %arg331, %1 : i32
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def slt_or_not_max_commute_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "ne" %arg58, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def test8_before := [llvm|
{
^0(%arg43 : i7):
  %0 = llvm.mlir.constant(4 : i7) : i7
  %1 = llvm.mlir.constant(3 : i7) : i7
  %2 = llvm.shl %arg43, %0 : i7
  %3 = llvm.shl %2, %1 : i7
  "llvm.return"(%3) : (i7) -> ()
}
]

def ashr_pow2_ult_before := [llvm|
{
^0(%arg59 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(-96 : i8) : i8
  %2 = llvm.ashr %0, %arg59 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def icmp_eq_zext_eq_zero_after := [llvm|
{
^0(%arg40 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def trunc_lshr_big_mask_before := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(31 : i6) : i6
  %2 = llvm.lshr %arg8, %0 : i8
  %3 = llvm.trunc %2 : i8 to i6
  %4 = llvm.and %3, %1 : i6
  "llvm.return"(%4) : (i6) -> ()
}
]

def and_slt_to_mask_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "slt" %arg5, %0 : i8
  %4 = llvm.and %arg5, %1 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def test9b_after := [llvm|
{
^0(%arg109 : i32, %arg110 : i32):
  %0 = llvm.or %arg109, %arg110 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def PoisonOr.getOrUB  : PoisonOr α → m α
  | .value x => pure x
  | .poison => throwUB

def getSuffixId : TSyntax ``mlir_suffix_id → String
  | `(mlir_suffix_id| $x:ident) => x.getId.toString
  | `(mlir_suffix_id| $x:num) => toString (x.getNat)
  | _ => "" 

def bitwise_and_logical_and_masked_icmp_allzeros_poison1_after := [llvm|
{
^0(%arg144 : i1, %arg145 : i32, %arg146 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.or %arg146, %0 : i32
  %4 = llvm.and %arg145, %3 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = "llvm.select"(%5, %arg144, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def p_constmask_after := [llvm|
{
^0(%arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(65280 : i32) : i32
  %1 = llvm.mlir.constant(-65281 : i32) : i32
  %2 = llvm.and %arg49, %0 : i32
  %3 = llvm.and %arg50, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

@[simp_llvm]
def sdiv? {w : Nat} (x y : BitVec w) : IntW w :=
  if y == 0 || (w != 1 && x == (BitVec.intMin w) && y == -1) then
    .poison
  else
    .value (x.sdiv y)

def shl_trunc_smaller_lshr_before := [llvm|
{
^0(%arg43 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.lshr %arg43, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.shl %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def lshr_exact_ne_0_after := [llvm|
{
^0(%arg121 : i32, %arg122 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "ne" %arg121, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def ashrslt_03_08_after := [llvm|
{
^0(%arg229 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def xor_logic_and_or2_after := [llvm|
{
^0(%arg15 : i1, %arg16 : i1, %arg17 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg16, %0 : i1
  %2 = "llvm.select"(%arg15, %1, %arg17) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def select_0_f : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1, %f: i64):
      %zero = llvm.mlir.constant (0) : i64
      %0 = llvm.select %c, %zero, %f : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1, %f: i64):
      %0 = llvm.not %c : i1
      %1 = llvm.sext %0: i1 to i64
      %2 = llvm.freeze %f : i64
      %3 = llvm.and %1, %2 : i64
      llvm.return %3 : i64
  }]

def zext_sext_ugt_known_nonneg_before := [llvm|
{
^0(%arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.and %arg22, %0 : i8
  %2 = llvm.zext %1 : i8 to i32
  %3 = llvm.sext %arg23 : i8 to i32
  %4 = llvm.icmp "ugt" %2, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def ule_swap_or_not_min_logical_after := [llvm|
{
^0(%arg262 : i8, %arg263 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def n5_after := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.lshr %arg3, %0 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test5_after := [llvm|
{
^0(%arg49 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def getSimpData (simpsetName : Name) : MetaM (SimpTheorems × Simprocs) := do
  let some ext ← (getSimpExtension? simpsetName)
    | throwError m!"'{simpsetName}' simp attribute not found!"
  let theorems ← ext.getTheorems
  let some ext ← (Simp.getSimprocExtension? simpsetName)
    | throwError m!"'{simpsetName}' simp attribute not found!"
  let simprocs ← ext.getSimprocs
  return (theorems, simprocs)

abbrev Expr (Γ) (ty) := _root_.Expr ExOp Γ .pure ty

def worklistGo_spec {st : worklist.St A S} (inv : StInv A S st.m st.map) :
    st.sim inits final f ∅ →
    (worklistRun'.go A S final f st |>.Sim $ nfa inits final f) :=

def llvm_shl_lower_riscv_nuw_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := shl_llvm_nuw_64
  rhs := shl_riscv_64

def test12_after := [llvm|
{
^0(%arg89 : i32, %arg90 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg89, %arg90 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def foo_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.or %0, %1 : i32
  %3 = llvm.and %arg0, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def or_not_and_commute3_before := [llvm|
{
^0(%arg528 : i32, %arg529 : i32, %arg530 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg529, %arg528 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %2, %arg530 : i32
  %4 = llvm.or %arg530, %arg528 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %5, %arg529 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def test9_before := [llvm|
{
^0(%arg5 : i1005):
  %0 = llvm.mlir.constant(-1 : i1005) : i1005
  %1 = llvm.and %arg5, %0 : i1005
  "llvm.return"(%1) : (i1005) -> ()
}
]

def lshrult_02_10_exact_after := [llvm|
{
^0(%arg123 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def f_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def mul_select_sext_after := [llvm|
{
^0(%arg17 : i1):
  %0 = llvm.mlir.constant(-64) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = "llvm.select"(%arg17, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def rem_euclid_2_before := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.srem %arg11, %0 : i32
  %3 = llvm.icmp "sgt" %2, %1 : i32
  %4 = llvm.add %2, %0 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_7_logical_after := [llvm|
{
^0(%arg55 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def samesign_inverted_commute3_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg97, %arg98 : i32
  %3 = llvm.icmp "sgt" %2, %0 : i32
  %4 = llvm.or %arg98, %arg97 : i32
  %5 = llvm.icmp "slt" %4, %1 : i32
  %6 = llvm.and %5, %3 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def sgt_swap_and_not_min_commute_after := [llvm|
{
^0(%arg82 : i8, %arg83 : i8):
  %0 = llvm.icmp "slt" %arg83, %arg82 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def anyext_trunc_fold_zext_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := [LV| {
    ^entry (%x: i32):
      %0 = llvm.zext %x: i32 to i64
      %1 = llvm.trunc %0: i64 to i32
      llvm.return %1 : i32
  }]
  rhs := [LV| {
    ^entry (%x: i32):
      llvm.return %x : i32
  }]

def x_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

instance : Lean.ToExpr RegIndex := inherit

def logical_and_not_before := [llvm|
{
^0(%arg262 : i1, %arg263 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg262, %0, %arg263) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def map (f : ι → ι') (i : Inputs ι n) : Inputs ι' n where
  ix := i.ix
  input := f i.input

def bools_logical_commute0_and1_after := [llvm|
{
^0(%arg105 : i1, %arg106 : i1, %arg107 : i1):
  %0 = "llvm.select"(%arg107, %arg106, %arg105) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def llvm_const_lower_riscv_li23 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM23, rhs:= liRiscv23,
   correct := by admit /- proof elided -/

def not_cmp_constant_before := [llvm|
{
^0(%arg144 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.xor %arg144, %0 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def n2_before := [llvm|
{
^0(%arg10 : i16):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.zext %arg10 : i16 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def flip_masked_bit_before := [llvm|
{
^0(%arg132 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.add %arg132, %0 : i8
  %2 = llvm.and %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def select_sub_icmp_bad_2_before := [llvm|
{
^0(%arg68 : i32, %arg69 : i32, %arg70 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg68, %0 : i32
  %2 = llvm.sub %arg70, %arg68 : i32
  %3 = "llvm.select"(%1, %2, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test_mul_nuw_nsw__none_are_safe_before := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(805306368 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mlir.constant(-1342177280 : i32) : i32
  %3 = llvm.icmp "eq" %arg3, %0 : i32
  %4 = llvm.mul %arg3, %1 overflow<nsw,nuw> : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def add_nsw_mul_nsw_after := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.mlir.constant(3 : i16) : i16
  %1 = llvm.mul %arg33, %0 overflow<nsw> : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def llvm_const_lower_riscv_li_41 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_41, rhs:= liRiscv_41,
   correct := by admit /- proof elided -/

def xor_nosignbit_select_shl_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg36, %0 : i32
  %3 = llvm.xor %2, %1 : i32
  %4 = "llvm.select"(%arg37, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def ashrsgt_01_03_after := [llvm|
{
^0(%arg314 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test19_before := [llvm|
{
^0(%arg15 : i37):
  %0 = llvm.mlir.constant(2 : i37) : i37
  %1 = llvm.mlir.constant(0 : i37) : i37
  %2 = llvm.ashr %arg15, %0 : i37
  %3 = llvm.icmp "eq" %2, %1 : i37
  "llvm.return"(%3) : (i1) -> ()
}
]

def main6c_logical_after := [llvm|
{
^0(%arg89 : i32):
  %0 = llvm.mlir.constant(55 : i32) : i32
  %1 = llvm.mlir.constant(19 : i32) : i32
  %2 = llvm.and %arg89, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.zext %3 : i1 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def sub_from_constant_of_sub_from_constant_before := [llvm|
{
^0(%arg170 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(11 : i8) : i8
  %2 = llvm.sub %0, %arg170 : i8
  %3 = llvm.sub %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

structure Tensor2d' (α : Type) where
  dim₀ : Index
  dim₁ : Index
  mat : Matrix (Fin dim₀) (Fin dim₁) α

def select_icmp_ne_0_and_4096_and_not_4096_before := [llvm|
{
^0(%arg227 : i32, %arg228 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-4097 : i32) : i32
  %3 = llvm.and %arg227, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.and %arg228, %2 : i32
  %6 = "llvm.select"(%4, %arg228, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def test22_after := [llvm|
{
^0(%arg9 : i14):
  %0 = llvm.mlir.constant(127 : i14) : i14
  %1 = llvm.mlir.constant(0 : i14) : i14
  %2 = llvm.and %arg9, %0 : i14
  %3 = llvm.icmp "eq" %2, %1 : i14
  "llvm.return"(%3) : (i1) -> ()
}
]

def merge {Γ : Ctxt _}  (a b : Γ.Var (MLIR2DCPlus.Ty.tokenstream)) : Expr (DCPlus) Γ .pure (.valuestream 1) :=
  Expr.mk
    (op := .merge)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .cons b <| .nil)
    (regArgs := .nil)

def t3_before := [llvm|
{
^0(%arg23 : i8, %arg24 : i2):
  %0 = llvm.sext %arg24 : i2 to i8
  %1 = llvm.add %0, %arg23 : i8
  %2 = llvm.xor %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def slt_to_ugt_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.icmp "ugt" %arg28, %arg29 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def and_or_not_not_commute3_before := [llvm|
{
^0(%arg366 : i32, %arg367 : i32, %arg368 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg367, %arg366 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg368, %arg366 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.or %4, %arg367 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def scalar_i32_udiv_and_negC_eq_X_is_constant3_after := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(1544 : i32) : i32
  %1 = llvm.icmp "ult" %arg7, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def narrow_sext_or_before := [llvm|
{
^0(%arg52 : i16, %arg53 : i32):
  %0 = llvm.sext %arg52 : i16 to i32
  %1 = llvm.or %0, %arg53 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_after := [llvm|
{
^0(%arg55 : i32, %arg56 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg56, %arg55 : i32
  %2 = llvm.icmp "sgt" %1, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def decrAux (x : BitStream) : Nat → Bool × Bool
  | 0 => (!(x 0), !(x 0))
  | (n+1) =>
    let borrow := (decrAux x n).2
    let a := x (n + 1)
    (xor a borrow, !a && borrow)

def sub_zext_trunc_lshr_after := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.mlir.constant(10 : i32) : i32
  %3 = llvm.trunc %arg15 : i64 to i32
  %4 = llvm.shl %3, %0 : i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.add %5, %2 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

instance : ToString FpPredicate := ⟨toString⟩

def CNFA.inter_bv_language (m₁ m₂ : CNFA n) :
    m₁.bv_recognizes L₁ →
    m₂.bv_recognizes L₂ →
    (m₁.inter m₂).bv_recognizes (L₁ ∩ L₂) :=

def sext_sub_nuw_after := [llvm|
{
^0(%arg14 : i8, %arg15 : i1):
  %0 = llvm.zext %arg15 : i1 to i8
  %1 = llvm.add %arg14, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def sub_ult_zext_after := [llvm|
{
^0(%arg161 : i1, %arg162 : i8, %arg163 : i8):
  %0 = llvm.icmp "eq" %arg162, %arg163 : i8
  %1 = llvm.and %0, %arg161 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

instance : GetElem? (Ctxt Ty) Nat Ty (fun Γ i => i < Γ.length) where
  getElem Γ i h := Γ.toList[i]
  getElem? Γ i  := Γ.toList[i]?

def original_sdiv_srem_correct := [LV| {
  ^entry (%a: i64, %b: i64):
    %0= llvm.sdiv %a, %b : i64
    %1 = llvm.srem %a, %b : i64
    llvm.return %1 : i64
  }]

def fold_and_zext_icmp_before := [llvm|
{
^0(%arg97 : i64, %arg98 : i64, %arg99 : i64):
  %0 = llvm.icmp "sgt" %arg97, %arg98 : i64
  %1 = llvm.zext %0 : i1 to i8
  %2 = llvm.icmp "slt" %arg97, %arg99 : i64
  %3 = llvm.zext %2 : i1 to i8
  %4 = llvm.and %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def Predicate.evalLand (t₁ t₂ : BitStream) : BitStream := (t₁ ||| t₂)

def pr40493_neg3_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.shl %arg15, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def add_nsw_poison_constant_fold_after := [llvm|
{
^0(%arg2 : i1, %arg3 : i8):
  %0 = llvm.mlir.constant(64 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.add %arg3, %0 overflow<nsw> : i8
  %3 = "llvm.select"(%arg2, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def different_size_zext_zext_sgt_after := [llvm|
{
^0(%arg16 : i7, %arg17 : i4):
  %0 = llvm.zext %arg17 : i4 to i7
  %1 = llvm.icmp "ugt" %arg16, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

def test_not_const_shr_and_1_ne_0_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.lshr %0, %arg7 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

RV64.xor in RISCV.Instructions

def trunc_unsigned_nsw_zext_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i8):
  %0 = llvm.trunc %arg32 overflow<nsw> : i32 to i16
  %1 = llvm.zext %arg33 : i8 to i16
  %2 = llvm.icmp "ult" %0, %1 : i16
  "llvm.return"(%2) : (i1) -> ()
}
]

def alive_AddSub_1043_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _, %RHS : _):
  %v1 = llvm.not %C1
  %v2 = llvm.or %Z, %v1
  %v3 = llvm.and %Z, %C1
  %v4 = llvm.xor %v3, %C1
  %v5 = llvm.mlir.constant 1
  %v6 = llvm.add %v4, %v5
  %v7 = llvm.sub %RHS, %v2
  llvm.return %v7
}]

def src_x_or_mask_ne_after := [llvm|
{
^0(%arg3 : i8, %arg4 : i8, %arg5 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.lshr %0, %arg4 : i8
  %3 = "llvm.select"(%arg5, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.icmp "ugt" %arg3, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def main7f_before := [llvm|
{
^0(%arg44 : i32, %arg45 : i32, %arg46 : i32, %arg47 : i32, %arg48 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg45, %arg47 : i32
  %3 = llvm.and %arg46, %arg48 : i32
  %4 = llvm.and %arg44, %2 : i32
  %5 = llvm.icmp "eq" %2, %4 : i32
  %6 = llvm.and %arg44, %3 : i32
  %7 = llvm.icmp "eq" %3, %6 : i32
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

def no_shift_xor_multiuse_or_before := [llvm|
{
^0(%arg134 : i32, %arg135 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg134, %0 : i32
  %3 = llvm.icmp "ne" %1, %2 : i32
  %4 = llvm.or %arg135, %0 : i32
  %5 = "llvm.select"(%3, %arg135, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.mul %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def eq_umin1_before := [llvm|
{
^0(%arg60 : i32, %arg61 : i32):
  %0 = llvm.icmp "ult" %arg60, %arg61 : i32
  %1 = "llvm.select"(%0, %arg60, %arg61) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "eq" %1, %arg60 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def urem? {w : Nat} (x y : BitVec w) : IntW w :=
  if y = 0 then
    .poison
  else
    .value <| x % y

structure Item where
 name : String
 tac : Syntax

@[match_pattern] abbrev trunc (w w': Nat) (flags: NoWrapFlags := {}) : LLVM.Op :=
  MOp.trunc (.concrete w) (.concrete w') flags

def t0_ult_slt_65536_after := [llvm|
{
^0(%arg66 : i32, %arg67 : i32, %arg68 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.icmp "slt" %arg66, %0 : i32
  %3 = llvm.icmp "sgt" %arg66, %1 : i32
  %4 = "llvm.select"(%2, %arg67, %arg66) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = "llvm.select"(%3, %arg68, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def or_umin_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def llvm_const_lower_riscv_li35 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM35, rhs:= liRiscv35,
   correct := by admit /- proof elided -/

def CliTest.params : CliTest → Type
| test => natParams test.mvars

def test_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.icmp "ugt" %arg1, %0 : i32
  %2 = llvm.icmp "sgt" %arg1, %0 : i32
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.zext %arg6 : i8 to i64
  %1 = llvm.zext %arg7 : i8 to i64
  %2 = llvm.add %0, %1 : i64
  %3 = llvm.trunc %2 : i64 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def or_and2_before := [llvm|
{
^0(%arg138 : i1, %arg139 : i1, %arg140 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg140, %0 : i1
  %2 = llvm.or %1, %arg138 : i1
  %3 = "llvm.select"(%2, %arg138, %arg139) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def test4_before := [llvm|
{
^0(%arg50 : i32):
  %0 = llvm.icmp "sgt" %arg50, %arg50 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def positive_samevar_shlnuwnsw_after := [llvm|
{
^0(%arg47 : i8, %arg48 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg48 overflow<nsw> : i8
  %2 = llvm.and %1, %arg47 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

@[simp_denote]
def icmp_ule_llvm_32 : Com LLVMPlusRiscV ⟨[.llvm (.bitvec 32), .llvm (.bitvec 32)]⟩
  .pure (.llvm (.bitvec 1)) := [LV| {
  ^entry (%lhs: i32, %rhs: i32):
    %1 = llvm.icmp.ule %lhs, %rhs : i32
    llvm.return %1 : i1
  }]

def andn_or_cmp_1_after := [llvm|
{
^0(%arg176 : i37, %arg177 : i37, %arg178 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.icmp "sle" %arg176, %arg177 : i37
  %2 = llvm.icmp "ugt" %arg178, %0 : i37
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrugt_02_04_after := [llvm|
{
^0(%arg395 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def negate_select_of_op_vs_negated_op_nsw_commuted_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i1):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg18 overflow<nsw> : i8
  %2 = "llvm.select"(%arg20, %arg18, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %arg19, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.icmp "eq" %arg2, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

instance : Inhabited BVExprWrapper where
  default := {bvExpr := GenBVExpr.const (BitVec.ofNat 0 0), width := 0}

def and_xor_commute4_before := [llvm|
{
^0(%arg149 : i32, %arg150 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.udiv %0, %arg149 : i32
  %2 = llvm.udiv %0, %arg150 : i32
  %3 = llvm.and %1, %2 : i32
  %4 = llvm.xor %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def icmp_power2_and_icmp_shifted_mask_2147483648_1610612736_after := [llvm|
{
^0(%arg45 : i32):
  %0 = llvm.mlir.constant(1610612736 : i32) : i32
  %1 = llvm.icmp "ult" %arg45, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

@[simp]
instance LLVMPlusRiscVSignature : DialectSignature LLVMPlusRiscV where
  signature
  | .llvm llvmOp => .llvm <$> DialectSignature.signature llvmOp
  | .riscv riscvOp => .riscv <$> DialectSignature.signature riscvOp
  | .castRiscv w =>
      {sig := [Ty.riscv .bv], returnTypes := [Ty.llvm (.bitvec w)], regSig := []}
  | .castLLVM w =>
      {sig := [Ty.llvm (.bitvec w)], returnTypes := [Ty.riscv .bv], regSig := []}

OptionT.run in Init.Control.Option

def llvm_add_lower_riscv_nuw_flag_8 : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8)] where
  lhs:= add_llvm_nuw_flags_8
  rhs:= add_riscv_8

def scalar_i32_shl_and_negC_eq_before := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(-262144 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg31, %arg32 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def lor_lor_left2_after := [llvm|
{
^0(%arg68 : i1, %arg69 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg69, %0, %arg68) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def test6_after := [llvm|
{
^0(%arg51 : i1023):
  %0 = llvm.mlir.constant(64 : i1023) : i1023
  %1 = llvm.and %arg51, %0 : i1023
  "llvm.return"(%1) : (i1023) -> ()
}
]

def shlPar (x : BitVec w) (n : Nat) : BitVec w :=
  x <<< n

def test_and3_before := [llvm|
{
^0(%arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg45, %0 : i32
  %3 = llvm.icmp "sgt" %2, %arg44 : i32
  %4 = llvm.icmp "sge" %arg44, %1 : i32
  %5 = llvm.and %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def not_sext_before := [llvm|
{
^0(%arg7 : i1):
  %0 = llvm.mlir.constant(0 : i999) : i999
  %1 = llvm.mlir.constant(-1 : i999) : i999
  %2 = "llvm.select"(%arg7, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i999, i999) -> i999
  "llvm.return"(%2) : (i999) -> ()
}
]

def select_icmp_ne_not_pow2_before := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg8, %0 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  %4 = llvm.xor %arg8, %0 : i8
  %5 = "llvm.select"(%3, %4, %arg8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def testi32i8_before := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(127 : i8) : i8
  %4 = llvm.lshr %arg32, %0 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.trunc %arg32 : i32 to i8
  %7 = llvm.ashr %6, %1 : i8
  %8 = llvm.icmp "eq" %7, %5 : i8
  %9 = llvm.ashr %arg32, %2 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.xor %10, %3 : i8
  %12 = "llvm.select"(%8, %6, %11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%12) : (i8) -> ()
}
]

def select_and_icmp_zero_after := [llvm|
{
^0(%arg152 : i32, %arg153 : i32, %arg154 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg152, %0 : i32
  %2 = "llvm.select"(%1, %0, %arg153) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test53_after := [llvm|
{
^0(%arg131 : i32):
  %0 = llvm.mlir.constant(7224 : i16) : i16
  %1 = llvm.mlir.constant(-32574 : i16) : i16
  %2 = llvm.trunc %arg131 : i32 to i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.or disjoint %3, %1 : i16
  %5 = llvm.zext %4 : i16 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def opName (op : RISCV64.Op) : String :=
  let op  : String := match op with
  | .li _ => "li"
  | .mulh => "mulh"
  | .mulhu => "mulhu"
  | .mulhsu => "mulhsu"
  | .divu => "divu"
  | .remuw => "remuw"
  | .remu => "remu"
  | .addiw _ => "addiw"
  | .lui _ => "lui"
  | .auipc _ => "auipc"
  | .slliw _ => "slliw"
  | .srliw _ => "srliw"
  | .sraiw _ => "sraiw"
  | .slli _ => "slli"
  | .srli _ => "srli"
  | .srai _ => "srai"
  | .addw => "addw"
  | .subw => "subw"
  | .sllw => "sllw"
  | .srlw => "srlw"
  | .sraw => "sraw"
  | .add => "add"
  | .slt => "slt"
  | .sltu => "sltu"
  | .and => "and"
  | .or => "or"
  | .xor => "xor"
  | .sll => "sll"
  | .srl => "srl"
  | .sub => "sub"
  | .sra => "sra"
  | .remw  => "remw"
  | .rem => "rem"
  | .mul => "mul"
  | .mulw => "mulw"
  | .div => "div"
  | .divw => "divw"
  | .divuw => "divuw"
  | .addi _ => "addi"
  | .slti _ => "slti"
  | .sltiu _ => "sltiu"
  | .andi _ => "andi"
  | .ori _ => "ori"
  | .xori _ => "xori"
  | .bclr => "bclr"
  | .bext => "bext"
  | .binv => "binv"
  | .bset => "bset"
  | .bclri _ => "bclri"
  | .bexti _ => "bexti"
  | .binvi _ => "binvi"
  | .bseti _ => "bseti"
  | .adduw => "add.uw"
  | .sh1adduw => "sh1add.uw"
  | .sh2adduw => "sh2add.uw"
  | .sh3adduw => "sh3add.uw"
  | .sh1add => "sh1add"
  | .sh2add => "sh2add"
  | .sh3add => "sh3add"
  | .slliuw _ => "slli.uw"
  | .andn => "andn"
  | .orn => "orn"
  | .xnor => "xnor"
  | .clz => "clz"
  | .clzw => "clzw"
  | .ctz => "ctz"
  | .ctzw => "ctzw"
  | .max => "max"
  | .maxu => "maxu"
  | .min  => "min"
  | .minu  => "minu"
  | .sextb => "sext.b"
  | .sexth => "sext.h"
  | .zexth => "zext.h"
  | .rol => "rol"
  | .rolw => "rolw"
  | .ror => "ror"
  | .rori _ => "rori"
  | .roriw _ => "roriw"
  | .rorw => "rorw"
  | .pack => "pack"
  | .packh => "packh"
  | .packw => "packw"
  
  | .mv => "mv"
  | .not => "not"
  | .neg => "neg"
  | .negw => "negw"
  | .sextw => "sext.w"
  | .zextb => "zext.b"
  | .zextw => "zext.w"
  | .seqz => "seqz"
  | .snez => "snez"
  | .sltz => "sltz"
  | .sgtz => "sgtz"
  op

def or_simplify_ugt_before := [llvm|
{
^0(%arg11 : i8, %arg12 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.or %arg11, %0 : i8
  %3 = llvm.and %arg12, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "ugt" %4, %3 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def test_nuw_nsw_and_signed_pred_before := [llvm|
{
^0(%arg54 : i64):
  %0 = llvm.mlir.constant(10) : i64
  %1 = llvm.mlir.constant(3) : i64
  %2 = llvm.sub %0, %arg54 overflow<nsw,nuw> : i64
  %3 = llvm.icmp "slt" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def main5c_like_before := [llvm|
{
^0(%arg103 : i32, %arg104 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg103, %0 : i32
  %4 = llvm.icmp "ne" %3, %0 : i32
  %5 = llvm.and %arg104, %0 : i32
  %6 = llvm.icmp "ne" %5, %0 : i32
  %7 = llvm.or %4, %6 : i1
  %8 = "llvm.select"(%7, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def main6b_before := [llvm|
{
^0(%arg92 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.mlir.constant(16 : i32) : i32
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.mlir.constant(1 : i32) : i32
  %5 = llvm.and %arg92, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %arg92, %2 : i32
  %8 = llvm.icmp "ne" %7, %3 : i32
  %9 = llvm.and %6, %8 : i1
  %10 = "llvm.select"(%9, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%10) : (i32) -> ()
}
]

def test_after := [llvm|
{
^0(%arg0 : i26):
  "llvm.return"(%arg0) : (i26) -> ()
}
]

def n2_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.shl %0, %arg1 overflow<nsw> : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.and %arg0, %4 : i8
  %6 = llvm.icmp "ne" %5, %2 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def eq_smax3_after := [llvm|
{
^0(%arg59 : i32, %arg60 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg59, %0 : i32
  %2 = llvm.icmp "sge" %1, %arg60 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def icmp_eq_mul_nsw_nonequal_commuted_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.add %arg30, %0 : i8
  %2 = llvm.mul %arg30, %arg31 overflow<nsw> : i8
  %3 = llvm.mul %arg31, %1 overflow<nsw> : i8
  %4 = llvm.icmp "eq" %2, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def test19_after := [llvm|
{
^0(%arg7 : i10):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.mlir.constant(0 : i3) : i3
  %2 = llvm.trunc %arg7 : i10 to i3
  %3 = llvm.and %2, %0 : i3
  %4 = llvm.sub %1, %3 overflow<nsw> : i3
  %5 = llvm.sext %4 : i3 to i10
  "llvm.return"(%5) : (i10) -> ()
}
]

def ugt_sext_before := [llvm|
{
^0(%arg130 : i1, %arg131 : i8):
  %0 = llvm.sext %arg130 : i1 to i8
  %1 = llvm.icmp "ugt" %0, %arg131 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def test8_after := [llvm|
{
^0(%arg6 : i999):
  %0 = llvm.mlir.constant(0 : i999) : i999
  "llvm.return"(%0) : (i999) -> ()
}
]

def add_const_sub_const_before := [llvm|
{
^0(%arg66 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.add %arg66, %0 : i32
  %3 = llvm.sub %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def main4e_like_logical_before := [llvm|
{
^0(%arg125 : i32, %arg126 : i32, %arg127 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg125, %arg126 : i32
  %4 = llvm.icmp "eq" %3, %arg126 : i32
  %5 = llvm.and %arg125, %arg127 : i32
  %6 = llvm.icmp "eq" %5, %arg127 : i32
  %7 = "llvm.select"(%4, %6, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %8 = "llvm.select"(%7, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def cadicalTimeoutSec : Nat := 1000

def slt_and_not_max_commute_after := [llvm|
{
^0(%arg122 : i8, %arg123 : i8):
  %0 = llvm.icmp "slt" %arg122, %arg123 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def and_zext_commuted_before := [llvm|
{
^0(%arg38 : i32, %arg39 : i1):
  %0 = llvm.zext %arg39 : i1 to i32
  %1 = llvm.and %0, %arg38 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def not_ashr_not_bitwidth_mask_after := [llvm|
{
^0(%arg97 : i8, %arg98 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg97, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.and %arg98, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def or_basic_before := [llvm|
{
^0(%arg15 : i16):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(-256 : i16) : i16
  %2 = llvm.mlir.constant(17664 : i16) : i16
  %3 = llvm.trunc %arg15 : i16 to i8
  %4 = llvm.icmp "ne" %3, %0 : i8
  %5 = llvm.and %arg15, %1 : i16
  %6 = llvm.icmp "ne" %5, %2 : i16
  %7 = llvm.or %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def fast_div_201_after := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(71 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.mlir.constant(1 : i8) : i8
  %3 = llvm.mlir.constant(7 : i8) : i8
  %4 = llvm.zext %arg0 : i8 to i16
  %5 = llvm.mul %4, %0 overflow<nsw,nuw> : i16
  %6 = llvm.lshr %5, %1 : i16
  %7 = llvm.trunc %6 overflow<nsw,nuw> : i16 to i8
  %8 = llvm.sub %arg0, %7 : i8
  %9 = llvm.lshr %8, %2 : i8
  %10 = llvm.add %9, %7 overflow<nuw> : i8
  %11 = llvm.lshr %10, %3 : i8
  "llvm.return"(%11) : (i8) -> ()
}
]

def lshr_xor_before := [llvm|
{
^0(%arg65 : i8, %arg66 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.srem %arg65, %0 : i8
  %3 = llvm.lshr %arg66, %1 : i8
  %4 = llvm.xor %3, %2 : i8
  %5 = llvm.shl %4, %1 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def or_xor_and_commuted1_after := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mul %arg51, %arg51 : i32
  %2 = llvm.xor %arg50, %0 : i32
  %3 = llvm.or %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def runParser (parser : @ParseFun ParseOutput) (fileName : String) : IO (Option ParseOutput) := do
   
  let packagePaths : List String :=
    match (← IO.getEnv "LEAN_PATH") with
    | .none => []
    | .some colonSeparatedPaths => colonSeparatedPaths.splitOn ":"
  if packagePaths.isEmpty then
    throw <| IO.userError ("Expected `LEAN_PATH` environment variable to be set. " ++
    " Are you running via `lake exec opt`?")
  initSearchPath (← Lean.findSysroot) packagePaths
  let modules : Array Import := #[⟨`LeanMLIR.MLIRSyntax.EDSL, false, false, false⟩]
  let env ← importModules (loadExts := true)  modules {}
  let filePath := System.mkFilePath [fileName]
  if !(← isFile filePath) then
    throw <| IO.userError s!"File {fileName} does not exist"
  parseFile env parser filePath

def ashr_sle_noexact_after := [llvm|
{
^0(%arg154 : i8):
  %0 = llvm.mlir.constant(88 : i8) : i8
  %1 = llvm.icmp "slt" %arg154, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def lt_signed_to_large_unsigned_after := [llvm|
{
^0(%arg55 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "sgt" %arg55, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def f_after := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "slt" %arg2, %0 : i32
  %4 = llvm.lshr %1, %arg2 : i32
  %5 = llvm.icmp "sgt" %arg2, %4 : i32
  %6 = "llvm.select"(%3, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def alive_AndOrXor_1280_ABA___AB_src :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %A, %v1 : i64
  %v3 = llvm.or %v2, %B : i64
  %v4 = llvm.and %v3, %A : i64
  llvm.return %v4 : i64
}]

def positive_with_icmp_logical_after := [llvm|
{
^0(%arg57 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg57, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def test_sub_fold_LHS :=
[mod_arith q, hq| {
  ^bb0():
    %e1 = mod_arith.constant 12 : !R
    %e2 = mod_arith.constant 34 : !R
    %sub = mod_arith.sub %e1, %e2 : !R
    %e3 = mod_arith.constant 56 : !R
    %sub2 = mod_arith.sub %sub, %e3 : !R
    return %sub2 : !R
}]

def dce' {Γ : Ctxt d.Ty} {t}
    (com : Com d Γ .pure t) :
    { com' : Com d Γ .pure t //  ∀ (V : Γ.Valuation), com.denote V = com'.denote V} :=
  let ⟨ Γ', hom, com', hcom'⟩ := dce_ com
  ⟨com'.changeVars hom, by admit /- proof elided -/
  ⟩

inductive Op
| add (w : Nat) (arity : Nat)
| and (w : Nat) (arity : Nat)

| divs (w : Nat)
| divu (w : Nat)
| extract (w : Nat) (n : Nat)
| icmp (p : String) (w : Nat)
| mods (w : Nat)
| modu (w : Nat)
| mul (w : Nat) (arity : Nat)
| mux (w : Nat)
| or (w : Nat) (arity : Nat)
| parity (w : Nat)
| replicate (w : Nat) (n : Nat)
| shl (w : Nat)
| shlPar (w n : Nat)
| shrs (w : Nat)
| shru (w : Nat)
| sub (w : Nat)
| xor (w : Nat) (arity : Nat)
deriving DecidableEq, Repr, ToExpr

def ashrslt_03_01_exact_before := [llvm|
{
^0(%arg20 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.ashr exact %arg20, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def icmp_sge_riscv_eq_icmp_sge_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_sge_llvm_32, rhs:= icmp_sge_riscv_32}

def runMainCmd (args : Cli.Parsed) : IO UInt32 := do
  let fileName := args.positionalArg! "file" |>.as! String
  if args.hasFlag "verbose" then 
    let code ← verbose_flag fileName
    return code
  if args.hasFlag "riscv" then 
    let code ←  parseAsRiscv fileName
    return code
  if args.hasFlag "passriscv64" then 
    let code ← passriscv64 fileName
    return code
  if args.hasFlag "passriscv64_optimized" then 
    let code ← passriscv64_optimized fileName
    return code
  if args.hasFlag "passriscv64_optimized_const" then 
    let code ← passriscv64_optimized fileName
    return code
  if args.hasFlag "passriscv64_selectiondag" then 
    let code ← passriscv64_selectiondag fileName
    return code
  else
    let code ← wellformed fileName
    return code

def udiv_i32_multiuse_before := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.zext %arg25 : i8 to i32
  %1 = llvm.zext %arg26 : i8 to i32
  %2 = llvm.udiv %0, %1 : i32
  %3 = llvm.add %0, %1 : i32
  %4 = llvm.mul %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def ashr_16_add_zext_basic_after := [llvm|
{
^0(%arg11 : i16, %arg12 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.xor %arg11, %0 : i16
  %2 = llvm.icmp "ugt" %arg12, %1 : i16
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def slt_zero_ult_i1_fail2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg7 : i1 to i32
  %2 = llvm.ashr %arg6, %0 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def liRiscv46 := [LV| {
  ^entry ():
    %0 = "li"() {imm = 46 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def not_and_and_or_not_or_or_commute2_and_after := [llvm|
{
^0(%arg241 : i32, %arg242 : i32, %arg243 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg242, %arg243 : i32
  %2 = llvm.or %1, %arg241 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def or_or_logic_and_2_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i1, %arg11 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg11, %arg10, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.or %arg9, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def t2_after := [llvm|
{
^0(%arg202 : i8, %arg203 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.shl %0, %arg203 : i8
  %2 = llvm.add %1, %arg202 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def icmp_mul_nsw_sgt_after := [llvm|
{
^0(%arg15 : i8, %arg16 : i8):
  %0 = llvm.icmp "sgt" %arg15, %arg16 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def trunc_shl_7_i8_i64_after := [llvm|
{
^0(%arg37 : i64):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.trunc %arg37 : i64 to i8
  %2 = llvm.shl %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def trunc_shl_1_i32_i64_after := [llvm|
{
^0(%arg50 : i64):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.trunc %arg50 : i64 to i32
  %2 = llvm.shl %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def lshrult_03_07_exact_before := [llvm|
{
^0(%arg110 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr exact %arg110, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def example_program := [DCPlus_com| {
  ^entry(%0 : !TokenStream, %1 : !ValueStream_1):
    %branch = "DCPlus.branch" (%1, %0) : (!ValueStream_1, !TokenStream) -> (!TokenStream2)
    %fst = "DCPlus.fst" (%branch) :  (!TokenStream2) -> (!TokenStream)
    "return" (%fst) : (!TokenStream) -> ()
  }]

def shrink_or_after := [llvm|
{
^0(%arg11 : i6):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.trunc %arg11 : i6 to i3
  %2 = llvm.or %1, %0 : i3
  "llvm.return"(%2) : (i3) -> ()
}
]

def ne_21_logical_before := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.lshr %arg52, %0 : i32
  %4 = llvm.trunc %3 : i32 to i8
  %5 = llvm.lshr %arg52, %1 : i32
  %6 = llvm.trunc %5 : i32 to i8
  %7 = llvm.lshr %arg53, %0 : i32
  %8 = llvm.trunc %7 : i32 to i8
  %9 = llvm.lshr %arg53, %1 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.icmp "ne" %4, %8 : i8
  %12 = llvm.icmp "ne" %6, %10 : i8
  %13 = "llvm.select"(%12, %2, %11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%13) : (i1) -> ()
}
]

def select_icmp_x_and_8_ne_0_y_xor_8_after := [llvm|
{
^0(%arg177 : i32, %arg178 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.and %arg177, %0 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  %4 = llvm.xor %arg178, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

Lean.findSysroot in Lean.Util.Path

def foo_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(223 : i32) : i32
  %1 = llvm.mlir.constant(29 : i32) : i32
  %2 = llvm.mlir.constant(1362915575 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.mlir.constant(290 : i32) : i32
  %5 = llvm.mlir.constant(1533579450 : i32) : i32
  %6 = llvm.mlir.constant(749011377 : i32) : i32
  %7 = llvm.and %arg0, %0 : i32
  %8 = llvm.xor %7, %1 : i32
  %9 = llvm.add %8, %2 overflow<nsw,nuw> : i32
  %10 = llvm.shl %8, %3 overflow<nsw,nuw> : i32
  %11 = llvm.and %10, %4 : i32
  %12 = llvm.sub %9, %11 overflow<nsw,nuw> : i32
  %13 = llvm.add %12, %5 overflow<nuw> : i32
  %14 = llvm.xor %13, %6 : i32
  "llvm.return"(%14) : (i32) -> ()
}
]

def PR42691_3_logical_after := [llvm|
{
^0(%arg338 : i32):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.icmp "ult" %arg338, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

Lean.Core.State in Lean.CoreM

def eval_sext_multi_use_in_one_inst_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(14 : i16) : i16
  %1 = llvm.mlir.constant(-32768 : i16) : i16
  %2 = llvm.trunc %arg6 : i32 to i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.mul %3, %3 overflow<nsw,nuw> : i16
  %5 = llvm.or %4, %1 : i16
  %6 = llvm.sext %5 : i16 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def or_ugt_before := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.or %arg58, %arg59 : i8
  %1 = llvm.icmp "ugt" %0, %arg58 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def and_or3_commuted_before := [llvm|
{
^0(%arg164 : i1, %arg165 : i1, %arg166 : i32, %arg167 : i32):
  %0 = llvm.icmp "eq" %arg166, %arg167 : i32
  %1 = llvm.and %0, %arg165 : i1
  %2 = "llvm.select"(%1, %arg164, %arg165) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def test88_before := [llvm|
{
^0(%arg57 : i16):
  %0 = llvm.mlir.constant(18 : i32) : i32
  %1 = llvm.sext %arg57 : i16 to i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.trunc %2 : i32 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def fold_sext_to_and_wrong8_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test2_after := [llvm|
{
^0(%arg25 : i47):
  "llvm.return"(%arg25) : (i47) -> ()
}
]

def or_xor_common_op_commute6_after := [llvm|
{
^0(%arg117 : i8, %arg118 : i8, %arg119 : i8):
  %0 = llvm.or %arg117, %arg118 : i8
  %1 = llvm.or %0, %arg119 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def or_simplify_ugt_fail_after := [llvm|
{
^0(%arg7 : i8, %arg8 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.or %arg8, %0 : i8
  %2 = llvm.or %arg7, %1 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def main13_before := [llvm|
{
^0(%arg18 : i32):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.trunc %arg18 : i32 to i16
  %5 = llvm.icmp "slt" %4, %0 : i16
  %6 = llvm.trunc %arg18 : i32 to i8
  %7 = llvm.icmp "slt" %6, %1 : i8
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

def and_xor_commute1_after := [llvm|
{
^0(%arg155 : i32, %arg156 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.udiv %0, %arg155 : i32
  %3 = llvm.udiv %0, %arg156 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.and %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def ne_21_logical_after := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.lshr %arg52, %0 : i32
  %2 = llvm.trunc %1 : i32 to i16
  %3 = llvm.lshr %arg53, %0 : i32
  %4 = llvm.trunc %3 : i32 to i16
  %5 = llvm.icmp "ne" %2, %4 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

def binop_same_val_and : RISCVPeepholeRewrite [Ty.riscv (.bv)] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = and %x, %x : !riscv.reg
      ret %0 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      ret %x : !riscv.reg
  }]

@[simp_denote]
def select_riscv_select_llvm_64 : LLVMPeepholeRewriteRefine 64
  [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := select_llvm_64
  rhs := select_riscv_64

def test_simplify_decrement_invalid_ne_before := [llvm|
{
^0(%arg209 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "ne" %arg209, %0 : i8
  %3 = llvm.sub %arg209, %1 : i8
  %4 = "llvm.select"(%2, %0, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def or_xor_tree_0011_before := [llvm|
{
^0(%arg36 : i32, %arg37 : i32, %arg38 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg36, %0 : i32
  %2 = llvm.mul %arg37, %0 : i32
  %3 = llvm.mul %arg38, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.xor %3, %2 : i32
  %6 = llvm.xor %5, %1 : i32
  %7 = llvm.or %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def src_is_mask_select_before := [llvm|
{
^0(%arg110 : i8, %arg111 : i8, %arg112 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(15 : i8) : i8
  %3 = llvm.xor %arg110, %0 : i8
  %4 = llvm.add %arg111, %1 : i8
  %5 = llvm.xor %arg111, %4 : i8
  %6 = "llvm.select"(%arg112, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.and %6, %3 : i8
  %8 = llvm.icmp "ne" %7, %3 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

def and_nosignbit_shl_before := [llvm|
{
^0(%arg22 : i32):
  %0 = llvm.mlir.constant(2147418112 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg22, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ashrsgt_01_12_exact_after := [llvm|
{
^0(%arg89 : i4):
  %0 = llvm.mlir.constant(-8 : i4) : i4
  %1 = llvm.icmp "ne" %arg89, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def n1_after := [llvm|
{
^0(%arg7 : i8, %arg8 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.shl %0, %arg8 overflow<nsw> : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "uge" %3, %arg7 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def land_lor_right1_before := [llvm|
{
^0(%arg46 : i1, %arg47 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg46, %arg47, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg46, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def mul_add_to_mul_9_after := [llvm|
{
^0(%arg23 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.shl %arg23, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

Polynomial.natDegree in Mathlib.Algebra.Polynomial.Degree.Definitions

def test_logical_or_eq_a_b_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i8, %arg11 : i8):
  %0 = "llvm.select"(%arg9, %arg10, %arg11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%0) : (i8) -> ()
}
]

def positive_with_extra_and_after := [llvm|
{
^0(%arg53 : i32, %arg54 : i1):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg53, %0 : i32
  %2 = llvm.and %1, %arg54 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def ofFinCases
    {motive : ∀ {t}, Γ.Var t → Sort u}
    (ofFin : (i : Fin Γ.length) → motive (ofFin i))
    (v : Γ.Var t) :
    motive v :=

def pr33078_2_after := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.ashr %arg4, %0 : i8
  %2 = llvm.sext %1 : i8 to i12
  "llvm.return"(%2) : (i12) -> ()
}
]

def src_srem_shl_demand_eliminate_signbit_after := [llvm|
{
^0(%arg19 : i32):
  %0 = llvm.mlir.constant(1073741824 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.srem %arg19, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw> : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test3_after := [llvm|
{
^0(%arg103 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.and %arg103, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def demorgan_nand_before := [llvm|
{
^0(%arg38 : i8, %arg39 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg38, %0 : i8
  %2 = llvm.and %1, %arg39 : i8
  %3 = llvm.xor %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

Lean.Name.mkSimple in Init.Prelude

Set.compl in Mathlib.Data.Set.Defs

def test15b_after := [llvm|
{
^0(%arg26 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.and %arg26, %0 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def trunc_before := [llvm|
{
^0(%arg15 : i32, %arg16 : i32, %arg17 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.icmp "ult" %arg15, %arg16 : i32
  %2 = "llvm.select"(%1, %0, %arg17) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.trunc %2 : i32 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def xor_or_xor_common_op_commute8_before := [llvm|
{
^0(%arg59 : i32, %arg60 : i32, %arg61 : i32):
  %0 = llvm.xor %arg61, %arg59 : i32
  %1 = llvm.or %arg60, %arg59 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def ashr_ugt_12_before := [llvm|
{
^0(%arg102 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-4 : i4) : i4
  %2 = llvm.ashr %arg102, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def xor_logic_and_logic_or4_before := [llvm|
{
^0(%arg45 : i1, %arg46 : i1, %arg47 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg45, %0, %arg47) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg46, %arg45, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = llvm.xor %3, %2 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def ashr_sgt_exact_after := [llvm|
{
^0(%arg167 : i8):
  %0 = llvm.mlir.constant(80 : i8) : i8
  %1 = llvm.icmp "sgt" %arg167, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def xor_or_xor_common_op_commute6_before := [llvm|
{
^0(%arg65 : i32, %arg66 : i32, %arg67 : i32):
  %0 = llvm.xor %arg67, %arg65 : i32
  %1 = llvm.or %arg65, %arg66 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_6_after := [llvm|
{
^0(%arg58 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg58, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def llvm_mul_lower_riscv_nsw_flag_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := mul_llvm_nsw_32
  rhs := mul_riscv_32

def negate_add_with_single_negatible_operand_depth2_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.mlir.constant(-21 : i8) : i8
  %1 = llvm.sub %0, %arg21 : i8
  %2 = llvm.mul %1, %arg22 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def test_nuw_dropped_after := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.shl %arg7, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

Id.run in Init.Control.Id

def ashr_ult_7_after := [llvm|
{
^0(%arg89 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.icmp "sgt" %arg89, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

One in Init.Prelude

def t1_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i1):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg28 : i8
  %2 = "llvm.select"(%arg29, %1, %arg28) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def zext_nneg_sext_sle_op0_narrow_before := [llvm|
{
^0(%arg50 : i8, %arg51 : i16):
  %0 = llvm.zext nneg %arg50 : i8 to i32
  %1 = llvm.sext %arg51 : i16 to i32
  %2 = llvm.icmp "sle" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def scalar_i64_shl_ult_const_after := [llvm|
{
^0(%arg14 : i64):
  %0 = llvm.mlir.constant(549755813632) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.and %arg14, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def sub_not_after := [llvm|
{
^0(%arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg22, %0 : i8
  %2 = llvm.add %arg23, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def is_rem2_neg_i8_before := [llvm|
{
^0(%arg57 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.srem %arg57, %0 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashr_eq_msb_low_second_zero_after := [llvm|
{
^0(%arg175 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.icmp "ugt" %arg175, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def p0_before := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg29 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.icmp "ult" %2, %arg28 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def add_nsw_or_and_before := [llvm|
{
^0(%arg11 : i32, %arg12 : i32):
  %0 = llvm.or %arg11, %arg12 : i32
  %1 = llvm.and %arg11, %arg12 : i32
  %2 = llvm.add %0, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test_mul_nsw__nsw_is_safe_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(-83886079 : i32) : i32
  %2 = llvm.mlir.constant(9 : i32) : i32
  %3 = llvm.mlir.constant(-754974711 : i32) : i32
  %4 = llvm.or %arg5, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.mul %4, %2 overflow<nsw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

RV64.sub in RISCV.Instructions

def test9_after := [llvm|
{
^0(%arg72 : i32):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.trunc %arg72 : i32 to i8
  %2 = llvm.and %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def negative4_logical_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.and %arg5, %0 : i32
  %4 = llvm.icmp "ne" %arg4, %3 : i32
  %5 = llvm.icmp "sge" %arg4, %1 : i32
  %6 = "llvm.select"(%4, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def elabDefSignatureFor (dialect : Term) (alts : TSyntax ``matchAltsSig) : CommandElabM Unit := do
  let msg := (return m!"{exceptEmoji ·} Defining operation signature for {dialect} dialect")
  withTraceNode `LeanMLIR.Elab msg (collapsed := false) <| do
    let alts := getMatchAlts alts
    let alts ← do
      alts.mapM fun view => do
        trace[LeanMLIR.Elab] m!"Parsing match alternative with\n\
          \tpatterns: {view.patterns}\n\
          \tsignature: {view.rhs}"
        let rhs ← parseSignature view.rhs
        return { view with rhs }

    |

def select_zext_different_condition_before := [llvm|
{
^0(%arg15 : i1, %arg16 : i1):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = "llvm.select"(%arg15, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %3 = llvm.zext %arg16 : i1 to i64
  %4 = llvm.add %2, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def xor_andn_commute4_before := [llvm|
{
^0(%arg66 : i32, %arg67 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.udiv %0, %arg66 : i32
  %3 = llvm.udiv %0, %arg67 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.and %3, %4 : i32
  %6 = llvm.xor %2, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def mulMax'Mask (wmask : BitVec o) (vmask : BitVec o) : BitVec o :=
    let added := unaryAdd wmask vmask
    unaryDouble added |> unaryIncr

def n0_after := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(-5 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg4, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def ex2_lhs : Com [.nat] .nat :=
  Com.var (rgn (k := 1) ⟨0, by admit /- proof elided -/
  ⟩ (
      Com.var (add ⟨0, by admit /- proof elided -/
      ⟩ ⟨0, by admit /- proof elided -/
      ⟩) 
      <| Com.ret ⟨0, by admit /- proof elided -/
      ⟩
  )) <|
  Com.ret ⟨0, by admit /- proof elided -/
  ⟩

def test_sext_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "ne" %arg30, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.sub %2, %arg31 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

@[simp] abbrev Hom.id {Γ : Ctxt Ty} : Γ.Hom Γ :=
  fun _ v => v

def const? (w : Nat) (i : Int): IntW w :=
  .value <| BitVec.ofInt w i

def test35_with_trunc_before := [llvm|
{
^0(%arg48 : i64):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(60 : i32) : i32
  %2 = llvm.mlir.constant(100 : i32) : i32
  %3 = llvm.trunc %arg48 : i64 to i32
  %4 = llvm.icmp "sge" %3, %0 : i32
  %5 = "llvm.select"(%4, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def llvm_const_lower_riscv_li_16 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_16, rhs:= liRiscv_16,
   correct := by admit /- proof elided -/

def ashrsgt_02_11_exact_before := [llvm|
{
^0(%arg74 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-5 : i4) : i4
  %2 = llvm.ashr exact %arg74, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_shift_and_cmp_changed4_after := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def mul? {w : Nat} (x y : BitVec w) : IntW w :=
  .value <| x * y

def PR42691_8_logical_after := [llvm|
{
^0(%arg328 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483635 : i32) : i32
  %2 = llvm.add %arg328, %0 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

private def attrVal7NestedSymbol : AttrVal := [mlir_attr_val| @func_foo::@"func_bar" ]

def shift_trunc_wrong_cmp_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.lshr %arg0, %0 : i32
  %3 = llvm.trunc %2 overflow<nuw> : i32 to i8
  %4 = llvm.icmp "slt" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def scalar_i8_shl_ult_const_3_after := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg17, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def positive_biggerShl_after := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(134217696 : i32) : i32
  %2 = llvm.shl %arg34, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def sgt_swap_and_min_commute_after := [llvm|
{
^0(%arg340 : i8, %arg341 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def t10_c1_c2_after := [llvm|
{
^0(%arg11 : i8, %arg12 : i8):
  %0 = llvm.mlir.constant(-66 : i8) : i8
  %1 = llvm.add %arg11, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test12_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1431655765 : i32) : i32
  %3 = llvm.add %arg47, %0 overflow<nsw> : i32
  %4 = llvm.or %arg46, %1 : i32
  %5 = llvm.xor %4, %2 : i32
  %6 = llvm.add %3, %5 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def lshrult_03_13_after := [llvm|
{
^0(%arg322 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def negate_lshr_after := [llvm|
{
^0(%arg108 : i8, %arg109 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg109, %0 : i8
  %2 = llvm.add %1, %arg108 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def not_and_and_or_no_or_commute1_after := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg154, %0 : i32
  %2 = llvm.xor %arg155, %0 : i32
  %3 = llvm.or %arg156, %2 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def select_same_val_self : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 1), Ty.llvm (.bitvec 64) ] where
  lhs := [LV| {
    ^entry (%x: i64, %c: i1):
      %0 = llvm.select %c, %x, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64, %c: i1):
      llvm.return %x : i64
  }]

def test36_before := [llvm|
{
^0(%arg244 : i32):
  %0 = llvm.mlir.constant(7) : i64
  %1 = llvm.mlir.constant(240) : i64
  %2 = llvm.zext %arg244 : i32 to i64
  %3 = llvm.add %2, %0 : i64
  %4 = llvm.and %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def slt_swap_and_not_max_logical_before := [llvm|
{
^0(%arg116 : i8, %arg117 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg117, %arg116 : i8
  %3 = llvm.icmp "ne" %arg116, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def bitwise_and_bitwise_and_icmps_before := [llvm|
{
^0(%arg244 : i8, %arg245 : i8, %arg246 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "eq" %arg245, %0 : i8
  %4 = llvm.and %arg244, %1 : i8
  %5 = llvm.shl %1, %arg246 : i8
  %6 = llvm.and %arg244, %5 : i8
  %7 = llvm.icmp "ne" %4, %2 : i8
  %8 = llvm.icmp "ne" %6, %2 : i8
  %9 = llvm.and %3, %7 : i1
  %10 = llvm.and %9, %8 : i1
  "llvm.return"(%10) : (i1) -> ()
}
]

def ashrsgt_03_09_before := [llvm|
{
^0(%arg276 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.ashr %arg276, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def BinaryRelationKind.toSmtLib : BinaryRelationKind → SexprPBV.BinaryRelationKind
| .eq => .eq
| .ne => .ne
| .ule => .ule
| .slt => .slt
| .sle => .sle
| .ult => .ult

def reduce_xor_common_op_commute0_before := [llvm|
{
^0(%arg10 : i4, %arg11 : i4, %arg12 : i4):
  %0 = llvm.xor %arg10, %arg11 : i4
  %1 = llvm.xor %0, %arg12 : i4
  %2 = llvm.or %1, %arg10 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

def sub_mask1_lshr_before := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.lshr %arg21, %0 : i8
  %3 = llvm.and %2, %0 : i8
  %4 = llvm.sub %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def castCtxt (h_eq : Γ = Δ) : Γ.Var ty → Δ.Var ty
  | ⟨i, h⟩ => ⟨i, h_eq ▸ h⟩

private def testBalancedBrackets : String := [balanced_brackets| < { xxasdasd } > ]

def ashrsgt_02_00_after := [llvm|
{
^0(%arg301 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.icmp "sgt" %arg301, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def not_and_and_or_not_or_or_commute1_and_before := [llvm|
{
^0(%arg244 : i32, %arg245 : i32, %arg246 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg245, %arg244 : i32
  %2 = llvm.or %1, %arg246 : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.xor %arg244, %0 : i32
  %5 = llvm.and %4, %arg246 : i32
  %6 = llvm.and %5, %arg245 : i32
  %7 = llvm.or %6, %3 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def test67_after := [llvm|
{
^0(%arg113 : i1, %arg114 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test15_after := [llvm|
{
^0(%arg44 : i8, %arg45 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.xor %arg45, %arg44 : i8
  %2 = llvm.xor %arg44, %arg45 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.and %1, %3 : i8
  %5 = llvm.mul %4, %3 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def lshrugt_01_15_exact_before := [llvm|
{
^0(%arg206 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-1 : i4) : i4
  %2 = llvm.lshr exact %arg206, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_xor_and_commuted2_before := [llvm|
{
^0(%arg48 : i32, %arg49 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mul %arg49, %arg49 : i32
  %2 = llvm.mul %arg48, %arg48 : i32
  %3 = llvm.xor %1, %0 : i32
  %4 = llvm.xor %2, %3 : i32
  %5 = llvm.or %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def sgt_swap_and_min_after := [llvm|
{
^0(%arg344 : i8, %arg345 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def nomask_lhs_before := [llvm|
{
^0(%arg115 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.icmp "eq" %arg115, %0 : i32
  %3 = llvm.and %arg115, %1 : i32
  %4 = llvm.icmp "eq" %3, %0 : i32
  %5 = llvm.or %2, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

inductive TermUnop where
| neg | not | shiftL (k : Nat)

def llvm_sdiv_lower_riscv_exact_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := sdiv_llvm_exact_32
  rhs := sdiv_riscv_32
  correct := sorry

def LiveBlock.lengthInBits (b : LiveBlock) : Nat :=
  8 * b.length

def test_srem_canonicalize_op0_before := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.sub %0, %arg8 overflow<nsw> : i32
  %2 = llvm.srem %1, %arg9 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def RawCNFA.transSet (m : RawCNFA A) (ss : Std.HashSet State) (a : A) : Std.HashSet State :=
  ss.fold (init := ∅) fun ss' s =>
    ss'.insertMany $ m.trans.getD (s, a) ∅

def rem_euclid_pow2_false_arm_folded_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.srem %arg2, %0 : i32
  %4 = llvm.icmp "sge" %3, %1 : i32
  %5 = "llvm.select"(%4, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

private def mkExt (name attr : Name) (descr : String) : IO NameExt := do
  let addEntryFn | m, (n3, n4) => m.insert n3 n4
  let ext ← registerSimplePersistentEnvExtension {
    name, addEntryFn
    addImportedFn := mkStateFromImportedEntries addEntryFn {}
  }
  registerBuiltinAttribute {
    name := attr
    descr
    add := fun declName stx attrKind => do
      let s := ext.getState (← getEnv)
      let ns ← stx[1].getArgs.mapM fun stx => do
        let n := stx.getId
        if s.contains n then throwErrorAt stx "test {n} already declared"
        pure n
      modifyEnv $ ns.foldl fun env n =>
        ext.addEntry env (n, declName)
  }
  pure ext

def test19_after := [llvm|
{
^0(%arg150 : i32, %arg151 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg150, %arg151 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def positive_biggershl_shlnuwnsw_lshrexact_after := [llvm|
{
^0(%arg24 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.shl %arg24, %0 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def bool_eq0_logical_before := [llvm|
{
^0(%arg32 : i64):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sgt" %arg32, %0 : i64
  %4 = llvm.icmp "eq" %arg32, %1 : i64
  %5 = llvm.icmp "eq" %4, %2 : i1
  %6 = "llvm.select"(%3, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def shl_nsw_ule_Csle0_fail_missing_flag_after := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(-18 : i8) : i8
  %1 = llvm.shl %arg12, %arg13 overflow<nsw> : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def select_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=
  [⟨[Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64),Ty.llvm (.bitvec 1)],
   [Ty.llvm (.bitvec 64)],(LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND select_riscv_select_llvm_64)⟩,
  ⟨[Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32),Ty.llvm (.bitvec 1)],
   [Ty.llvm (.bitvec 32)],(LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND select_riscv_select_llvm_32)⟩,
   ⟨[Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8),Ty.llvm (.bitvec 1)],
   [Ty.llvm (.bitvec 8)],(LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND select_riscv_select_llvm_8)⟩]

def test7_after := [llvm|
{
^0(%arg93 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

@[match_pattern] def lshr (w : Width φ)
  (ExactFlag : ExactFlag := {exact := false} ) : MOp φ
    := .binary w (.lshr ExactFlag )

def xor_of_icmps_neg_to_ne_after := [llvm|
{
^0(%arg27 : i64):
  %0 = llvm.mlir.constant(-5) : i64
  %1 = llvm.icmp "ne" %arg27, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

def logical_and_implies_folds_before := [llvm|
{
^0(%arg248 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "ugt" %arg248, %0 : i32
  %4 = llvm.icmp "ne" %arg248, %1 : i32
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def icmp_and_ashr_multiuse_logical_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(240 : i32) : i32
  %1 = llvm.mlir.constant(224 : i32) : i32
  %2 = llvm.mlir.constant(496 : i32) : i32
  %3 = llvm.mlir.constant(432 : i32) : i32
  %4 = llvm.and %arg4, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg4, %2 : i32
  %7 = llvm.icmp "ne" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def test66_after := [llvm|
{
^0(%arg41 : i64):
  %0 = llvm.mlir.constant(4294967296) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(42 : i32) : i32
  %3 = llvm.mlir.constant(40 : i32) : i32
  %4 = llvm.and %arg41, %0 : i64
  %5 = llvm.icmp "eq" %4, %1 : i64
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def sdiv_shl_pair2_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32, %arg42 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg41 overflow<nsw,nuw> : i32
  %2 = llvm.lshr %1, %arg42 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def sub_ashr_and_i8_before := [llvm|
{
^0(%arg31 : i8, %arg32 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.sub %arg32, %arg31 overflow<nsw> : i8
  %2 = llvm.ashr %1, %0 : i8
  %3 = llvm.and %2, %arg31 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def NFA.msbLang : Language (BitVec 1) := { bvs  | bvs.getLast? = some 1 }

def llvm_or_lower_riscv_noflag_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := or_llvm_noflag_64
  rhs := or_riscv_64

def or_eq_with_one_bit_diff_constants2_logical_after := [llvm|
{
^0(%arg361 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.mlir.constant(65 : i32) : i32
  %2 = llvm.and %arg361, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def rewritePeepholeRecursivelyRegArgs (fuel : ℕ)
    (pr : PeepholeRewrite d Γ t) {ts :  List (Ctxt d.Ty × List d.Ty)}
    (args : HVector (fun t => Com d t.1 EffectKind.impure t.2) ts)
    : { out : HVector (fun t => Com d t.1 EffectKind.impure t.2) ts // out.denote = args.denote} :=
  match ts with
  | .nil =>
    match args with
    | .nil => ⟨HVector.nil, rfl⟩
  | .cons .. =>
    match args with
    | .cons (a := a) (as := as) com coms =>
      let ⟨com', hcom'⟩ := rewritePeepholeRecursively fuel pr com
      let ⟨coms', hcoms'⟩ := (rewritePeepholeRecursivelyRegArgs fuel pr coms)
      ⟨.cons com' coms', by admit /- proof elided -/
      ⟩
termination_by (fuel, ts.length + 2)

def ult_and_max_commute_logical_after := [llvm|
{
^0(%arg362 : i8, %arg363 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

elab "[poly" qi:term "," ni:term "," hq:term " | " reg:mlir_region "]" : term => do
  let q : Q(Nat) ← elabTermEnsuringTypeQ qi q(Nat)
  let n : Q(Nat) ← elabTermEnsuringTypeQ ni q(Nat)
  let _factval ← elabTermEnsuringTypeQ hq q(Fact ($q > 1))

  SSA.elabIntoCom reg q(FHE $q $n)

def testi128i128_before := [llvm|
{
^0(%arg7 : i128):
  %0 = llvm.mlir.constant(127 : i128) : i128
  %1 = llvm.mlir.constant(27 : i128) : i128
  %2 = llvm.ashr %arg7, %0 : i128
  %3 = llvm.xor %2, %1 : i128
  "llvm.return"(%3) : (i128) -> ()
}
]

def invert_icmp_after := [llvm|
{
^0(%arg151 : i32, %arg152 : i32):
  %0 = llvm.icmp "sgt" %arg151, %arg152 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def basic_before := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg25, %0 : i8
  %2 = llvm.add %1, %arg26 : i8
  %3 = llvm.xor %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def test24_before := [llvm|
{
^0(%arg183 : i32, %arg184 : i32):
  %0 = llvm.xor %arg184, %arg183 : i32
  %1 = llvm.icmp "ne" %0, %arg183 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def shl_add_nuw_after := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def and_xor_or4_before := [llvm|
{
^0(%arg664 : i64, %arg665 : i64, %arg666 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg664 : i64
  %2 = llvm.udiv %0, %arg665 : i64
  %3 = llvm.udiv %0, %arg666 : i64
  %4 = llvm.and %2, %1 : i64
  %5 = llvm.xor %3, %4 : i64
  %6 = llvm.or %5, %2 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

def lshrult_01_01_after := [llvm|
{
^0(%arg366 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.icmp "ult" %arg366, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def ashr_ule_exact_before := [llvm|
{
^0(%arg168 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.ashr exact %arg168, %0 : i8
  %3 = llvm.icmp "ule" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

@[simp_denote]
def llvm_sub_nsw_lower_riscv_16: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16)] where
  lhs := llvm_sub_nsw_16
  rhs := sub_riscv_16

def or_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := or_llvm_i32
  rhs := or_riscv_i32

def and_logic_and_logic_or_6_before := [llvm|
{
^0(%arg123 : i1, %arg124 : i1, %arg125 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg123, %arg124 : i1
  %3 = "llvm.select"(%arg125, %arg123, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def pr51551_neg2_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(-7 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg3, %0 : i32
  %4 = llvm.mul %3, %arg2 overflow<nsw> : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

def inputSnd : (CIRCTStream.DCOp.TokenStream × CIRCTStream.DCOp.TokenStream) := (tok1, tok2)

def ugt_and_min_commute_logical_before := [llvm|
{
^0(%arg330 : i8, %arg331 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ugt" %arg330, %arg331 : i8
  %3 = llvm.icmp "eq" %arg330, %0 : i8
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test0_before := [llvm|
{
^0(%arg3 : i32):
  %0 = llvm.mlir.constant(1431655765 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg3, %0 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %4, %2 overflow<nsw> : i32
  %6 = llvm.add %arg3, %5 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def uge_swap_and_max_logical_before := [llvm|
{
^0(%arg228 : i8, %arg229 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ule" %arg229, %arg228 : i8
  %3 = llvm.icmp "eq" %arg228, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test_lshr_exact__exact_is_safe_before := [llvm|
{
^0(%arg62 : i32, %arg63 : i64):
  %0 = llvm.mlir.constant(60 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg62, %0 : i32
  %4 = llvm.lshr exact %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg63, %5 : i64
  %8 = "llvm.select"(%6, %arg63, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

def or_xor_tree_1001_before := [llvm|
{
^0(%arg18 : i32, %arg19 : i32, %arg20 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg18, %0 : i32
  %2 = llvm.mul %arg19, %0 : i32
  %3 = llvm.mul %arg20, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.xor %2, %3 : i32
  %6 = llvm.xor %5, %1 : i32
  %7 = llvm.or %6, %4 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def flip_add_of_shift_neg_before := [llvm|
{
^0(%arg12 : i8, %arg13 : i8, %arg14 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg12 : i8
  %2 = llvm.shl %1, %arg13 overflow<nsw,nuw> : i8
  %3 = llvm.add %2, %arg14 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def toHom (d : Diff Γ₁ Γ₂) : Hom Γ₁ Γ₂ :=
  fun _ v => ⟨v.val + d.val, d.property v.property⟩

def udiv_pow2_128 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (128) : i64
      %0 = llvm.udiv %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (7) : i64
      %0 = llvm.lshr %x, %c : i64
      llvm.return %0 : i64
  }]

def and_not_or_after := [llvm|
{
^0(%arg481 : i32, %arg482 : i32, %arg483 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg482, %arg483 : i32
  %2 = llvm.and %1, %arg481 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ashrsgt_02_14_exact_before := [llvm|
{
^0(%arg71 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.ashr exact %arg71, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def eq_and_shl_one_after := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg36 overflow<nuw> : i8
  %3 = llvm.and %2, %arg35 : i8
  %4 = llvm.icmp "ne" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

Lean.Declaration.defnDecl in Lean.Declaration

inductive Body
  | mk (lets : Lets) (terminator : T)

def lshrult_01_11_before := [llvm|
{
^0(%arg356 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-5 : i4) : i4
  %2 = llvm.lshr %arg356, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def is_ascii_alphabetic_after := [llvm|
{
^0(%arg248 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.mlir.constant(-65 : i32) : i32
  %2 = llvm.mlir.constant(26 : i32) : i32
  %3 = llvm.and %arg248, %0 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def main5_like_after := [llvm|
{
^0(%arg113 : i32, %arg114 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.and %arg113, %arg114 : i32
  %2 = llvm.and %1, %0 : i32
  %3 = llvm.icmp "ne" %2, %0 : i32
  %4 = llvm.zext %3 : i1 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def shl_nsw_add_nuw_after := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def lshrult_01_06_exact_before := [llvm|
{
^0(%arg143 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.lshr exact %arg143, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def select_icmp_ne_0_and_32_xor_4096_before := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(4096 : i32) : i32
  %3 = llvm.and %arg199, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.xor %arg200, %2 : i32
  %6 = "llvm.select"(%4, %arg200, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def test_imply_not2_after := [llvm|
{
^0(%arg3 : i32, %arg4 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ne" %arg3, %0 : i32
  %3 = "llvm.select"(%2, %1, %arg4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg3 : i16):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.zext %arg3 : i16 to i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.mul %2, %1 : i32
  %5 = llvm.or %3, %4 : i32
  %6 = llvm.trunc %5 : i32 to i16
  "llvm.return"(%6) : (i16) -> ()
}
]

def logic_or_logic_and_6_after := [llvm|
{
^0(%arg72 : i1, %arg73 : i1, %arg74 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg74, %arg73, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg72, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def mkTermFSM (wcard tcard bcard ncard icard pcard : Nat) (t : Nondep.Term) :
    (TermFSM wcard tcard bcard ncard icard pcard t) :=
  match t with
  | .bvOfBool b =>
     let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
     let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard (.const 1)
     {
      toFsmZext := fsmB.toFsmZext &&& fsmW.toFsm
      width := fsmW
     }
  | .ofNat w n =>
    let fsmW  := (mkWidthFSM wcard tcard bcard ncard icard pcard w)
    let fsmN : FSM (StateSpace wcard tcard bcard ncard icard pcard) := (FSM.ofNat n).map Fin.elim0
    {
      toFsmZext := fsmW.toFsm &&& fsmN,
      width := fsmW
    }
  | .var v w =>
    let wfsm := mkWidthFSM wcard tcard bcard ncard icard pcard w
    if h : v < tcard then
      let varFsm : FSM (StateSpace wcard tcard bcard ncard icard pcard) :=
       (FSM.var' (StateSpace.termVar ⟨v, h⟩))
      {
        toFsmZext := varFsm &&& wfsm.toFsm,
        width := wfsm
      }
    else
      
      { toFsmZext := FSM.zero.map Fin.elim0, width := mkWidthFSM wcard tcard bcard ncard icard pcard w }
  | .add w a b =>
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    { toFsmZext :=
      composeBinaryAux' FSM.and
        fsmW.toFsm
        (composeBinaryAux' FSM.add fsmA.toFsmZext fsmB.toFsmZext),
      width := fsmW
    }
  | .zext a wnew =>
      
      let afsm := mkTermFSM wcard tcard bcard ncard icard pcard a
      
      let wnewFsm := mkWidthFSM wcard tcard bcard ncard icard pcard wnew
      { toFsmZext := fsmZext afsm.toFsmZext wnewFsm.toFsm, width := wnewFsm }
  | .setWidth a wnew =>
    let afsm := mkTermFSM wcard tcard bcard ncard icard pcard a
    let wnewFsm := mkWidthFSM wcard tcard bcard ncard icard pcard wnew
    { toFsmZext := fsmZext afsm.toFsmZext wnewFsm.toFsm, width := wnewFsm }
  | .sext a v =>
    let wold := a.width
    let afsm := mkTermFSM wcard tcard bcard ncard icard pcard a
    let woldFsm := mkWidthFSM wcard tcard bcard ncard icard pcard wold
    let vFsm := mkWidthFSM wcard tcard bcard ncard icard pcard v
    { toFsmZext := fsmSext afsm.toFsmZext woldFsm.toFsm vFsm.toFsm, width := vFsm }
  | .band w a b =>
      let aFsm := mkTermFSM wcard tcard bcard ncard icard pcard a
      let bFsm := mkTermFSM wcard tcard bcard ncard icard pcard b
      {
        toFsmZext :=
            (composeBinaryAux' FSM.and aFsm.toFsmZext bFsm.toFsmZext),
        width := mkWidthFSM wcard tcard bcard ncard icard pcard w

      }
  | .bor w a b =>
    let aFsm := mkTermFSM wcard tcard bcard ncard icard pcard a
    let bFsm := mkTermFSM wcard tcard bcard ncard icard pcard b
    {   toFsmZext := (composeBinaryAux' FSM.or aFsm.toFsmZext bFsm.toFsmZext) ,
        width := mkWidthFSM wcard tcard bcard ncard icard pcard w
    }
  | .bxor w a b =>
    let aFsm := mkTermFSM wcard tcard bcard ncard icard pcard a
    let bFsm := mkTermFSM wcard tcard bcard ncard icard pcard b
    { toFsmZext := (composeBinaryAux' FSM.xor aFsm.toFsmZext bFsm.toFsmZext),
      width := mkWidthFSM wcard tcard bcard ncard icard pcard w
    }
  | .bnot w a =>
    let aFsm := mkTermFSM wcard tcard bcard ncard icard pcard a
    let wFsm := mkWidthFSM wcard tcard bcard ncard icard pcard w
    { toFsmZext :=
          composeBinaryAux' FSM.and wFsm.toFsm
            (composeUnaryAux FSM.not aFsm.toFsmZext),
      width := wFsm
    }
  | .boolVar v =>
    
    
    
    
    
    
    
    if h : v < bcard then
      let varFsm : FSM (StateSpace wcard tcard bcard ncard icard pcard) :=
       (FSM.var' (StateSpace.boolVar ⟨v, h⟩))
      {
        toFsmZext := composeUnaryAux FSM.hold0Forever varFsm,
        width := mkWidthFSM wcard tcard bcard ncard icard pcard (.const 1)
      }
    else
      
      {
        toFsmZext := FSM.zero.map Fin.elim0,
        width := mkWidthFSM wcard tcard bcard ncard icard pcard (.const 1)
      }
  | .boolConst b =>
      {
        toFsmZext := (FSM.repeatForever b).map Fin.elim0,
        width := mkWidthFSM wcard tcard bcard ncard icard pcard (.const 1)
      }
  | .shiftl w a n =>
    let aFsm := mkTermFSM wcard tcard bcard ncard icard pcard a
    let wFsm := mkWidthFSM wcard tcard bcard ncard icard pcard w
    {
      toFsmZext :=
        composeBinaryAux' FSM.and wFsm.toFsm
          (composeUnaryAux (FSM.shiftLeft n) aFsm.toFsmZext),
      width := wFsm
    }
  | .pvar x =>
    if hx : x < pcard then
      {
        toFsmZext := FSM.var' (StateSpace.predVar ⟨x, hx⟩),
        width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
      }
    else
      {
        toFsmZext := FSM.zero.map Fin.elim0,
        width := NatFSM.mk ((FSM.negOne).map Fin.elim0)

      } 
  | .binWidthRel .eq a b =>
    let fsmA := mkWidthFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkWidthFSM wcard tcard bcard ncard icard pcard b
    { toFsmZext := fsmWidthEq fsmA.toFsm fsmB.toFsm,
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0) }
  | .binWidthRel .le a b =>
    let fsmA := mkWidthFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkWidthFSM wcard tcard bcard ncard icard pcard b
    { toFsmZext := fsmWidthUle fsmA.toFsm fsmB.toFsm,
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0) }
  | .binRel .eq w a b =>
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    { toFsmZext := ~~~ fsmW.toFsm ||| fsmTermEq fsmA fsmB,
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0) }
  | .binRel .ne w a b =>
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    { toFsmZext := fsmW.toFsm ||| fsmTermNe fsmA fsmB,
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0) }
  | .binRel .ult w a b =>
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    { toFsmZext :=
      
      
      
      
      fsmW.toFsm ||| (fsmTermUlt fsmA fsmB),
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
    }
  | .binRel .ule w a b =>
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    { toFsmZext :=
      
      
      
      
      fsmW.toFsm ||| (fsmTermUle fsmA fsmB),
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
    }
  | .binRel .slt w a b =>
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    { toFsmZext :=
      
      
      
      
      fsmW.toFsm ||| (fsmTermSlt fsmW fsmA fsmB),
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
    }
  | .binRel .sle w a b =>
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    let fsmW := mkWidthFSM wcard tcard bcard ncard icard pcard w
    { toFsmZext :=
      
      
      
      
      fsmW.toFsm ||| (fsmTermSle fsmW fsmA fsmB),
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
    }
  | .or p q  =>
    let fsmP :=  mkTermFSM wcard tcard bcard ncard icard pcard p
    let fsmQ :=  mkTermFSM wcard tcard bcard ncard icard pcard q
    let fsmP := composeUnaryAux FSM.scanAnd fsmP.toFsmZext
    let fsmQ := composeUnaryAux FSM.scanAnd fsmQ.toFsmZext
    { toFsmZext := (fsmP ||| fsmQ),
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
    }
  | .and p q =>
    let fsmP := mkTermFSM wcard tcard bcard ncard icard pcard p
    let fsmQ := mkTermFSM wcard tcard bcard ncard icard pcard q
    { toFsmZext := (fsmP.toFsmZext &&& fsmQ.toFsmZext),
      width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
    }
  | .boolBinRel k a b  =>
    let fsmA := mkTermFSM wcard tcard bcard ncard icard pcard a
    let fsmB := mkTermFSM wcard tcard bcard ncard icard pcard b
    match k with
    | .eq =>
      
      let fsmEq := composeBinaryAux' FSM.nxor (fsmA.toFsmZext) (fsmB.toFsmZext)
      { toFsmZext := composeUnaryAux FSM.scanAnd (fsmEq) ,
        width := NatFSM.mk ((FSM.negOne).map Fin.elim0)
      }

@[inline]
def CNFA.proj (m: CNFA n2) (f : Fin n1 → Fin n2) : CNFA n1 :=
  ⟨m.m.proj f, m.m.proj_wf m.wf⟩

def lshr_by_const_cmp_sge_value_after := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "slt" %arg7, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

Int.negOfNat in Init.Data.Int.Basic

def Com.letSup (e : Expr d Γ eff₁ t) (body : Com d (e.outContext) eff₂ u) :
    Com d Γ (eff₁ ⊔ eff₂) u :=
  Com.var (e.changeEffect <| by admit /- proof elided -/
  ) (body.changeEffect <| by admit /- proof elided -/
  )

def test_srem_canonicalize_op0_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.srem %arg8, %arg9 : i32
  %2 = llvm.sub %0, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def branch (x : ValueStream (BitVec 1)): TokenStream × TokenStream  :=
  Stream.corec₂ (β := ValueStream (BitVec 1)) x fun x =>
    Id.run <| do
      match x 0 with
        | none => (none, none, (x.tail))
        | some x₀ =>
          if x₀.msb then
            (some (), none, (x.tail))
          else
            (none, some (), (x.tail))

def udiv_icmp2_before := [llvm|
{
^0(%arg20 : i64):
  %0 = llvm.mlir.constant(5) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.udiv exact %arg20, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def irc_constants_APlusC1MinusC2_neg2_1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.add %a, %c1 : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]

def ashrsgt_02_06_after := [llvm|
{
^0(%arg295 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def or_not_and_wrong_c_before := [llvm|
{
^0(%arg488 : i32, %arg489 : i32, %arg490 : i32, %arg491 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg488, %arg489 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %2, %arg490 : i32
  %4 = llvm.or %arg488, %arg491 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %5, %arg489 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def ashrsgt_02_15_exact_after := [llvm|
{
^0(%arg70 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.icmp "sgt" %arg70, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def ashrslt_01_06_after := [llvm|
{
^0(%arg263 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

macro "[balanced_brackets|" xs:balancedBrackets "]" : term => do
  match xs.raw[0] with
  | .atom _ val => return (Lean.quote val: TSyntax `str)
  | _  => Macro.throwErrorAt xs "expected balanced bracts to have atom"

def lshrugt_03_07_exact_before := [llvm|
{
^0(%arg182 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr exact %arg182, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def udiv_common_divisor_before := [llvm|
{
^0(%arg65 : i1, %arg66 : i5, %arg67 : i5, %arg68 : i5):
  %0 = llvm.udiv %arg67, %arg66 : i5
  %1 = llvm.udiv %arg68, %arg66 : i5
  %2 = "llvm.select"(%arg65, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  "llvm.return"(%2) : (i5) -> ()
}
]

def test_mul_nuw_nsw__all_are_safe_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg15, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def in_constant_14_vary_after := [llvm|
{
^0(%arg22 : i4, %arg23 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.and %arg22, %0 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

RV64.sh3adduw in RISCV.Instructions

@[simp_denote]
def udiv_llvm_exact_32 : Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 32), .llvm (.bitvec 32)]⟩
  .pure (.llvm (.bitvec 32)) := [LV| {
  ^entry (%x: i32, %y: i32):
    %0 = llvm.udiv exact %x, %y : i32
    llvm.return %0 : i32
  }]

def test_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(71 : i32) : i32
  %1 = llvm.mlir.constant(-12 : i32) : i32
  %2 = llvm.add %arg1, %0 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def t9_nocse_before := [llvm|
{
^0(%arg9 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg9 : i8
  %3 = llvm.shl %0, %arg9 : i8
  %4 = llvm.add %2, %1 : i8
  %5 = llvm.or %4, %3 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_after := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg21, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

instance : DecidableEq TestDialect.Ty :=

def f_var0_before := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg52, %arg53 : i32
  %3 = llvm.icmp "eq" %2, %0 : i32
  %4 = llvm.lshr %arg52, %1 : i32
  %5 = llvm.and %4, %1 : i32
  %6 = "llvm.select"(%3, %5, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

abbrev Index := ℕ

def ashrsgt_02_03_exact_before := [llvm|
{
^0(%arg82 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(3 : i4) : i4
  %2 = llvm.ashr exact %arg82, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def one_inst_concrete_macro_proof :
    one_inst_concrete_macro ⊑ one_inst_concrete_macro :=

def or_logic_or_logic_and_8_after := [llvm|
{
^0(%arg27 : i1, %arg28 : i1, %arg29 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg29, %arg28, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.or %arg27, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def ashr_llvm_exact_flag_8 := [LV| {
  ^entry (%x: i8, %amount: i8):
    %1 = llvm.ashr exact %x, %amount : i8
    llvm.return %1 : i8
  }]

def ashrsgt_03_00_before := [llvm|
{
^0(%arg285 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(0 : i4) : i4
  %2 = llvm.ashr %arg285, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrugt_01_07_exact_after := [llvm|
{
^0(%arg214 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

@[simp_denote] def add {Γ : Ctxt _} (e₁ e₂ : Var Γ .int) : Expr ScfArith Γ .pure .int :=
  Expr.mk
    (op := .coe <| .add)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := .nil)

def Com.changeEffect {eff₁ eff₂ : EffectKind} (h : eff₁ ≤ eff₂) :
    Com d Γ eff₁ t → Com d Γ eff₂ t := fun com =>
  Com.rec' (motive := @fun Γ _ => eff₁ ≤ eff₂ → Com d Γ eff₂ t)
            (fun v _h               => rets v)
      (fun e _body castBody h => var (e.changeEffect h) (castBody h))
    com h

def reassoc_x2_add_nuw_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.add %arg20, %0 overflow<nuw> : i32
  %3 = llvm.add %arg21, %1 overflow<nuw> : i32
  %4 = llvm.add %2, %3 overflow<nuw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def neg_nsw_slt_0_after := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "sgt" %arg20, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def not_and_and_or_no_or_commute2_and_after := [llvm|
{
^0(%arg157 : i32, %arg158 : i32, %arg159 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg157, %0 : i32
  %2 = llvm.xor %arg158, %0 : i32
  %3 = llvm.or %arg159, %2 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def logical_and_cond_reuse_after := [llvm|
{
^0(%arg258 : i1, %arg259 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg258, %arg259, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg309 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.and %arg309, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def ashr_can_be_lshr_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.ashr exact %arg1, %0 : i32
  %2 = llvm.trunc %1 overflow<nsw> : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def ugt_swap_or_not_min_logical_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg4, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def irc_constants_C1Minus2MinusC2_neg2_neg2 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (-2) : i64
      %0 = llvm.sub %c1, %a : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (-2) : i64
      %c2 = llvm.mlir.constant (-2) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.sub %0, %a : i64
      llvm.return %1 : i64
  }]

def trunc_shl_15_i16_i64_before := [llvm|
{
^0(%arg39 : i64):
  %0 = llvm.mlir.constant(15) : i64
  %1 = llvm.shl %arg39, %0 : i64
  %2 = llvm.trunc %1 : i64 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def select_icmp_ne_pow2_before := [llvm|
{
^0(%arg10 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg10, %0 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  %4 = llvm.xor %arg10, %0 : i8
  %5 = "llvm.select"(%3, %4, %arg10) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def test_negative_nuw_and_signed_pred_before := [llvm|
{
^0(%arg53 : i64):
  %0 = llvm.mlir.constant(10) : i64
  %1 = llvm.mlir.constant(3) : i64
  %2 = llvm.sub %0, %arg53 overflow<nuw> : i64
  %3 = llvm.icmp "slt" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

def exact_ashr_ne_both_equal_before := [llvm|
{
^0(%arg167 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.ashr exact %0, %arg167 : i8
  %2 = llvm.icmp "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def icmp_slt_0_and_icmp_sge_neg1_i64_fail_after := [llvm|
{
^0(%arg59 : i64):
  %0 = llvm.mlir.constant(-2) : i64
  %1 = llvm.mlir.constant(62) : i64
  %2 = llvm.mlir.constant(1) : i64
  %3 = llvm.mlir.constant(0) : i64
  %4 = llvm.icmp "sgt" %arg59, %0 : i64
  %5 = llvm.lshr %arg59, %1 : i64
  %6 = llvm.and %5, %2 : i64
  %7 = "llvm.select"(%4, %6, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%7) : (i64) -> ()
}
]

def lshrult_03_05_exact_after := [llvm|
{
^0(%arg112 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def invert_both_cmp_operands_sub_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(-43 : i32) : i32
  %1 = llvm.add %arg36, %arg37 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def slt_swap_or_not_max_commute_logical_after := [llvm|
{
^0(%arg48 : i8, %arg49 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "ne" %arg48, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def icmp_slt_0_and_icmp_ne_neg2_i32_fail_before := [llvm|
{
^0(%arg44 : i32):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.icmp "ne" %arg44, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.lshr %arg44, %1 : i32
  %5 = llvm.and %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

@[simp]
def eval : Circuit α → (α → Bool) → Bool
  | tru, _ => true
  | fals, _ => false
  | var b x, f => if b then f x else !(f x)
  | and c₁ c₂, f => (eval c₁ f) && (eval c₂ f)
  | or c₁ c₂, f => (eval c₁ f) || (eval c₂ f)
  | xor c₁ c₂, f => Bool.xor (eval c₁ f) (eval c₂ f)

def select_icmp_ne_0_and_8_or_1073741824_after := [llvm|
{
^0(%arg189 : i8, %arg190 : i32):
  %0 = llvm.mlir.constant(8 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(1073741824 : i32) : i32
  %3 = llvm.and %arg189, %0 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  %5 = llvm.or %arg190, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg190) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def trunc_lshr_zext_exact_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.lshr %arg11, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test2_before := [llvm|
{
^0(%arg0 : i999, %arg1 : i999):
  %0 = llvm.mlir.constant(65280 : i999) : i999
  %1 = llvm.and %arg0, %0 : i999
  %2 = llvm.and %arg1, %0 : i999
  %3 = llvm.icmp "ne" %1, %2 : i999
  "llvm.return"(%3) : (i1) -> ()
}
]

def Body.return : (body : Body Op Γ ty) → Var body.returnContext ty
  | ⟨⟨_, ret⟩, h⟩ => ⟨ret, by admit /- proof elided -/
  ⟩

def sll_i32_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := sll_llvm_i64
  rhs := sll_riscv_i64

def pr40493_neg1_before := [llvm|
{
^0(%arg17 : i32):
  %0 = llvm.mlir.constant(11 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.mul %arg17, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def shl_bad_sub_i64_before := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(67) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.sub %0, %arg7 : i64
  %3 = llvm.shl %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def main14_logical_before := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.mlir.constant(2 : i32) : i32
  %4 = llvm.mlir.constant(1 : i32) : i32
  %5 = llvm.trunc %arg15 : i32 to i16
  %6 = llvm.icmp "sge" %5, %0 : i16
  %7 = llvm.trunc %arg15 : i32 to i8
  %8 = llvm.icmp "sge" %7, %1 : i8
  %9 = "llvm.select"(%6, %8, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %10 = "llvm.select"(%9, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%10) : (i32) -> ()
}
]

def test_shl__nuw_is_safe_before := [llvm|
{
^0(%arg76 : i32, %arg77 : i64):
  %0 = llvm.mlir.constant(1073741822 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg76, %0 : i32
  %4 = llvm.shl %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg77, %5 : i64
  %8 = "llvm.select"(%6, %arg77, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

def ashrslt_02_01_exact_before := [llvm|
{
^0(%arg36 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.ashr exact %arg36, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.icmp "slt" %arg14, %arg15 : i32
  %1 = llvm.zext %0 : i1 to i32
  %2 = llvm.icmp "sgt" %arg14, %arg15 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.trunc %4 : i32 to i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def n2_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.shl %0, %arg1 overflow<nsw> : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.and %arg0, %4 : i8
  %6 = llvm.icmp "eq" %5, %2 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def llvm_trunc_riscv_32_to_8_nuw_nsw : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 32)] :=
  {lhs:= trunc_llvm_32_to_8_nsw_nuw, rhs:= trunc_riscv_32_to_8_nsw_nuw}

instance : DecidableNFA' (NFA'.autMsbSet) where

def src_x_and_nmask_slt_fail_maybe_z_after := [llvm|
{
^0(%arg14 : i8, %arg15 : i8, %arg16 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg15 overflow<nsw> : i8
  %3 = "llvm.select"(%arg16, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.and %arg14, %3 : i8
  %5 = llvm.icmp "slt" %4, %3 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def t0_after := [llvm|
{
^0(%arg12 : i16):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.sext %arg12 : i16 to i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def select_icmp_eq_0_and_1_or_1_before := [llvm|
{
^0(%arg217 : i64, %arg218 : i32):
  %0 = llvm.mlir.constant(1) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg217, %0 : i64
  %4 = llvm.icmp "eq" %3, %1 : i64
  %5 = llvm.or %arg218, %2 : i32
  %6 = "llvm.select"(%4, %arg218, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def compose [FinEnum arity] [DecidableEq arity] [Hashable arity]
    (new_arity : Type)        
    (q_arity : arity → Type)  
    (vars : ∀ (a : arity), q_arity a → new_arity)
    
    
    (q : ∀ (a : arity), FSM (q_arity a)) : 
    FSM new_arity :=
  { α := p.α ⊕ (Σ a, (q a).α),
    i := by admit /- proof elided -/

def bools_logical_commute1_and2_after := [llvm|
{
^0(%arg91 : i1, %arg92 : i1, %arg93 : i1):
  %0 = "llvm.select"(%arg93, %arg92, %arg91) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def mkEqRflNativeDecideProof (lhsExpr : Expr) (rhs : Bool) : TermElabM Expr := do
    
  let auxDeclName ← Term.mkAuxName `_mkEqRflNativeDecideProof
  let decl := Declaration.defnDecl {
    name := auxDeclName
    levelParams := []
    type := mkConst ``Bool
    value := lhsExpr
    hints := .abbrev
    safety := .safe
  }
  addAndCompile decl
  let lhsDef : Expr := mkConst auxDeclName
  let rflProof ← mkEqRefl (toExpr rhs)
  mkAppM ``Lean.ofReduceBool #[lhsDef, toExpr rhs, rflProof]

def scalar_i32_shl_ult_const_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(2097088 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg15, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashrsgt_01_10_exact_before := [llvm|
{
^0(%arg91 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-6 : i4) : i4
  %2 = llvm.ashr exact %arg91, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def eq_umin3_before := [llvm|
{
^0(%arg56 : i32, %arg57 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg56, %0 : i32
  %2 = llvm.icmp "ult" %1, %arg57 : i32
  %3 = "llvm.select"(%2, %1, %arg57) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "eq" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def ex1_pre_cse : Com Ex ∅ .pure [.nat] :=
  Com.var (cst 1) <|
  Com.var (cst 1) <|
  Com.var (add ⟨0, rfl⟩ ⟨1, rfl⟩) <|
  Com.ret ⟨0, rfl⟩

def icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_before := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.mlir.constant(31 : i32) : i32
  %3 = llvm.add %arg38, %0 : i32
  %4 = llvm.icmp "sge" %3, %1 : i32
  %5 = llvm.zext %4 : i1 to i32
  %6 = llvm.lshr %arg38, %2 : i32
  %7 = llvm.or %6, %5 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def Expr.KInductionCircuits.mkN (fsm : Expr) (n : Expr) : MetaM Expr :=
  mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkN #[fsm, n]

def test_shl_nsw__nsw_is_safe_after := [llvm|
{
^0(%arg73 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.or %arg73, %0 : i32
  %3 = llvm.shl %2, %1 overflow<nsw> : i32
  %4 = llvm.mul %3, %2 : i32
  %5 = llvm.mul %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def neg_not_signbit2_before := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg4, %0 : i8
  %3 = llvm.zext %2 : i8 to i32
  %4 = llvm.sub %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def uaddo_commute4_before := [llvm|
{
^0(%arg22 : i32, %arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg23, %0 : i32
  %2 = llvm.add %arg23, %arg22 : i32
  %3 = llvm.icmp "ult" %1, %arg22 : i32
  %4 = "llvm.select"(%3, %arg24, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def or_eq_notY_eq_0_before := [llvm|
{
^0(%arg45 : i8, %arg46 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg46, %0 : i8
  %2 = llvm.or %arg45, %1 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_ashr_not_after := [llvm|
{
^0(%arg54 : i8, %arg55 : i8, %arg56 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg55, %0 : i8
  %2 = llvm.or %arg54, %1 : i8
  %3 = llvm.ashr %2, %arg56 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def inf : EffectKind → EffectKind → EffectKind
  | .impure, .impure => .impure
  | _, _ => .pure

def logic_or_logic_and_7_after := [llvm|
{
^0(%arg69 : i1, %arg70 : i1, %arg71 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg71, %arg70, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%2, %1, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_sub_nsw__all_are_safe_before := [llvm|
{
^0(%arg29 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.mlir.constant(-254 : i32) : i32
  %3 = llvm.mlir.constant(-260 : i32) : i32
  %4 = llvm.and %arg29, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.sub %2, %4 overflow<nsw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def icmp_eq_x_invertable_y2_before := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg3, %0 : i8
  %2 = llvm.and %arg2, %1 : i8
  %3 = llvm.icmp "eq" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def EnvFin.getAll1 (n : Nat) : { envs : List (EnvFin 1 n) // ∀ (envFin : EnvFin 1 n), envFin ∈ envs } :=
  match hn : n with
  | 0 => ⟨[fun i => i.elim0], by admit /- proof elided -/
  ⟩
  | n' + 1 =>
     let ⟨envs, henvs⟩ := EnvFin.getAll1 n'
     let out := envs.flatMap (fun env => [env.cons (BitVec.ofBool false), env.cons (BitVec.ofBool true)])
     ⟨out, by admit /- proof elided -/
     ⟩

def fold_sext_to_and2_after := [llvm|
{
^0(%arg15 : i8):
  %0 = llvm.mlir.constant(-126 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.and %arg15, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrult_01_10_after := [llvm|
{
^0(%arg357 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ashrsgt_03_13_exact_after := [llvm|
{
^0(%arg56 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def and_two_ranges_to_mask_and_range_no_add_on_one_range_before := [llvm|
{
^0(%arg249 : i16):
  %0 = llvm.mlir.constant(12 : i16) : i16
  %1 = llvm.mlir.constant(16 : i16) : i16
  %2 = llvm.mlir.constant(28 : i16) : i16
  %3 = llvm.icmp "uge" %arg249, %0 : i16
  %4 = llvm.icmp "ult" %arg249, %1 : i16
  %5 = llvm.icmp "uge" %arg249, %2 : i16
  %6 = llvm.or %4, %5 : i1
  %7 = llvm.and %3, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical_after := [llvm|
{
^0(%arg49 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg49, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def reflectTermCoeff (e : Expr) : M Int :=
  match_expr e with
  | BitVec.ofInt _w i => do
    let .some i := Expr.int? i
      | throwError "Expected 'BitVec.ofInt w <constant int>' at '{e}', found {i}"
    return i
  | Int.cast _ _ i => do
    let .some i := Expr.int? i
      | throwError "Expected Int.cast <constant int>' at '{indentD e}', found {i}"
    return i
  | _ => throwError "unable to reflect term coefficient '{indentD e}'. Expected an integer."

def Expr.KInductionCircuits.mkMkSafetyCircuit (circs : Expr) : MetaM Expr :=
  mkAppM ``ReflectVerif.BvDecide.KInductionCircuits.mkSafetyCircuit #[circs]

def shift_xor_multiuse_cmp_or_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32, %arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg36, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg37, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg37) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg39, %arg38) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

def add_smax_simplify_before := [llvm|
{
^0(%arg25 : i8):
  %0 = llvm.mlir.constant(126 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.add %arg25, %0 overflow<nsw> : i8
  %3 = llvm.icmp "sgt" %2, %1 : i8
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def sgt_and_min_logical_after := [llvm|
{
^0(%arg350 : i9, %arg351 : i9):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def and_xor_common_op_commute1_after := [llvm|
{
^0(%arg693 : i32, %arg694 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(43 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.udiv %0, %arg693 : i32
  %4 = llvm.udiv %1, %arg694 : i32
  %5 = llvm.xor %4, %2 : i32
  %6 = llvm.and %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def both_sides_fold_slt_after := [llvm|
{
^0(%arg39 : i32, %arg40 : i1):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def xor_nosignbit_select_shl_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg36, %0 : i32
  %3 = llvm.xor %2, %1 : i32
  %4 = "llvm.select"(%arg37, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test9_before := [llvm|
{
^0(%arg87 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.and %arg87, %0 : i32
  %2 = llvm.trunc %1 : i32 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def t2_before := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg11 overflow<nsw> : i8
  %2 = llvm.icmp "slt" %1, %arg11 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def same_signbit_wrong_type_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i32):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.lshr %arg34, %0 : i8
  %3 = llvm.icmp "sgt" %arg35, %1 : i32
  %4 = llvm.zext %3 : i1 to i8
  %5 = llvm.icmp "ne" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def lshrult_03_02_exact_after := [llvm|
{
^0(%arg115 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def not_is_canonical_after := [llvm|
{
^0(%arg87 : i32, %arg88 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.xor %arg87, %0 : i32
  %3 = llvm.add %arg88, %2 : i32
  %4 = llvm.shl %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def scalar_i32_lshr_and_negC_eq_X_is_constant1_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(12345 : i32) : i32
  %1 = llvm.mlir.constant(-8 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.lshr %0, %arg9 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

@[simp_denote]
def sext_llvm_i16_to_32 := [LV| {
  ^entry (%arg: i16):
    %0 = llvm.sext %arg: i16 to i32
    llvm.return %0: i32
  }]

def test6_after := [llvm|
{
^0(%arg1 : i7):
  "llvm.return"(%arg1) : (i7) -> ()
}
]

def shrink_select_before := [llvm|
{
^0(%arg52 : i1, %arg53 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = "llvm.select"(%arg52, %arg53, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.trunc %1 : i32 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def lshr_or_or_no_const_after := [llvm|
{
^0(%arg142 : i8, %arg143 : i8, %arg144 : i8, %arg145 : i8):
  %0 = llvm.or %arg143, %arg142 : i8
  %1 = llvm.lshr %0, %arg144 : i8
  %2 = llvm.or %1, %arg145 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_7_logical_before := [llvm|
{
^0(%arg55 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(8 : i32) : i32
  %4 = llvm.mlir.constant(true) : i1
  %5 = llvm.and %arg55, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %arg55, %2 : i32
  %8 = llvm.icmp "ne" %7, %3 : i32
  %9 = "llvm.select"(%6, %4, %8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def mul_add_to_mul_3_before := [llvm|
{
^0(%arg30 : i16):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.mlir.constant(3 : i16) : i16
  %2 = llvm.mul %arg30, %0 : i16
  %3 = llvm.mul %arg30, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def ne_smax4_before := [llvm|
{
^0(%arg41 : i32, %arg42 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg41, %0 : i32
  %2 = llvm.icmp "sgt" %arg42, %1 : i32
  %3 = "llvm.select"(%2, %arg42, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def xor_icmp_to_ne_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.icmp "sgt" %arg6, %0 : i32
  %3 = llvm.icmp "slt" %arg6, %1 : i32
  %4 = llvm.xor %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def icmp_ne_zext_ne_non_boolean_after := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "ne" %arg33, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def multiuse_shl_shl_after := [llvm|
{
^0(%arg36 : i42):
  %0 = llvm.mlir.constant(8 : i42) : i42
  %1 = llvm.mlir.constant(17 : i42) : i42
  %2 = llvm.shl %arg36, %0 : i42
  %3 = llvm.shl %arg36, %1 : i42
  %4 = llvm.mul %2, %3 : i42
  "llvm.return"(%4) : (i42) -> ()
}
]

def test13_before := [llvm|
{
^0(%arg288 : i32, %arg289 : i32):
  %0 = llvm.icmp "ult" %arg288, %arg289 : i32
  %1 = llvm.icmp "ugt" %arg288, %arg289 : i32
  %2 = llvm.and %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def add_shl_moreOneUse_sh4add_riscv := [LV| {
    ^entry (%a: i64):
    %a0 = "builtin.unrealized_conversion_cast" (%a) : (i64) -> (!i64)
    %0 = ori %a0, 1 : !i64
    %1 = slli %a0, 4 : !i64
    %2 = ori %1, 16 : !i64
    %3 = add %2, %0 : !i64
    %4 = "builtin.unrealized_conversion_cast" (%3) : (!i64) -> (i64)
    llvm.return %4 : i64
  }]

def positive_biggerashr_shlnsw_before := [llvm|
{
^0(%arg50 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.ashr %arg50, %0 : i8
  %3 = llvm.shl %2, %1 overflow<nsw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

@[match_pattern] abbrev sub (w : Nat) (flags: NoWrapFlags := {}) : LLVM.Op := MOp.sub (.concrete w) flags

def ashr_slt_exact_after := [llvm|
{
^0(%arg165 : i8):
  %0 = llvm.mlir.constant(80 : i8) : i8
  %1 = llvm.icmp "slt" %arg165, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

@[simp]
def instantiate_ofNat_eq (as : List.Vector Nat φ) (x : Nat) :
   ConcreteOrMVar.instantiate as (OfNat.ofNat x) = x := rfl

@[simp_llvm]
def add? {w : Nat} (x y : BitVec w) : IntW w :=
  .value <| x + y

def select_xor_inv_icmp_before := [llvm|
{
^0(%arg266 : i32, %arg267 : i32, %arg268 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg266, %0 : i32
  %2 = llvm.xor %arg268, %arg266 : i32
  %3 = "llvm.select"(%1, %2, %arg267) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def n10_before := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.lshr %arg0, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.sub %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

instance : DecidableEq VarName :=

def lshrult_03_07_before := [llvm|
{
^0(%arg328 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr %arg328, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def buggy_ISEL_pattern : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= original_sdiv_srem
  rhs:= combined_sdiv_srem
  correct := by admit /- proof elided -/

def select_icmp_eq_and_1_0_lshr_fv_after := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.shl %arg2, %0 : i8
  %3 = llvm.and %2, %1 : i8
  %4 = llvm.lshr %arg3, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

@[simp_denote]
def trunc_llvm_64_to_32_nuw := [LV| {
  ^entry (%lhs: i64):
    %0 = llvm.trunc %lhs overflow<nuw> : i64 to i32
    llvm.return %0 : i32
  }]

def test_shift_negative_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test1_before := [llvm|
{
^0(%arg10 : i32, %arg11 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg10, %0 : i32
  %3 = llvm.and %arg11, %1 : i32
  %4 = llvm.or %2, %3 : i32
  %5 = llvm.and %4, %0 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def one_side_fold_slt_after := [llvm|
{
^0(%arg33 : i32, %arg34 : i32, %arg35 : i32, %arg36 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "slt" %arg34, %arg33 : i32
  %2 = "llvm.select"(%arg36, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def negative3_logical_before := [llvm|
{
^0(%arg8 : i32, %arg9 : i32, %arg10 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.and %arg10, %0 : i32
  %4 = llvm.icmp "slt" %arg8, %3 : i32
  %5 = llvm.icmp "sge" %arg9, %1 : i32
  %6 = "llvm.select"(%4, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def main4e_like_logical_after := [llvm|
{
^0(%arg125 : i32, %arg126 : i32, %arg127 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg125, %arg126 : i32
  %2 = llvm.icmp "ne" %1, %arg126 : i32
  %3 = llvm.and %arg125, %arg127 : i32
  %4 = llvm.icmp "ne" %3, %arg127 : i32
  %5 = "llvm.select"(%2, %0, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def or_eq_with_one_bit_diff_constants1_logical_before := [llvm|
{
^0(%arg365 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(51 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "eq" %arg365, %0 : i32
  %4 = llvm.icmp "eq" %arg365, %1 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

@[simp_denote]
def and_llvm_i16:= [LV| {
    ^entry (%a: i16,%b: i16 ):
    %0 = llvm.and %a, %b : i16
    llvm.return %0 :i16
  }]

def t0_basic_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.icmp "ugt" %arg25, %arg24 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def DialectMorphism.preserves_sig (op : d.Op) :
    DialectSignature.sig (f.mapOp op) = (DialectSignature.sig op).map f.mapTy :=

def select_icmp_ne_0_and_4096_or_4096_after := [llvm|
{
^0(%arg233 : i32, %arg234 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg233, %0 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg234, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def t2_symmetry_after := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg37, %0 : i8
  %2 = llvm.icmp "ule" %arg38, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def test6a_before := [llvm|
{
^0(%arg1 : i1):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.zext %arg1 : i1 to i32
  %2 = llvm.icmp "ne" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def function : Parser :=
  leading_parser argumentList >> arrow >> termParser

def closed_set (M : NFA α σ) (S : Set σ) := M.start ⊆ S ∧ ∀ a, M.stepSet S a ⊆ S

def positive_biggershl_shlnuw_after := [llvm|
{
^0(%arg54 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(-64 : i8) : i8
  %2 = llvm.shl %arg54, %0 overflow<nuw> : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def ashrsgt_01_01_exact_before := [llvm|
{
^0(%arg100 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.ashr exact %arg100, %0 : i4
  %2 = llvm.icmp "sgt" %1, %0 : i4
  "llvm.return"(%2) : (i1) -> ()
}
]

def negate_sext_before := [llvm|
{
^0(%arg98 : i8, %arg99 : i1):
  %0 = llvm.sext %arg99 : i1 to i8
  %1 = llvm.sub %arg98, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def dec_mask_neg_i32_after := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.add %arg7, %0 : i32
  %2 = llvm.xor %arg7, %0 : i32
  %3 = llvm.and %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def sle_swap_and_min_logical_after := [llvm|
{
^0(%arg212 : i8, %arg213 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "eq" %arg212, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def n5_after := [llvm|
{
^0(%arg9 : i8, %arg10 : i8, %arg11 : i8):
  "llvm.return"(%arg11) : (i8) -> ()
}
]

def icmp_eq_x_invertable_y_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.and %arg8, %arg9 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def test23_before := [llvm|
{
^0(%arg185 : i32, %arg186 : i32):
  %0 = llvm.xor %arg186, %arg185 : i32
  %1 = llvm.icmp "eq" %0, %arg185 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def uaddo_commute4_after := [llvm|
{
^0(%arg22 : i32, %arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg23, %0 : i32
  %2 = llvm.add %arg23, %arg22 : i32
  %3 = llvm.icmp "ugt" %arg22, %1 : i32
  %4 = "llvm.select"(%3, %arg24, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def ule_umax2_after := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.icmp "ule" %arg51, %arg50 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def t9_ashr_exact_flag_preservation_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.sub %0, %arg26 : i32
  %3 = llvm.ashr exact %arg25, %2 : i32
  %4 = llvm.add %arg26, %1 : i32
  %5 = llvm.ashr exact %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def shl_nsw_nuw_add_nsw_before := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.shl %0, %arg13 overflow<nsw,nuw> : i32
  %3 = llvm.add %2, %1 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def sle_swap_or_not_min_after := [llvm|
{
^0(%arg280 : i8, %arg281 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test7_before := [llvm|
{
^0(%arg16 : i77):
  %0 = llvm.mlir.constant(-1 : i77) : i77
  %1 = llvm.sub %0, %arg16 : i77
  "llvm.return"(%1) : (i77) -> ()
}
]

def and_and_logic_or_1_after := [llvm|
{
^0(%arg102 : i1, %arg103 : i1, %arg104 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg103, %0, %arg104) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.and %arg102, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def cmp_x_and_negp2_with_eq_before := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.and %arg4, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashrsgt_01_01_exact_before := [llvm|
{
^0(%arg100 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.ashr exact %arg100, %0 : i4
  %2 = llvm.icmp "sgt" %1, %0 : i4
  "llvm.return"(%2) : (i1) -> ()
}
]

def positive_sameconst_shlnuwnsw_lshrexact_after := [llvm|
{
^0(%arg26 : i8):
  "llvm.return"(%arg26) : (i8) -> ()
}
]

def n2_badmask_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg9, %0 : i32
  %2 = llvm.or %1, %arg6 : i32
  %3 = llvm.or %arg8, %arg7 : i32
  %4 = llvm.and %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def xor_signbit_select_lshr_before := [llvm|
{
^0(%arg22 : i32, %arg23 : i1):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.xor %arg22, %0 : i32
  %3 = "llvm.select"(%arg23, %2, %arg22) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.lshr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def llvm_freeze_lower_riscv_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := freeze_llvm_64
  rhs := freeze_riscv_64

def masked_icmps_mask_notallzeros_bmask_mixed_7b_after := [llvm|
{
^0(%arg76 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def lshr_exact_add_negative_shift_positive_after := [llvm|
{
^0(%arg56 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.lshr exact %0, %arg56 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

RV64.sh2add in RISCV.Instructions

def a_or_b_const_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i32, %arg12 : i32):
  %0 = llvm.icmp "eq" %arg10, %arg12 : i32
  %1 = llvm.icmp "eq" %arg11, %arg12 : i32
  %2 = llvm.xor %0, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

instance : DialectSignature RV64 where
  signature o := {sig := Op.sig o, returnTypes := [Op.outTy o], regSig := []}

def t6_ugt_sgt_65536_before := [llvm|
{
^0(%arg48 : i32, %arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.icmp "sgt" %arg48, %0 : i32
  %2 = "llvm.select"(%1, %arg50, %arg49) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.icmp "ugt" %arg48, %0 : i32
  %4 = "llvm.select"(%3, %2, %arg48) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def or_not_and_wrong_c_after := [llvm|
{
^0(%arg488 : i32, %arg489 : i32, %arg490 : i32, %arg491 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg488, %arg489 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg490, %2 : i32
  %4 = llvm.or %arg488, %arg491 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %arg489, %5 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def land_land_left2_before := [llvm|
{
^0(%arg100 : i1, %arg101 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg101, %arg100, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = "llvm.select"(%1, %arg100, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def expand_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.and %arg0, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = llvm.and %3, %0 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test3_logical_after := [llvm|
{
^0(%arg306 : i1):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ashrsgt_02_08_after := [llvm|
{
^0(%arg293 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def t20_before := [llvm|
{
^0(%arg145 : i8, %arg146 : i16):
  %0 = llvm.mlir.constant(-42 : i16) : i16
  %1 = llvm.shl %0, %arg146 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.sub %arg145, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def lshr_shl_pow2_const_case2_before := [llvm|
{
^0(%arg58 : i16):
  %0 = llvm.mlir.constant(8192 : i16) : i16
  %1 = llvm.mlir.constant(4 : i16) : i16
  %2 = llvm.mlir.constant(32 : i16) : i16
  %3 = llvm.lshr %0, %arg58 : i16
  %4 = llvm.shl %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

def test19_commutative0_before := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg74 : i32
  %2 = llvm.shl %0, %arg75 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.urem %arg75, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def not_signbit_trunc_after := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.icmp "sgt" %arg16, %0 : i16
  %2 = llvm.zext %1 : i1 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def xor_ashr_not_fail_invalid_xor_constant_after := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.xor %arg16, %arg15 : i8
  %2 = llvm.ashr %1, %arg17 : i8
  %3 = llvm.xor %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def no_shift_xor_multiuse_or_before := [llvm|
{
^0(%arg134 : i32, %arg135 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg134, %0 : i32
  %3 = llvm.icmp "ne" %1, %2 : i32
  %4 = llvm.or %arg135, %0 : i32
  %5 = "llvm.select"(%3, %arg135, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.mul %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def not_before := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.udiv %arg7, %0 : i8
  %3 = llvm.xor %1, %arg7 : i8
  %4 = llvm.mul %3, %2 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def lshrult_03_08_exact_after := [llvm|
{
^0(%arg109 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

elab "[HSxComb_com| " reg:mlir_region "]" : term => do
  SSA.elabIntoCom' reg HSxComb

Std.Tactic.BVDecide.BVLogicalExpr in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

def scalar_i32_lshr_and_negC_eq_X_is_constant2_after := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(25 : i32) : i32
  %1 = llvm.icmp "ugt" %arg8, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def slt_zero_sgt_minus1_after := [llvm|
{
^0(%arg22 : i4, %arg23 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.xor %arg22, %arg23 : i4
  %2 = llvm.icmp "sgt" %1, %0 : i4
  "llvm.return"(%2) : (i1) -> ()
}
]

def matchMulO: List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, mulo_by_2_unsigned_signed⟩,
  ⟨_, mulo_by_2_unsigned⟩,
  ⟨_, mulo_by_2_signed⟩]

def test4_logical_after := [llvm|
{
^0(%arg304 : i1):
  "llvm.return"(%arg304) : (i1) -> ()
}
]

def t7_twoshifts2_after := [llvm|
{
^0(%arg28 : i32, %arg29 : i32, %arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg29 overflow<nuw> : i32
  %3 = llvm.shl %arg30, %arg31 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def mul_to_shl_2 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (2) : i64
      %0 = llvm.mul %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (1) : i64
      %0 = llvm.shl %x, %c : i64
      llvm.return %0 : i64
  }]

def alive_Select_1105_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%Y : _, %X : _):
  %v1 = llvm.mlir.constant 0 :  i1
  %v2 = llvm.select %v1,%X, %Y
  llvm.return %v2
}]

@[simp_denote]
def xor_llvm_i32 := [LV| {
    ^entry (%a: i32, %b: i32):
    %0 = llvm.xor %a, %b : i32
    llvm.return %0 : i32
  }]

def _root_.Blase.dummy : Unit := ()

def ashrsgt_03_11_before := [llvm|
{
^0(%arg274 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-5 : i4) : i4
  %2 = llvm.ashr %arg274, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_xor_tree_1001_before := [llvm|
{
^0(%arg18 : i32, %arg19 : i32, %arg20 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg18, %0 : i32
  %2 = llvm.mul %arg19, %0 : i32
  %3 = llvm.mul %arg20, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.xor %2, %3 : i32
  %6 = llvm.xor %5, %1 : i32
  %7 = llvm.or %6, %4 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

partial def GenBVExpr.toSmtLib (bvExpr : GenBVExpr w)
      (vars : Std.HashMap Nat HydraVariable) (widthVals : Std.HashMap Nat HydraVariable) : SexprPBV.Term :=
    match bvExpr with
    | .var idx =>
       let varInfo := vars.getD idx default
       let widthIx := varInfo.width
       .var idx (.var widthIx) 
    | .const bv =>
        
        .ofNat (.var w) bv.toNat
    | .bin lhs op rhs =>
      
      let w := SexprPBV.WidthExpr.var w
      match op with
      | .add => SexprPBV.Term.add w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
      | .mul => SexprPBV.Term.mul w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
      | .umod => SexprPBV.Term.umod w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
      | .udiv => SexprPBV.Term.udiv w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
      | .and => SexprPBV.Term.band w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
      | .or  => SexprPBV.Term.bor w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
      | .xor  => SexprPBV.Term.bxor w
        (GenBVExpr.toSmtLib lhs vars widthVals)
        (GenBVExpr.toSmtLib rhs vars widthVals)
    | .un op operand =>
      
      let w := SexprPBV.WidthExpr.var w
      match op with
      | .not => SexprPBV.Term.bnot w (GenBVExpr.toSmtLib operand vars widthVals)
      | _ => .junk bvExpr.toString
    | .signExtend (w := w) v expr =>
          let var : GenBVExpr w := GenBVExpr.var widthVals[v]!.id
          SexprPBV.Term.sext (GenBVExpr.toSmtLib var vars widthVals) (SexprPBV.WidthExpr.var v)
    | .zeroExtend v expr =>
          let var : GenBVExpr w := GenBVExpr.var widthVals[v]!.id
      SexprPBV.Term.zext (GenBVExpr.toSmtLib var vars widthVals) (SexprPBV.WidthExpr.var v)
    | .truncate v expr =>
        let var : GenBVExpr w := GenBVExpr.var widthVals[v]!.id
      SexprPBV.Term.zext (GenBVExpr.toSmtLib var vars widthVals) (SexprPBV.WidthExpr.var v)
    | .shiftLeft _lhs _rhs =>
        .junk bvExpr.toString
    | .shiftRight _lhs _rhs =>
        .junk bvExpr.toString
    | .arithShiftRight _lhs _rhs =>
        .junk bvExpr.toString
    | _ => .junk bvExpr.toString

def and_or_not_not_commute7_after := [llvm|
{
^0(%arg354 : i32, %arg355 : i32, %arg356 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg356, %arg355 : i32
  %2 = llvm.and %1, %arg354 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def mul_of_bool_no_lz_other_op_after := [llvm|
{
^0(%arg85 : i32, %arg86 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def unmasked_shlop_insufficient_mask_shift_amount_after := [llvm|
{
^0(%arg14 : i16, %arg15 : i16, %arg16 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.mlir.constant(255 : i16) : i16
  %2 = llvm.mlir.constant(8 : i16) : i16
  %3 = llvm.and %arg16, %0 : i16
  %4 = llvm.and %arg14, %1 : i16
  %5 = llvm.sub %2, %3 overflow<nsw> : i16
  %6 = llvm.shl %arg15, %5 : i16
  %7 = llvm.lshr %4, %3 : i16
  %8 = llvm.or %6, %7 : i16
  %9 = llvm.trunc %8 : i16 to i8
  "llvm.return"(%9) : (i8) -> ()
}
]

def ult_swap_or_not_max_commute_logical_before := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg33, %arg32 : i8
  %3 = llvm.icmp "ne" %arg32, %0 : i8
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test6_after := [llvm|
{
^0(%arg204 : i8):
  "llvm.return"(%arg204) : (i8) -> ()
}
]

def fold_icmp_shl_nuw_c2_precondition2_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ashrslt_03_03_exact_before := [llvm|
{
^0(%arg18 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.ashr exact %arg18, %0 : i4
  %2 = llvm.icmp "slt" %1, %0 : i4
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def lshr_llvm_exact_64 := [LV| {
  ^entry (%x: i64, %amount: i64):
    %1 = llvm.lshr exact %x, %amount : i64
    llvm.return %1 : i64
  }]

def test13_after := [llvm|
{
^0(%arg40 : i1, %arg41 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg41, %0 : i1
  %2 = llvm.or %arg40, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def or_xor_common_op_commute7_before := [llvm|
{
^0(%arg114 : i8, %arg115 : i8, %arg116 : i8):
  %0 = llvm.or %arg115, %arg114 : i8
  %1 = llvm.xor %arg116, %arg114 : i8
  %2 = llvm.or %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def add_constant_equal_with_the_top_bit_of_demandedbits_pass_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.add %arg9, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ashr_lshr_shift_wrong_pred2_after := [llvm|
{
^0(%arg79 : i32, %arg80 : i32, %arg81 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.lshr %arg79, %arg80 : i32
  %2 = llvm.ashr %arg79, %arg80 : i32
  %3 = llvm.icmp "slt" %arg81, %0 : i32
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def shl_lshr_pow2_const_case1_after := [llvm|
{
^0(%arg80 : i16):
  %0 = llvm.mlir.constant(7 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.mlir.constant(0 : i16) : i16
  %3 = llvm.icmp "eq" %arg80, %0 : i16
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def positive_easyinvert_before := [llvm|
{
^0(%arg7 : i16, %arg8 : i8):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "slt" %arg7, %0 : i16
  %4 = llvm.icmp "slt" %arg8, %1 : i8
  %5 = llvm.xor %4, %3 : i1
  %6 = llvm.xor %5, %2 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def same_signbit_wrong_type_signed_after := [llvm|
{
^0(%arg14 : i8, %arg15 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.icmp "sgt" %arg15, %0 : i32
  %3 = llvm.icmp "slt" %arg14, %1 : i8
  %4 = llvm.xor %3, %2 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def uge_swap_and_max_commute_before := [llvm|
{
^0(%arg226 : i8, %arg227 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ule" %arg227, %arg226 : i8
  %2 = llvm.icmp "eq" %arg226, %0 : i8
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def logic_and_logic_or_8_before := [llvm|
{
^0(%arg156 : i1, %arg157 : i1, %arg158 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg156, %arg157, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg158, %arg156, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def not_or_or_and_no_and_commute1_or_before := [llvm|
{
^0(%arg118 : i32, %arg119 : i32, %arg120 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg119, %arg118 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.xor %arg118, %0 : i32
  %4 = llvm.or %arg120, %arg119 : i32
  %5 = llvm.or %4, %3 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def shl_nsw_add_negative_before := [llvm|
{
^0(%arg45 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.add %arg45, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def or_not_xor_common_op_commute7_after := [llvm|
{
^0(%arg86 : i8, %arg87 : i8, %arg88 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sub %0, %arg88 : i8
  %3 = llvm.and %arg87, %arg86 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def lshrult_03_09_before := [llvm|
{
^0(%arg326 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.lshr %arg326, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def t_1_10_before := [llvm|
{
^0(%arg13 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.icmp "ugt" %arg13, %0 : i8
  %3 = "llvm.select"(%2, %arg13, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.and %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def bools2_logical_commute0_and1_before := [llvm|
{
^0(%arg61 : i1, %arg62 : i1, %arg63 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg63, %0 : i1
  %3 = llvm.and %arg63, %arg61 : i1
  %4 = "llvm.select"(%2, %arg62, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = "llvm.select"(%3, %0, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def sle_smax3_after := [llvm|
{
^0(%arg51 : i32, %arg52 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg51, %0 : i32
  %2 = llvm.icmp "sle" %arg52, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def and_signbit_select_lshr_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16776960 : i32) : i32
  %2 = llvm.lshr %arg30, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = "llvm.select"(%arg31, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def Lets.ValidDenotation (lets : Lets d Γ_in eff Γ_out) :=
  { V // ∀ {t ts} {v : Var _ t} {w : Var ⟨ts⟩ t} {e} ,
          lets.getPureExpr v = some ⟨ts, w, e⟩
          → (e.pdenoteOp V)[w] = V v }

def test48_after := [llvm|
{
^0(%arg137 : i8, %arg138 : i8):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.zext %arg137 : i8 to i32
  %2 = llvm.shl %1, %0 overflow<nsw,nuw> : i32
  %3 = llvm.or disjoint %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def positive_sameconst_shlnsw_ashrexact_after := [llvm|
{
^0(%arg36 : i8):
  "llvm.return"(%arg36) : (i8) -> ()
}
]

Array.emptyWithCapacity in Init.Prelude

def select_sub_icmp_after := [llvm|
{
^0(%arg214 : i32, %arg215 : i32, %arg216 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg214, %0 : i32
  %2 = "llvm.select"(%1, %arg216, %arg215) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test82_after := [llvm|
{
^0(%arg64 : i64):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-512 : i32) : i32
  %2 = llvm.trunc %arg64 : i64 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def llvm_const_lower_riscv_li_30 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_30, rhs:= liRiscv_30,
   correct := by admit /- proof elided -/

def neg_not_signbit3_after := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.ashr %arg3, %0 : i8
  %3 = llvm.zext %2 : i8 to i32
  %4 = llvm.sub %1, %3 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def src_srem_shl_demand_min_signbit_mask_hit_last_demand_after := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(536870912 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(-1073741822 : i32) : i32
  %3 = llvm.srem %arg20, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw> : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def trunc_equality_nsw_zext_after := [llvm|
{
^0(%arg16 : i32, %arg17 : i8):
  %0 = llvm.zext %arg17 : i8 to i32
  %1 = llvm.icmp "ne" %arg16, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def irc_constants_AMinusC1PlusC2_2_neg1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %a, %c1 : i64
      %1 = llvm.add %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (-1) : i64
      %0 = llvm.sub %c2, %c1 : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]

def bitwise_or_logical_or_icmps_comm3_before := [llvm|
{
^0(%arg175 : i8, %arg176 : i8, %arg177 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mlir.constant(true) : i1
  %4 = llvm.icmp "eq" %arg176, %0 : i8
  %5 = llvm.and %arg175, %1 : i8
  %6 = llvm.shl %1, %arg177 : i8
  %7 = llvm.and %arg175, %6 : i8
  %8 = llvm.icmp "eq" %5, %2 : i8
  %9 = llvm.icmp "eq" %7, %2 : i8
  %10 = "llvm.select"(%8, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = llvm.or %9, %10 : i1
  "llvm.return"(%11) : (i1) -> ()
}
]

def constLLVM38 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (38) : i64
    llvm.return %1 : i64
  }]

def PR42691_8_after := [llvm|
{
^0(%arg329 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483635 : i32) : i32
  %2 = llvm.add %arg329, %0 : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_with_5_before := [llvm|
{
^0(%arg315 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.shl %0, %arg315 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def ashrsgt_03_01_after := [llvm|
{
^0(%arg284 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def squared_nsw_eq0_after := [llvm|
{
^0(%arg185 : i5):
  %0 = llvm.mlir.constant(0 : i5) : i5
  %1 = llvm.icmp "eq" %arg185, %0 : i5
  "llvm.return"(%1) : (i1) -> ()
}
]

def lshrult_03_10_after := [llvm|
{
^0(%arg325 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def ult_rem_zero_after := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.icmp "ult" %arg174, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def masked_or_allzeroes_notoptimised_logical_after := [llvm|
{
^0(%arg116 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(39 : i32) : i32
  %3 = llvm.and %arg116, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg116, %2 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.or %4, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def mul_add_to_mul_7_before := [llvm|
{
^0(%arg25 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.mul %arg25, %0 overflow<nsw> : i16
  %2 = llvm.add %arg25, %1 overflow<nsw> : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def land_land_right1_before := [llvm|
{
^0(%arg54 : i1, %arg55 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg54, %arg55, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = "llvm.select"(%arg54, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def neg_mask_before := [llvm|
{
^0(%arg1 : i32, %arg2 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.sext %arg2 : i16 to i32
  %3 = llvm.sub %arg1, %2 overflow<nsw> : i32
  %4 = llvm.lshr %arg2, %0 : i16
  %5 = llvm.zext %4 : i16 to i32
  %6 = llvm.sub %1, %5 overflow<nsw> : i32
  %7 = llvm.and %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def trunc_shl_ashr_infloop_before := [llvm|
{
^0(%arg21 : i64):
  %0 = llvm.mlir.constant(3) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = llvm.ashr %arg21, %0 : i64
  %3 = llvm.shl %2, %1 : i64
  %4 = llvm.trunc %3 : i64 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def irc_constants_APlusC1MinusC2_0_0 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (0) : i64
      %c2 = llvm.mlir.constant (0) : i64
      %0 = llvm.add %a, %c1 : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (0) : i64
      %c2 = llvm.mlir.constant (0) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.add %a, %0 : i64
      llvm.return %1 : i64
  }]

def not_and_and_or_no_or_after := [llvm|
{
^0(%arg163 : i32, %arg164 : i32, %arg165 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg163, %0 : i32
  %2 = llvm.xor %arg164, %0 : i32
  %3 = llvm.or %arg165, %2 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test6a_after := [llvm|
{
^0(%arg1 : i1):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def same_source_shifted_signbit_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.lshr %arg2, %0 : i32
  %2 = llvm.trunc %1 : i32 to i8
  %3 = llvm.sext %2 : i8 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def r : Com (.ofList [.nat, .nat]) .nat :=
  .var (add ⟨1, by admit /- proof elided -/
  ⟩ ⟨0, by admit /- proof elided -/
  ⟩) (.ret ⟨0, by admit /- proof elided -/
  ⟩)

def main5_like_logical_before := [llvm|
{
^0(%arg111 : i32, %arg112 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg111, %0 : i32
  %5 = llvm.icmp "eq" %4, %0 : i32
  %6 = llvm.and %arg112, %0 : i32
  %7 = llvm.icmp "eq" %6, %0 : i32
  %8 = "llvm.select"(%5, %7, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %9 = "llvm.select"(%8, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

def p0_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.lshr %arg28, %arg29 : i8
  %2 = llvm.icmp "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

@[simp_denote]
def add_llvm_nsw_flags_8 := [LV| {
  ^entry (%lhs: i8, %rhs: i8):
    %1 = llvm.add %lhs, %rhs overflow<nsw> : i8
    llvm.return %1 : i8
  }]

Sum.inr in Init.Core

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical_before := [llvm|
{
^0(%arg49 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.mlir.constant(false) : i1
  %5 = llvm.and %arg49, %0 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %arg49, %2 : i32
  %8 = llvm.icmp "eq" %7, %3 : i32
  %9 = "llvm.select"(%8, %6, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def PR30273_three_bools_after := [llvm|
{
^0(%arg41 : i1, %arg42 : i1, %arg43 : i1):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.zext %arg41 : i1 to i32
  %3 = "llvm.select"(%arg41, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = "llvm.select"(%arg42, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.zext %arg43 : i1 to i32
  %6 = llvm.add %4, %5 overflow<nsw,nuw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def add_const_const_sub_nsw_after := [llvm|
{
^0(%arg58 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.sub %0, %arg58 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def t1_ult_slt_0_after := [llvm|
{
^0(%arg63 : i32, %arg64 : i32, %arg65 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.icmp "slt" %arg63, %0 : i32
  %3 = llvm.icmp "sgt" %arg63, %1 : i32
  %4 = "llvm.select"(%2, %arg64, %arg63) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = "llvm.select"(%3, %arg65, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

@[simp_denote]
def andi_llvm := [LV| {
    ^entry (%a: i16):
    %0 = llvm.mlir.constant (6) : i16
    %1 = llvm.and %a, %0 : i16
    llvm.return %1 :i16
  }]

def positive_biggerShl_before := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.shl %arg34, %0 : i32
  %3 = llvm.lshr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def src_x_and_nmask_uge_before := [llvm|
{
^0(%arg21 : i8, %arg22 : i8, %arg23 : i1):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg22 : i8
  %3 = "llvm.select"(%arg23, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.and %arg21, %3 : i8
  %5 = llvm.icmp "uge" %4, %3 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

inductive Op
| fst
| snd
| pair (w : Nat)
| fstVal (w : Nat)
| sndVal (w : Nat)
| fstVal' (w : Nat)
| sndVal' (w : Nat)
| tokVal' (w : Nat)
| merge
| branch
| fork
| join
| select
| sink
| source
| pack (w : Nat)
| pack2 (w : Nat)
| unpack (w : Nat)
| unpack2 (w : Nat)
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

def orcond.010.inv.inner.cond.in.inner.sel_after := [llvm|
{
^0(%arg60 : i1, %arg61 : i1, %arg62 : i1, %arg63 : i1, %arg64 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg61, %0, %arg64) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = "llvm.select"(%arg60, %arg62, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def ashrsgt_02_07_after := [llvm|
{
^0(%arg294 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def canonicalize_logic_first_and0_before := [llvm|
{
^0(%arg28 : i8):
  %0 = llvm.mlir.constant(48 : i8) : i8
  %1 = llvm.mlir.constant(-10 : i8) : i8
  %2 = llvm.add %arg28, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def or_eq_notY_eq_0_after := [llvm|
{
^0(%arg45 : i8, %arg46 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.and %arg45, %arg46 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def ult_swap_or_not_max_logical_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg37, %arg36 : i8
  %3 = llvm.icmp "ne" %arg36, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def simplify_and_common_op_commute2_after := [llvm|
{
^0(%arg25 : i4, %arg26 : i4, %arg27 : i4, %arg28 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  "llvm.return"(%0) : (i4) -> ()
}
]

def test82_before := [llvm|
{
^0(%arg64 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.trunc %arg64 : i64 to i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.shl %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def counterDecorator (δ : Int) (f : LoopBody α) : Int × α → Int × α :=
  fun (i, v) => (i + δ, f i v)

def ashr_mul_after := [llvm|
{
^0(%arg99 : i8, %arg100 : i8):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.sext %arg99 : i8 to i16
  %2 = llvm.sext %arg100 : i8 to i16
  %3 = llvm.mul %1, %2 overflow<nsw> : i16
  %4 = llvm.ashr %3, %0 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

Language.instMembershipList in Mathlib.Computability.Language

def lowmask_add_2_before := [llvm|
{
^0(%arg144 : i8):
  %0 = llvm.mlir.constant(-64 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.add %arg144, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def findExprBitwidths (target : Expr) : MetaM WidthToExprMap := do
  let (_, out) ← StateT.run (go target) ∅
  return out
  where
    go (target : Expr) : StateT WidthToExprMap MetaM Unit := do
      
      forEachExpr target fun e => do
        match_expr ← inferType e with
        | BitVec n =>
          
          modify (fun arr => arr.insert n.cleanupAnnotations e)
        | _ => return ()

def mkReturn (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) : MLIR.AST.ReaderM (Handshake)
    (Σ eff ty, Com Handshake Γ eff ty) :=
  if opStx.name == "return"
  then match opStx.args with
  | vStx::[] => do
    let ⟨ty, v⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ vStx
    return ⟨.pure, [ty], Com.ret v⟩
  | _ => throw <| .generic s!"Ill-formed return statement (wrong arity, expected 1, got {opStx.args.length})"
  else throw <| .generic s!"Tried to build return out of non-return statement {opStx.name}"

def ashr_mul_times_3_div_2_exact_before := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mul %arg21, %0 overflow<nsw> : i32
  %3 = llvm.ashr exact %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def llvm_const_lower_riscv_li47 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM47, rhs:= liRiscv47,
   correct := by admit /- proof elided -/

def select_icmp_ne_0_and_1073741824_and_not_8_after := [llvm|
{
^0(%arg191 : i32, %arg192 : i8):
  %0 = llvm.mlir.constant(1073741824 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-9 : i8) : i8
  %3 = llvm.and %arg191, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg192, %2 : i8
  %6 = "llvm.select"(%4, %5, %arg192) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def ashrslt_03_06_exact_before := [llvm|
{
^0(%arg15 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.ashr exact %arg15, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def lshrugt_01_11_exact_after := [llvm|
{
^0(%arg210 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def uadd_sat_flipped_wrong_bounds7_after := [llvm|
{
^0(%arg90 : i32):
  %0 = llvm.mlir.constant(-11 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.icmp "ult" %arg90, %0 : i32
  %4 = llvm.add %arg90, %1 : i32
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def test48_before := [llvm|
{
^0(%arg137 : i8, %arg138 : i8):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.zext %arg138 : i8 to i32
  %2 = llvm.zext %arg137 : i8 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.or %3, %2 : i32
  %5 = llvm.zext %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def mul_add_to_mul_7_before := [llvm|
{
^0(%arg25 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.mul %arg25, %0 overflow<nsw> : i16
  %2 = llvm.add %arg25, %1 overflow<nsw> : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def lshrugt_01_07_exact_before := [llvm|
{
^0(%arg214 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr exact %arg214, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def add_select_not_zext_after := [llvm|
{
^0(%arg27 : i1):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = "llvm.select"(%arg27, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def test12commuted_after := [llvm|
{
^0(%arg87 : i32, %arg88 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg87, %arg88 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def ashrslt_01_13_exact_before := [llvm|
{
^0(%arg40 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-3 : i4) : i4
  %2 = llvm.ashr exact %arg40, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def land_lor_right1_after := [llvm|
{
^0(%arg46 : i1, %arg47 : i1):
  "llvm.return"(%arg46) : (i1) -> ()
}
]

def icmp_slt_sext_ne_zero_nofold_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "ne" %arg5, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.icmp "slt" %2, %arg5 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashrsgt_01_08_after := [llvm|
{
^0(%arg309 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def icmp_eq_sext_ne_otherwise_before := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.icmp "ne" %arg14, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.icmp "eq" %2, %arg14 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def ult_swap_and_max_commute_before := [llvm|
{
^0(%arg356 : i8, %arg357 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ugt" %arg357, %arg356 : i8
  %2 = llvm.icmp "eq" %arg356, %0 : i8
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

Coe in Init.Coe
</all_available_defs>

<all_available_lemmas>
Array.mem_push in Init.Data.Array.Lemmas
Array.mem_toList_iff in Init.Data.Array.Lemmas
Array.toList_push in Init.Data.Array.Bootstrap
Function.Injective2.eq_iff in Mathlib.Logic.Function.Basic
List.Nodup.append in Mathlib.Data.List.Nodup
List.append_assoc in Init.Data.List.Basic
List.disjoint_singleton in Batteries.Data.List.Lemmas
List.mem_append in Init.Data.List.Lemmas
List.mem_singleton in Init.Data.List.Lemmas
Set.mem_empty_iff_false in Mathlib.Data.Set.Basic
Set.mem_insert_iff in Mathlib.Data.Set.Insert
Set.union_singleton in Mathlib.Data.Set.Insert
and_false in Init.SimpLemmas
iff_and_self in Init.SimpLemmas
ne_eq in Init.SimpLemmas
or_false in Init.SimpLemmas
true_and in Init.SimpLemmas
ne_or_eq in Mathlib.Logic.Basic
Array.mem_def in Init.Data.Array.Basic
Array.not_mem_empty in Init.Data.Array.Lemmas
FinEnum.nodup_toList in Mathlib.Data.FinEnum
List.Nodup.notMem in Mathlib.Data.List.Nodup
List.dedup_eq_self in Mathlib.Data.List.Dedup
List.foldl_nil in Init.Data.List.Basic
List.mem_cons in Init.Data.List.Lemmas
List.nodup_cons in Init.Data.List.Pairwise
List.not_mem_nil in Init.Data.List.Lemmas
false_and in Init.SimpLemmas
false_or in Init.SimpLemmas

theorem Std.HashSet.fold_induction [BEq α] [LawfulBEq α] [Hashable α]
  {f : β → α → β} {m : HashSet α} {motive : β → Set α → Prop} :
    motive b ∅ →
    (∀ b x s, x ∉ s → motive b s → motive (f b x) (s ∪ {x})) →
    motive (m.fold f b) m.toSet

theorem Std.HashSet.toSet_toList[BEq α] [LawfulBEq α] [Hashable α] (m : HashSet α) : m.toSet = { x | x ∈ m.toList }

@[simp]
lemma Std.HashSet.mem_toSet [BEq α] [Hashable α] (m : HashSet α) : x ∈ m.toSet ↔ x ∈ m

@[simp]
theorem Std.HashSet.mem_attachWith_mem [BEq α] [Hashable α] [LawfulBEq α] (m : HashSet α) {P H} (x : α) h :
    ⟨x, h⟩ ∈ m.attachWith P H ↔ x ∈ m

lemma CNFA.autWidth_bv_language :
    (autWidth wp n).bv_recognizes { bv | wp.sat bv.w n }

theorem test82_thm (e : IntW 64) :
  zext 64 (shl (lshr (trunc 32 e) (const? 32 8)) (const? 32 9)) ⊑
    zext 64 (LLVM.and (shl (trunc 32 e) (const? 32 1)) (const? 32 (-512)))

theorem sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#41 = signExtend 41 x

theorem add_or_sub_comb_i8_commuted2_nsw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x * x).saddOverflow (0#8 - x * x ||| x * x) = true) → True ∧ (x * x).saddOverflow (-1#8) = true → False

theorem ashrsgt_02_02_proof : ashrsgt_02_02_before ⊑ ashrsgt_02_02_after

theorem ashrsgt_01_09_exact_proof : ashrsgt_01_09_exact_before ⊑ ashrsgt_01_09_exact_after

theorem src4_proof : src4_before ⊑ src4_after

theorem mul130_low_thm (e e_1 : IntW 130) :
  add
      (shl
        (add (mul (lshr e_1 (const? 130 65)) (LLVM.and e (const? 130 36893488147419103231)))
          (mul (LLVM.and e_1 (const? 130 36893488147419103231)) (lshr e (const? 130 65))))
        (const? 130 65))
      (mul (LLVM.and e_1 (const? 130 36893488147419103231)) (LLVM.and e (const? 130 36893488147419103231))) ⊑
    mul e e_1

theorem lt_unsigned_to_small_unsigned_proof : lt_unsigned_to_small_unsigned_before ⊑ lt_unsigned_to_small_unsigned_after

theorem avg_lsb_thm (e e_1 : IntW 8) :
  lshr (add (LLVM.and e_1 (const? 8 1)) (LLVM.and e (const? 8 1)) { «nsw» := true, «nuw» := true }) (const? 8 1) ⊑
    LLVM.and e_1 (LLVM.and e (const? 8 1))

theorem t0_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 == x_1) = 1#1 → ¬ofBool (x_2 != x_1) = 1#1 → False

theorem slt_swap_and_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ₛ x_1) = 1#1 → ofBool (x == 127#8) = 0#1

theorem bitwise_and_logical_and_icmps_comm3_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (x_2 &&& 1#8 != 0#8) = 1#1 →
      ¬(True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 ∨ True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8) →
        ¬ofBool (x_2 &&& (1#8 <<< x_1 ||| 1#8) == 1#8 <<< x_1 ||| 1#8) = 1#1 →
          ofBool (x_2 &&& 1#8 <<< x_1 != 0#8) &&& ofBool (x == 42#8) = 0#1

theorem addhshlhsdivhnegative1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((-1#32 == 0 || 32 != 1 && x == intMin 32 && -1#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    x.sdiv (-1#32) <<< 1#32 + x = 0#32 - x

theorem shl_or_thm (e e_1 : IntW 16) :
  shl (LLVM.or (LLVM.srem e_1 (const? 16 42)) (shl e (const? 16 5))) (const? 16 7) ⊑
    LLVM.or (shl e (const? 16 12))
      (shl (LLVM.srem e_1 (const? 16 42)) (const? 16 7) { «nsw» := true, «nuw» := false })

theorem test24_proof : test24_before ⊑ test24_after

theorem and_and_logic_or_2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 &&& x = 1#1 → x = 1#1 → 1#1 = x_1 &&& 1#1

theorem t2_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 →
    63#64 ≥ ↑64 ∨
        True ∧ signExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 ∨
          True ∧ zeroExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 →
      False

@[simp] theorem val_toArgResult (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn) :
    mapOut.toArgResult.val = mapOut.val

theorem bools2_logical_commute1_and1_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 &&& x_1 = 1#1 → x_1 = 1#1 → 1#1 = x_2

theorem test_ashr__exact_is_unsafe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2147483585) == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨
        True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
          zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64 →
      False

theorem zext_zext_sle_op0_narrow_proof : zext_zext_sle_op0_narrow_before ⊑ zext_zext_sle_op0_narrow_after

theorem lshrugt_02_13_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-3) <ᵤ x >>> 2#4) = 0#1

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_logical_after

theorem sel_false_val_is_a_masked_lshr_of_true_val1_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 60#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 60#32) >>> 2#32) ≥ ↑64) →
      2#32 ≥ ↑32 ∨ True ∧ (x_1 >>> 2#32 &&& 15#32).msb = true ∨ zeroExtend 64 (x_1 >>> 2#32 &&& 15#32) ≥ ↑64 → False

theorem ashrslt_03_08_proof : ashrslt_03_08_before ⊑ ashrslt_03_08_after

theorem not_not_false_thm (e e_1 : IntW 1) :
  select (LLVM.xor e_1 (const? 1 1)) (LLVM.xor e (const? 1 1)) (const? 1 0) ⊑
    LLVM.xor (select e_1 (const? 1 1) e) (const? 1 1)

@[simp, simp_llvm]
theorem isRefinedBy_iff (x y : LLVM.IntW w) :
    x ⊑ y ↔ @HRefinement.IsRefinedBy (PoisonOr _) (PoisonOr _) _ x y

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

theorem logic_or_logic_and_7_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → ¬x = 1#1 → ¬0#1 = 1#1 → 0#1 = x

theorem ashrsgt_03_05_proof : ashrsgt_03_05_before ⊑ ashrsgt_03_05_after

theorem trunc_lshr_exact_mask_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬2#8 ≥ ↑8 → ¬2#6 ≥ ↑6 → truncate 6 (x >>> 2#8) &&& 15#6 = truncate 6 x >>> 2#6

theorem e_2259 :
    2 * ((d ||| e) &&& (e ^^^ f)) + 7 * ((e &&& f) ||| (d &&& (e ||| f))) - 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 7 * (e ^^^ ( ~~~d ||| (e ||| f))) + 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 2 * (e ||| (d &&& f)) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * f + 11 * ( ~~~e ||| (d ^^^ f)) - 3 * (f |||  ~~~(d ||| e)) + 1 * ( ~~~e &&&  ~~~(d ^^^ f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 3 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 *  ~~~e - 2 * (e |||  ~~~(d |||  ~~~f)) - 3 * (f ||| (d &&&  ~~~e)) - 6 * ((d &&& f) ^^^ (e ||| f)) - 5 *  ~~~(d ^^^ e) - 11 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 *  ~~~(d &&& (e ||| f)) + 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 * (e ^^^ (d &&& f)) + 11 * (f &&&  ~~~(d &&&  ~~~e)) - 11 * (d ||| (e ^^^ f)) + 1 * (e ||| (d &&&  ~~~f)) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (d |||  ~~~e) - 1 * (f &&& (d ^^^ e)) - 11 * (d ^^^ (e ^^^ f)) + 11 * ((d ^^^ e) ||| (d ^^^ f)) + 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 11 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 5 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (e ^^^  ~~~(d &&& f)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e &&& (d ^^^ f)) + 3 *  ~~~(d &&&  ~~~e) + 7 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) - 7 * (e ^^^ f) - 3 * ( ~~~d &&& ( ~~~e ||| f)) + 3 *  ~~~(d ^^^ (e &&& f)) - 2 * ( ~~~d &&& (e ||| f)) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 20 *  ~~~(d ||| (e ||| f)) + 12 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) - 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 18 * ( ~~~d &&& ( ~~~e &&& f)) - 39 * ( ~~~d &&& (e &&& f)) + 14 * (d &&& ( ~~~e &&& f)) + 22 * (d &&& (e &&& f)) = 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 11 * ((d &&& e) |||  ~~~(e ||| f))

theorem pr33078_1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬8#16 ≥ ↑16 → ¬7#8 ≥ ↑8 → truncate 8 (signExtend 16 x >>> 8#16) = x.sshiftRight' 7#8

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 33),
  ofBool (x_1 &&& 65280#33 != x &&& 65280#33) = ofBool ((x_1 ^^^ x) &&& 65280#33 != 0#33)

theorem or_ranges_single_elem_left_proof : or_ranges_single_elem_left_before ⊑ or_ranges_single_elem_left_after

theorem mul_add_to_mul_2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ x.smulOverflow 8#16 = true ∨ True ∧ (x * 8#16).saddOverflow x = true) →
    True ∧ x.smulOverflow 9#16 = true → False

theorem e_1993 :
     - 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 7 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 11 * (a |||  ~~~b) - 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * (b ^^^ (a &&& ( ~~~b ||| c))) - 2 * (c ^^^ (a &&&  ~~~b)) - 11 * b - 1 *  ~~~(b ||| c) - 2 * (b &&& c) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 11 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 3 * (a ^^^ (b ||| c)) - 1 * (c ^^^ (a &&& b)) + 5 *  ~~~(a &&& (b ||| c)) + 1 * (b ^^^  ~~~(a &&&  ~~~c)) + 1 *  ~~~(a &&& b) - 5 * (b ^^^  ~~~(a &&& c)) + 1 * (c ^^^ (a ||| (b &&& c))) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 4 * (a ^^^ c) - 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 6 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 * (c &&&  ~~~(a &&&  ~~~b)) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 3 * (c &&& (a ^^^ b)) - 1 * (b ^^^ ( ~~~a ||| (b ||| c))) + 7 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 5 * (b ^^^  ~~~(a ||| c)) + 4 * (c ^^^ (a ||| ( ~~~b &&& c))) - 6 * (a &&& c) + 5 *  ~~~(a ^^^ c) + 2 *  ~~~( ~~~a &&& (b ||| c)) + 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 1 * (b &&& (a ||| c)) + 5 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 7 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 11 * (c ^^^ (a &&& (b ||| c))) + 4 * ( ~~~c &&& (a ^^^ b)) - 2 * (c ^^^ (a ||| (b ||| c))) - 3 * (c ^^^  ~~~(a &&& (b &&& c))) + 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 6 * (b &&&  ~~~c) - 1 * (a &&& (b ^^^ c)) + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 7 * (c &&&  ~~~(a ^^^ b)) + 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * (b ||| (a &&& c)) - 15 *  ~~~(a ||| (b ||| c)) + 5 *  ~~~(a ||| ( ~~~b ||| c)) - 16 *  ~~~( ~~~a ||| (b ||| c)) + 36 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 13 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) + 21 * (a &&& (b &&& c)) =  - 2 * ((a ^^^ b) &&& (a ^^^ c)) + 1 * (c ||| (a &&&  ~~~b))

theorem add_or_sub_comb_i8_negative_y_or_thm (e e_1 : IntW 8) :
  add (LLVM.or (sub (const? 8 0) e_1) e) e_1 ⊑ add (LLVM.or e (sub (const? 8 0) e_1)) e_1

theorem test4c_proof : test4c_before ⊑ test4c_after

theorem lshrult_03_10_proof : lshrult_03_10_before ⊑ lshrult_03_10_after

theorem lshrugt_01_11_exact_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1) { «exact» := true }) (const? 4 (-5)) ⊑ const? 1 0

theorem e_1144 :
    2 * z - 3 * (z ||| t) + 1 *  ~~~(z &&&  ~~~z) - 1 * t - 1 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 3 * (z &&&  ~~~t) + 1 * (z &&& t) = 3 * (z ^^^ t)

theorem t0_sub_of_trueval_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  sub (select e_2 e_1 e) e_1 ⊑ select e_2 (const? 8 0) (sub e e_1)

theorem sel_false_val_is_a_masked_shl_of_true_val2_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(True ∧ ((x_1 &&& 15#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 15#32 ∨
        True ∧ (x_1 &&& 15#32) <<< 2#32 >>> 2#32 ≠ x_1 &&& 15#32 ∨ 2#32 ≥ ↑32) →
    ofBool ((x_1 &&& 15#32) <<< 2#32 == 0#32) = 1#1 →
      ¬(2#32 ≥ ↑32 ∨ True ∧ (x_1 <<< 2#32 &&& 60#32).msb = true ∨ zeroExtend 64 (x_1 <<< 2#32 &&& 60#32) ≥ ↑64) →
        x = x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& 60#32))

theorem nonexact_ashr_eq_exactdiv_thm (e : IntW 8) :
  icmp IntPred.eq (ashr (const? 8 (-80)) e) (const? 8 (-5)) ⊑ icmp IntPred.eq e (const? 8 4)

theorem ashrslt_01_04_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (x.sshiftRight' 1#4 <ₛ 4#4) = 1#1

theorem icmp_sle9_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 7#8).sshiftRight' 7#8 ≠ x ∨ 7#8 ≥ ↑8) →
    ofBool (x <<< 7#8 ≤ₛ BitVec.ofInt 8 (-128)) = ofBool (x != 0#8)

theorem test_shift_nonnegative_thm (e : IntW 32) :
  icmp IntPred.sge (shl (lshr e (const? 32 2)) (const? 32 3) { «nsw» := true, «nuw» := false }) (const? 32 0) ⊑
    const? 1 1

theorem test88_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬18#32 ≥ ↑32 → ¬15#16 ≥ ↑16 → truncate 16 ((signExtend 32 x).sshiftRight' 18#32) = x.sshiftRight' 15#16

theorem e_545 :
     - 2 * x - 1 *  ~~~(x &&& y) - 1 *  ~~~(x ^^^ y) - 5 * (x ||| y) - 11 * y + 3 * (x |||  ~~~y) + 18 *  ~~~(x |||  ~~~y) + 6 * (x &&&  ~~~y) + 17 * (x &&& y) = 1 *  ~~~(x &&&  ~~~x)

theorem sext_zext_apint1_thm.extracted_1._1 : ∀ (x : BitVec 77),
  signExtend 1024 (zeroExtend 533 x) = zeroExtend 1024 x

theorem logic_or_logic_and_3_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x = 1#1 → x_1 = 1#1 → 0#1 = 1#1 → x_1 = 1#1

theorem e_1376 :
     - 5 * (z ^^^ t) - 1 * (z |||  ~~~t) + 1 * t - 7 *  ~~~(z &&&  ~~~z) + 5 *  ~~~t + 2 *  ~~~z - 9 *  ~~~(z ||| t) + 10 *  ~~~(z |||  ~~~t) + 9 * (z &&&  ~~~t) - 4 * (z &&& t) =  - 11 *  ~~~(z ^^^ t) + 1 *  ~~~(z &&& t)

theorem PR30273_three_bools_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 →
    ¬x_1 = 1#1 →
      ¬(True ∧ (zeroExtend 32 x).saddOverflow 1#32 = true) →
        ¬(True ∧ (zeroExtend 32 x).saddOverflow (zeroExtend 32 x_2) = true ∨
              True ∧ (zeroExtend 32 x).uaddOverflow (zeroExtend 32 x_2) = true) →
          zeroExtend 32 x + 1#32 = zeroExtend 32 x + zeroExtend 32 x_2

theorem sub_from_variable_of_sub_from_constant_proof : sub_from_variable_of_sub_from_constant_before ⊑ sub_from_variable_of_sub_from_constant_after

theorem icmp_power2_and_icmp_shifted_mask_8_6_proof : icmp_power2_and_icmp_shifted_mask_8_6_before ⊑ icmp_power2_and_icmp_shifted_mask_8_6_after

theorem test23_logical_proof : test23_logical_before ⊑ test23_logical_after

theorem f_proof : f_before ⊑ f_after

theorem icmp_equality_test_commute_select2_proof : icmp_equality_test_commute_select2_before ⊑ icmp_equality_test_commute_select2_after

theorem no_shift_xor_multiuse_or_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 4096#32) = 1#1 →
    (x ||| 4096#32) * (x ||| 4096#32) = (x ||| x_1 &&& 4096#32 ^^^ 4096#32) * (x ||| 4096#32)

theorem bv_AndOrXor_887_2 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.and (LLVM.icmp LLVM.IntPred.eq e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.const? 1 0

theorem ashrsgt_01_01_exact_proof : ashrsgt_01_01_exact_before ⊑ ashrsgt_01_01_exact_after

theorem test19_proof : test19_before ⊑ test19_after

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 49), ¬1#49 ≥ ↑49 → (x_1 ||| x <<< 1#49) &&& 1#49 = x_1 &&& 1#49

theorem and_or1_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 ||

theorem or_xor_xor_normal_variant3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  x_1 ^^^ x_1 &&& x ||

theorem or_xor_tree_0000_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42)))
      (LLVM.xor (LLVM.xor (mul e_1 (const? 32 42)) (mul e (const? 32 42))) (mul e_2 (const? 32 42))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42))) (mul e (const? 32 42))

theorem trunc_sandwich_min_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(20#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) →
    21#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 12 (x >>> 21#32)) ≠ x >>> 21#32 ∨
          True ∧ zeroExtend 32 (truncate 12 (x >>> 21#32)) ≠ x >>> 21#32 →
      False

theorem ashrslt_02_07_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 2) { «exact» := true }) (const? 4 7) ⊑ const? 1 1

theorem p3_sgt_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (65534#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 65535#32) = 1#1 → x = 65535#32

theorem add_select_not_zext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 + zeroExtend 64 (x ^^^ 1#1) = 2#64

theorem main7a_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 == x_2) = 1#1 →
    ofBool (x_2 &&& x_1 != x_2) = 1#1 → ¬ofBool (x &&& x_1 == x) = 1#1 → 1#32 = zeroExtend 32 1#1

theorem neg_or_add (i : Nat) :
    (b.negAux i).2 = false ∨ (a.addAux b.neg i).2 = false

theorem trunc_shl_lshr_infloop_thm (e : IntW 64) :
  trunc 32 (shl (lshr e (const? 64 1)) (const? 64 2)) ⊑
    LLVM.and (shl (trunc 32 e) (const? 32 1)) (const? 32 (-4))

theorem t3_ult_sgt_neg1_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 <ᵤ 65536#32) = 1#1 → ¬ofBool (-1#32 <ₛ x_2) = 1#1 → ofBool (65535#32 <ₛ x_2) = 1#1 → x = x_1

theorem test_shl_nsw__none_are_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2))) (const? 32 0)) e
      (ashr e (zext 64 (shl (LLVM.and e_1 (const? 32 (-2))) (const? 32 2) { «nsw» := true, «nuw» := false }))) ⊑
    ashr e (zext 64 (LLVM.and (shl e_1 (const? 32 2)) (const? 32 (-8))) { «nneg» := true })

theorem land_land_right2_proof : land_land_right2_before ⊑ land_land_right2_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8)

theorem not_and_and_or_not_or_or_commute1_and_proof : not_and_and_or_not_or_or_commute1_and_before ⊑ not_and_and_or_not_or_or_commute1_and_after

theorem AvoidCollision_setWidth_xor {x y : BitVec w} :
    (x ^^^ y).setWidth k = x.setWidth k ^^^ y.setWidth k

theorem logic_or_logic_and_8_proof : logic_or_logic_and_8_before ⊑ logic_or_logic_and_8_after

theorem and_not_or_commute2_proof : and_not_or_commute2_before ⊑ and_not_or_commute2_after

theorem udiv_one_eq_self (w : Nat) (x : BitVec w) : x.udiv 1#w = x

theorem t7_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8), x_1 = 1#1 → x_2 - 0#8 = 0#8 + x_2

theorem e_415 :
    2 * y + 1 *  ~~~(x &&&  ~~~y) + 3 *  ~~~y + 1 * (x ^^^ y) - 1 *  ~~~(x ^^^ y) + 2 * x - 3 *  ~~~(x ||| y) - 6 * (x &&&  ~~~y) = 4 * (x &&& y) + 4 *  ~~~(x |||  ~~~y)

theorem test_shift_and_cmp_changed1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ 5#8 ≥ ↑8) →
    ¬5#8 ≥ ↑8 →
      ofBool (((x_1 &&& 8#8 ||| x &&& 6#8) <<< 5#8).sshiftRight' 5#8 <ₛ 1#8) =
        ofBool (x <<< 5#8 &&& BitVec.ofInt 8 (-64) <ₛ 32#8)

theorem icmp_shl_nsw_sge1_proof : icmp_shl_nsw_sge1_before ⊑ icmp_shl_nsw_sge1_after

theorem lshrugt_02_05_exact_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 2) { «exact» := true }) (const? 4 5) ⊑ const? 1 0

theorem positive_samevar_thm (e e_1 : IntW 8) :
  shl (lshr e_1 e) e ⊑ LLVM.and (shl (const? 8 (-1)) e { «nsw» := true, «nuw» := false }) e_1

theorem test2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 999),
  ofBool (x_1 &&& 65280#999 != x &&& 65280#999) = ofBool ((x_1 ^^^ x) &&& 65280#999 != 0#999)

theorem andn_or_cmp_1_proof : andn_or_cmp_1_before ⊑ andn_or_cmp_1_after

theorem test0_proof : test0_before ⊑ test0_after

theorem lshr_neg_slt_zero_proof : lshr_neg_slt_zero_before ⊑ lshr_neg_slt_zero_after

theorem ashrslt_02_10_exact_proof : ashrslt_02_10_exact_before ⊑ ashrslt_02_10_exact_after

theorem test_nuw_nsw_and_unsigned_pred_proof : test_nuw_nsw_and_unsigned_pred_before ⊑ test_nuw_nsw_and_unsigned_pred_after

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

theorem e_1516 :
    5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 1 *  ~~~c + 7 * (b ^^^ (a |||  ~~~c)) + 4 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 2 *  ~~~( ~~~a ||| (b &&& c)) - 15 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) - 8 *  ~~~( ~~~a ||| (b ||| c)) - 16 * ( ~~~a &&& (b &&& c)) - 4 * (a &&& (b &&& c)) = 9 * (a &&& ( ~~~b &&& c)) + 2 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem icmp_eq_or_z_or_pow2orz_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8 - x &&& x) ||

theorem sel_zext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 64 42#32 = 42#64

theorem or_nosignbit_select_shl_proof : or_nosignbit_select_shl_before ⊑ or_nosignbit_select_shl_after

theorem ashr_and_or_disjoint_thm (e e_1 : IntW 8) :
  shl (LLVM.or (LLVM.srem e_1 (const? 8 42)) (LLVM.and (ashr e (const? 8 2)) (const? 8 13)) { «disjoint» := true })
      (const? 8 2) ⊑
    LLVM.or (LLVM.and e (const? 8 52)) (shl (LLVM.srem e_1 (const? 8 42)) (const? 8 2)) { «disjoint» := true }

theorem main7e_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 &&& x_2 &&& x_1 == x_3 &&& x_2) = 1#1 →
    ofBool (x_3 &&& x_2 &&& x_1 != x_3 &&& x_2) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem e_1277 :
    1 * z + 1 * (z ||| t) - 1 * (z ^^^ t) - 5 * (z |||  ~~~t) - 1 *  ~~~(z ^^^ t) + 8 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) + 4 * (z &&& t) = 2 *  ~~~(z &&& t)

theorem ne_smax2_proof : ne_smax2_before ⊑ ne_smax2_after

theorem shl_fold_or_disjoint_cnt_proof : shl_fold_or_disjoint_cnt_before ⊑ shl_fold_or_disjoint_cnt_after

theorem test_ule_xor_proof : test_ule_xor_before ⊑ test_ule_xor_after

theorem samesign_inverted_commute1_proof : samesign_inverted_commute1_before ⊑ samesign_inverted_commute1_after

theorem t2_ult_sgt_128_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → False

theorem lshr_sub_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨ 3#8 ≥ ↑8 ∨ 3#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
        3#8 ≥ ↑8 ∨ True ∧ (x_1.srem 42#8).ssubOverflow (x >>> 3#8) = true ∨ 3#8 ≥ ↑8 →
      False

theorem main10_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 64#32 == 0#32) = 1#1 →
    ¬ofBool (x &&& 192#32 == 0#32) = 1#1 → ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 2#32 = 1#32

theorem e_2374 :
     - 5 * (d ||| (e &&& f)) + 11 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * e - 2 * (e &&& (d |||  ~~~f)) + 3 * (e &&& f) - 3 * (e ^^^ (d &&& (e ||| f))) - 5 * ( ~~~d &&& (e ^^^ f)) + 2 * (f ^^^ (d ||| e)) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 2 * (e ^^^ (d &&& f)) + 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 * (d ^^^ (e ^^^ f)) + 11 * (f ^^^ (d &&&  ~~~e)) - 11 *  ~~~(e &&&  ~~~f) - 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (e ^^^ (d |||  ~~~f)) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 5 * (e ^^^ f) - 2 * (d &&& (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& e)) + 11 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 *  ~~~(d |||  ~~~f) + 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * ( ~~~e &&& (d ^^^ f)) + 1 * (e &&&  ~~~(d &&&  ~~~f)) - 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 11 * ((d &&& f) |||  ~~~(e ||| f)) - 11 * (e ^^^ (d &&& (e ^^^ f))) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 3 * (e &&&  ~~~(d ^^^ f)) - 1 * (d ||| (e ^^^ f)) - 3 * (e |||  ~~~(d |||  ~~~f)) - 11 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 *  ~~~(d &&& (e ||| f)) - 6 * (f ||| (d &&&  ~~~e)) + 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 2 *  ~~~(e &&& f) + 7 *  ~~~(d &&&  ~~~d) - 2 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (e ||| f) + 1 *  ~~~( ~~~d ||| (e &&& f)) + 1 * (f ^^^ (d &&& e)) + 2 * (f ^^^ ( ~~~d ||| (e ||| f))) + 4 *  ~~~f + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 * (f |||  ~~~(d |||  ~~~e)) + 4 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 *  ~~~(d &&&  ~~~f) - 6 * (f &&& (d ^^^ e)) + 2 *  ~~~(d ^^^ (e &&& f)) + 1 * (e ||| (d &&& f)) + 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 5 * (e ^^^ (d ||| ( ~~~e &&& f))) - 3 * (e ^^^ (d ||| (e ^^^ f))) - 7 * ((d &&& f) ^^^ (e ||| f)) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) - 27 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 25 *  ~~~( ~~~d ||| (e ||| f)) - 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 6 * ( ~~~d &&& ( ~~~e &&& f)) + 29 * ( ~~~d &&& (e &&& f)) - 10 * (d &&& ( ~~~e &&& f)) + 7 * (d &&& (e &&& f)) =  - 4 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (f ^^^ ( ~~~d ||| (e &&& f)))

theorem src_srem_shl_demand_max_signbit_proof : src_srem_shl_demand_max_signbit_before ⊑ src_srem_shl_demand_max_signbit_after

theorem land_lor_left1_proof : land_lor_left1_before ⊑ land_lor_left1_after

theorem test_sub__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == BitVec.ofInt 32 (-2147483647)) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true → False

theorem drop_both_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x ∨
        True ∧ zeroExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x) →
    truncate 8 (x_1 &&& 255#16 &&& x) = truncate 8 (x_1 &&& x)

theorem zext_nneg_proof : zext_nneg_before ⊑ zext_nneg_after

theorem neg_of_add_with_constant_proof : neg_of_add_with_constant_before ⊑ neg_of_add_with_constant_after

theorem a_or_b_const2_proof : a_or_b_const2_before ⊑ a_or_b_const2_after

theorem positive_easyinvert_proof : positive_easyinvert_before ⊑ positive_easyinvert_after

theorem sext_false_val_must_be_zero_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → signExtend 32 x = 0#32

theorem neg_signbit_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → 0#32 - zeroExtend 32 (x >>> 7#8) = signExtend 32 (x.sshiftRight' 7#8)

theorem not_or_or_and_not_and_and_commute4_proof : not_or_or_and_not_and_and_commute4_before ⊑ not_or_or_and_not_and_and_commute4_after

theorem ne_umin2_proof : ne_umin2_before ⊑ ne_umin2_after

theorem e_1124 :
    5 * z - 1 *  ~~~(z &&&  ~~~t) - 1 * (z ^^^ t) + 7 *  ~~~t + 1 * t - 5 *  ~~~(z ^^^ t) - 2 *  ~~~(z ||| t) - 11 * (z &&&  ~~~t) =  - 1 *  ~~~z

theorem lshrugt_02_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬2#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-2) <ᵤ x >>> 2#4) = 0#1

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem test_with_even_proof : test_with_even_before ⊑ test_with_even_after

theorem t0_ult_slt_128_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (127#32 <ₛ x_2) = 1#1 → ofBool (x_2 <ₛ BitVec.ofInt 32 (-16)) = 1#1 → x_2 = x_1

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem test_proof : test_before ⊑ test_after

theorem mul_add_to_mul_9_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ x.smulOverflow 16384#16 = true ∨
        True ∧ x.smulOverflow 16384#16 = true ∨ True ∧ (x * 16384#16).saddOverflow (x * 16384#16) = true) →
    ¬15#16 ≥ ↑16 → x * 16384#16 + x * 16384#16 = x <<< 15#16

theorem shift_no_xor_multiuse_cmp_thm.extracted_1._7 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 &&& 1#32 == 0#32) = 1#1 →
    True ∧ ((x_3 &&& 1#32) <<< 1#32).sshiftRight' 1#32 ≠ x_3 &&& 1#32 ∨
        True ∧ (x_3 &&& 1#32) <<< 1#32 >>> 1#32 ≠ x_3 &&& 1#32 ∨ 1#32 ≥ ↑32 →
      False

theorem test_thm.extracted_1._1 : zeroExtend 32 (ofBool (1#32 == 2#32)) = 0#32

theorem width5 (w : Nat) (a b : BitVec w) : (a + b = a - a) → a = - b

theorem t4_ugt_slt_128_thm.extracted_1._8 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (143#32 <ᵤ x_1 + 16#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → x_1 = x

theorem shl_nuw_eq_0_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (shl e_1 e { «nsw» := false, «nuw» := true }) (const? 8 0) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

theorem positive_samevar_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬(True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8) → x_1.sshiftRight' x <<< x = (-1#8) <<< x &&& x_1

theorem PR39793_bswap_u32_as_u16_trunc_thm (e : IntW 32) :
  trunc 8
      (LLVM.or (LLVM.and (lshr e (const? 32 8)) (const? 32 255)) (LLVM.and (shl e (const? 32 8)) (const? 32 65280))) ⊑
    trunc 8 (lshr e (const? 32 8))

theorem lshrult_01_07_proof : lshrult_01_07_before ⊑ lshrult_01_07_after

theorem lor_land_right2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → 0#1 = x_1

theorem icmp_shl_nsw_sgt_thm (e : IntW 32) :
  icmp IntPred.sgt (shl e (const? 32 21) { «nsw» := true, «nuw» := false }) (const? 32 0) ⊑
    icmp IntPred.sgt e (const? 32 0)

theorem fold_xor_zext_icmp_proof : fold_xor_zext_icmp_before ⊑ fold_xor_zext_icmp_after

theorem test4_proof : test4_before ⊑ test4_after

theorem e_385 :
     - 2 *  ~~~(x &&& y) + 2 *  ~~~x + 7 *  ~~~(x &&&  ~~~y) - 5 * (x |||  ~~~y) - 11 * x - 7 *  ~~~(x |||  ~~~y) + 20 * (x &&&  ~~~y) + 9 * (x &&& y) = 2 *  ~~~y

theorem test24_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (lshr (LLVM.and e (const? 32 4)) (const? 32 2)) (const? 32 0)) ⊑
    LLVM.xor (LLVM.and (lshr e (const? 32 2)) (const? 32 1)) (const? 32 1)

theorem ashrslt_03_15_exact_proof : ashrslt_03_15_exact_before ⊑ ashrslt_03_15_exact_after

theorem or_eq_with_one_bit_diff_constants1_proof : or_eq_with_one_bit_diff_constants1_before ⊑ or_eq_with_one_bit_diff_constants1_after

@[simp] theorem carry_succ (initCarry : Bool) (x y : BitStream) :
    (carry initCarry x y (i + 1)) =
  let out

theorem e_2025 :
    3 * (f ^^^ (d &&& (e ||| f))) + 4 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 6 *  ~~~(d |||  ~~~e) - 5 * (e ^^^  ~~~(d ||| f)) + 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 5 * d - 1 *  ~~~f - 5 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 1 * e - 11 * (e ^^^ ( ~~~d ||| (e ||| f))) + 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 11 * (d ^^^ (e ^^^ f)) + 1 *  ~~~(d ||| (e &&& f)) + 4 * (e &&&  ~~~(d ^^^ f)) + 1 * (f &&& (d ||| e)) + 5 * (f &&&  ~~~(d &&& e)) - 1 * ((d &&& e) ||| (e ^^^ f)) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 * (f ^^^ (d ||| (e ||| f))) - 2 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 4 *  ~~~(d ||| (e ||| f)) - 17 *  ~~~(d ||| ( ~~~e ||| f)) - 18 *  ~~~( ~~~d ||| (e ||| f)) - 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 13 * ( ~~~d &&& ( ~~~e &&& f)) - 4 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) - 21 * (d &&& (e &&& f)) = 2 * (d ||| f) - 1 * (f ^^^ (d ||| (e &&& f)))

theorem ashr_slt_exact_near_pow2_cmpval_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 1) { «exact» := true }) (const? 8 5) ⊑
    icmp IntPred.slt e (const? 8 9)

theorem and_not_or_or_not_or_xor_commute5_proof : and_not_or_or_not_or_xor_commute5_before ⊑ and_not_or_or_not_or_xor_commute5_after

theorem urem_i8_proof : urem_i8_before ⊑ urem_i8_after

theorem test15c_thm.extracted_1._2 : ∀ (x : BitVec 32), ¬ofBool (x &&& 16#32 == 16#32) = 1#1 → 0#32 = x &&& 16#32

theorem ashrsgt_02_03_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 2)) (const? 4 3) ⊑ const? 1 0

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

theorem select_icmp_eq_0_and_1_xor_1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 64),
  ofBool (x_1 &&& 1#64 == 0#64) = 1#1 → x = x ^^^ truncate 32 x_1 &&& 1#32

theorem bool3 (x y : Bool) : BitVec.ofBool x = BitVec.ofBool y ↔ x = y

theorem select_icmp_ne_0_and_4096_and_not_32_proof : select_icmp_ne_0_and_4096_and_not_32_before ⊑ select_icmp_ne_0_and_4096_and_not_32_after

@[bv_automata_nnf]
theorem slt_iff_sle_eq_false {a b : BitVec w} : a.sle b = false ↔ b.slt a

theorem or_and_not_constant_commute2_proof : or_and_not_constant_commute2_before ⊑ or_and_not_constant_commute2_after

theorem sub_to_xor_thm (e e_1 : IntW 32) : sub (LLVM.or e_1 e) (LLVM.and e_1 e) ⊑ LLVM.xor e_1 e

theorem neg_sgt_0_proof : neg_sgt_0_before ⊑ neg_sgt_0_after

theorem t0_proof : t0_before ⊑ t0_after

theorem main5f_like_logical_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != x_2) = 1#1 → ¬ofBool (x_2 &&& x_1 == x_2) = 1#1 → ¬True → 0#32 = zeroExtend 32 0#1

theorem icmp_ne_and_pow2_minus1_shl1_proof : icmp_ne_and_pow2_minus1_shl1_before ⊑ icmp_ne_and_pow2_minus1_shl1_after

theorem bv_AndOrXor_2243__B__C__A__B___B__A__C :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.or (LLVM.and (LLVM.or e_2 e_1) e) e_2 ⊑ LLVM.or e_2 (LLVM.and e e_1)

theorem main3f_like_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != 0#32) = 1#1 →
    ofBool (x_2 &&& x_1 == 0#32) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x_2 &&& x == 0#32))

theorem add_const_const_sub_nuw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (BitVec.ofInt 8 (-127)).usubOverflow (x + 1#8) = true) →
    BitVec.ofInt 8 (-127) - (x + 1#8) = BitVec.ofInt 8 (-128) - x

theorem not_logicalOr_not_op1_proof : not_logicalOr_not_op1_before ⊑ not_logicalOr_not_op1_after

theorem fold_icmp_shl_nuw_c2_div_non_pow2_proof : fold_icmp_shl_nuw_c2_div_non_pow2_before ⊑ fold_icmp_shl_nuw_c2_div_non_pow2_after

theorem lowmask_or_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 24),
  (x_1 ||| zeroExtend 24 x) &&& 65535#24 = zeroExtend 24 (x ||| truncate 16 x_1)

theorem ashrsgt_02_02_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (2#4 <ₛ x.sshiftRight' 2#4) = 0#1

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem ashr_ugt_11_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-5) <ᵤ x.sshiftRight' 1#4) = ofBool (x <ₛ 0#4)

theorem add_nsw_const_const_sub_nsw_ov_proof : add_nsw_const_const_sub_nsw_ov_before ⊑ add_nsw_const_const_sub_nsw_ov_after

theorem or_signbit_select_ashr_proof : or_signbit_select_ashr_before ⊑ or_signbit_select_ashr_after

theorem test6a_thm (e : IntW 1) : icmp IntPred.ne (zext 32 e) (const? 32 (-1)) ⊑ const? 1 1

theorem e_1390 :
     - 6 *  ~~~(z ^^^ t) + 5 * t + 2 *  ~~~z - 11 *  ~~~(z &&&  ~~~z) + 11 * (z ||| t) - 6 * (z ^^^ t) - 7 * (z |||  ~~~t) - 1 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 13 * (z &&& t) = 5 * z - 22 *  ~~~(z ||| t)

theorem main4c_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 7#32) ||

theorem select_add_icmp_bad_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → x_2 + x_1 = x_1 + 1#32

theorem negate_add_with_single_negatible_operand_thm (e : IntW 8) : sub (const? 8 0) (add e (const? 8 42)) ⊑ sub (const? 8 (-42)) e

theorem p14_commutativity1_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 65536)) (const? 32 65535) (const? 32 42) ⊑
    select (icmp IntPred.ugt e (const? 32 65535)) (const? 32 42) (const? 32 65535)

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬zeroExtend 32 x ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem exact_ashr_ne_noexactdiv_proof : exact_ashr_ne_noexactdiv_before ⊑ exact_ashr_ne_noexactdiv_after

@[simp]
lemma BitVec.cons_ugt_iff {w} {bv1 bv2 : BitVec w} :
    ((BitVec.cons b2 bv2).ult (BitVec.cons b1 bv1)) ↔ (if b1 = b2 then bv2.ult bv1 else b1)

theorem lshr_neg_sgt_minus_1_thm (e : IntW 8) :
  icmp IntPred.sgt (lshr (const? 8 (-17)) e) (const? 8 (-1)) ⊑ icmp IntPred.ne e (const? 8 0)

theorem equiv_arg1 (x1Stream x2Stream : Stream (BitVec 1)) :
    x1Stream ≈ (BranchEg1.denote (Valuation.ofPair x1Stream x2Stream) |>.getN 0)

theorem sub_ashr_or_i64_proof : sub_ashr_or_i64_before ⊑ sub_ashr_or_i64_after

theorem lshr_C1_add_A_C2_i32_proof : lshr_C1_add_A_C2_i32_before ⊑ lshr_C1_add_A_C2_i32_after

theorem main4f_like_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != x_1) = 1#1 →
    ofBool (x_2 &&& x_1 == x_1) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x_2 &&& x == x))

theorem e_2285 :
    1 * ( ~~~d ||| (e ^^^ f)) - 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 4 * (d ^^^ (e &&& f)) - 1 * (d &&& e) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 5 *  ~~~(d &&& ( ~~~e ||| f)) - 5 * (d ||| ( ~~~e ||| f)) + 3 *  ~~~(e ||| f) + 2 *  ~~~(d &&& (e ||| f)) + 5 * (e ^^^ ( ~~~d ||| (e ||| f))) + 1 * ((d &&& e) ||| (e ^^^ f)) - 3 *  ~~~( ~~~d &&& (e &&& f)) - 7 * (e ^^^ (d &&& f)) + 1 * (d |||  ~~~f) - 1 * (e ^^^  ~~~(d ||| f)) + 7 *  ~~~(e ^^^ f) - 5 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * (e ||| f) - 1 * (e ||| (d &&& f)) - 6 *  ~~~(d &&& (e &&& f)) + 1 * d - 3 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * f - 5 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 1 *  ~~~(d ||| e) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * (f ^^^ (d ||| e)) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d &&&  ~~~d) - 5 *  ~~~(d ||| (e ^^^ f)) - 1 * (d ^^^ ( ~~~e ||| f)) + 1 *  ~~~(d ^^^ e) + 1 * ( ~~~e ||| (d ^^^ f)) - 2 * (e ^^^ (d ||| (e ^^^ f))) + 3 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ( ~~~d &&& (e ^^^ f)) - 1 * ((d ^^^ e) &&& (d ^^^ f)) + 3 * (f ||| (d &&&  ~~~e)) - 11 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 11 *  ~~~(e &&& f) + 2 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 * (d ^^^ e) - 1 * ( ~~~f &&& (d ^^^ e)) - 3 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 16 *  ~~~(d ||| (e ||| f)) + 9 *  ~~~(d ||| ( ~~~e ||| f)) - 9 *  ~~~( ~~~d ||| (e ||| f)) - 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e &&& f)) + 27 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) + 24 * (d &&& (e &&& f)) =  - 4 * ((d &&& f) ^^^ (d ^^^ (e &&& f)))

theorem positive_biggerLshr_shlnuw_lshrexact_thm (e : IntW 32) :
  lshr (shl e (const? 32 5) { «nsw» := false, «nuw» := true }) (const? 32 10) { «exact» := true } ⊑
    lshr e (const? 32 5) { «exact» := true }

theorem icmp_eq_and_pow2_shl_pow2_proof : icmp_eq_and_pow2_shl_pow2_before ⊑ icmp_eq_and_pow2_shl_pow2_after

theorem test9_thm (e : IntW 32) : trunc 8 (LLVM.and e (const? 32 42)) ⊑ LLVM.and (trunc 8 e) (const? 8 42)

theorem alive_290__292 : alive_290__292_src ⊑ alive_290__292_tgt

theorem lshr_shl_pow2_const_case1_proof : lshr_shl_pow2_const_case1_before ⊑ lshr_shl_pow2_const_case1_after

theorem sle_swap_or_min_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x ≤ₛ x_1) = 1#1 → ofBool (x == BitVec.ofInt 8 (-128)) = ofBool (x ≤ₛ x_1)

theorem test14a_thm.extracted_1._1 : ∀ (x : BitVec 79),
  ¬(4#79 ≥ ↑79 ∨ 4#79 ≥ ↑79) → (x <<< 4#79 &&& 1234#79) >>> 4#79 = x &&& 77#79

theorem e_161 :
     - 11 *  ~~~(x &&&  ~~~y) - 7 * y + 11 *  ~~~(x ||| y) + 19 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 19 * (x &&& y) = 1 * (x ||| y)

theorem demorgan_nand_apint2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 117),
  (x_1 ^^^ -1#117) &&& x ^^^ -1#117 = x_1 ||

theorem select_bittest_to_shl_negative_test_proof : select_bittest_to_shl_negative_test_before ⊑ select_bittest_to_shl_negative_test_after

theorem icmp_slt_0_and_icmp_sge_neg1_i64_thm (e : IntW 64) :
  LLVM.and (lshr e (const? 64 63)) (zext 64 (icmp IntPred.sge e (const? 64 (-1)))) ⊑
    zext 64 (icmp IntPred.eq e (const? 64 (-1)))

theorem and_xor_or7_thm (e e_1 e_2 : IntW 64) :
  LLVM.or (LLVM.udiv (const? 64 42) e_2)
      (LLVM.xor (LLVM.udiv (const? 64 42) e_1) (LLVM.and (LLVM.udiv (const? 64 42) e) (LLVM.udiv (const? 64 42) e_2))) ⊑
    LLVM.or (LLVM.udiv (const? 64 42) e_2) (LLVM.udiv (const? 64 42) e_1)

theorem sgt_and_min_logical_proof : sgt_and_min_logical_before ⊑ sgt_and_min_logical_after

theorem sub_select_zext_op_swapped_non_const_args_thm.extracted_1._4 : ∀ (x x_1 : BitVec 6) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → zeroExtend 6 x_2 - x = 0#6 - x

theorem e_107 :
     - 1 * y + 7 * x + 1 *  ~~~x + 11 *  ~~~(x &&& y) - 18 * (x &&&  ~~~y) - 6 * (x &&& y) = 11 *  ~~~(x |||  ~~~y) + 12 *  ~~~(x ||| y)

theorem or_disjoint_with_xor_proof : or_disjoint_with_xor_before ⊑ or_disjoint_with_xor_after

theorem foo_thm (e e_1 : IntW 64) :
  zext 64 (LLVM.and (trunc 32 e_1) (trunc 32 e)) ⊑ LLVM.and (LLVM.and e_1 e) (const? 64 4294967295)

theorem ashr_eq_msb_low_second_zero_proof : ashr_eq_msb_low_second_zero_before ⊑ ashr_eq_msb_low_second_zero_after

theorem test_shl_nuw_nsw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 15#32 == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨ True ∧ (x_1 <<< 2#32 &&& 60#32).msb = true ∨ zeroExtend 64 (x_1 <<< 2#32 &&& 60#32) ≥ ↑64 → False

theorem test2_proof : test2_before ⊑ test2_after

theorem lshrult_02_13_proof : lshrult_02_13_before ⊑ lshrult_02_13_after

theorem ne_umin1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ x) = 1#1 → ofBool (x != x_1) = ofBool (x <ᵤ x_1)

theorem substitute_constant_and_eq_eq_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e_1 e) (const? 1 0) ⊑
    select (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42)) (const? 1 0)

theorem test36_thm.extracted_1._1 : ∀ (x : BitVec 32), True ∧ (x + 7#32 &&& 240#32).msb = true → False

theorem lshrult_01_01_exact_proof : lshrult_01_01_exact_before ⊑ lshrult_01_01_exact_after

theorem icmp_sle1_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 (-128)) ⊑
    icmp IntPred.eq e (const? 8 (-64))

theorem lshrugt_02_01_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 1) ⊑ icmp IntPred.slt e (const? 4 0)

theorem ashrsgt_02_00_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2)) (const? 4 0) ⊑ icmp IntPred.sgt e (const? 4 3)

theorem e_206 :
     - 1 *  ~~~y + 3 *  ~~~x - 2 * (x ||| y) - 4 *  ~~~(x ||| y) - 3 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) =  - 2 *  ~~~(x &&&  ~~~y)

theorem or_and_not_not_proof : or_and_not_not_before ⊑ or_and_not_not_after

theorem icmp_lshr_and_overshift_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (lshr e (const? 8 5)) (const? 8 15)) (const? 8 0) ⊑
    icmp IntPred.ugt e (const? 8 31)

theorem alive_Select_741 : forall (w : Nat) (A : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  w %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v7 %v1;
  %v9 := op:select w %v8;
  %v10 := op:const (-1) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  w %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub w %v14;
  %v16 := triple:%v12 %v15 %v9;
  %v17 := op:select w %v16
  dsl_ret %v17
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  1 %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v7 %v1;
  %v9 := op:select 1 %v8;
  %v10 := op:const (-1) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  1 %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub 1 %v14;
  %v16 := triple:%v4 %v7 %v1;
  %v17 := op:select 1 %v16
  dsl_ret %v17
  ]

theorem e_1215 :
     - 2 *  ~~~t + 5 *  ~~~z - 2 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z &&& t) + 3 * (z ||| t) - 7 *  ~~~(z &&&  ~~~z) + 1 * (z ^^^ t) + 5 *  ~~~(z ||| t) + 4 * (z &&&  ~~~t) =  - 6 * (z &&& t) + 1 *  ~~~(z |||  ~~~t)

theorem zext_nneg_i1_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬(True ∧ x.msb = true) → zeroExtend 32 x = 0#32

theorem trunc_equality_both_sext_proof : trunc_equality_both_sext_before ⊑ trunc_equality_both_sext_after

theorem t0_proof : t0_before ⊑ t0_after

theorem test3_thm.extracted_1._3 : ∀ (x : BitVec 41), ¬ofBool (x <ₛ 0#41) = 1#1 → 40#41 ≥ ↑41 → False

theorem trunc_shl_lshr_infloop_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(1#64 ≥ ↑64 ∨ 2#64 ≥ ↑64) → 1#32 ≥ ↑32 → False

theorem e_427 :
     - 11 * (x ^^^ y) + 7 * y + 1 *  ~~~(x &&& y) - 1 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x ^^^ y) + 4 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) - 5 * (x &&& y) =  - 1 *  ~~~y

@[simp, simp_denote, simp_sllvm]
lemma run_map (x : EffectM α) :
    StateT.run (f <$> x : EffectM β) s = (fun p => (f p.1, p.2)) <$> StateT.run x s

theorem e_1189 :
     - 11 *  ~~~(z ^^^ t) + 4 * z + 1 * (z |||  ~~~t) - 5 *  ~~~(z &&& t) + 3 *  ~~~(z &&&  ~~~t) + 23 *  ~~~(z ||| t) + 13 *  ~~~(z |||  ~~~t) + 14 * (z &&& t) =  - 11 * (z &&&  ~~~t) + 11 *  ~~~(z &&&  ~~~z)

@[simp] theorem Hom.castDomain_apply {h : Δ = Δ'} {f : Γ.Hom Δ} {v : Γ.Var t} :
    f.castCodomain h v = (f v).castCtxt h

theorem ashr_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x &&& (BitVec.ofInt 8 (-128)).sshiftRight' (x + 1#8) =
        (BitVec.ofInt 8 (-64)).sshiftRight' x

@[grind ., simp, aesop 50% unsafe]
lemma wf_addManyTrans [LawfulBEq A] (m : RawCNFA A) (hwf : m.WF) s as s'
  (hin : s ∈ m.states) (hin' : s' ∈ m.states) :
    (m.addManyTrans as s s').WF

@[symm] theorem Bisim.symm {a b : Stream α} : a ~ b → b ~ a

theorem neg_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬42#8 = 0 → 0#8 - x ^^^ x / 42#8 = x / 42#8 ^^^ 0#8 - x

theorem and_xor_or8_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x_2 = 0 ∨ x = 0) → x_2 = 0 ∨ x_1 = 0 → False

theorem lshrult_01_05_proof : lshrult_01_05_before ⊑ lshrult_01_05_after

theorem shr_umax_proof : shr_umax_before ⊑ shr_umax_after

lemma complete_stepSet_sink {M : NFA α σ} :
    .inr () ∈ S → .inr () ∈ M.complete.stepSet S a

theorem lshr_shl_pow2_const_case1_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 2#16 ≥ ↑16) → ¬ofBool (x == 7#16) = 1#1 → 256#16 >>> x <<< 2#16 &&& 8#16 = 0#16

theorem sle_swap_and_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 == BitVec.ofInt 8 (-128)) = 1#1 → 0#1 = ofBool (x_1 == BitVec.ofInt 8 (-128))

theorem e_1311 :
     - 1 * t - 11 * z + 1 *  ~~~(z &&& t) + 2 * (z |||  ~~~t) - 3 *  ~~~(z &&&  ~~~t) + 11 * (z ||| t) + 4 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) + 5 * (z &&& t) = 3 *  ~~~(z &&&  ~~~z) + 1 *  ~~~z

theorem e_1018 :
     - 1 * t + 7 *  ~~~(z &&& t) + 1 * (z |||  ~~~t) - 2 * (z ||| t) - 8 *  ~~~(z ||| t) - 6 * (z &&&  ~~~t) + 2 * (z &&& t) = 4 *  ~~~(z |||  ~~~t)

theorem ule_or_min_commute_proof : ule_or_min_commute_before ⊑ ule_or_min_commute_after

theorem zext_lshr_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬4#16 ≥ ↑16 → 4#8 ≥ ↑8 ∨ True ∧ (x >>> 4#8 &&& x).msb = true → False

theorem xor_ashr_not_fail_invalid_xor_constant_thm (e e_1 e_2 : IntW 8) :
  LLVM.xor (ashr e_2 e_1) (LLVM.xor (ashr e e_1) (const? 8 (-2))) ⊑
    LLVM.xor (ashr (LLVM.xor e e_2) e_1) (const? 8 (-2))

theorem test_mul__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 805306368#32) = 1#1 → BitVec.ofInt 32 (-1342177280) = x * 9#32

theorem carry_add_succ (x : Bool → BitStream) (n : ℕ) :
    add.carry x (n+1) =
      fun _ => (BitStream.addAux (x true) (x false) n).2

theorem shl_mul_mask_proof : shl_mul_mask_before ⊑ shl_mul_mask_after

theorem set_shl_mask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → (x_1 ||| 196609#32) <<< x &&& 65536#32 = (x_1 ||| 65537#32) <<< x &&& 65536#32

theorem test_shift_and_cmp_changed1_thm (e e_1 : IntW 8) :
  icmp IntPred.slt
      (ashr (shl (LLVM.or (LLVM.and e_1 (const? 8 8)) (LLVM.and e (const? 8 6))) (const? 8 5)) (const? 8 5))
      (const? 8 1) ⊑
    icmp IntPred.slt (LLVM.and (shl e (const? 8 5)) (const? 8 (-64))) (const? 8 32)

theorem PR42691_1_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.slt e (const? 32 0)) (icmp IntPred.eq e (const? 32 2147483647)) ⊑
    icmp IntPred.ugt e (const? 32 2147483646)

theorem Com.denoteLets_eq {com : Com d Γ eff t} : com.denoteLets = com.toLets.denote

theorem main7g_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 &&& x_2 == x_3 &&& x_2 &&& x_1) = 1#1 →
    ofBool (x_3 &&& x_2 != x_3 &&& x_2 &&& x_1) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem t0_ult_slt_65536_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ 65536#32) = 1#1 →
    ofBool (x_1 <ₛ 65536#32) = 1#1 → ¬ofBool (65535#32 <ₛ x_1) = 1#1 → ¬ofBool (x_1 <ₛ 0#32) = 1#1 → x = x_1

theorem lshrugt_02_12_exact_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 2) { «exact» := true }) (const? 4 (-4)) ⊑ const? 1 0

theorem udiv2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(x ≥ ↑32 ∨ True ∧ x_1.umod (1#32 <<< x) ≠ 0 ∨ 1#32 <<< x = 0) → True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32 → False

theorem lshrugt_02_06_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 2#4 <<< 2#4 ≠ x ∨ 2#4 ≥ ↑4) → ofBool (6#4 <ᵤ x >>> 2#4) = 0#1

@[simp] theorem cons_getElem_toCons (x : A a) (v : Var Γ u)
    (h : as = Γ.toList := by rfl) (h' : a :: as = (Γ.cons a).toList := by rfl) :
    (HVector.cons x xs)[v.toCons (t' := a)]'h' = xs[v]'h

theorem test1_proof : test1_before ⊑ test1_after

theorem test5_proof : test5_before ⊑ test5_after

theorem select_constants_and_icmp_eq0_zero_tval_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x = 1#1 → ofBool (12#8 &&& 12#8 == 0#8) = x

theorem bitwise_and_bitwise_and_icmps_comm2_proof : bitwise_and_bitwise_and_icmps_comm2_before ⊑ bitwise_and_bitwise_and_icmps_comm2_after

theorem sub_from_constant_of_add_with_constant_thm.extracted_1._1 : ∀ (x : BitVec 8),
  11#8 - (x + 42#8) = BitVec.ofInt 8 (-31) - x

theorem test_ne_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1073741823#32 != 0#32) = 1#1 → 2#32 ≥ ↑32 → False

theorem scalar_i64_shl_and_negC_eq_proof : scalar_i64_shl_and_negC_eq_before ⊑ scalar_i64_shl_and_negC_eq_after

theorem ugt_swap_and_min_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ult e_1 e) (icmp IntPred.eq e (const? 8 0)) (const? 1 0) ⊑ const? 1 0

theorem ashrsgt_01_13_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) →
    ofBool (BitVec.ofInt 4 (-3) <ₛ x.sshiftRight' 1#4) = ofBool (BitVec.ofInt 4 (-6) <ₛ x)

theorem sext_sext_add_mismatched_types_proof : sext_sext_add_mismatched_types_before ⊑ sext_sext_add_mismatched_types_after

theorem t2_thm (e : IntW 64) :
  sub (const? 32 0) (trunc 32 (ashr e (const? 64 63))) ⊑
    trunc 32 (lshr e (const? 64 63)) { «nsw» := true, «nuw» := true }

theorem sextinreg_thm (e : IntW 32) :
  add (LLVM.xor (LLVM.and e (const? 32 65535)) (const? 32 (-32768))) (const? 32 32768) ⊑
    ashr (shl e (const? 32 16)) (const? 32 16) { «exact» := true }

theorem masked_and_notA_slightly_optimized_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.uge e (const? 32 8)) (icmp IntPred.ne (LLVM.and e (const? 32 39)) e) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 (-40))) (const? 32 0)

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
lemma processOneElem_preserves_mem (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s : State) :
    let st' := processOneElem _ _  final s st (a, sa')
    sa ∈ st.map →
    sa ∈ st'.map

theorem test22_logical_proof : test22_logical_before ⊑ test22_logical_after

theorem fold_icmp_shl_nuw_c2_non_pow2_thm (e : IntW 32) :
  icmp IntPred.ult (shl (const? 32 48) e { «nsw» := false, «nuw» := true }) (const? 32 192) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem bitwise_and_logical_and_icmps_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 == 42#8) = 1#1 →
    ¬x ≥ ↑8 →
      ¬(True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8) →
        ofBool (x_1 &&& 1#8 != 0#8) &&& ofBool (x_1 &&& 1#8 <<< x != 0#8) =
          ofBool (x_1 &&& (1#8 <<< x ||| 1#8) == 1#8 <<< x ||| 1#8)

theorem main4c_proof : main4c_before ⊑ main4c_after

theorem t1_ult_slt_0_thm.extracted_1._10 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 <ᵤ 65536#32) = 1#1 → ofBool (x_2 <ₛ 0#32) = 1#1 → ofBool (65535#32 <ₛ x_2) = 1#1 → x_1 = x

theorem PR44545_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 →
    ¬(True ∧ x.saddOverflow 1#32 = true ∨ True ∧ x.uaddOverflow 1#32 = true) →
      ¬(True ∧ (truncate 16 (x + 1#32)).saddOverflow (-1#16) = true) → truncate 16 (x + 1#32) + -1#16 = truncate 16 x

theorem e_615 :
    7 *  ~~~(x ^^^ y) - 1 *  ~~~x - 5 *  ~~~(x &&&  ~~~y) + 3 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) + 5 * (x ||| y) - 1 * x - 7 *  ~~~(x ||| y) - 10 * (x &&&  ~~~y) - 9 * (x &&& y) = 2 *  ~~~(x |||  ~~~y)

theorem nonexact_lshr_ne_noexactlog_proof : nonexact_lshr_ne_noexactlog_before ⊑ nonexact_lshr_ne_noexactlog_after

theorem negate_lowbitmask_proof : negate_lowbitmask_before ⊑ negate_lowbitmask_after

theorem test47_thm (e : IntW 8) :
  zext 64 (LLVM.or (sext 32 e) (const? 32 42)) ⊑ zext 64 (sext 32 (LLVM.or e (const? 8 42)))

theorem ashrsgt_01_10_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (BitVec.ofInt 4 (-6) <ₛ x.sshiftRight' 1#4) = 1#1

theorem e_2360 :
     - 1 * ( ~~~d ||| (e ||| f)) - 3 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 *  ~~~(d |||  ~~~e) + 7 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (f ||| (d &&& e)) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 *  ~~~(d ^^^ e) - 11 * ((d &&& e) ||| (e ^^^ f)) - 1 * (d ||| e) - 2 * (e ^^^ (d ||| (e &&& f))) + 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 3 * ( ~~~d ||| ( ~~~e ||| f)) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 5 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 5 *  ~~~(d ||| (e ^^^ f)) - 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 11 * ( ~~~d &&& (e ^^^ f)) - 6 *  ~~~(d &&&  ~~~f) + 2 * (e &&&  ~~~f) - 7 *  ~~~(d &&& (e &&& f)) - 11 *  ~~~(d &&& e) - 5 * (e ^^^ f) + 5 * ( ~~~f &&& (d ^^^ e)) + 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 4 * (e ^^^  ~~~(d ||| (e &&& f))) + 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 *  ~~~e - 1 * (e ^^^ (d |||  ~~~f)) + 7 * ( ~~~f &&&  ~~~(d ^^^ e)) - 11 *  ~~~d - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (d ^^^ ( ~~~e ||| f)) - 6 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) + 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * (e ||| (d &&&  ~~~f)) + 4 *  ~~~(d &&&  ~~~d) - 2 * (d ^^^ (e ^^^ f)) + 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f |||  ~~~(d ||| e)) + 4 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (d &&&  ~~~e) + 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 4 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 7 * (d ||| ( ~~~e ||| f)) + 3 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (d &&& e) - 2 *  ~~~(e |||  ~~~f) - 5 *  ~~~(e ^^^ f) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 5 * (f &&&  ~~~(d &&&  ~~~e)) + 11 *  ~~~(e &&& f) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 6 * (d &&& (e ^^^ f)) - 3 * ( ~~~e &&& (d ^^^ f)) + 17 *  ~~~(d ||| (e ||| f)) - 7 *  ~~~(d ||| ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ||| f)) + 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 22 * ( ~~~d &&& ( ~~~e &&& f)) + 25 * ( ~~~d &&& (e &&& f)) + 24 * (d &&& ( ~~~e &&& f)) + 29 * (d &&& (e &&& f)) = 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f)))

theorem test6_proof : test6_before ⊑ test6_after

theorem ashrsgt_02_08_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2) { «exact» := true }) (const? 4 (-8)) ⊑ const? 1 1

theorem xor_or_thm.extracted_1._4 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → 1#1 ^^^ 1#1 = 0#1

theorem positive_with_signbit_proof : positive_with_signbit_before ⊑ positive_with_signbit_after

theorem ugt_or_not_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 0#8) = 1#1 → ofBool (x <ᵤ x_1) = ofBool (x_1 != 0#8)

theorem simplify_or_common_op_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  x_2 &&& x_1 &&& x ^^^ -1#4 ||

theorem and_sel_op0_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#32 &&& 1#32 = zeroExtend 32 x

theorem xor_nosignbit_select_ashr_thm (e : IntW 32) (e_1 : IntW 1) :
  ashr (select e_1 (LLVM.xor e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (LLVM.xor (ashr e (const? 32 8)) (const? 32 8388352)) (ashr e (const? 32 8))

theorem samesign_inverted_commute3_proof : samesign_inverted_commute3_before ⊑ samesign_inverted_commute3_after

theorem uadd_sat_canon_y_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.uaddOverflow x = true) → ofBool (x_1 + x <ᵤ x) = 1#1 → -1#32 = x_1 + x

theorem ugt_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umulOverflow 5#8 = true) → ofBool (21#8 <ᵤ x * 5#8) = ofBool (4#8 <ᵤ x)

theorem or_sext_to_sel_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 32 x_1 ||

theorem e_74 :
     - 6 * (x ||| y) + 4 * (x ^^^ y) + 2 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) + 2 * (x &&&  ~~~y) = 2 *  ~~~x - 6 * (x &&& y)

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

theorem sel_false_val_is_a_masked_ashr_of_true_val1_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2147483588) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
              zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

theorem not_or_or_and_not_and_and_commute2_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (LLVM.or (LLVM.or (LLVM.xor e_2 (const? 32 (-1))) e_1) (LLVM.sdiv (const? 32 42) e))
      (LLVM.xor (LLVM.and (LLVM.sdiv (const? 32 42) e) (LLVM.and e_1 e_2)) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.xor (LLVM.sdiv (const? 32 42) e) e_1) (LLVM.xor e_2 (const? 32 (-1)))

theorem fold_mask_cmps_to_true_proof : fold_mask_cmps_to_true_before ⊑ fold_mask_cmps_to_true_after

theorem sdiv_shl_pair3_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        x_1 ≥ ↑32 ∨
          True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
            x ≥ ↑32 ∨ (x_2 <<< x == 0 || 32 != 1 && x_2 <<< x_1 == intMin 32 && x_2 <<< x == -1) = true) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32) → (x_2 <<< x_1).sdiv (x_2 <<< x) = 1#32 <<< x_1 >>> x

theorem logic_and_logic_or_3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x = 1#1 → 1#1 = x

theorem test_with_1_proof : test_with_1_before ⊑ test_with_1_after

theorem test6a_thm.extracted_1._1 : ∀ (x : BitVec 1), ofBool (zeroExtend 32 x != -1#32) = 1#1

theorem PR42691_3_logical_thm (e : IntW 32) :
  select (icmp IntPred.sge e (const? 32 0)) (const? 1 1) (icmp IntPred.eq e (const? 32 (-2147483648))) ⊑
    icmp IntPred.ult e (const? 32 (-2147483647))

theorem test1_thm (e : IntW 17) :
  trunc 17 (LLVM.or (lshr (zext 37 e) (const? 37 8)) (shl (zext 37 e) (const? 37 8))) ⊑
    LLVM.or (lshr e (const? 17 8)) (shl e (const? 17 8))

theorem masked_icmps_mask_notallzeros_bmask_mixed_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_0_logical_after

theorem test_zext1_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#32 = zeroExtend 32 0#1

theorem test19_thm (e : IntW 32) : LLVM.and (shl e (const? 32 3)) (const? 32 (-2)) ⊑ shl e (const? 32 3)

@[simp low]
theorem eval_latchImmediate_zero_eq (initVal : Bool)
    (x : Bool → BitStream) :
    (latchImmediate initVal).eval x 0 =
      if (x true 0) then (x false 0) else initVal

theorem bad_shl2_sub_i32_proof : bad_shl2_sub_i32_before ⊑ bad_shl2_sub_i32_after

theorem e_1059 :
     - 2 *  ~~~(z ^^^ t) + 1 *  ~~~t - 3 * z - 5 *  ~~~(z &&&  ~~~z) + 6 *  ~~~(z ||| t) + 7 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 5 *  ~~~(z |||  ~~~t)

theorem lor_land_right2_proof : lor_land_right2_before ⊑ lor_land_right2_after

theorem logic_or_logic_and_7_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → 0#1 = 1#1

theorem shl_nsw_nuw_uge_Csle0_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (shl e_1 e { «nsw» := true, «nuw» := true }) (const? 8 (-120)) ⊑
    icmp IntPred.ugt e_1 (const? 8 (-121))

theorem ne_umin2_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (select (icmp IntPred.ult e_1 e) e_1 e) e ⊑ icmp IntPred.ugt e e_1

theorem test_mul_nsw__nsw_is_safe_proof : test_mul_nsw__nsw_is_safe_before ⊑ test_mul_nsw__nsw_is_safe_after

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

theorem test_shl_nsw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨
        True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
          zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64 →
      False

theorem trunc_ashr_trunc_outofrange_thm (e : IntW 64) :
  trunc 8 (ashr (trunc 32 e) (const? 32 25)) ⊑
    trunc 8 (ashr (trunc 32 e) (const? 32 25)) { «nsw» := true, «nuw» := false }

theorem toTensor_length_eq_rep_length [Fact (q > 1)] (a : R q n) :
  a.toTensor.length = a.repLength

theorem main12_thm (e : IntW 32) :
  select (LLVM.or (icmp IntPred.slt (trunc 16 e) (const? 16 0)) (icmp IntPred.slt (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 32896)) (const? 32 0)) (const? 32 1) (const? 32 2)

theorem icmp_select_var_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 == 0#8) = 1#1 → ofBool (x == x) = 1#1

theorem t2_ult_sgt_65536_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ 65536#32) = 1#1 → ¬ofBool (65535#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → False

theorem eq_irregular_bit_widths_proof : eq_irregular_bit_widths_before ⊑ eq_irregular_bit_widths_after

theorem sext_sext_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 <ₛ signExtend 32 x) = ofBool (x_1 <ₛ x)

theorem logical_and_logical_and_icmps_proof : logical_and_logical_and_icmps_before ⊑ logical_and_logical_and_icmps_after

theorem ripple_no_nsw2_proof : ripple_no_nsw2_before ⊑ ripple_no_nsw2_after

theorem add_and_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) + (x_1 ||| x) = x_1 + x

theorem or_trunc_lshr_more_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬4#8 ≥ ↑8 →
    ¬(4#6 ≥ ↑6 ∨ True ∧ (truncate 6 x >>> 4#6 &&& BitVec.ofInt 6 (-4) != 0) = true) →
      truncate 6 (x >>> 4#8) ||

theorem e_1641 :
     - 2 * (b ^^^ (a |||  ~~~c)) - 3 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 7 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 2 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 7 * (c &&& (a |||  ~~~b)) - 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 3 * (b ^^^ (a ||| ( ~~~b ||| c))) + 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 11 *  ~~~(b |||  ~~~c) + 4 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 11 * (c ^^^ (a &&& (b ||| c))) - 1 *  ~~~(a ||| (b ^^^ c)) - 2 *  ~~~(a &&& (b ^^^ c)) + 5 *  ~~~(a ||| (b ||| c)) - 10 *  ~~~(a ||| ( ~~~b ||| c)) - 8 *  ~~~( ~~~a ||| (b ||| c)) - 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 16 * ( ~~~a &&& ( ~~~b &&& c)) - 7 * ( ~~~a &&& (b &&& c)) + 1 * (a &&& ( ~~~b &&& c)) - 11 * (a &&& (b &&& c)) =  - 1 *  ~~~(a ^^^ c)

theorem ne_rem_zero_nonuw_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x * 5#8 != 30#8) = ofBool (x != 6#8)

theorem icmp_ugt_proof : icmp_ugt_before ⊑ icmp_ugt_after

theorem shl_lshr_and_exact_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨
        x_1 ≥ ↑32 ∨ True ∧ (x_2 <<< x_1 &&& x) >>> x_1 <<< x_1 ≠ x_2 <<< x_1 &&& x ∨ x_1 ≥ ↑32) →
    x_1 ≥ ↑32 → False

theorem PR42691_3_logical_proof : PR42691_3_logical_before ⊑ PR42691_3_logical_after

theorem lshrugt_03_04_proof : lshrugt_03_04_before ⊑ lshrugt_03_04_after

theorem test15_proof : test15_before ⊑ test15_after

theorem bitwise_and_logical_and_masked_icmp_asymmetric_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 &&& 255#32 != 0#32) = 1#1 →
    ¬ofBool (x_1 &&& 11#32 == 11#32) = 1#1 → x &&& ofBool (x_1 &&& 11#32 == 11#32) = 0#1

theorem eq_21_proof : eq_21_before ⊑ eq_21_after

theorem PR30273_three_bools_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 →
    ¬x_1 = 1#1 →
      ¬(True ∧ (zeroExtend 32 x).saddOverflow 1#32 = true) →
        ¬(True ∧ (zeroExtend 32 x).saddOverflow (zeroExtend 32 x_2) = true ∨
              True ∧ (zeroExtend 32 x).uaddOverflow (zeroExtend 32 x_2) = true) →
          zeroExtend 32 x + 1#32 = zeroExtend 32 x + zeroExtend 32 x_2

theorem narrow_sext_mul_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (signExtend 32 x_1 * x) = x_1 * truncate 16 x

theorem masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_after

lemma sim_full_cod (m : RawCNFA A) (M : NFA A Q) (D : Set Q) (T : Set (Q × A × Q)) R :
    T = ∅ →
    m.Simul M R D T →
    R.cod = D →
    m.Sim M

@[aesop 50% unsafe]
theorem Std.HashMap.mem_of_getElem? [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} :
    m[k]? = some v → k ∈ m

theorem zext_sext_add_icmp_sgt_minus1_proof : zext_sext_add_icmp_sgt_minus1_before ⊑ zext_sext_add_icmp_sgt_minus1_after

theorem and_shl_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 <<< x_2 &&& (x_1 <<< x_2 &&& x) = (x_1 &&& x_3) <<< x_2 &&& x

theorem AvoidCollision_setWidth_add_eq_mod {x y : BitVec w} : BitVec.setWidth i (x + y) = (BitVec.setWidth i x + BitVec.setWidth i y) % (BitVec.twoPow i w)

theorem or_ne_notY_eq_1s_proof : or_ne_notY_eq_1s_before ⊑ or_ne_notY_eq_1s_after

theorem and_or3_proof : and_or3_before ⊑ and_or3_after

theorem sdiv_exact_ne_1_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.sdiv e_1 e { «exact» := true }) (const? 8 0) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

theorem sext_multiuse_proof : sext_multiuse_before ⊑ sext_multiuse_after

theorem sle_or_not_min_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-128))) (icmp IntPred.sle e_1 e) ⊑ const? 1 1

theorem src_is_mask_shl_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬(x ≥ ↑8 ∨ x ≥ ↑8) → x ≥ ↑8 → False

theorem sge_and_max_logical_samesign_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sge e_1 e) (icmp IntPred.eq e_1 (const? 8 127)) (const? 1 0) ⊑
    icmp IntPred.eq e_1 (const? 8 127)

theorem logical_and_bitwise_and_icmps_comm3_proof : logical_and_bitwise_and_icmps_comm3_before ⊑ logical_and_bitwise_and_icmps_comm3_after

theorem main2_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e (const? 32 1)) (const? 32 0)) (const? 1 1)
        (icmp IntPred.eq (LLVM.and e (const? 32 2)) (const? 32 0)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 3)) (const? 32 3))

theorem ashrsgt_01_03_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (3#4 <ₛ x.sshiftRight' 1#4) = 0#1

theorem e_1475 :
     - 2 *  ~~~(z &&&  ~~~t) - 2 *  ~~~t + 1 * t + 2 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z ^^^ t) - 3 * (z ||| t) - 19 *  ~~~(z ||| t) - 16 *  ~~~(z |||  ~~~t) - 3 * (z &&&  ~~~t) - 5 * (z &&& t) = 1 * z - 11 *  ~~~z

theorem test22_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2147483647#32 == 0 || 32 != 1 && x &&& 2147483647#32 == intMin 32 && 2147483647#32 == -1) = true →
    ¬2147483647#32 = 0 → (x &&& 2147483647#32).srem 2147483647#32 = (x &&& 2147483647#32) % 2147483647#32

theorem BitVec.even_mul_eq_shiftLeft_mul_of_eq_mul_two
    (w : Nat) (x : BitVec w) (n e : Nat) (he : e = n * 2) :
    (BitVec.ofNat w e) * x = (BitVec.ofNat w n) * (x <<< (1 : Nat))

theorem scalar_i64_lshr_and_signbit_eq_proof : scalar_i64_lshr_and_signbit_eq_before ⊑ scalar_i64_lshr_and_signbit_eq_after

theorem shl_add_log_may_cause_poison_pr62175_with_nsw_thm (e e_1 : IntW 8) :
  mul e_1 (shl (const? 8 4) e { «nsw» := true, «nuw» := false }) ⊑ shl e_1 (add e (const? 8 2))

theorem e_693 :
     - 11 * x + 1 *  ~~~(x &&& y) + 2 *  ~~~(x &&&  ~~~x) + 1 *  ~~~x + 1 * (x |||  ~~~y) + 1 * y + 1 *  ~~~(x ^^^ y) - 6 *  ~~~y + 13 * (x &&&  ~~~y) + 6 * (x &&& y) = 5 *  ~~~(x |||  ~~~y)

theorem alive_283   : alive_283_src ⊑ alive_283_tgt

theorem and_xor_or4_thm (e e_1 e_2 : IntW 64) :
  LLVM.or
      (LLVM.xor (LLVM.udiv (const? 64 42) e_2) (LLVM.and (LLVM.udiv (const? 64 42) e_1) (LLVM.udiv (const? 64 42) e)))
      (LLVM.udiv (const? 64 42) e_1) ⊑
    LLVM.or (LLVM.udiv (const? 64 42) e_2) (LLVM.udiv (const? 64 42) e_1)

theorem and1_lshr1_is_cmp_eq_0_proof : and1_lshr1_is_cmp_eq_0_before ⊑ and1_lshr1_is_cmp_eq_0_after

theorem max_sub_uge_c32_proof : max_sub_uge_c32_before ⊑ max_sub_uge_c32_after

theorem test18 (x y : BitVec w) : (x &&&  (~~~ y)) = ((x ||| y) - y)

theorem narrow_zext_xor_proof : narrow_zext_xor_before ⊑ narrow_zext_xor_after

theorem test_negative_combined_sub_unsigned_overflow_thm (e : IntW 64) :
  icmp IntPred.ult (sub (const? 64 10) e { «nsw» := false, «nuw» := true }) (const? 64 11) ⊑ const? 1 1

theorem p0_thm (e : IntW 8) :
  icmp IntPred.sge (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 4)

theorem shl_sub_lshr_reverse_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨
        x ≥ ↑32 ∨
          True ∧ x_2.ssubOverflow (x_1 <<< x) = true ∨
            True ∧ x_2.usubOverflow (x_1 <<< x) = true ∨
              True ∧ (x_2 - x_1 <<< x) >>> x <<< x ≠ x_2 - x_1 <<< x ∨ x ≥ ↑32) →
    ¬(True ∧ x_2 >>> x <<< x ≠ x_2 ∨
          x ≥ ↑32 ∨ True ∧ (x_2 >>> x).ssubOverflow x_1 = true ∨ True ∧ (x_2 >>> x).usubOverflow x_1 = true) →
      (x_2 - x_1 <<< x) >>> x = x_2 >>> x - x_1

theorem shl_sub_lshr_reverse_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨
        x ≥ ↑32 ∨
          True ∧ x_2.ssubOverflow (x_1 <<< x) = true ∨
            True ∧ x_2.usubOverflow (x_1 <<< x) = true ∨
              True ∧ (x_2 - x_1 <<< x) >>> x <<< x ≠ x_2 - x_1 <<< x ∨ x ≥ ↑32) →
    True ∧ x_2 >>> x <<< x ≠ x_2 ∨
        x ≥ ↑32 ∨ True ∧ (x_2 >>> x).ssubOverflow x_1 = true ∨ True ∧ (x_2 >>> x).usubOverflow x_1 = true →
      False

theorem e_1987 :
     - 3 * (b |||  ~~~(a |||  ~~~c)) + 3 * (a &&& ( ~~~b ||| c)) - 11 * ( ~~~a ||| ( ~~~b ||| c)) - 7 * b - 3 *  ~~~( ~~~a ||| (b &&& c)) + 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 2 *  ~~~(a &&& (b ^^^ c)) - 7 * (c ^^^ (a ||| (b ||| c))) + 1 * ( ~~~b &&& (a ^^^ c)) + 1 * (b ^^^ ( ~~~a ||| (b &&& c))) - 2 * (b ^^^ (a ||| ( ~~~b &&& c))) - 6 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 1 *  ~~~(a ||| b) + 3 * (c &&&  ~~~(a &&&  ~~~b)) - 3 * (c ^^^ (a ||| (b &&& c))) - 2 * (b ^^^ (a &&& (b ^^^ c))) - 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 11 *  ~~~(b |||  ~~~c) + 7 * (b ^^^  ~~~(a &&& c)) + 2 * (b ^^^ (a ||| c)) - 1 *  ~~~(b &&& c) + 3 *  ~~~(a &&&  ~~~b) - 1 * (a &&&  ~~~c) + 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 4 * (c ^^^ (a ||| b)) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 1 *  ~~~(a |||  ~~~b) - 11 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * ( ~~~a ||| (b &&& c)) - 5 * (b ^^^  ~~~(a |||  ~~~c)) - 1 * ((a ^^^ b) &&& (a ^^^ c)) + 4 * (a ||| (b ^^^ c)) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * (b ^^^ c) + 11 * (b |||  ~~~(a ||| c)) + 1 * (b ||| c) - 3 * (c ||| (a ^^^ b)) + 5 * (c ^^^ (a &&& b)) - 6 *  ~~~(a ||| (b ^^^ c)) - 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 3 * (a &&& (b ^^^ c)) + 7 *  ~~~(a |||  ~~~c) + 4 * ((a ^^^ b) ||| (a ^^^ c)) - 1 *  ~~~(a &&& b) - 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 5 * (b ^^^  ~~~(a ||| c)) - 2 * (b ^^^ (a &&& (b ||| c))) - 1 * (a &&& (b ||| c)) - 1 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 3 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 4 *  ~~~(a ||| (b ||| c)) + 29 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| (b ||| c)) + 9 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) + 8 * ( ~~~a &&& (b &&& c)) + 21 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) =  - 5 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c)))

theorem and_shl_proof : and_shl_before ⊑ and_shl_after

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

theorem select_icmp_and_2147483648_ne_0_xor_2147483648_proof : select_icmp_and_2147483648_ne_0_xor_2147483648_before ⊑ select_icmp_and_2147483648_ne_0_xor_2147483648_after

theorem src_proof : src_before ⊑ src_after

theorem bitwise_and_bitwise_and_icmps_comm2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x ≥ ↑8 →
    ¬(True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8) →
      ofBool (x_2 &&& 1#8 != 0#8) &&& ofBool (x_1 == 42#8) &&& ofBool (x_2 &&& 1#8 <<< x != 0#8) =
        ofBool (x_2 &&& (1#8 <<< x ||| 1#8) == 1#8 <<< x ||| 1#8) &&& ofBool (x_1 == 42#8)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 15#32 != 8#32) = 1#1 → 1#1 = ofBool (x &&& 15#32 != 8#32)

theorem icmp_and_ashr_multiuse_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬4#32 ≥ ↑32 →
    ofBool (x.sshiftRight' 4#32 &&& 15#32 != 14#32) = 1#1 →
      ofBool (x.sshiftRight' 4#32 &&& 31#32 != 27#32) =
        ofBool (x &&& 240#32 != 224#32) &&& ofBool (x &&& 496#32 != 432#32)

theorem icmp_mul_nsw_slt_proof : icmp_mul_nsw_slt_before ⊑ icmp_mul_nsw_slt_after

theorem negative4_logical_proof : negative4_logical_before ⊑ negative4_logical_after

theorem select_constants_and_icmp_eq0_zero_fval_proof : select_constants_and_icmp_eq0_zero_fval_before ⊑ select_constants_and_icmp_eq0_zero_fval_after

theorem ashr_ult_6_proof : ashr_ult_6_before ⊑ ashr_ult_6_after

theorem sext_sub_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8), x_1 - signExtend 8 x = x_1 + zeroExtend 8 x

theorem sextinreg_thm.extracted_1._1 : ∀ (x : BitVec 32),
  16#32 ≥ ↑32 ∨ True ∧ x <<< 16#32 >>> 16#32 <<< 16#32 ≠ x <<< 16#32 ∨ 16#32 ≥ ↑32 → False

theorem bar_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_2 <ₛ x_1) = 1#1 →
    x_3 &&& (signExtend 32 (ofBool (x_2 <ₛ x_1)) ^^^ -1#32) ||

theorem mul_constant_eq_proof : mul_constant_eq_before ⊑ mul_constant_eq_after

theorem t0_proof : t0_before ⊑ t0_after

@[bv_multi_width_normalize] theorem neg_ofBool_eq (x : Bool) :
  - (BitVec.ofBool x) = BitVec.ofBool x

theorem icmp_sle4_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 (-2)) ⊑
    icmp IntPred.slt e (const? 8 0)

theorem unsigned_sign_bit_extract_with_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ofBool (truncate 32 (x >>> 63#64) != 0#32) = ofBool (x <ₛ 0#64)

theorem zext_zext_ule_op0_wide_proof : zext_zext_ule_op0_wide_before ⊑ zext_zext_ule_op0_wide_after

@[simp]
theorem BitVec.zero_concat (b : Bool) : (0#0).concat b = BitVec.ofBool b

theorem or_and_not_not_commute6_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.and (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))))
      (LLVM.xor (LLVM.or (LLVM.sdiv (const? 32 42) e_2) e) (const? 32 (-1))) ⊑
    LLVM.xor (LLVM.or (LLVM.and e_1 (LLVM.sdiv (const? 32 42) e_2)) e) (const? 32 (-1))

theorem t0_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smod (BitVec.ofInt 8 (-32)) ≠ 0 ∨
        (BitVec.ofInt 8 (-32) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-32) == -1) = true) →
    ¬(True ∧ x >>> 5#8 <<< 5#8 ≠ x ∨ 5#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 5#8) = true) →
      x.sdiv (BitVec.ofInt 8 (-32)) = 0#8 - x.sshiftRight' 5#8

theorem test19a_thm.extracted_1._1 : ∀ (x : BitVec 39),
  ¬2#39 ≥ ↑39 → ofBool (x.sshiftRight' 2#39 == -1#39) = ofBool (BitVec.ofInt 39 (-5) <ᵤ x)

theorem xor_of_icmps_to_ne_commute_proof : xor_of_icmps_to_ne_commute_before ⊑ xor_of_icmps_to_ne_commute_after

theorem ashr_16_to_64_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#64 ≥ ↑64 →
    (zeroExtend 64 x_1 + zeroExtend 64 x).sshiftRight' 16#64 = zeroExtend 64 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

theorem ashrsgt_03_09_proof : ashrsgt_03_09_before ⊑ ashrsgt_03_09_after

theorem and_or1_commuted_proof : and_or1_commuted_before ⊑ and_or1_commuted_after

theorem zext_zext_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.eq e_1 e

theorem or_not_and_commute3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ((x_2 ||| x_1) ^^^ -1#32) &&& x ||

theorem xor_of_icmps_to_eq_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ BitVec.ofInt 8 (-128)) ^^^ ofBool (126#8 <ₛ x) = ofBool (x == 127#8)

theorem and_and_proof : and_and_before ⊑ and_and_after

theorem e_2059 :
    2 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (e ||| (d &&& f)) + 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (d &&& e) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * (e ^^^ ( ~~~d ||| (e ||| f))) + 7 * (f &&& (d ^^^ e)) - 1 * (f &&&  ~~~(d ^^^ e)) - 11 * (f ^^^  ~~~(d ||| (e &&& f))) - 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 *  ~~~(d &&&  ~~~f) + 1 *  ~~~(d ||| ( ~~~e &&& f)) - 3 * (f &&&  ~~~(d &&&  ~~~e)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) + 5 * (e ^^^ (d ||| (e &&& f))) - 3 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 7 * (e &&&  ~~~(d &&& f)) - 1 *  ~~~(d ||| (e &&& f)) - 3 * ( ~~~e &&& (d ^^^ f)) - 7 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 5 * ( ~~~d &&& (e ||| f)) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 11 *  ~~~(d ||| e) + 12 *  ~~~(d ||| (e ||| f)) + 5 *  ~~~(d ||| ( ~~~e ||| f)) - 1 *  ~~~( ~~~d ||| (e ||| f)) + 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 23 * ( ~~~d &&& ( ~~~e &&& f)) + 9 * ( ~~~d &&& (e &&& f)) - 9 * (d &&& ( ~~~e &&& f)) + 8 * (d &&& (e &&& f)) =  - 1 * (d |||  ~~~f) - 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f)))

theorem ult_1_impliesF_eq_1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ofBool (x <ᵤ 1#8) = 1#1 → ¬ofBool (x != 0#8) = 1#1 → ofBool (x == 1#8) = 0#1

theorem test8_proof : test8_before ⊑ test8_after

theorem and_or_not_not_commute3_proof : and_or_not_not_commute3_before ⊑ and_or_not_not_commute3_after

theorem test10_proof : test10_before ⊑ test10_after

theorem ashrsgt_02_09_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 2)) (const? 4 (-7)) ⊑ const? 1 1

theorem e_1280 :
    11 * z - 2 *  ~~~z - 2 * (z ^^^ t) - 5 *  ~~~(z &&& t) + 3 *  ~~~(z &&&  ~~~t) - 3 * (z ||| t) + 4 *  ~~~(z ||| t) + 9 *  ~~~(z |||  ~~~t) - 11 * (z &&& t) = 1 * (z &&&  ~~~t)

theorem trunc_proof : trunc_before ⊑ trunc_after

theorem main3e_like_logical_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 == 0#32) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != 0#32) = 1#1 →
      ¬ofBool (x_2 &&& x == 0#32) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x_2 &&& x != 0#32))

theorem substitute_constant_and_eq_eq_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e_1 e) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42))

theorem lshrugt_01_14_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (BitVec.ofInt 4 (-2) <ᵤ x >>> 1#4) = 0#1

theorem lshrugt_02_08_exact_proof : lshrugt_02_08_exact_before ⊑ lshrugt_02_08_exact_after

theorem test_add_nsw__none_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq e (const? 32 3)) (const? 32 4) (add e (const? 32 1) { «nsw» := true, «nuw» := false }) ⊑
    add e (const? 32 1)

theorem bitwise_and_bitwise_and_icmps_comm3_thm (e e_1 e_2 : IntW 8) :
  LLVM.and (icmp IntPred.ne (LLVM.and e_2 (shl (const? 8 1) e_1)) (const? 8 0))
      (LLVM.and (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0))
        (icmp IntPred.eq e (const? 8 42))) ⊑
    LLVM.and
      (icmp IntPred.eq
        (LLVM.and e_2 (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
        (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
      (icmp IntPred.eq e (const? 8 42))

theorem test14_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) → 8#32 ≥ ↑32 → False

@[simp] lemma liftMaxSuccSucc2_cast {x : Fin m} : liftMaxSuccSucc2 n m x.castSucc = x.castLE (by omega)

theorem test_mul__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 268435457#32 == 268435456#32) = 1#1 → True ∧ (x &&& 268435457#32).umulOverflow 9#32 = true → False

theorem carry_incr (x : Unit → BitStream) : ∀ (n : ℕ),
    incr.carry x (n+1) = fun _ => (BitStream.incrAux (x ()) n).2

theorem test_or3_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sle (LLVM.and e_1 (const? 32 2147483647)) e) (const? 1 1)
      (icmp IntPred.slt e (const? 32 0)) ⊑
    icmp IntPred.uge e (LLVM.and e_1 (const? 32 2147483647))

theorem ashr_mul_times_3_div_2_exact_2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 3#32 = true ∨ True ∧ (x * 3#32) >>> 1#32 <<< 1#32 ≠ x * 3#32 ∨ 1#32 ≥ ↑32) →
    ¬(True ∧ x >>> 1#32 <<< 1#32 ≠ x ∨ 1#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x.sshiftRight' 1#32) = true) →
      (x * 3#32).sshiftRight' 1#32 = x + x.sshiftRight' 1#32

theorem bv_AndOrXor_1253_A__AB___A__B :
    ∀ (e e_1 : LLVM.IntW w), LLVM.and (LLVM.xor e e_1) e ⊑ LLVM.and e (LLVM.xor e_1 (LLVM.const? w (-1)))

theorem and_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 4),
  signExtend 16 x_1 &&& signExtend 16 x = signExtend 16 (x &&& signExtend 8 x_1)

theorem and_logic_and_logic_or_8_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#1 = 1#1 → False

theorem test9_thm (e : IntW 32) : urem (mul e (const? 32 64)) (const? 32 32) ⊑ const? 32 0

theorem sle_swap_or_not_min_proof : sle_swap_or_not_min_before ⊑ sle_swap_or_not_min_after

theorem samesign_inverted_different_sign_bittest2_proof : samesign_inverted_different_sign_bittest2_before ⊑ samesign_inverted_different_sign_bittest2_after

theorem sext_multi_uses_proof : sext_multi_uses_before ⊑ sext_multi_uses_after

theorem scalar1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 4),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 4 (-2) &&& (x &&& 1#4) != 0) = true) →
    (x_1 ^^^ x) &&& BitVec.ofInt 4 (-2) ^^^ x = x_1 &&& BitVec.ofInt 4 (-2) ||

theorem test13_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 ((signExtend 128 x_1).sshiftRight' (zeroExtend 128 x &&& 31#128)) =
        (signExtend 64 x_1).sshiftRight' (zeroExtend 64 (x &&& 31#32))

theorem n8_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 1#32) = 1#1 → ¬ofBool (x &&& 1#32 == 0#32) = 1#1 → ¬2#32 ≥ ↑32 → 1#32 = x >>> 2#32 &&& 1#32

theorem demorgan_nor_use2a_proof : demorgan_nor_use2a_before ⊑ demorgan_nor_use2a_after

theorem icmp_eq_and_pow2_minus1_shl_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 15#32 == 0#32)) = zeroExtend 32 (ofBool (2#32 <ᵤ x))

theorem test51_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → True ∧ (truncate 32 x &&& BitVec.ofInt 32 (-2) &&& zeroExtend 32 (x_1 ^^^ 1#1) != 0) = true → False

theorem canonicalize_logic_first_and0_nswnuw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.saddOverflow 48#8 = true ∨ True ∧ x.uaddOverflow 48#8 = true) →
    ¬(True ∧ (x &&& BitVec.ofInt 8 (-10)).saddOverflow 48#8 = true ∨
          True ∧ (x &&& BitVec.ofInt 8 (-10)).uaddOverflow 48#8 = true) →
      x + 48#8 &&& BitVec.ofInt 8 (-10) = (x &&& BitVec.ofInt 8 (-10)) + 48#8

theorem List.attachWith_nodup (l : List α) (hnd : l.Nodup) P H : (l.attachWith P H).Nodup

theorem lt_unsigned_to_large_signed_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (zeroExtend 32 x <ₛ 1024#32) = 1#1

theorem e_1647 :
     - 1 * (b ^^^ (a ||| (b &&& c))) + 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (b ^^^ (a ||| c)) - 7 * (b ^^^ (a &&& c)) - 7 * (a |||  ~~~b) - 5 * ((a &&& c) ^^^ (b ||| c)) + 7 * (b ||| (a &&&  ~~~c)) - 6 * (c ^^^ (a &&& ( ~~~b ||| c))) + 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 * ( ~~~c &&& (a ^^^ b)) - 1 * (b &&&  ~~~(a &&&  ~~~c)) - 3 * c - 2 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 3 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * (c &&&  ~~~(a &&& b)) + 4 *  ~~~(a ||| (b ||| c)) + 1 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 13 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 10 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& (b &&& c)) =  - 20 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * (a &&& ( ~~~b &&& c))

theorem e_613 :
     - 6 * x + 1 *  ~~~(x ^^^ y) - 11 * (x |||  ~~~y) + 5 *  ~~~(x &&&  ~~~x) + 4 * y - 2 * (x ^^^ y) + 8 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) + 14 * (x &&&  ~~~y) + 10 * (x &&& y) = 3 *  ~~~(x &&&  ~~~y)

theorem lshr_exact_ne_0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → ofBool (x_1 >>> x != 0#32) = ofBool (x_1 != 0#32)

theorem bswap_and_mask_1_thm (e : IntW 64) :
  LLVM.or (LLVM.and (lshr e (const? 64 40)) (const? 64 65280)) (lshr e (const? 64 56)) ⊑
    LLVM.or (LLVM.and (lshr e (const? 64 40)) (const? 64 65280)) (lshr e (const? 64 56)) { «disjoint» := true }

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem no_shift_xor_multiuse_cmp_xor_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (0#32 != x_2 &&& 4096#32) = 1#1 → ¬ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → False

theorem land_land_left1_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → 0#1 = 1#1 → x_1 = 0#1

theorem test42_proof : test42_before ⊑ test42_after

theorem PR42691_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ₛ 0#32) = 1#1 → 1#1 = ofBool (2147483646#32 <ᵤ x)

theorem negate_sdiv_proof : negate_sdiv_before ⊑ negate_sdiv_after

theorem not_and_and_or_not_or_or_commute3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true → False

@[symm]
theorem equal_up_to_symm (e : a ≈ʷ b) : b ≈ʷ a

theorem ashr_can_be_lshr_2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(34#64 ≥ ↑64 ∨
        True ∧
            (zeroExtend 64 x ||| 4278190080#64) <<< 34#64 >>> 32#64 <<< 32#64 ≠
              (zeroExtend 64 x ||| 4278190080#64) <<< 34#64 ∨
          32#64 ≥ ↑64 ∨
            True ∧
              signExtend 64 (truncate 32 (((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64)) ≠
                ((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64) →
    ¬2#32 ≥ ↑32 →
      truncate 32 (((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64) =
        x <<< 2#32 ||

theorem test1_proof : test1_before ⊑ test1_after

theorem uge_swap_or_max_commute_proof : uge_swap_or_max_commute_before ⊑ uge_swap_or_max_commute_after

theorem and_umax_less_thm (e : IntW 32) :
  LLVM.and (select (icmp IntPred.ugt (const? 32 31) e) (const? 32 31) e) (const? 32 (-32)) ⊑
    LLVM.and e (const? 32 (-32))

theorem com_ty : com.2.2.1 = [.bitvec 32]

theorem test_shl_nuw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 >>> 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨ 2#32 ≥ ↑32) →
      (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 * (x ||| BitVec.ofInt 32 (-83886080)) *
          (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 =
        0#32

theorem positive_sameconst_shlnuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x <<< 5#32 >>> 5#32 ≠ x ∨ 5#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) → x <<< 5#32 >>> 5#32 = x

theorem main15_logical_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (0#16 ≤ₛ truncate 16 x) = 1#1 →
    ¬ofBool (x &&& 32896#32 == 32896#32) = 1#1 → ¬ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 1#32 = 2#32

theorem src_is_notmask_sext_proof : src_is_notmask_sext_before ⊑ src_is_notmask_sext_after

theorem select_constants_and_icmp_ne0_zero_tval_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x = 1#1 → ofBool (12#8 &&& 12#8 != 0#8) = x ^^^ 1#1

theorem and_sel_op0_proof : and_sel_op0_before ⊑ and_sel_op0_after

theorem lshrult_02_13_exact_proof : lshrult_02_13_exact_before ⊑ lshrult_02_13_exact_after

theorem ugt_swap_and_min_logical_proof : ugt_swap_and_min_logical_before ⊑ ugt_swap_and_min_logical_after

theorem test48_proof : test48_before ⊑ test48_after

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

theorem bools_multi_uses2_logical_thm.extracted_1._19 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → ¬0#1 = 1#1 → False

theorem or_not_and_and_not_and_xor_commute2_proof : or_not_and_and_not_and_xor_commute2_before ⊑ or_not_and_and_not_and_xor_commute2_after

theorem test_sub_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true → False

theorem positive_biggershl_shlnuw_ashrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨
        3#8 ≥ ↑8 ∨ True ∧ x.sshiftRight' 3#8 <<< 6#8 >>> 6#8 ≠ x.sshiftRight' 3#8 ∨ 6#8 ≥ ↑8) →
    True ∧ x <<< 3#8 >>> 3#8 ≠ x ∨ 3#8 ≥ ↑8 → False

theorem zext_zext_sgt_proof : zext_zext_sgt_before ⊑ zext_zext_sgt_after

theorem ugt_umax2_proof : ugt_umax2_before ⊑ ugt_umax2_after

theorem ashr_thm (e : IntW 32) :
  add (LLVM.xor (lshr e (const? 32 5)) (const? 32 67108864)) (const? 32 (-67108864)) ⊑ ashr e (const? 32 5)

theorem ne_nsw_rem_nz_thm (e : IntW 8) :
  icmp IntPred.ne (mul e (const? 8 5) { «nsw» := true, «nuw» := false }) (const? 8 (-126)) ⊑ const? 1 1

theorem eval_zext_multi_use_in_one_inst_proof : eval_zext_multi_use_in_one_inst_before ⊑ eval_zext_multi_use_in_one_inst_after

theorem n10_wrong_pred2_proof : n10_wrong_pred2_before ⊑ n10_wrong_pred2_after

theorem or_logic_or_logic_and_2_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

theorem test37_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (truncate 8 (x >>> 31#32 ||| 512#32) == 11#8) = 0#1

@[simp]
theorem some_some {α : Type u} {x y : α} :
  (some x) ⊑ (some y) ↔ x = y

theorem ashrslt_03_11_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 3)) (const? 4 (-5)) ⊑ const? 1 0

theorem test_add_nuw__nuw_is_safe_proof : test_add_nuw__nuw_is_safe_before ⊑ test_add_nuw__nuw_is_safe_after

theorem dec_mask_commute_neg_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
    ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
          True ∧ ((42#32).sdiv x).saddOverflow (-1#32) = true ∨
            (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
      ((42#32).sdiv x &&& 0#32 - (42#32).sdiv x) + -1#32 = (42#32).sdiv x + -1#32 &&& ((42#32).sdiv x ^^^ -1#32)

lemma RawCNFA.WF.trans_tgt_lt_equiv_internal {m : RawCNFA A} [LawfulBEq A] :
    (∀ s a s', s' ∈ m.tr s a → s' ∈ m.states) ↔
    (∀ (s_a : State × A) (ss' s'), m.trans[s_a]? = some ss' → s' ∈ ss' → s' ∈ m.states)

theorem bools2_logical_commute2_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → ¬0#1 = 1#1 → x_1 ^^^ 1#1 = x

theorem e_437 :
     - 1 * (x ^^^ y) + 1 *  ~~~(x ^^^ y) + 4 *  ~~~x - 6 * (x ||| y) - 1 * (x |||  ~~~y) - 4 *  ~~~(x ||| y) + 8 * (x &&&  ~~~y) + 6 * (x &&& y) =  - 3 *  ~~~(x |||  ~~~y)

theorem main7b_logical_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_1 &&& x_2) = 1#1 →
    ¬ofBool (x_2 != x_1 &&& x_2) = 1#1 →
      ¬ofBool (x == x_1 &&& x) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x != x_1 &&& x))

theorem canonicalize_logic_first_xor_0_nsw_proof : canonicalize_logic_first_xor_0_nsw_before ⊑ canonicalize_logic_first_xor_0_nsw_after

theorem ashr_lshr_cst2_proof : ashr_lshr_cst2_before ⊑ ashr_lshr_cst2_after

theorem icmp_eq_and1_lshr_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (8#32 >>> x &&& 1#32 == 0#32)) = zeroExtend 32 (ofBool (x != 3#32))

theorem test15_thm (e : IntW 32) :
  sext 32 (icmp IntPred.ne (LLVM.and e (const? 32 16)) (const? 32 0)) ⊑
    ashr (shl e (const? 32 27)) (const? 32 31)

theorem PR2844_logical_proof : PR2844_logical_before ⊑ PR2844_logical_after

theorem ashr_mul_times_5_div_4_exact_proof : ashr_mul_times_5_div_4_exact_before ⊑ ashr_mul_times_5_div_4_exact_after

theorem icmp_eq_and_pow2_minus1_shl_pow2_proof : icmp_eq_and_pow2_minus1_shl_pow2_before ⊑ icmp_eq_and_pow2_minus1_shl_pow2_after

theorem and_and_logic_or_1_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.and e_2 e_1) (const? 1 1) (LLVM.and e_2 e) ⊑ LLVM.and e_2 (select e_1 (const? 1 1) e)

theorem e_1169 :
    1 *  ~~~(z &&&  ~~~z) - 1 *  ~~~(z &&&  ~~~t) - 7 *  ~~~z + 1 * t - 2 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) - 8 * (z &&&  ~~~t) - 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t) - 7 * (z |||  ~~~t)

theorem mul_of_pow2s_thm (e e_1 : IntW 32) :
  LLVM.or (mul (LLVM.and e_1 (const? 32 8)) (LLVM.and e (const? 32 16))) (const? 32 128) ⊑ const? 32 128

theorem smear_sign_and_widen_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬24#32 ≥ ↑32 → ¬7#8 ≥ ↑8 → signExtend 32 x >>> 24#32 = zeroExtend 32 (x.sshiftRight' 7#8)

theorem sel_false_val_is_a_masked_ashr_of_true_val2_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬2#32 ≥ ↑32 →
    ofBool ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32 == 0#32) = 1#1 →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)).msb = true ∨
              zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)) ≥ ↑64) →
        x = x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

theorem test_add_nuw_nsw__none_are_safe_proof : test_add_nuw_nsw__none_are_safe_before ⊑ test_add_nuw_nsw__none_are_safe_after

theorem lor_land_right1_thm (e e_1 : IntW 1) : select e_1 (select e_1 (const? 1 1) e) (const? 1 0) ⊑ e_1

theorem t4_ugt_slt_65536_thm.extracted_1._10 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (65535#32 <ᵤ x_2) = 1#1 → ofBool (x_2 <ₛ 65536#32) = 1#1 → ofBool (65535#32 <ₛ x_2) = 1#1 → x_1 = x

theorem or_xor_tree_0101_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42)))
      (LLVM.xor (mul e_1 (const? 32 42)) (LLVM.xor (mul e_2 (const? 32 42)) (mul e (const? 32 42)))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e_1 (const? 32 42))) (mul e (const? 32 42))

theorem lshrugt_02_15_exact_proof : lshrugt_02_15_exact_before ⊑ lshrugt_02_15_exact_after

theorem e_1868 :
     - 5 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ^^^ (a ||| c)) - 1 * (b ^^^ (a ||| (b &&& c))) + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 5 * ((a ^^^ b) ||| (a ^^^ c)) - 2 * ((a &&& b) |||  ~~~(b ||| c)) - 1 *  ~~~(a ||| ( ~~~b &&& c)) - 7 * (a &&& c) + 7 * ((a &&& b) |||  ~~~(b ^^^ c)) + 5 * ((a ||| b) &&& (b ^^^ c)) + 11 * (b ^^^  ~~~(a &&& c)) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) - 1 *  ~~~(a |||  ~~~b) + 4 * (c ^^^ (a ||| (b &&& c))) - 1 * (b ^^^  ~~~(a |||  ~~~c)) + 7 *  ~~~(b &&& c) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 1 * ( ~~~a ||| (b &&& c)) - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) + 2 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 3 * (b &&& (a |||  ~~~c)) - 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 3 * ((a &&& c) |||  ~~~(b ||| c)) - 6 * (b |||  ~~~(a |||  ~~~c)) - 1 * ( ~~~a ||| ( ~~~b &&& c)) - 11 * (c &&&  ~~~(a &&& b)) + 4 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * b - 6 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 7 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 11 * (a ||| (b ^^^ c)) + 7 * (a |||  ~~~b) - 11 * ((a &&& c) ^^^ (b ||| c)) - 1 * (c ^^^ (a |||  ~~~b)) - 6 * (c ^^^ ( ~~~a &&& (b ||| c))) + 11 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 5 * (c ^^^ (a &&& ( ~~~b ||| c))) - 49 *  ~~~(a ||| (b ||| c)) - 6 *  ~~~(a ||| ( ~~~b ||| c)) - 18 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 30 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) - 15 * (a &&& (b &&& c)) =  - 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 22 * ( ~~~a &&& ( ~~~b &&& c))

theorem annihilate_xor_common_op_commute2_proof : annihilate_xor_common_op_commute2_before ⊑ annihilate_xor_common_op_commute2_after

theorem test_with_5_proof : test_with_5_before ⊑ test_with_5_after

theorem e_1904 :
    1 *  ~~~(b &&& c) - 7 * ( ~~~a ||| (b ^^^ c)) + 11 * ((a &&& b) ^^^ (b |||  ~~~c)) + 4 * (a ^^^ ( ~~~b &&& c)) - 2 * (c ^^^ (a &&& b)) - 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b ^^^ c)) - 1 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 5 *  ~~~(a ^^^ (b ||| c)) + 2 * (b ^^^ (a ||| (b ||| c))) - 7 *  ~~~(a &&& ( ~~~b &&& c)) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 3 * (b &&&  ~~~(a ^^^ c)) - 2 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 3 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 3 * ( ~~~a ||| ( ~~~b &&& c)) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * (b |||  ~~~c) + 2 * (a |||  ~~~c) - 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 3 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * (b ||| (a &&&  ~~~c)) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * (b &&&  ~~~(a &&& c)) - 11 * ((a ||| b) &&& (b ^^^ c)) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * (a ^^^ c) + 7 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 5 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * (c &&&  ~~~(a &&& b)) + 2 * (b ^^^ (a |||  ~~~c)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) - 5 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~a ||| ( ~~~b ||| c)) + 3 * ((a &&& b) ^^^ (b ||| c)) - 5 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 23 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) + 56 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 23 * ( ~~~a &&& (b &&& c)) + 11 * (a &&& ( ~~~b &&& c)) + 31 * (a &&& (b &&& c)) = 7 * (b &&& (a ||| c))

theorem positive_samevar_shlnsw_ashrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨
        x ≥ ↑8 ∨ True ∧ (x_1.sshiftRight' x <<< x).sshiftRight' x ≠ x_1.sshiftRight' x ∨ x ≥ ↑8) →
    x_1.sshiftRight' x <<< x = x_1

theorem add_or_sub_comb_i64_commuted4_proof : add_or_sub_comb_i64_commuted4_before ⊑ add_or_sub_comb_i64_commuted4_after

theorem bools_logical_commute0_and1_and2_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  (x_2 ^^^ 1#1) &&& x_1 = 1#1 → ¬x_2 = 1#1 → 1#1 = x_1

theorem e_421 :
    1 *  ~~~x - 11 * (x ^^^ y) - 7 *  ~~~(x &&&  ~~~y) - 7 *  ~~~(x &&& y) + 2 *  ~~~(x ^^^ y) + 25 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) - 5 * (x &&& y) = 1 * (x ||| y) - 11 * (x |||  ~~~y)

theorem sub_eq (a b : BitStream) : a.sub b = a - b

theorem fold_inverted_icmp_preds_proof : fold_inverted_icmp_preds_before ⊑ fold_inverted_icmp_preds_after

theorem lshrult_03_10_exact_proof : lshrult_03_10_exact_before ⊑ lshrult_03_10_exact_after

theorem for_return {t : Arith.Ty} (istart istep: Var Γ Arith.Ty.int)
    (niters : Var Γ .nat) (v : Var Γ t) :
    Expr.denoteOp (for_ (t := t) istart istep niters v (RegionRet t ⟨1, by simp⟩)) Γv = [Γv v]ₕ

theorem thisdoesnotloop_proof : thisdoesnotloop_before ⊑ thisdoesnotloop_after

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬1#64 ≥ ↑64 → ofBool (0#64 <ᵤ x >>> 1#64) = ofBool (1#64 <ᵤ x)

theorem and_ne_with_one_bit_diff_constants2_thm.extracted_1._1 : ∀ (x : BitVec 19),
  ofBool (x != 65#19) &&& ofBool (x != 193#19) = ofBool (x &&& BitVec.ofInt 19 (-129) != 65#19)

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 != 0#8) = 1#1 →
    ¬(True ∧ x_1.umulOverflow x_2 = true ∨ True ∧ x.umulOverflow x_2 = true) →
      ofBool (x_2 == 0#8) = 1#1 → ofBool (x * x_2 <ᵤ x_1 * x_2) = 1#1

theorem n5_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8), ofBool (x_2 &&& 1#8 == 2#8) = 1#1 → x_1 = x

theorem urem_i32_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem test_sdiv_canonicalize_op0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    ¬((x == 0 || 32 != 1 && x_1 == intMin 32 && x == -1) = true ∨ True ∧ (0#32).ssubOverflow (x_1.sdiv x) = true) →
      (0#32 - x_1).sdiv x = 0#32 - x_1.sdiv x

theorem bv_AddSub_1176 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add e (LLVM.sub (LLVM.const? w 0) e_1) ⊑ LLVM.sub e e_1

theorem sel_false_val_is_a_masked_ashr_of_true_val1_proof : sel_false_val_is_a_masked_ashr_of_true_val1_before ⊑ sel_false_val_is_a_masked_ashr_of_true_val1_after

theorem test7_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (0#32 ≤ᵤ x) = 1#1

theorem p0_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.ugt e (const? 8 3)

theorem e_1210 :
    5 *  ~~~(z &&& t) + 2 *  ~~~(z ^^^ t) + 11 *  ~~~(z &&&  ~~~z) + 2 * (z ^^^ t) + 2 * (z ||| t) - 13 *  ~~~(z ||| t) - 20 *  ~~~(z |||  ~~~t) - 13 * (z &&&  ~~~t) - 8 * (z &&& t) = 5 * (z |||  ~~~t) + 2 * z

theorem icmp_eq_mul_nsw_nonequal_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smulOverflow x = true ∨ True ∧ x.smulOverflow (x_1 + 1#8) = true) →
    ofBool (x_1 * x == x * (x_1 + 1#8)) = ofBool (x == 0#8)

theorem main6c_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 3))
        (icmp IntPred.ne (LLVM.and e (const? 32 48)) (const? 32 16)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 55)) (const? 32 19))

theorem e_563 :
    2 * (x ^^^ y) + 2 *  ~~~y + 7 * y - 1 *  ~~~x - 7 *  ~~~(x &&& y) + 1 * (x |||  ~~~y) - 1 *  ~~~(x &&&  ~~~y) + 6 *  ~~~(x ||| y) + 2 * (x &&&  ~~~y) = 7 * (x &&& y)

theorem t7_thm (e : IntW 8) :
  icmp IntPred.ule (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.slt e (const? 8 1)

theorem lshr_neg_sgt_minus_1_proof : lshr_neg_sgt_minus_1_before ⊑ lshr_neg_sgt_minus_1_after

theorem udiv_illegal_type_thm.extracted_1._2 : ∀ (x x_1 : BitVec 9),
  ¬zeroExtend 32 x = 0 → ¬x = 0 → zeroExtend 32 x_1 / zeroExtend 32 x = zeroExtend 32 (x_1 / x)

theorem scalar_i32_shl_and_signbit_eq_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.sgt (shl e_1 e) (const? 32 (-1))

theorem ashr_mul_sign_bits_thm (e e_1 : IntW 8) :
  trunc 16 (ashr (mul (sext 32 e_1) (sext 32 e)) (const? 32 3)) ⊑
    ashr (mul (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 3)

theorem t11_shl_nsw_flag_preservation_thm (e e_1 : IntW 32) :
  shl (shl e_1 (sub (const? 32 32) e) { «nsw» := true, «nuw» := false }) (add e (const? 32 (-2)))
      { «nsw» := true, «nuw» := true } ⊑
    shl e_1 (const? 32 30) { «nsw» := true, «nuw» := false }

theorem p_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 ^^^ -1#32 ||| x_1) &&& (x ||| x_2) = (x_1 ||| x_2 ^^^ -1#32) &&& (x ||| x_2)

theorem masked_and_notallzeroes_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 0#32) = 1#1 → 0#1 = ofBool (x &&& 7#32 != 0#32)

theorem rem_euclid_wrong_sign_test_proof : rem_euclid_wrong_sign_test_before ⊑ rem_euclid_wrong_sign_test_after

theorem test4a_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(31#32 ≥ ↑32 ∨ 31#32 ≥ ↑32) → ofBool (x.sshiftRight' 31#32 ||| (0#32 - x) >>> 31#32 <ₛ 1#32) = ofBool (x <ₛ 1#32)

theorem sge_or_not_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x ≤ₛ x_1) ||

theorem test16_thm (e e_1 : IntW 8) :
  mul (LLVM.and (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) (LLVM.xor e e_1)) (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) ⊑
    mul (LLVM.and (LLVM.xor (LLVM.xor e_1 e) (const? 8 33)) (LLVM.xor e e_1))
      (LLVM.xor (LLVM.xor e_1 e) (const? 8 33))

theorem main7c_logical_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 == x_2 &&& x_1) = 1#1 →
    ¬ofBool (x_2 != x_2 &&& x_1) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x != x &&& x_1))

theorem t7_ashr_proof : t7_ashr_before ⊑ t7_ashr_after

theorem or_xor_commute1_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.udiv (const? 32 42) e_1) (LLVM.or (LLVM.udiv (const? 32 42) e_1) (LLVM.udiv (const? 32 42) e)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

theorem sub_from_constant_proof : sub_from_constant_before ⊑ sub_from_constant_after

theorem t0_shl_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬signExtend 32 x ≥ ↑32 →
    ¬(True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32) → x_1 <<< signExtend 32 x = x_1 <<< zeroExtend 32 x

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

theorem test_invert_demorgan_and2_thm.extracted_1._1 : ∀ (x : BitVec 64),
  x + 9223372036854775807#64 &&& 9223372036854775807#64 ^^^ -1#64 =
    0#64 - x ||

theorem ashrslt_03_01_exact_proof : ashrslt_03_01_exact_before ⊑ ashrslt_03_01_exact_after

theorem icmp_ne_sext_ne_allones_proof : icmp_ne_sext_ne_allones_before ⊑ icmp_ne_sext_ne_allones_after

theorem e_145 :
     - 7 * (x ^^^ y) - 5 * x + 2 *  ~~~(x &&&  ~~~x) - 1 * (x ||| y) - 2 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) =  - 11 * (x &&&  ~~~y) - 4 * (x &&& y)

theorem uge_or_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x ≤ᵤ x_1) = 1#1 → 1#1 = ofBool (x ≤ᵤ x_1)

theorem test2_proof : test2_before ⊑ test2_after

theorem positive_biggerlshr_shlnuwnsw_lshrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 6#8 <<< 6#8 ≠ x ∨
        6#8 ≥ ↑8 ∨
          True ∧ (x >>> 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 6#8 ∨
            True ∧ x >>> 6#8 <<< 3#8 >>> 3#8 ≠ x >>> 6#8 ∨ 3#8 ≥ ↑8) →
    True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8 → False

theorem icmp_eq_zext_ne_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x) = ofBool (x <ᵤ 2#32)

theorem test17_proof : test17_before ⊑ test17_after

theorem test1_thm (e : IntW 33) : LLVM.udiv e (const? 33 4096) ⊑ lshr e (const? 33 12)

theorem isRefinedBy_trans [IsTrans α (· ⊑ ·)] (a? b? c? : PoisonOr α) :
    a? ⊑ b? → b? ⊑ c? → a? ⊑ c?

theorem test21_proof : test21_before ⊑ test21_after

theorem test_shl_nsw__nsw_is_safe_proof : test_shl_nsw__nsw_is_safe_before ⊑ test_shl_nsw__nsw_is_safe_after

theorem t3_exact_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) → 0#64 - x.sshiftRight' 63#64 = x >>> 63#64

theorem n8_wrong_pred3_proof : n8_wrong_pred3_before ⊑ n8_wrong_pred3_after

theorem xor_and_logic_or2_proof : xor_and_logic_or2_before ⊑ xor_and_logic_or2_after

theorem evalWith_add_eq_evalWith_carryWith
  (p : FSM arity) (carryState : p.α → Bool) (x : arity → BitStream) (n : Nat) :
  p.evalWith carryState x (n + m) =
  p.evalWith (p.carryWith carryState x n) (fun a i => x a (n + i)) m

theorem e_1074 :
    5 *  ~~~z - 11 *  ~~~(z ^^^ t) - 2 * t - 2 * (z ^^^ t) + 3 *  ~~~t - 4 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) =  - 10 * (z &&& t) - 3 *  ~~~(z &&&  ~~~t)

theorem BitVec.even_mul_eq_shiftLeft_mul_of_eq_mul_two (w : Nat) (x : BitVec w) (n e : Nat) (he : e = n * 2) :
    (BitVec.ofNat w e) * x = (BitVec.ofNat w n) * (x <<< (1 : Nat))

theorem n9_wrong_x0_proof : n9_wrong_x0_before ⊑ n9_wrong_x0_after

@[simp] theorem MatchVarM.liftM_eq_some_iff (x? : Option α) :
    (liftM x? : no_index MatchVarM Δ Γ α) mapIn = some (x, mapOut)
    ↔ x? = some x ∧ mapIn = mapOut

theorem test2_proof : test2_before ⊑ test2_after

theorem or_not_and_and_not_and_xor_commute4_proof : or_not_and_and_not_and_xor_commute4_before ⊑ or_not_and_and_not_and_xor_commute4_after

theorem e_1543 :
     - 1 *  ~~~(b &&& c) - 2 *  ~~~(a &&& ( ~~~b ||| c)) + 7 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * ((a |||  ~~~b) &&& (b ^^^ c)) + 2 *  ~~~b + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 *  ~~~(b ||| c) - 4 *  ~~~(a ||| (b ||| c)) - 11 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) - 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 1 * ( ~~~a &&& ( ~~~b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) = 12 * ( ~~~a &&& (b &&& c))

theorem exact_lshr_eq_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 7)

theorem sub_ult_zext_thm (e : IntW 1) (e_1 e_2 : IntW 8) :
  icmp IntPred.ult (sub e_2 e_1) (zext 8 e) ⊑ LLVM.and (icmp IntPred.eq e_2 e_1) e

theorem and_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  x = 1#1 → x_1 &&& zeroExtend 32 x = x_1 &&& 1#32

theorem bools_logical_commute3_and2_thm.extracted_1._13 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → 1#1 = x_2

theorem icmp_select_var_proof : icmp_select_var_before ⊑ icmp_select_var_after

theorem shl_bad_sub2_i32_thm (e : IntW 32) :
  shl (const? 32 1) (sub e (const? 32 31)) ⊑
    shl (const? 32 1) (add e (const? 32 (-31))) { «nsw» := false, «nuw» := true }

theorem masked_bit_wrong_pred_proof : masked_bit_wrong_pred_before ⊑ masked_bit_wrong_pred_after

theorem gt_signed_to_small_unsigned_proof : gt_signed_to_small_unsigned_before ⊑ gt_signed_to_small_unsigned_after

theorem t2_ult_sgt_128_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (127#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ BitVec.ofInt 32 (-16)) = 1#1 → False

theorem ult_to_slt_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor e_1 (const? 8 (-128))) (LLVM.xor e (const? 8 (-128))) ⊑
    icmp IntPred.slt e_1 e

theorem and_nosignbit_select_shl_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x &&& 2147418112#32) <<< 8#32 = x <<< 8#32 &&& BitVec.ofInt 32 (-16777216)

theorem not_or_or_and_not_and_and_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 ^^^ -1#32 ||| x_1 ||| x) &&& (x_2 &&& x_1 &&& x ^^^ -1#32) = x ^^^ x_1 ||

theorem shl_xor_proof : shl_xor_before ⊑ shl_xor_after

theorem test_sub_nsw__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 2147483647)) (const? 32 1073741824)) (const? 32 1073741824)
      (sub (const? 32 (-2147483648)) (LLVM.and e (const? 32 2147483647)) { «nsw» := true, «nuw» := false }) ⊑
    sub (const? 32 (-2147483648)) (LLVM.and e (const? 32 2147483647)) { «nsw» := false, «nuw» := true }

theorem ashr_ult_2_proof : ashr_ult_2_before ⊑ ashr_ult_2_after

theorem is_rem2_neg_i8_proof : is_rem2_neg_i8_before ⊑ is_rem2_neg_i8_after

theorem twoway_clamp_lt_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 13768#32) = 1#1 →
    ¬ofBool (13767#32 <ₛ x) = 1#1 → ofBool (13767#32 <ₛ 13768#32) = 1#1 → 13768#32 = 13767#32

theorem e_1394 :
     - 6 *  ~~~t - 3 * (z ^^^ t) - 2 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z &&& t) - 1 * (z ||| t) + 1 * z - 2 *  ~~~(z ||| t) + 3 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) - 5 * (z &&& t) =  - 7 *  ~~~(z ^^^ t)

theorem src2_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 e) (LLVM.xor (LLVM.or e e_1) (const? 32 (-1))) ⊑ LLVM.xor (LLVM.xor e_1 e) (const? 32 (-1))

theorem main7d_logical_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& (x_1 &&& x) == x_1 &&& x) = 1#1 →
    ofBool (x_2 &&& (x_1 &&& x) != x_1 &&& x) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem corec₂_eq_corec_of_corec₂ (streamInt: DCOp.ValueStream Int) :
    (corec₂ streamInt fun x => (x 0, x 0, x.tail)).1 ≈
    corec
      ((corec₂ streamInt fun (x : DCOp.ValueStream Int) =>
            (match x 0 with
              | some val => (x 0, some (), x.tail)
              | none => (none, none, x.tail))).1,
        (corec₂
            (corec₂ streamInt fun x =>
                (match x 0 with
                  | some val => (x 0, some (), x.tail)
                  | none => (none, none, x.tail))).2
            fun x => Id.run (x 0, x 0, tail x)).1)
      fun x =>
      match x.1 0, x.2 0 with

theorem narrow_zext_ashr_keep_trunc3_thm (e e_1 : IntW 8) :
  trunc 7 (ashr (add (sext 64 e_1) (sext 64 e) { «nsw» := true, «nuw» := false }) (const? 64 1)) ⊑
    trunc 7 (lshr (add (zext 14 e_1) (zext 14 e) { «nsw» := true, «nuw» := true }) (const? 14 1))

theorem basic_com_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 + (x ^^^ -1#8) ^^^ -1#8 = x - x_1

theorem sdiv_mul_shl_nsw_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2.smulOverflow x_1 = true ∨
        True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
          x ≥ ↑5 ∨ (x_2 <<< x == 0 || 5 != 1 && x_2 * x_1 == intMin 5 && x_2 <<< x == -1) = true) →
    True ∧ 1#5 <<< x >>> x ≠ 1#5 ∨ x ≥ ↑5 ∨ (1#5 <<< x == 0 || 5 != 1 && x_1 == intMin 5 && 1#5 <<< x == -1) = true →
      False

theorem sge_or_max_proof : sge_or_max_before ⊑ sge_or_max_after

theorem fold_sext_to_and_wrong7_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) != 128#32) = 1#1

theorem pow2_or_zero_is_not_negative_commute_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (-1#8 <ₛ 0#8 - 42#8 * x &&& 42#8 * x) = ofBool (x * 42#8 != BitVec.ofInt 8 (-128))

theorem test_shl_nsw__nsw_is_safe_thm (e : IntW 32) :
  mul
      (mul
        (select (icmp IntPred.eq (LLVM.or e (const? 32 (-83886080))) (const? 32 (-83886079)))
          (const? 32 (-335544316))
          (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := false }))
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := false }) ⊑
    mul
      (mul (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := false })
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := true, «nuw» := false })

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬8#32 = 0 → x % 8#32 = x &&& 7#32

theorem sub_shl_same_amount_partial_nsw2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(x_1 ≥ ↑6 ∨
        True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6 ∨ True ∧ (x_2 <<< x_1).ssubOverflow (x <<< x_1) = true) →
    x_1 ≥ ↑6 → False

theorem logic_and_logic_or_7_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x = 1#1 → x_1 = 1#1 → 1#1 = x_1

@[simp]
theorem ite_value_value {c : Prop} [Decidable c] {a b : α} :
    (if c then value a else value b : no_index _) = value (if c then a else b)

theorem t3_exact_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) →
    ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 ∨
              True ∧ zeroExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64) →
      0#32 - truncate 32 (x.sshiftRight' 63#64) = truncate 32 (x >>> 63#64)

theorem ne_umax3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ᵤ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 != x) = ofBool (x_1 + 3#32 <ᵤ x)

theorem n2_badmask_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  x_3 &&& x_2 ^^^ (x_1 ^^^ -1#32) &&& x = x_3 &&& x_2 ^^^ x &&& (x_1 ^^^ -1#32)

theorem sub_ashr_and_i32_commute_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x.ssubOverflow x_1 = true ∨ 31#32 ≥ ↑32) →
    ¬ofBool (x <ₛ x_1) = 1#1 → x_1 &&& (x - x_1).sshiftRight' 31#32 = 0#32

theorem slt_zero_eq_i1_fail_thm (e : IntW 32) (e_1 : IntW 1) :
  icmp IntPred.eq (zext 32 e_1) (ashr e (const? 32 31)) ⊑
    icmp IntPred.eq (ashr e (const? 32 31)) (zext 32 e_1)

theorem ashrsgt_02_03_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (3#4 <ₛ x.sshiftRight' 2#4) = 0#1

theorem p13_commutativity0_proof : p13_commutativity0_before ⊑ p13_commutativity0_after

theorem reduce_xor_common_op_commute0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  x_2 ^^^ x_1 ^^^ x ||

theorem icmp_ne_zext_eq_zero_proof : icmp_ne_zext_eq_zero_before ⊑ icmp_ne_zext_eq_zero_after

@[simp] lemma swapLastTwoBlock_Sn {n : Nat} : swapLastTwoBlock (n := n) (n+1) = Fin.last _

theorem pr40493_neg3_proof : pr40493_neg3_before ⊑ pr40493_neg3_after

theorem lshrult_02_10_exact_proof : lshrult_02_10_exact_before ⊑ lshrult_02_10_exact_after

theorem main7g_logical_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x_2 &&& x_1 &&& x) = 1#1 →
    ofBool (x_2 &&& x_1 != x_2 &&& x_1 &&& x) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem test_shl_nuw__nuw_is_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(True ∧ (x_1 &&& 1073741822#32) <<< 2#32 >>> 2#32 ≠ x_1 &&& 1073741822#32 ∨
          2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
              zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

theorem main7b_logical_proof : main7b_logical_before ⊑ main7b_logical_after

@[simp] theorem Valuation.append_appendInr {v : Var Δ t} :
    (V ++ W) v.appendInr = W v

theorem sext_diff_i1_xor_sub_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  True ∧ (zeroExtend 64 x).saddOverflow (signExtend 64 x_1) = true → False

theorem test_shl_nuw__none_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨
          True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
            zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem trunc_signed_nsw_zext_proof : trunc_signed_nsw_zext_before ⊑ trunc_signed_nsw_zext_after

theorem bools2_logical_commute3_and1_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& x_1 = 1#1 → x = 1#1 → ¬x_1 = 1#1 → x_1 ^^^ 1#1 = x

theorem ashr_ult_8_proof : ashr_ult_8_before ⊑ ashr_ult_8_after

theorem e_2190 :
     - 7 * (e ^^^ ( ~~~d ||| (e &&& f))) - 5 * (e &&& (d ^^^ f)) - 2 *  ~~~(d ||| ( ~~~e &&& f)) + 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) + 11 * (f ^^^ (d &&&  ~~~e)) - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (d ^^^ ( ~~~e ||| f)) + 1 * (d &&&  ~~~f) - 6 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 5 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * (f ||| (d &&&  ~~~e)) + 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 6 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 11 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 2 * (f &&&  ~~~(d ^^^ e)) - 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * ( ~~~d &&& ( ~~~e ||| f)) + 1 * (e ^^^ (d &&& (e ||| f))) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 3 * (e &&& (d ||| f)) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (e |||  ~~~(d ^^^ f)) - 6 * (e ^^^  ~~~(d &&& (e ||| f))) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 *  ~~~( ~~~d &&& (e ||| f)) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * (e |||  ~~~(d ||| f)) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 3 *  ~~~(e ^^^ f) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * ((d &&& e) ^^^ (e ||| f)) - 1 *  ~~~(d &&& f) - 7 *  ~~~(e &&& f) + 2 * ( ~~~e &&& (d ^^^ f)) + 5 * (f ^^^ ( ~~~d ||| (e &&& f))) + 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * (f ^^^  ~~~(d &&&  ~~~e)) - 11 * (d ^^^ e) + 39 *  ~~~(d ||| (e ||| f)) + 32 *  ~~~(d ||| ( ~~~e ||| f)) + 10 *  ~~~( ~~~d ||| (e ||| f)) + 35 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 25 * ( ~~~d &&& (e &&& f)) + 21 * (d &&& ( ~~~e &&& f)) + 9 * (d &&& (e &&& f)) =  - 2 * (e &&&  ~~~(d ^^^ f)) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f)))

theorem icmp_and_ashr_multiuse_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and (ashr e (const? 32 4)) (const? 32 15)) (const? 32 14))
      (icmp IntPred.ne (LLVM.and (ashr e (const? 32 4)) (const? 32 31)) (const? 32 27)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 240)) (const? 32 224))
      (icmp IntPred.ne (LLVM.and e (const? 32 496)) (const? 32 432))

theorem sle_smax3_proof : sle_smax3_before ⊑ sle_smax3_after

theorem e_734 :
     - 7 * (x |||  ~~~y) - 11 *  ~~~y + 3 * (x ^^^ y) - 3 *  ~~~x + 1 * x + 11 *  ~~~(x &&&  ~~~x) - 5 *  ~~~(x &&& y) + 14 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) - 13 * (x &&& y) =  - 7 * (x ||| y) - 1 *  ~~~(x ^^^ y)

theorem no_masks_with_logical_or2_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 != -1#32) = 1#1 → ofBool (x_2 &&& x != -1#32) = 1#1 → 1#1 ||

theorem test9_proof : test9_before ⊑ test9_after

theorem sub_to_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 ||| x) - (x_1 &&& x) = x_1 ^^^ x

theorem trunc_sandwich_max_sum_shift2_thm (e : IntW 32) :
  lshr (trunc 12 (lshr e (const? 32 30))) (const? 12 1) ⊑
    trunc 12 (lshr e (const? 32 31)) { «nsw» := true, «nuw» := true }

theorem sub_ashr_and_i64_proof : sub_ashr_and_i64_before ⊑ sub_ashr_and_i64_after

theorem uge_or_not_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-1))) (icmp IntPred.uge e_1 e) ⊑ const? 1 1

theorem shl_C1_add_A_C2_i32_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬zeroExtend 32 x + 5#32 ≥ ↑32 → True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32 → False

theorem test11_proof : test11_before ⊑ test11_after

theorem mul_select_sext_thm.extracted_1._1 : ∀ (x : BitVec 1),
  x = 1#1 → 64#64 * signExtend 64 x = BitVec.ofInt 64 (-64)

theorem shl_mask_wrong_shl_const_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬7#32 ≥ ↑32 →
    True ∧ ((x &&& 255#32) <<< 7#32).sshiftRight' 7#32 ≠ x &&& 255#32 ∨
        True ∧ (x &&& 255#32) <<< 7#32 >>> 7#32 ≠ x &&& 255#32 ∨ 7#32 ≥ ↑32 →
      False

theorem shl_add_proof : shl_add_before ⊑ shl_add_after

theorem andn_or_cmp_4_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_1) = 1#1 → ofBool (x_2 != x_1) = 1#1 → ¬True → ofBool (x_2 != x_1) = ofBool (42#32 <ᵤ x)

theorem mul_of_bool_commute_thm (e e_1 : IntW 32) :
  icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 255)) (LLVM.and e (const? 32 1))) (const? 32 255) ⊑
    const? 1 0

theorem e_1799 :
    5 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) - 7 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 11 * (b ^^^ (a ||| ( ~~~b &&& c))) + 3 * (a &&& ( ~~~b ||| c)) - 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 6 *  ~~~(a &&&  ~~~b) + 2 * (b |||  ~~~(a |||  ~~~c)) + 1 * (b ^^^  ~~~(a &&&  ~~~c)) - 2 * (c ||| (a &&& b)) - 3 * (b ^^^ (a &&& ( ~~~b ||| c))) - 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 * (a ^^^ ( ~~~b &&& c)) + 3 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 *  ~~~(a ^^^ c) - 11 *  ~~~(a &&& b) + 7 *  ~~~( ~~~a ||| (b &&& c)) - 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 4 * (a ^^^ (b ||| c)) + 2 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 2 * (a &&& c) - 7 * (b ^^^ (a &&&  ~~~c)) - 5 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 2 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 3 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 5 * (c ^^^ ( ~~~a ||| (b ||| c))) + 24 *  ~~~(a ||| (b ||| c)) + 53 *  ~~~(a ||| ( ~~~b ||| c)) + 26 *  ~~~( ~~~a ||| (b ||| c)) + 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 40 * ( ~~~a &&& ( ~~~b &&& c)) + 46 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 39 * (a &&& (b &&& c)) =  - 5 *  ~~~(b ||| c) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c)))

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem ashr_ugt_13_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (BitVec.ofInt 4 (-3) <ᵤ x.sshiftRight' 1#4) = ofBool (BitVec.ofInt 4 (-5) <ᵤ x)

theorem ashr_ult_9_proof : ashr_ult_9_before ⊑ ashr_ult_9_after

theorem mul_of_udiv_fail_bad_remainder_proof : mul_of_udiv_fail_bad_remainder_before ⊑ mul_of_udiv_fail_bad_remainder_after

theorem wide_source_matching_signbits_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ ((-1#32) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠ -1#32 ∨ x &&& 7#32 ≥ ↑32) →
    True ∧ ((-1#32) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠ -1#32 ∨
        x &&& 7#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 24 ((-1#32) <<< (x &&& 7#32))) ≠ (-1#32) <<< (x &&& 7#32) →
      False

theorem n10_wrong_pred2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (add e_1 e) e ⊑ icmp IntPred.eq e_1 (const? 8 0)

theorem test2_proof : test2_before ⊑ test2_after

@[bv_automata_preprocess] theorem BitVec.zero_mul (x : BitVec w) : 0#w * x = 0#w

theorem sel_zext_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1), ¬x_1 = 1#1 → zeroExtend 64 42#32 = 42#64

theorem or_not_xor_common_op_commute2_proof : or_not_xor_common_op_commute2_before ⊑ or_not_xor_common_op_commute2_after

theorem bor_land_right2_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → 0#1 = x

theorem neg_slt_42_proof : neg_slt_42_before ⊑ neg_slt_42_after

theorem shl_nsw_sgt_n1_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (shl e_1 e { «nsw» := true, «nuw» := false }) (const? 8 (-1)) ⊑
    icmp IntPred.sgt e_1 (const? 8 (-1))

theorem uge_swap_and_max_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ule e_1 e) (icmp IntPred.eq e (const? 8 (-1))) ⊑
    icmp IntPred.eq e (const? 8 (-1))

theorem icmp_ne_sext_ne_otherwise_i128_thm (e : IntW 128) :
  icmp IntPred.ne (sext 128 (icmp IntPred.ne e (const? 128 2))) e ⊑
    icmp IntPred.ne e (const? 128 (-1))

theorem trunc_shl_15_i16_i32_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬15#32 ≥ ↑32 → 15#16 ≥ ↑16 → False

lemma NFA'.autEq_correct : autEq.correct2 (fun _ => eqRel) eqRel

theorem xor_add_thm (e : IntW 32) :
  add (LLVM.xor (LLVM.and e (const? 32 31)) (const? 32 31)) (const? 32 42) ⊑
    sub (const? 32 73) (LLVM.and e (const? 32 31)) { «nsw» := true, «nuw» := true }

theorem e_7 :
    11 *  ~~~(x &&&  ~~~y) - 11 * x + 11 * (x &&&  ~~~y) + 11 * (x &&& y) = 11 *  ~~~(x ||| y) + 11 * y

theorem main6d_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 3#32) = 1#1 → ¬True → 0#32 = zeroExtend 32 (ofBool (x &&& 23#32 == 19#32))

theorem ofBitVec_one_eqTo_ofNat : @ofBitVecSext w 1 ≈ʷ ofNat 1

theorem e_335 :
     - 1 * x - 6 *  ~~~(x ^^^ y) - 7 *  ~~~(x &&&  ~~~y) - 5 *  ~~~(x &&& y) + 15 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) + 3 * (x &&& y) =  - 11 * (x ||| y) - 3 *  ~~~x

theorem is_ascii_alphabetic_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-65)) { «nsw» := true, «nuw» := false }) (const? 32 26)) (const? 1 1)
      (icmp IntPred.ult (add e (const? 32 (-97)) { «nsw» := true, «nuw» := false }) (const? 32 26)) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 32 (-33))) (const? 32 (-65))) (const? 32 26)

theorem e_1760 :
    1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 2 *  ~~~(a &&&  ~~~b) + 1 *  ~~~(a &&&  ~~~a) - 5 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 2 *  ~~~( ~~~a &&& (b &&& c)) - 3 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 3 * (b |||  ~~~(a |||  ~~~c)) - 1 * (a &&& c) - 6 * (a ||| ( ~~~b &&& c)) - 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 1 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 4 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~c + 2 * c + 3 * (b ^^^ (a &&&  ~~~c)) - 7 * b + 2 * (a ||| (b &&& c)) + 4 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * (b &&& (a ^^^ c)) - 6 * (c ^^^ (a ||| (b &&& c))) + 4 * (c ^^^  ~~~(a &&& (b ||| c))) - 6 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 5 *  ~~~(a ^^^ c) + 2 *  ~~~(a |||  ~~~b) + 2 * (b ^^^ c) + 2 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 7 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 16 *  ~~~(a ||| (b ||| c)) + 9 *  ~~~( ~~~a ||| (b ||| c)) + 22 * ( ~~~a &&& ( ~~~b &&& c)) + 7 * ( ~~~a &&& (b &&& c)) + 6 * (a &&& ( ~~~b &&& c)) + 16 * (a &&& (b &&& c)) =  - 33 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem test1_proof : test1_before ⊑ test1_after

theorem lshrugt_02_05_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬2#4 ≥ ↑4 → ofBool (5#4 <ᵤ x >>> 2#4) = 0#1

theorem main4b_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

theorem trunc_sandwich_small_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(19#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) → 20#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 12 (x >>> 20#32)) ≠ x >>> 20#32 → False

theorem test9_proof : test9_before ⊑ test9_after

theorem e_744 :
    1 * (x ^^^ y) - 11 *  ~~~(x &&&  ~~~x) + 11 * x + 3 *  ~~~(x &&& y) - 3 *  ~~~(x &&&  ~~~y) - 1 *  ~~~y + 1 * y + 14 *  ~~~(x ||| y) + 15 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 2 * (x &&& y) =  - 4 *  ~~~(x ^^^ y) + 6 *  ~~~x

theorem select2_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → truncate 8 (zeroExtend 32 x_1 + zeroExtend 32 x) = x_1 + x

theorem ule_swap_and_min_commute_logical_proof : ule_swap_and_min_commute_logical_before ⊑ ule_swap_and_min_commute_logical_after

theorem nonexact_ashr_ne_exactdiv_proof : nonexact_ashr_ne_exactdiv_before ⊑ nonexact_ashr_ne_exactdiv_after

theorem foo_thm (e : IntW 1) : e ⊑ e

theorem xor_and_or_proof : xor_and_or_before ⊑ xor_and_or_after

theorem test28 {w : Nat} (x : BitVec w) :
    x &&& x &&& x &&& x &&& x &&& x = x

theorem R.trimTensor_trimTensor (tensor : List Int) :
  trimTensor (trimTensor tensor) = trimTensor tensor

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

theorem bv_AndOrXor_2647 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.xor (LLVM.and e e_1) (LLVM.xor e e_1) ⊑ LLVM.or e e_1

theorem icmp_sle5_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) → ofBool (x <<< 1#8 ≤ₛ 1#8) = ofBool (x <ₛ 1#8)

theorem sdiv_mul_shl_nsw_proof : sdiv_mul_shl_nsw_before ⊑ sdiv_mul_shl_nsw_after

theorem substitute_constant_and_ne_ugt_swap_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x <ᵤ x_1) = 1#1 → 0#1 = ofBool (x <ᵤ x_1) &&& ofBool (x != 42#8)

theorem PR56294_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (zext 32 (icmp IntPred.eq e (const? 8 2))) (zext 32 (LLVM.and e (const? 8 1))))
      (const? 32 0) ⊑
    const? 1 0

theorem bools2_logical_commute1_and2_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_1 = 1#1 → (x_1 ^^^ 1#1) &&& x = x

theorem test69_proof : test69_before ⊑ test69_after

theorem test12commuted_proof : test12commuted_before ⊑ test12commuted_after

theorem test37_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (x * 7#32 &&& 240#32).msb = true) →
    zeroExtend 64 x * 7#64 &&& 240#64 = zeroExtend 64 (x * 7#32 &&& 240#32)

theorem land_band_right1_proof : land_band_right1_before ⊑ land_band_right1_after

theorem test_lshr_exact__exact_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 60#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ True ∧ (x_1 >>> 2#32 &&& 15#32).msb = true ∨ zeroExtend 64 (x_1 >>> 2#32 &&& 15#32) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 >>> 2#32 &&& 15#32))

theorem lshrult_01_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x >>> 1#4 <ᵤ BitVec.ofInt 4 (-2)) = 1#1

theorem test_and4_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0))
      (const? 1 0) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

theorem icmp_eq_and_pow2_shl_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 16#32 == 0#32)) = zeroExtend 32 (ofBool (x != 3#32))

theorem ule_umax1_proof : ule_umax1_before ⊑ ule_umax1_after

theorem fold_select_trunc_nuw_false_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ zeroExtend 8 (truncate 1 x_1) ≠ x_1) → ¬truncate 1 x_1 = 1#1 → x_1 = 0#8

private theorem BitVec.lt_iff_ult {x y : BitVec w} : (x < y) ↔ (x.ult y)

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem t0_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.xor (select (icmp IntPred.eq e_3 e_2) (const? 1 1) (icmp IntPred.eq e_1 e)) (const? 1 1) ⊑
    select (icmp IntPred.ne e_3 e_2) (icmp IntPred.ne e_1 e) (const? 1 0)

theorem PR42691_8_logical_proof : PR42691_8_logical_before ⊑ PR42691_8_logical_after

theorem neg_test_icmp_non_equality_proof : neg_test_icmp_non_equality_before ⊑ neg_test_icmp_non_equality_after

theorem e_1726 :
     - 5 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 6 * c - 1 *  ~~~(a |||  ~~~c) - 1 * ((a &&& b) ^^^ (b |||  ~~~c)) - 5 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 4 * (c ^^^ (a ||| (b &&& c))) - 1 *  ~~~(a &&&  ~~~a) + 1 * (b ^^^ (a ||| c)) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 5 * (b ^^^ (a &&&  ~~~c)) - 1 * ((a ^^^ b) &&& (a ^^^ c)) + 11 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 2 * (a ^^^ ( ~~~b &&& c)) - 11 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 1 *  ~~~(a ^^^ (b ||| c)) + 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 11 * (b ^^^  ~~~(a &&& (b ||| c))) + 11 * (c ^^^  ~~~(a &&&  ~~~b)) + 3 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 11 * (a &&&  ~~~b) + 8 *  ~~~(a ||| (b ||| c)) - 20 *  ~~~(a ||| ( ~~~b ||| c)) + 17 *  ~~~( ~~~a ||| (b ||| c)) - 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 34 * ( ~~~a &&& ( ~~~b &&& c)) + 18 * ( ~~~a &&& (b &&& c)) + 11 * (a &&& ( ~~~b &&& c)) + 29 * (a &&& (b &&& c)) = 11 *  ~~~(a ||| (b &&& c))

theorem n2_thm (e : IntW 8) :
  LLVM.sdiv e (const? 8 (-128)) ⊑ zext 8 (icmp IntPred.eq e (const? 8 (-128)))

theorem xor_signbit_lshr_proof : xor_signbit_lshr_before ⊑ xor_signbit_lshr_after

theorem and_or_not_not_commute2_proof : and_or_not_not_commute2_before ⊑ and_or_not_not_commute2_after

theorem t2_ult_sgt_128_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (127#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ BitVec.ofInt 32 (-16)) = 1#1 → x_1 = x

theorem shl_xor_xor_good_mask_proof : shl_xor_xor_good_mask_before ⊑ shl_xor_xor_good_mask_after

theorem src_srem_shl_demand_max_signbit_mask_hit_first_demand_proof : src_srem_shl_demand_max_signbit_mask_hit_first_demand_before ⊑ src_srem_shl_demand_max_signbit_mask_hit_first_demand_after

theorem test_shl_nsw__nuw_is_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(True ∧ ((x_1 &&& 1073741822#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 1073741822#32 ∨
          2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
              zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem slt_0_proof : slt_0_before ⊑ slt_0_after

theorem e_646 :
    3 * (x |||  ~~~y) + 3 *  ~~~(x &&&  ~~~y) - 2 * y - 11 *  ~~~x + 1 * (x ||| y) + 2 *  ~~~(x &&& y) - 2 * x - 4 *  ~~~(x |||  ~~~y) - 15 * (x &&&  ~~~y) - 3 * (x &&& y) =  - 11 * (x ^^^ y) - 3 *  ~~~(x ||| y)

theorem test5_proof : test5_before ⊑ test5_after

theorem ashrsgt_02_11_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2) { «exact» := true }) (const? 4 (-5)) ⊑ const? 1 1

theorem shl_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬((42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨ 5#16 ≥ ↑16 ∨ 7#16 ≥ ↑16) →
    12#16 ≥ ↑16 ∨
        (42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨
          True ∧ (x_1.srem 42#16 <<< 7#16).sshiftRight' 7#16 ≠ x_1.srem 42#16 ∨ 7#16 ≥ ↑16 →
      False

theorem hoist_ashr_ahead_of_sext_2_thm (e : IntW 8) : ashr (sext 32 e) (const? 32 8) ⊑ sext 32 (ashr e (const? 8 7))

theorem udiv_i80_thm.extracted_1._1 : ∀ (x : BitVec 80), ¬(2#80 ≥ ↑80 ∨ 100#80 = 0) → 400#80 = 0 → False

theorem basic_preserve_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 ^^^ -1#8).saddOverflow x = true) → True ∧ x_1.ssubOverflow x = true → False

theorem icmp_eq_sext_ne_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x != 0#32)) == x) = ofBool (x + 1#32 <ᵤ 2#32)

theorem srem_i1_is_zero_proof : srem_i1_is_zero_before ⊑ srem_i1_is_zero_after

theorem e_264 :
     - 1 *  ~~~(x &&& y) - 1 * y - 2 * (x ||| y) - 1 * (x ^^^ y) + 1 *  ~~~(x ||| y) + 5 *  ~~~(x |||  ~~~y) + 3 * (x &&& y) =  - 4 * (x &&&  ~~~y)

@[simp]
lemma proj_accepts (M : NFA' m) (f : Fin n → Fin m) :
    (M.proj f).accepts = BitVecs.transport f '' M.accepts

theorem icmp_select_var_select_thm.extracted_1._16 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬(ofBool (x_1 == 0#8) = 1#1 ∧ x_2 = 1#1) → ofBool (x_1 == 0#8) = 1#1 → True → ofBool (x == x) = 1#1

theorem in_constant_6_vary_invmask_thm (e e_1 : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e_1 (const? 4 6)) (LLVM.xor e (const? 4 (-1)))) e_1 ⊑
    LLVM.xor (LLVM.and (LLVM.xor e_1 (const? 4 6)) e) (const? 4 6)

theorem ashr_sub_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 17),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 16#17 ≥ ↑17) →
    (x_1 - x).sshiftRight' 16#17 = signExtend 17 (ofBool (x_1 <ₛ x))

theorem t8_lshr_exact_flag_preservation_proof : t8_lshr_exact_flag_preservation_before ⊑ t8_lshr_exact_flag_preservation_after

theorem e_1431 :
    2 *  ~~~(z ^^^ t) + 4 * z - 3 *  ~~~(z &&& t) + 4 *  ~~~z + 2 * (z ^^^ t) - 6 *  ~~~t + 6 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) - 3 * (z &&& t) = 3 * (z |||  ~~~t)

theorem e_199 :
    3 * (x ||| y) - 11 *  ~~~(x &&&  ~~~y) + 4 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&&  ~~~x) + 3 * y - 4 * (x &&&  ~~~y) =  - 6 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y)

theorem uaddo_commute4_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult (LLVM.xor e_2 (const? 32 (-1))) e_1) e (add e_2 e_1) ⊑
    select (icmp IntPred.ugt e_1 (LLVM.xor e_2 (const? 32 (-1)))) e (add e_2 e_1)

theorem slt_swap_and_max_logical_proof : slt_swap_and_max_logical_before ⊑ slt_swap_and_max_logical_after

theorem test14_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 64),
  ¬(x ≥ ↑32 ∨ zeroExtend 64 (1#32 <<< x) = 0) →
    ¬(True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ (zeroExtend 64 (1#32 <<< x)).saddOverflow (-1#64) = true) →
      x_1 % zeroExtend 64 (1#32 <<< x) = x_1 &&& zeroExtend 64 (1#32 <<< x) + -1#64

theorem addhshlhsdivhscalar1_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-64) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-64) == -1) = true ∨ 6#8 ≥ ↑8) →
    ¬(64#8 == 0 || 8 != 1 && x == intMin 8 && 64#8 == -1) = true →
      x.sdiv (BitVec.ofInt 8 (-64)) <<< 6#8 + x = x.srem 64#8

theorem scalar_i32_udiv_and_negC_eq_X_is_constant3_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.and (LLVM.udiv (const? 32 12345) e) (const? 32 16376)) (const? 32 0) ⊑
    icmp IntPred.ult e (const? 32 1544)

theorem e_833 :
     - 1 *  ~~~(z ^^^ t) + 12 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) + 9 * (z &&& t) =  - 3 * (z ||| t) + 11 * (z |||  ~~~t)

theorem ashrsgt_02_07_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 2#4 <<< 2#4 ≠ x ∨ 2#4 ≥ ↑4) → ofBool (7#4 <ₛ x.sshiftRight' 2#4) = 0#1

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 12#32 == 0#32) = 1#1 → ofBool (x &&& 7#32 != 1#32) = ofBool (x &&& 15#32 != 9#32)

@[simp]
theorem mem_mkLowerTriangularPairs {n : Nat} {i j : Nat} :
  ((i, j) ∈ mkLowerTriangularPairs n) ↔
  (i < j ∧ j ≤ n)

theorem lor_land_left2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → ¬x = 1#1 → 0#1 = x

theorem foo_thm.extracted_1._1 : ∀ (x : BitVec 32), x &&& (0#32 ||| 7#32) = x &&& 7#32

theorem slt_zero_ne_ne_0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (zeroExtend 32 (ofBool (x != 0#32)) != x >>> 31#32) = ofBool (0#32 <ₛ x)

theorem e_1443 :
     - 1 * z - 3 *  ~~~(z &&& t) - 7 *  ~~~t + 11 *  ~~~z + 11 *  ~~~(z &&&  ~~~z) - 1 * (z |||  ~~~t) - 10 *  ~~~(z ||| t) - 19 *  ~~~(z |||  ~~~t) + 1 * (z &&&  ~~~t) - 8 * (z &&& t) = 1 *  ~~~(z ^^^ t)

theorem ashr_can_be_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x >>> 16#32 <<< 16#32 ≠ x ∨
        16#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 16 (x.sshiftRight' 16#32)) ≠ x.sshiftRight' 16#32) →
    True ∧ x >>> 16#32 <<< 16#32 ≠ x ∨ 16#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 16 (x >>> 16#32)) ≠ x >>> 16#32 →
      False

theorem xor_to_xor4_thm (e e_1 : IntW 32) : LLVM.xor (LLVM.or e_1 e) (LLVM.and e e_1) ⊑ LLVM.xor e e_1

theorem no_shift_xor_multiuse_cmp_xor_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
      (x_2 ^^^ 4096#32) * x * (x_2 ^^^ 4096#32) = x_2 * x_1 * (x_2 ^^^ 4096#32)

theorem ult_swap_or_not_max_proof : ult_swap_or_not_max_before ⊑ ult_swap_or_not_max_after

theorem udiv_i32_c_multiuse_thm (e : IntW 8) :
  add (zext 32 e) (LLVM.udiv (zext 32 e) (const? 32 10)) ⊑
    add (LLVM.udiv (zext 32 e) (const? 32 10)) (zext 32 e) { «nsw» := true, «nuw» := true }

theorem main7b_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 == x_1 &&& x_2) &&& ofBool (x * 42#32 == x_1 &&& x * 42#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x_1 &&& (x_2 ||| x * 42#32) != x_2 ||| x * 42#32))

theorem bad_shl2_sub_i32_thm (e : IntW 32) :
  shl (const? 32 1) (sub e (const? 32 31)) ⊑
    shl (const? 32 1) (add e (const? 32 (-31))) { «nsw» := false, «nuw» := true }

theorem dec_sub_proof : dec_sub_before ⊑ dec_sub_after

@[simp]
lemma bv_to_set_or {m : CNFA n} (x y : BitVec m.m.stateMax) :
    (s ∈ bv_to_set (x ||| y)) ↔ (s ∈ bv_to_set x ∨ s ∈ bv_to_set y)

theorem test86_thm.extracted_1._1 : ∀ (x : BitVec 16), ¬4#32 ≥ ↑32 → 4#16 ≥ ↑16 → False

theorem icmp_eq_x_invertable_y2_todo_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  icmp IntPred.eq (select e_2 (const? 8 7) (LLVM.xor e_1 (const? 8 (-1))))
      (LLVM.or e (select e_2 (const? 8 7) (LLVM.xor e_1 (const? 8 (-1))))) ⊑
    icmp IntPred.eq (LLVM.and e (select e_2 (const? 8 (-8)) e_1)) (const? 8 0)

theorem ashrslt_02_06_exact_proof : ashrslt_02_06_exact_before ⊑ ashrslt_02_06_exact_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_5_after

theorem trunc_shl_lshr_infloop_proof : trunc_shl_lshr_infloop_before ⊑ trunc_shl_lshr_infloop_after

theorem nonexact_lshr_eq_noexactlog_proof : nonexact_lshr_eq_noexactlog_before ⊑ nonexact_lshr_eq_noexactlog_after
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Fintype.Prod

import Blase.AutoStructs.Worklist

import Mathlib.Tactic.ApplyFun

open SetRel

section sink

variable {A : Type} [BEq A] [Hashable A] [DecidableEq A] [FinEnum A]

end sink

section generic_prod

variable {α} [BEq α] [Hashable α] [LawfulBEq α]

variable {β} [BEq β] [Hashable β] [LawfulBEq β]

variable {S₁ : Finset α} {S₂ : Finset β}

variable {γ} (f : S₁ → S₂ → γ) (hinj : Function.Injective2 f)

variable {m₁ : Std.HashSet α} (hm₁ : ∀ s₁ ∈ m₁, s₁ ∈ S₁)

variable {m₂ : Std.HashSet β} (hm₂ : ∀ s₂ ∈ m₂, s₂ ∈ S₂)

@[inline]
def product.prodArray' (a : Array γ) :=
  m₁.attachWith _ hm₁ |>.fold (init := a) fun is s1 =>
    m₂.attachWith _ hm₂ |>.fold (init := is) fun is s2 =>
      is.push (f s1 s2)

end generic_prod

section product

variable {A : Type} [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

def product (final? : Bool → Bool → Bool) (m₁ m₂ : CNFA n) : CNFA n :=
  worklistRun (m₁.m.states × m₂.m.states) final (product.inits m₁ m₂)
    (by admit /- proof elided -/
    ) f
where final (ss : m₁.m.states × m₂.m.states) := final? (ss.1 ∈ m₁.m.finals) (ss.2 ∈ m₂.m.finals)
      f (ss : m₁.m.states × m₂.m.states) :=
        let (s1, s2) := ss
        (FinEnum.toList (α := BitVec n)).foldl (init := Array.empty) fun as a =>
          product.prodArray' (λ s₁ s₂ ↦ (a, (s₁, s₂)))
            (fun s' => m₁.wf.trans_tgt_lt (s := s1) (a := a)) (fun s' => m₂.wf.trans_tgt_lt (s := s2) (a := a)) as
</local_ctx>

<target_theorem>
lemma product.f_spec {m₁ m₂ : CNFA n} {s₁ : m₁.m.states} {s₂ : m₂.m.states} :
    ∀ a s₁' s₂',
      (a, (s₁', s₂')) ∈ f m₁ m₂ (s₁, s₂) ↔ s₁'.val ∈ m₁.m.tr s₁ a ∧ s₂'.val ∈ m₂.m.tr s₂ a :=
</target_theorem>

