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>
Bool in Init.Prelude
Nat in Init.Prelude
BitVec in Init.Prelude
BitVec.adcb in Init.Data.BitVec.Bitblast
Prod in Init.Prelude
Fin in Init.Prelude
BitVec.iunfoldr in Init.Data.BitVec.Folds
FinEnum in Mathlib.Data.FinEnum
FinEnum.card in Mathlib.Data.FinEnum
Polynomial.X in Mathlib.Algebra.Polynomial.Basic
ZMod in Mathlib.Data.ZMod.Defs
BEq in Init.Prelude
DecidableEq in Init.Prelude
Hashable in Init.Prelude
Repr in Init.Data.Repr
Std.HashMap in Std.Data.HashMap.Basic
Std.HashSet in Std.Data.HashSet.Basic
Array in Init.Prelude
List.map in Init.Prelude
Array.foldl in Init.Data.Array.Basic
Std.HashMap.emptyWithCapacity in Std.Data.HashMap.Basic
Array.size in Init.Prelude
List in Init.Prelude
Vector in Init.Data.Vector.Basic
String in Init.Prelude
Unit in Init.Prelude
Field in Mathlib.Algebra.Field.Defs
FinEnum.equiv in Mathlib.Data.FinEnum
NFA in Mathlib.Computability.NFA
NFA.accept in Mathlib.Computability.NFA
NFA.start in Mathlib.Computability.NFA
NFA.step in Mathlib.Computability.NFA
FinEnum.toList in Mathlib.Data.FinEnum
BitVec.ofNat in Init.Prelude
BitVec.cons in Init.Data.BitVec.Basic
BitVec.cast in Init.Data.BitVec.Basic
Function.Injective in Init.Data.Function
Function.LeftInverse in Init.Data.Function

def carry (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n => (addAux' initCarry x y n).2

def BitStream : Type := Nat → Bool

def addAux' (carryIn : Bool) (x y : BitStream) (i : Nat) :  Bool × Bool :=
  let carryIn : Bool := match i with
    | 0 => carryIn
    | i + 1 => (addAux' carryIn x y i).2
  Prod.swap (BitVec.adcb (x i) (y i) carryIn)

def BitVec.ofFn {w : Nat} (f : Fin w → Bool) : BitVec w :=
  BitVec.iunfoldr (fun i _ => ((), f i)) () |>.2

noncomputable def f : (ZMod q)[X] := X^(2^n) + 1

def worklistRun (final : S → Bool) (inits : Array S)
    (hinits : inits.toList.Nodup) (f : S → Array (BitVec n × S)) : CNFA n :=
  ⟨worklistRun' _ S final inits hinits f, worklistRun'_wf (BitVec n) S⟩

def worklistRun' (final : S → Bool) (inits : Array S) (hinits : inits.toList.Nodup) (f : S → Array (A × S)) : RawCNFA A :=
  let st0 := worklist.initState _ _ inits hinits final
  go st0
where go (st0 : worklist.St A S) : RawCNFA A :=
  if hemp : st0.worklist.isEmpty then st0.m else
  let sa? := st0.worklist.back?
  match heq : sa? with
  | some sa =>
    let wl := st0.worklist.pop
    let st1 := { st0 with worklist := wl,
                          worklist_nodup := by admit /- proof elided -/

structure worklist.St where
  m : RawCNFA A
  map : Std.HashMap S State := ∅
  worklist : Array S := ∅
  worklist_nodup : worklist.toList.Nodup
  worklist_incl : ∀ sa ∈ worklist, sa ∈ map

def worklist.initState (inits : Array S) (hinits : inits.toList.Nodup) (final? : S → Bool) : worklist.St A S :=
  let m := RawCNFA.empty (A := A)
  let mapm := inits.foldl (init := (Std.HashMap.emptyWithCapacity, m)) fun (map, m) sa =>
    let (s, m) := m.newState
    let m := m.addInitial s
    let m := if final? sa then m.addFinal s else m
    (map.insert sa s, m)
  let map := mapm.1
  let m := mapm.2
  let worklist_incl : ∀ sa ∈ inits, sa ∈ map :=

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

abbrev State := Nat

def RawCNFA.empty : RawCNFA A := {
  stateMax := 0
  initials := ∅
  finals := ∅
  trans := ∅
}

def processOneElem (final : S → Bool) (s : State) (st : worklist.St A S) : A × S → worklist.St A S :=
  fun (a', sa') =>
    let (s', st') := st.addOrCreateState _ _ (final sa') sa'
    let m := st'.m.addTrans a' s s'
    { st' with m }

def worklist.St.addOrCreateState (st : worklist.St A S) (final? : Bool) (sa : S) : State × worklist.St A S :=
  match heq : st.map[sa]? with
  | some s => (s, st)
  | none =>
    let (s, m) := st.m.newState
    let m := if final? then m.addFinal s else m
    let map := st.map.insert sa s
    let worklist := st.worklist.push sa
    have worklist_nodup : worklist.toList.Nodup := by admit /- proof elided -/

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

structure FSM (arity : Type) : Type 1 where
   
  ( α  : Type )
  [ i : FinEnum α ]
  [ h : Hashable α ]
  [ dec_eq : DecidableEq α ]
   
  ( initCarry : α → Bool )
   
  outputCirc : Circuit (α ⊕ arity)
  nextStateCirc : α → Circuit (α ⊕ arity)

inductive Circuit (α : Type u) : Type u
  | tru : Circuit α
  | fals : Circuit α
   
  | var : (positive: Bool) → α → Circuit α
  | and : Circuit α → Circuit α → Circuit α
  | or : Circuit α → Circuit α → Circuit α
  | xor : Circuit α → Circuit α → Circuit α
deriving Repr, DecidableEq

def Var (Γ : Context Ty) (ty : Ty) : Type := { v : VarName // Γ.hasType v ty }

def bv2 : BitVec 4 := BitVec.ofNat 4 1

def bv1 : BitVec 4 := BitVec.ofNat 4 5

@[simp_denote]
def slt_llvm_i32 := [LV| {
    ^entry (%a: i32, %b: i32):
    %0 = llvm.icmp.slt %a, %b : i32
    %1 = llvm.zext %0 : i1 to i32
    llvm.return %1 : i32
  }]

def slt_zero_eq_i1_signed_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.sext %arg3 : i1 to i32
  %2 = llvm.ashr %arg2, %0 : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def shift_xor_multiuse_or_after := [llvm|
{
^0(%arg128 : i32, %arg129 : 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 %arg128, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg129, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg129) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %6, %5 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def lshr_add_exact_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(-4 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.and %arg6, %0 : i8
  %3 = llvm.and %arg7, %1 : i8
  %4 = llvm.lshr exact %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def add_shl_same_amount_nuw_after := [llvm|
{
^0(%arg53 : i64, %arg54 : i64, %arg55 : i64):
  %0 = llvm.add %arg53, %arg54 overflow<nuw> : i64
  %1 = llvm.shl %0, %arg55 overflow<nuw> : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def xor_lshr_after := [llvm|
{
^0(%arg624 : i8, %arg625 : i8, %arg626 : i8, %arg627 : i8):
  %0 = llvm.xor %arg624, %arg625 : i8
  %1 = llvm.lshr %0, %arg627 : i8
  %2 = llvm.xor %1, %arg626 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

@[implemented_by evalExprOfTypeRegionAux]
partial def evalExprOfTypeRegion (φ : Nat) : Q(Region $φ) → MetaM (Region φ) :=
  default

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 test12_after := [llvm|
{
^0(%arg42 : i1):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test_sext_before := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "eq" %arg30, %0 : i32
  %3 = llvm.sext %2 : i1 to i32
  %4 = llvm.add %arg31, %3 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

instance : HydrableGetInputWidth where
  getWidth := getWidth

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 test_invert_demorgan_logical_or_before := [llvm|
{
^0(%arg11 : i64, %arg12 : i64):
  %0 = llvm.mlir.constant(27) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "eq" %arg11, %0 : i64
  %4 = llvm.icmp "eq" %arg12, %1 : i64
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.icmp "eq" %arg11, %1 : i64
  %7 = llvm.or %6, %5 : i1
  %8 = llvm.xor %7, %2 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

@[simp_denote]
def add_shl_sext_riscv := [LV| {
    ^entry (%a: i32):
    %a0 = "builtin.unrealized_conversion_cast" (%a) : (i32) -> (!i64)
    %0 = addi %a0, 3 : !i64
    %1 = sllw %0, %a0 : !i64
    %2 = "builtin.unrealized_conversion_cast" (%1) : (!i64) -> (i64)
    llvm.return %2 : i64
  }]

def test1_before := [llvm|
{
^0(%arg3 : i57, %arg4 : i57, %arg5 : i57):
  %0 = llvm.lshr %arg3, %arg5 : i57
  %1 = llvm.lshr %arg4, %arg5 : i57
  %2 = llvm.or %0, %1 : i57
  "llvm.return"(%2) : (i57) -> ()
}
]

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

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

List.foldl in Init.Prelude

def llvm_const_lower_riscv_li_47 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_47, rhs:= liRiscv_47,
   correct := by admit /- proof elided -/

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) -> ()
}
]

BitVec.mul in Init.Data.BitVec.Basic

def both_before := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg17 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.shl %0, %arg18 : i8
  %4 = llvm.xor %3, %0 : i8
  %5 = llvm.icmp "ult" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def positive_with_signbit_before := [llvm|
{
^0(%arg62 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.icmp "sgt" %arg62, %0 : i32
  %4 = llvm.add %arg62, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  %6 = llvm.and %3, %5 : 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) -> ()
}
]

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

def sub_ashr_and_i16_after := [llvm|
{
^0(%arg29 : i16, %arg30 : i16):
  %0 = llvm.mlir.constant(0 : i16) : i16
  %1 = llvm.icmp "slt" %arg30, %arg29 : i16
  %2 = "llvm.select"(%1, %arg29, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def or_or_and_pat5_before := [llvm|
{
^0(%arg58 : i8, %arg59 : i8, %arg60 : i8, %arg61 : i8):
  %0 = llvm.and %arg58, %arg59 : i8
  %1 = llvm.and %arg58, %arg61 : i8
  %2 = llvm.or %1, %arg60 : i8
  %3 = llvm.or %2, %0 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

abbrev ReaderM  (d : Dialect) := ReaderT NameMapping (ExceptM d)

structure TermFSM (wcard tcard bcard ncard icard pcard : Nat) (t : Nondep.Term) where
  toFsmZext : FSM (StateSpace wcard tcard bcard ncard icard pcard)
  width : NatFSM wcard tcard bcard ncard icard pcard t.width

def shl_nsw_nuw_poison_constant_fold_after := [llvm|
{
^0(%arg6 : i1, %arg7 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.shl %0, %arg7 overflow<nsw,nuw> : i8
  %3 = "llvm.select"(%arg6, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def bitwise_and_bitwise_and_icmps_comm3_after := [llvm|
{
^0(%arg235 : i8, %arg236 : i8, %arg237 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg236, %0 : i8
  %3 = llvm.shl %1, %arg237 overflow<nuw> : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.and %arg235, %4 : i8
  %6 = llvm.icmp "eq" %5, %4 : i8
  %7 = llvm.and %6, %2 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def prove_exact_with_high_mask_limit_after := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.ashr %arg6, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

macro "deftest" name:ident " := " test_reg:mlir_region : command => do
  `(@[reducible, llvmTest $name] def $(name) : ConcreteCliTest :=
       let code := [llvm()| $test_reg]
       { name := $(quote name.getId), ty := code.ty, context := code.ctxt, code := code, })

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 positive_with_mask_after := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg60, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def MatchArgResult.toHom
    (map : MatchArgResult lets matchLets vs ws mapIn)
    (hvars : ∀ t (v : Var Δ_in t), ⟨t, v⟩ ∈ matchLets.varsOfVec ws) :
    Δ_in.Hom Γ_out :=
  map.val.toHom <| map.isTotal_of hvars

variable
  {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty}
  {lets : Lets d Γ_in eff Γ_out}
  {matchTy}
  {v : Var Γ_out matchTy}
  {matchLets : Lets d Δ_in .pure Δ_out}
  {w : Var Δ_out matchTy}
in

def not_and_and_or_no_or_commute3_before := [llvm|
{
^0(%arg148 : i32, %arg149 : i32, %arg150 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg150 : i32
  %3 = llvm.or %arg149, %arg148 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.xor %arg148, %1 : i32
  %6 = llvm.and %5, %arg149 : i32
  %7 = llvm.and %2, %6 : i32
  %8 = llvm.or %7, %4 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def lshr_mul_negative_nsw_after := [llvm|
{
^0(%arg29 : i64):
  %0 = llvm.mlir.constant(52) : i64
  %1 = llvm.mlir.constant(2) : i64
  %2 = llvm.mul %arg29, %0 overflow<nsw> : i64
  %3 = llvm.lshr exact %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def mul_constant_eq_nsw_before := [llvm|
{
^0(%arg130 : i32, %arg131 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mul %arg130, %0 overflow<nsw> : i32
  %2 = llvm.mul %arg131, %0 overflow<nsw> : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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 select_shl_icmp_bad_after := [llvm|
{
^0(%arg51 : i32, %arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg51, %0 : i32
  %2 = llvm.shl %arg53, %0 : i32
  %3 = "llvm.select"(%1, %2, %arg52) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def irc_constants_C2MinusAPlusC1_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 %c2, %0 : 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.sub %0, %a : i64
      llvm.return %1 : i64
  }]

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 no_shift_xor_multiuse_cmp_and_after := [llvm|
{
^0(%arg40 : i32, %arg41 : i32, %arg42 : i32, %arg43 : 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 %arg40, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg41, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg41) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg43, %arg42) <{"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 n4_after := [llvm|
{
^0(%arg8 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(-1073741824 : i32) : i32
  %2 = llvm.zext %arg8 : i16 to i32
  %3 = llvm.shl %2, %0 overflow<nuw> : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def binop_left_to_zero: List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, binop_left_to_zero_shl⟩,
  ⟨_, binop_left_to_zero_lshr⟩,
  ⟨_, binop_left_to_zero_ashr⟩,
  ⟨_, binop_left_to_zero_sdiv⟩,
  ⟨_, binop_left_to_zero_udiv⟩,
  ⟨_, binop_left_to_zero_srem⟩,
  ⟨_, binop_left_to_zero_urem⟩,
  ⟨_, binop_left_to_zero_mul⟩]

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

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

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

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

def shift_no_xor_multiuse_cmp_with_xor_after := [llvm|
{
^0(%arg116 : i32, %arg117 : i32, %arg118 : i32, %arg119 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg116, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.shl %2, %0 overflow<nsw,nuw> : i32
  %5 = llvm.xor %arg117, %4 : i32
  %6 = "llvm.select"(%3, %arg118, %arg119) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def neg_or_ashr_i32_before := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.sub %0, %arg32 : i32
  %3 = llvm.or %2, %arg32 : i32
  %4 = llvm.ashr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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 not_or_or_and_no_and_commute2_or_after := [llvm|
{
^0(%arg115 : i32, %arg116 : i32, %arg117 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg115, %0 : i32
  %2 = llvm.xor %arg116, %0 : i32
  %3 = llvm.and %arg117, %2 : i32
  %4 = llvm.or %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def trunc_lshr_sext_narrow_input_after := [llvm|
{
^0(%arg24 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.ashr %arg24, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

elab "[llvm(" mvars:term,* ")| " reg:mlir_region "]" : term => do
  withTraceNode `LeanMLIR.Elab (pure m!"{exceptEmoji ·} elaborate LLVM program") <| do

  let φ : Nat := mvars.getElems.size
  let ⟨_, _, _, mcom⟩ ← SSA.elabIntoComObj reg (MetaLLVM φ)

  let res ← mcom.metaMap <| MetaLLVM.instantiate <| ←do
    let mvars : Vector _ φ := ⟨mvars.getElems, rfl⟩
    mvars.mapM fun (stx : Term) =>
      elabTermEnsuringType stx (mkConst ``Nat)

  trace[LeanMLIR.Elab] "elaborated expression: {res}"
  return res

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

def test10_before := [llvm|
{
^0(%arg187 : i16):
  %0 = llvm.sext %arg187 : i16 to i32
  %1 = llvm.trunc %0 : i32 to i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def main7b_logical_before := [llvm|
{
^0(%arg75 : i32, %arg76 : i32, %arg77 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg75, %arg76 : i32
  %4 = llvm.icmp "eq" %arg76, %3 : i32
  %5 = llvm.and %arg75, %arg77 : i32
  %6 = llvm.icmp "eq" %arg77, %5 : 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 ashrsgt_03_04_exact_before := [llvm|
{
^0(%arg65 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(4 : i4) : i4
  %2 = llvm.ashr exact %arg65, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def test9_before := [llvm|
{
^0(%arg52 : i16):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.mlir.constant(32767 : i16) : i16
  %2 = llvm.mul %arg52, %0 : i16
  %3 = llvm.mul %arg52, %1 : i16
  %4 = llvm.add %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

def eq_umax1_after := [llvm|
{
^0(%arg60 : i32, %arg61 : i32):
  %0 = llvm.icmp "uge" %arg60, %arg61 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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 nomask_lhs_after := [llvm|
{
^0(%arg115 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg115, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

ZMod.val in Mathlib.Data.ZMod.Basic

Lean.DefinitionSafety.safe in Lean.Declaration

def ashrslt_01_03_after := [llvm|
{
^0(%arg266 : i4):
  %0 = llvm.mlir.constant(6 : i4) : i4
  %1 = llvm.icmp "slt" %arg266, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def xor_or_xor_common_op_commute7_before := [llvm|
{
^0(%arg62 : i32, %arg63 : i32, %arg64 : i32):
  %0 = llvm.xor %arg62, %arg64 : i32
  %1 = llvm.or %arg63, %arg62 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def PR21222_after := [llvm|
{
^0(%arg131 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.icmp "eq" %arg131, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

def samesign_commute1_after := [llvm|
{
^0(%arg125 : i32, %arg126 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg125, %arg126 : i32
  %2 = llvm.icmp "sgt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def icmp_slt_0_xor_icmp_sge_neg2_i32_fail_after := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.icmp "ult" %arg39, %0 : i32
  %2 = llvm.zext %1 : i1 to 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) -> ()
}
]

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

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

@[simp_denote]
def xori_llvm_i64 := [LV| {
    ^entry (%a: i64):
    %0 = llvm.mlir.constant (4) : i64
    %1 = llvm.xor %a, %0 : i64
    llvm.return %1 : i64
  }]

def or_or_and_pat1_after := [llvm|
{
^0(%arg74 : i8, %arg75 : i8, %arg76 : i8, %arg77 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg76 : i8
  %2 = llvm.or %arg77, %arg75 : i8
  %3 = llvm.and %arg74, %2 : i8
  %4 = llvm.or %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def add_2_before := [llvm|
{
^0(%arg121 : i8, %arg122 : i1, %arg123 : i8, %arg124 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.xor %arg123, %0 : i8
  %3 = llvm.xor %arg124, %1 : i8
  %4 = "llvm.select"(%arg122, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.add %arg121, %4 : i8
  %6 = llvm.xor %5, %0 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def test14a_after := [llvm|
{
^0(%arg25 : i79):
  %0 = llvm.mlir.constant(77 : i79) : i79
  %1 = llvm.and %arg25, %0 : i79
  "llvm.return"(%1) : (i79) -> ()
}
]

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

def trunc_sel_smaller_zext_after := [llvm|
{
^0(%arg69 : i64, %arg70 : i1):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.trunc %arg69 : i64 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = "llvm.select"(%arg70, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def invert_both_cmp_operands_add_before := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.xor %arg38, %0 : i32
  %3 = llvm.add %arg39, %2 : i32
  %4 = llvm.icmp "sgt" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def worklistRun_init_post (inits : Array S) (final : S → Bool)
    (map : Std.HashMap S State) (m : RawCNFA A) :=
  (forall sa, sa ∈ map ↔ sa ∈ inits) ∧
  (∀ s a, m.tr s a = ∅) ∧
  ∀ sa s, map[sa]? = some s → (s ∈ m.initials) ∧ (s ∈ m.finals ↔ final sa)

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

def positive_biggerlshr_shlnuw_after := [llvm|
{
^0(%arg55 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(24 : i8) : i8
  %2 = llvm.lshr %arg55, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

@[simp_denote]
def add_negative_low_bound_reject_riscv := [LV| {
  ^entry (%arg: i32):
  %0 = li (843949575) : !i64 
  %1 = "lui" (%0) {imm = 1048575 : !i64} : (!i64) -> (!i64)
  %2 = "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
  %3 = "addi" (%1) {imm = -1 : !i64} : (!i64) -> (!i64)
  %4 = addw %2, %3 : !i64
  %5 =  "builtin.unrealized_conversion_cast" (%4) : (!i64) -> (i32)
  llvm.return %5 : i32
}]

@[simp_denote]
def trunc_riscv_32_to_16 := [LV| {
  ^entry (%lhs: i32):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i32) -> (!i64)
    %0= "builtin.unrealized_conversion_cast"(%lhsr) : (!i64) -> (i16)
    llvm.return %0 : i16
  }]

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

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

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

def and_signbit_select_shl_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i1):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg46, %0 : i32
  %3 = "llvm.select"(%arg47, %2, %arg46) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.shl %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def t6_no_extrause_before := [llvm|
{
^0(%arg19 : i8, %arg20 : i8):
  %0 = llvm.add %arg19, %arg20 : i8
  %1 = llvm.icmp "uge" %0, %arg20 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def test9_after := [llvm|
{
^0(%arg52 : i16):
  %0 = llvm.mlir.constant(-32767 : i16) : i16
  %1 = llvm.mul %arg52, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def test36_before := [llvm|
{
^0(%arg158 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.lshr %arg158, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

Std.Refl in Init.Core

def test10_before := [llvm|
{
^0(%arg50 : i32, %arg51 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(-1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1431655765 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.ashr %arg50, %0 : i32
  %5 = llvm.or %4, %1 : i32
  %6 = llvm.xor %5, %2 : i32
  %7 = llvm.add %arg51, %3 : i32
  %8 = llvm.add %7, %6 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

def sel_false_val_is_a_masked_lshr_of_true_val1_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.lshr %arg6, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg7, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

def test_nuw_dropped_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(1073741823 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.and %arg7, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.shl %arg7, %2 overflow<nuw> : i32
  %6 = "llvm.select"(%4, %1, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def shl {w : Nat} (x y : IntW w) (flags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w := do
  let x' ← x
  let y' ← y
    
  if flags.nsw ∧ ((x' <<< y').sshiftRight'  y' ≠ x') then
    .poison
  else if flags.nuw ∧ ((x' <<< y') >>> y' ≠ x') then
    .poison
  else
    shl? x' y'

def and_orn_cmp_3_logical_after := [llvm|
{
^0(%arg182 : i72, %arg183 : i72, %arg184 : i72):
  %0 = llvm.mlir.constant(42 : i72) : i72
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ugt" %arg182, %arg183 : i72
  %3 = llvm.icmp "ugt" %arg184, %0 : i72
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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 prove_exact_with_high_mask_limit_before := [llvm|
{
^0(%arg6 : i8, %arg7 : i8):
  %0 = llvm.mlir.constant(-32 : i8) : i8
  %1 = llvm.and %arg6, %0 : i8
  %2 = llvm.sdiv %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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 ashrslt_01_09_exact_after := [llvm|
{
^0(%arg44 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test2_before := [llvm|
{
^0(%arg208 : i1):
  %0 = llvm.xor %arg208, %arg208 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def logical_and_implies_after := [llvm|
{
^0(%arg249 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.icmp "ne" %arg249, %0 : i32
  %3 = llvm.icmp "ne" %arg249, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def mul_add_to_mul_6_after := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mul %arg26, %arg27 overflow<nsw> : i32
  %2 = llvm.mul %1, %0 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def add_1_after := [llvm|
{
^0(%arg125 : i8, %arg126 : i1, %arg127 : i8, %arg128 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.xor %arg128, %0 : i8
  %2 = "llvm.select"(%arg126, %arg127, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %2, %arg125 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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 test16_after := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.xor %arg43, %arg42 : i8
  %2 = llvm.xor %arg42, %arg43 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.mul %4, %3 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

inductive WidthAbstractionKind
 
| generalizeGeq (cutoff : Nat)
 
| always
 
| never
deriving DecidableEq, Repr

def t_1_10_after := [llvm|
{
^0(%arg13 : i8):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.and %arg13, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test84_before := [llvm|
{
^0(%arg61 : i32):
  %0 = llvm.mlir.constant(-16777216 : i32) : i32
  %1 = llvm.mlir.constant(23 : i32) : i32
  %2 = llvm.add %arg61, %0 overflow<nsw> : i32
  %3 = llvm.lshr exact %2, %1 : i32
  %4 = llvm.trunc %3 : i32 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def and_two_ranges_to_mask_and_range_different_sizes_before := [llvm|
{
^0(%arg250 : i8):
  %0 = llvm.mlir.constant(-97 : i8) : i8
  %1 = llvm.mlir.constant(25 : i8) : i8
  %2 = llvm.mlir.constant(-65 : i8) : i8
  %3 = llvm.mlir.constant(24 : i8) : i8
  %4 = llvm.add %arg250, %0 : i8
  %5 = llvm.icmp "ugt" %4, %1 : i8
  %6 = llvm.add %arg250, %2 : i8
  %7 = llvm.icmp "ugt" %6, %3 : i8
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

def sdiv_mul_shl_nsw_before := [llvm|
{
^0(%arg193 : i5, %arg194 : i5, %arg195 : i5):
  %0 = llvm.mul %arg193, %arg194 overflow<nsw> : i5
  %1 = llvm.shl %arg193, %arg195 overflow<nsw> : i5
  %2 = llvm.sdiv %0, %1 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

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

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

def test4_after := [llvm|
{
^0(%arg97 : i32, %arg98 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = "llvm.select"(%arg98, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.and %arg97, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def shl_xor_xor_no_const_before := [llvm|
{
^0(%arg134 : i8, %arg135 : i8, %arg136 : i8, %arg137 : i8):
  %0 = llvm.shl %arg134, %arg136 : i8
  %1 = llvm.shl %arg135, %arg136 : i8
  %2 = llvm.xor %1, %arg137 : i8
  %3 = llvm.xor %0, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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 or_simplify_uge_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i1):
  %0 = llvm.mlir.constant(-127 : i8) : i8
  %1 = llvm.mlir.constant(127 : i8) : i8
  %2 = llvm.or %arg15, %0 : i8
  %3 = llvm.and %arg16, %1 : i8
  %4 = llvm.or %2, %3 : i8
  %5 = llvm.icmp "uge" %3, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

structure Config where
  check? : Bool := true
  
  niter : Nat := 30
   
  startVerifyAtIter : Nat := 0
   
  verbose?: Bool := false
   
  widthAbstraction : WidthAbstractionKind := .generalizeGeq 2
   
  debugFillFinalReflectionProofWithSorry : Bool := false
   
  debugPrintSmtLib : Bool := false
   
  debugDumpAiger: Option String := none
deriving DecidableEq, Repr

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

instance : Lean.ToExpr (LLVM.Op) :=

def test5_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.udiv %0, %arg23 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

BEq.beq in Init.Prelude

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

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

def mkReturn (Γ : Ctxt (MetaLLVM φ).Ty) (opStx : MLIR.AST.Op φ) :
    MLIR.AST.ReaderM (MetaLLVM φ) (Σ eff ty, Com (MetaLLVM φ) Γ eff ty) := do
  if opStx.name ≠ "llvm.return" then
    throw <| .unsupportedOp s!"Tried to build return out of non-return statement {opStx.name}"
  else
    let args ← (← opStx.parseArgs Γ).assumeArity 1
    let ⟨ty, v⟩ := args[0]
    return ⟨.pure, [ty], Com.ret v⟩

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

def select_icmp_ne_not_pow2_after := [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 "eq" %2, %1 : i8
  %4 = llvm.xor %arg8, %0 : i8
  %5 = "llvm.select"(%3, %arg8, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def VarList (Γ : Context Ty) (tys : List Ty) : Type :=
  { vs : List VarName // vs.length = tys.length ∧ ∀ v ∈ vs.zip tys, Γ.hasType v.fst v.snd }

def shl_lshr_demand3_before := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(40 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(-64 : i8) : i8
  %3 = llvm.shl %0, %arg18 : i8
  %4 = llvm.lshr %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def test47_after := [llvm|
{
^0(%arg197 : i32, %arg198 : i32):
  %0 = llvm.and %arg198, %arg197 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def one_inst_concrete_macro :=
  [llvm()|{
  ^bb0(%arg0: i1):
    %0 = llvm.not %arg0 : i1
    llvm.return %0 : i1
  }]

Stream'.const in Mathlib.Data.Stream.Defs

def mkOutEqZeroCircuitLeN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
    let ixs := List.range (n + 1) |>.attach
    let circs := ixs.map fun ⟨i, hi⟩ =>
      mkOutEqZeroCircuitN p i |>.map (fun v => v.castLe (by admit /- proof elided -/
      ))
    Circuit.bigOr circs

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

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

def or_or_xor_commute2_before := [llvm|
{
^0(%arg100 : i4, %arg101 : i4, %arg102 : i4):
  %0 = llvm.or %arg102, %arg100 : i4
  %1 = llvm.or %arg101, %arg102 : i4
  %2 = llvm.xor %0, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

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

def llvm_const_lower_riscv_li43 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM43, rhs:= liRiscv43,
   correct := by admit /- proof elided -/

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

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 shl_add_and_lshr_after := [llvm|
{
^0(%arg9 : i32, %arg10 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.shl %arg10, %0 : i32
  %3 = llvm.and %arg9, %1 : i32
  %4 = llvm.add %3, %2 : i32
  "llvm.return"(%4) : (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 t0_sub_of_trueval_before := [llvm|
{
^0(%arg13 : i1, %arg14 : i8, %arg15 : i8):
  %0 = "llvm.select"(%arg13, %arg14, %arg15) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %1 = llvm.sub %0, %arg14 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

structure Item where
 name : String
 tac : Syntax

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

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

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) -> ()
}
]

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

def bitwise_or_bitwise_or_icmps_comm3_after := [llvm|
{
^0(%arg187 : i8, %arg188 : i8, %arg189 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg188, %0 : i8
  %3 = llvm.shl %1, %arg189 overflow<nuw> : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.and %arg187, %4 : i8
  %6 = llvm.icmp "ne" %5, %4 : i8
  %7 = llvm.or %6, %2 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def wide_source_matching_signbits_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.and %arg5, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nsw> : i32
  %4 = llvm.trunc %3 : i32 to i8
  %5 = llvm.sext %4 : i8 to i24
  "llvm.return"(%5) : (i24) -> ()
}
]

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 slt_or_not_max_commute_logical_before := [llvm|
{
^0(%arg56 : i8, %arg57 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "slt" %arg56, %arg57 : i8
  %3 = llvm.icmp "ne" %arg56, %0 : i8
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def llvm_sub_lower_riscv_no_flag_self_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := llvm_sub_self_64
  rhs := sub_riscv_self_64

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

private def pretty_test_icmp :=
  [llvm()|{
  ^bb0(%arg0: i1):
    %1 = llvm.icmp "eq" %arg0, %arg0 : i1
    llvm.return %1 : i1
  }]

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

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

def composeBinary
    (p : FSM Bool)
    {t₁ t₂ : Term}
    (q₁ : FSMTermSolution t₁)
    (q₂ : FSMTermSolution t₂) :
    FSM (Fin (max t₁.arity t₂.arity)) := composeBinaryAux p q₁.toFSM q₂.toFSM

def irc_constants_C1Minus2MinusC2_neg2_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 %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 (-1) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.sub %0, %a : i64
      llvm.return %1 : i64
  }]

def not_or_or_not_after := [llvm|
{
^0(%arg552 : i32, %arg553 : i32, %arg554 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg552 : i32
  %3 = llvm.and %arg553, %arg554 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical_before := [llvm|
{
^0(%arg69 : i32):
  %0 = llvm.mlir.constant(14 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.mlir.constant(true) : i1
  %5 = llvm.and %arg69, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %arg69, %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 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 rev8_mul_and_lshr_before := [llvm|
{
^0(%arg29 : i8):
  %0 = llvm.mlir.constant(2050) : i64
  %1 = llvm.mlir.constant(139536) : i64
  %2 = llvm.mlir.constant(32800) : i64
  %3 = llvm.mlir.constant(558144) : i64
  %4 = llvm.mlir.constant(65793) : i64
  %5 = llvm.mlir.constant(16) : i64
  %6 = llvm.zext %arg29 : i8 to i64
  %7 = llvm.mul %6, %0 overflow<nsw,nuw> : i64
  %8 = llvm.and %7, %1 : i64
  %9 = llvm.mul %6, %2 overflow<nsw,nuw> : i64
  %10 = llvm.and %9, %3 : i64
  %11 = llvm.or %8, %10 : i64
  %12 = llvm.mul %11, %4 overflow<nsw,nuw> : i64
  %13 = llvm.lshr %12, %5 : i64
  %14 = llvm.trunc %13 : i64 to i8
  "llvm.return"(%14) : (i8) -> ()
}
]

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) -> ()
}
]

instance : GetElem (LengthIndexedList α n) Nat α fun _xs i => LT.lt i n where
  getElem xs i h := nth xs ⟨i, h⟩

def zero_sign_bit2_before := [llvm|
{
^0(%arg29 : i16, %arg30 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.and %arg29, %0 : i16
  %2 = llvm.and %arg30, %0 : i16
  %3 = llvm.add %1, %2 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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) -> ()
}
]

def invert_signbit_splat_mask_before := [llvm|
{
^0(%arg93 : i8, %arg94 : i16):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg93, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.sext %3 : i8 to i16
  %5 = llvm.and %4, %arg94 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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 test_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg0, %0 : i32
  %3 = llvm.lshr %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def or_simplify_uge_after := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i1):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def andn_or_cmp_1_logical_after := [llvm|
{
^0(%arg173 : i37, %arg174 : i37, %arg175 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sle" %arg173, %arg174 : i37
  %3 = llvm.icmp "ugt" %arg175, %0 : i37
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def trunc_equality_nuw_after := [llvm|
{
^0(%arg44 : i16, %arg45 : i16):
  %0 = llvm.icmp "eq" %arg44, %arg45 : i16
  "llvm.return"(%0) : (i1) -> ()
}
]

def or_lshr_after := [llvm|
{
^0(%arg628 : i8, %arg629 : i8, %arg630 : i8, %arg631 : i8):
  %0 = llvm.or %arg628, %arg629 : i8
  %1 = llvm.lshr %0, %arg631 : i8
  %2 = llvm.or %1, %arg630 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def narrow_zext_and_before := [llvm|
{
^0(%arg54 : i16, %arg55 : i32):
  %0 = llvm.zext %arg54 : i16 to i32
  %1 = llvm.and %0, %arg55 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

def and_sext_multiuse_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32, %arg3 : i32):
  %0 = llvm.icmp "sgt" %arg0, %arg1 : i32
  %1 = llvm.sext %0 : i1 to i32
  %2 = llvm.and %1, %arg2 : i32
  %3 = llvm.and %1, %arg3 : i32
  %4 = llvm.add %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def and_ne_with_one_bit_diff_constants2_before := [llvm|
{
^0(%arg360 : i19):
  %0 = llvm.mlir.constant(65 : i19) : i19
  %1 = llvm.mlir.constant(193 : i19) : i19
  %2 = llvm.icmp "ne" %arg360, %0 : i19
  %3 = llvm.icmp "ne" %arg360, %1 : i19
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def or_xor_tree_1111_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg0, %0 : i32
  %2 = llvm.mul %arg1, %0 : i32
  %3 = llvm.mul %arg2, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def reassoc_sub_nuw_after := [llvm|
{
^0(%arg25 : i32):
  %0 = llvm.mlir.constant(-68 : i32) : i32
  %1 = llvm.add %arg25, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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) -> ()
}
]

def ashrsgt_03_07_exact_before := [llvm|
{
^0(%arg62 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.ashr exact %arg62, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (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 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 alive_AndOrXor_1288_A__B__B__C__A___A__B__C_src :=
[sllvm| {
^bb0(%A : i64, %C : i64, %B : i64):
  %v1 = llvm.xor %A, %B : i64
  %v2 = llvm.xor %B, %C : i64
  %v3 = llvm.xor %v2, %A : i64
  %v4 = llvm.and %v1, %v3 : i64
  llvm.return %v4 : i64
}]

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

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

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

inductive IcmpPredicate where
  | eq
  | ne
  | slt
  | sle
  | sgt
  | sge
  | ult
  | ule
  | ugt
  | uge
deriving Inhabited, DecidableEq, Repr

def shl_add_lshr_after := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.lshr %arg156, %arg155 : i32
  %1 = llvm.add %0, %arg154 overflow<nuw> : 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) -> ()
}
]

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

def shl_sub_lshr_reverse_after := [llvm|
{
^0(%arg136 : i32, %arg137 : i32, %arg138 : i32):
  %0 = llvm.lshr exact %arg138, %arg137 : i32
  %1 = llvm.sub %0, %arg136 overflow<nsw,nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

AndOp in Init.Prelude

def test1_after := [llvm|
{
^0(%arg3 : i57, %arg4 : i57, %arg5 : i57):
  %0 = llvm.xor %arg3, %arg4 : i57
  %1 = llvm.and %arg5, %0 : i57
  "llvm.return"(%1) : (i57) -> ()
}
]

def match_unsigned_after := [llvm|
{
^0(%arg18 : i64):
  %0 = llvm.mlir.constant(19136) : i64
  %1 = llvm.urem %arg18, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def trunc {w: Nat} (w': Nat) (x: IntW w) (noWrapFlags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w' := do
  let x' <- x
  if noWrapFlags.nsw ∧ ((x'.truncate w').signExtend w ≠ x') then
    .poison
  else if noWrapFlags.nuw ∧ ((x'.truncate w').zeroExtend w ≠ x') then
    .poison
  else
    trunc? w' x'

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

def sge_to_ugt_before := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.xor %arg21, %0 : i8
  %3 = llvm.icmp "sge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def bitwise_or_bitwise_or_icmps_comm2_after := [llvm|
{
^0(%arg190 : i8, %arg191 : i8, %arg192 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg191, %0 : i8
  %3 = llvm.shl %1, %arg192 overflow<nuw> : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.and %arg190, %4 : i8
  %6 = llvm.icmp "ne" %5, %4 : i8
  %7 = llvm.or %6, %2 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

structure Dialect where
  (Op : Type)
  (Ty : Type)
  (m : Type → Type := Id)

instance instTransformTy : MLIR.AST.TransformTy DCPlus 0 where
  mkTy := mkTy

def test_mul_nsw__none_are_safe_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(9 : i32) : i32
  %1 = llvm.mul %arg1, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def factorize2_before := [llvm|
{
^0(%arg8 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mul %0, %arg8 : i32
  %3 = llvm.mul %1, %arg8 : i32
  %4 = llvm.sub %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def not_or_or_not_commute1_after := [llvm|
{
^0(%arg546 : i32, %arg547 : i32, %arg548 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg547, %arg548 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg546, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def add_umin_simplify_before := [llvm|
{
^0(%arg54 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.add %arg54, %0 overflow<nuw> : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  %3 = "llvm.select"(%2, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def zext_masked_bit_zero_to_larger_bitwidth_after := [llvm|
{
^0(%arg39 : i32, %arg40 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.xor %arg39, %0 : i32
  %3 = llvm.lshr %2, %arg40 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.zext nneg %4 : i32 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

def masked_and_notallones_after := [llvm|
{
^0(%arg129 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.and %arg129, %0 : i32
  %2 = llvm.icmp "ne" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def n11_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.shl %arg1, %0 : i8
  %3 = llvm.ashr %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def sge_smin1_after := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.icmp "sge" %arg80, %arg79 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def getBoolAttr (attr : String) : Except TransformError Bool := do
  let .bool b ← op.getAttr attr
    | .error <| .generic s!"Expected attribute `{attr}` to be of type Bool, but found:\n\
        \t{attr}"
  return b

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 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) -> ()
}
]

Matrix.of in Mathlib.LinearAlgebra.Matrix.Defs

def mullo_after := [llvm|
{
^0(%arg6 : i64, %arg7 : i64):
  %0 = llvm.mlir.constant(4294967295) : i64
  %1 = llvm.mlir.constant(32) : i64
  %2 = llvm.and %arg6, %0 : i64
  %3 = llvm.lshr %arg6, %1 : i64
  %4 = llvm.and %arg7, %0 : i64
  %5 = llvm.lshr %arg7, %1 : i64
  %6 = llvm.mul %4, %2 overflow<nuw> : i64
  %7 = llvm.mul %arg7, %3 : i64
  %8 = llvm.mul %5, %arg6 : i64
  %9 = llvm.and %6, %0 : i64
  %10 = llvm.lshr %6, %1 : i64
  %11 = llvm.add %10, %7 : i64
  %12 = llvm.add %11, %8 : i64
  %13 = llvm.shl %12, %1 : i64
  %14 = llvm.or disjoint %13, %9 : i64
  "llvm.return"(%14) : (i64) -> ()
}
]

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

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

instance instTransformTy : MLIR.AST.TransformTy RV64 0 where
  mkTy := mkTy

def lshr_16_add_known_16_leading_zeroes_after := [llvm|
{
^0(%arg29 : i32, %arg30 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.and %arg29, %0 : i32
  %3 = llvm.and %arg30, %0 : i32
  %4 = llvm.add %2, %3 overflow<nsw,nuw> : i32
  %5 = llvm.lshr %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def test_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(-5 : i32) : i32
  %2 = llvm.add %arg0, %0 : i32
  %3 = llvm.add %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def lshrugt_02_11_after := [llvm|
{
^0(%arg388 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 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 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) -> ()
}
]

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

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

@[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 ashr_not_after := [llvm|
{
^0(%arg78 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg78, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def foo1_and_commuted_after := [llvm|
{
^0(%arg172 : i32, %arg173 : i32, %arg174 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mul %arg172, %arg172 : i32
  %2 = llvm.shl %0, %arg173 overflow<nuw> : i32
  %3 = llvm.shl %0, %arg174 overflow<nuw> : i32
  %4 = llvm.or %2, %3 : i32
  %5 = llvm.and %1, %4 : i32
  %6 = llvm.icmp "ne" %5, %4 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

def t1_flags_sub_nsw_sub_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8, %arg44 : i8):
  %0 = llvm.sub %arg42, %arg43 overflow<nsw> : i8
  %1 = llvm.sub %0, %arg44 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def not_mul_of_bool_before := [llvm|
{
^0(%arg89 : i32, %arg90 : i8):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.and %arg89, %0 : i32
  %3 = llvm.zext %arg90 : i8 to i32
  %4 = llvm.mul %2, %3 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def flip_add_of_shift_neg_after := [llvm|
{
^0(%arg12 : i8, %arg13 : i8, %arg14 : i8):
  %0 = llvm.shl %arg12, %arg13 : i8
  %1 = llvm.sub %arg14, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

private def mkOmittedMsg : Option Expr → MessageData
  | none   => "<not imported>"
  | some e => e

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

def accepts' (M : NFA' n) : Set (BitVecs' n) := M.M.accepts

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

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 lshrult_01_12_exact_before := [llvm|
{
^0(%arg137 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-4 : i4) : i4
  %2 = llvm.lshr exact %arg137, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

Sigma.fst in Init.Core

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

def matchArg [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (matchLets : Lets d Δ_in .pure Δ_out) :
    {l : List d.Ty} → HVector (Var Γ_out) l → HVector (Var Δ_out) l →
    MatchVar Δ_in Γ_out
  | _, .nil, .nil => return
  | t::l, .cons vₗ vsₗ, .cons vᵣ vsᵣ => do
      matchVar (t := t) lets vₗ matchLets vᵣ
      matchArg lets matchLets vsₗ vsᵣ
  termination_by l => (sizeOf matchLets, l.length + 1)

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

def test13_before := [llvm|
{
^0(%arg178 : i32, %arg179 : i32):
  %0 = llvm.xor %arg179, %arg178 : i32
  %1 = llvm.or %arg179, %arg178 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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 masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_after := [llvm|
{
^0(%arg91 : i32):
  %0 = llvm.mlir.constant(14 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg91, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg91, %2 : i32
  %7 = llvm.icmp "eq" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def demorgan_or_apint1_before := [llvm|
{
^0(%arg62 : i43, %arg63 : i43):
  %0 = llvm.mlir.constant(-1 : i43) : i43
  %1 = llvm.xor %arg62, %0 : i43
  %2 = llvm.xor %arg63, %0 : i43
  %3 = llvm.or %1, %2 : i43
  "llvm.return"(%3) : (i43) -> ()
}
]

def NFA.autWidth (wp : WidthPredicate) (n : Nat) : NFA (BitVec 0) (Fin (n+2)) where
  start := { 0 }
  accept := { s | wp.final? n s }
  step s₁ _ := { s₂ | if s₁ = Fin.last (n+1) then s₁ = s₂ else s₂ = s₁ + 1 }

@[tactic bvAutomataGen]
def evalBvAutomataCircuit : Tactic := fun
| `(tactic| bv_automata_gen $[$cfg]?) => do
  let cfg ← elabBvAutomataCircuitConfig (mkOptionalNode cfg)
  let g ← getMainGoal
  g.withContext do
    let gs ← reflectUniversalWidthBVs g cfg
    replaceMainGoal gs
    match gs  with
    | [] => return ()
    | [g] => do
      trace[Bits.Frontend] m!"goal being decided via boolean reflection: {indentD g}"
      evalDecideCore `bv_automata_circuit (cfg := { native := true : Parser.Tactic.DecideConfig })
    | _gs => throwError m!"expected single goal after reflecting, found multiple goals. quitting"
| _ => throwUnsupportedSyntax

def test35_with_trunc_after := [llvm|
{
^0(%arg48 : i64):
  %0 = llvm.mlir.constant(2147483648) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(60 : i32) : i32
  %3 = llvm.mlir.constant(100 : i32) : i32
  %4 = llvm.and %arg48, %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 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 shrMax (a : BitVec v) (b : BitVec w) : BitVec (max v w) :=
    a.signExtend (max v w) >>> b.signExtend (max v w)

def test9_before := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.udiv %0, %arg15 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def positive_trunc_signbit_logical_before := [llvm|
{
^0(%arg40 : i32):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.trunc %arg40 : i32 to i8
  %5 = llvm.icmp "sgt" %4, %0 : i8
  %6 = llvm.add %arg40, %1 : i32
  %7 = llvm.icmp "ult" %6, %2 : i32
  %8 = "llvm.select"(%5, %7, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def sext_after := [llvm|
{
^0(%arg9 : i16):
  %0 = llvm.sext %arg9 : i16 to i32
  "llvm.return"(%0) : (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) -> ()
}
]

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

def enc (bvs : BitVecs n) : BitVecs' n :=
  (List.finRange bvs.w).map (fun i =>
    BitVec.ofFn (fun (k : Fin n) => (bvs.bvs.get k)[i]))

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 add_shl_same_amount_nuw_before := [llvm|
{
^0(%arg53 : i64, %arg54 : i64, %arg55 : i64):
  %0 = llvm.shl %arg53, %arg55 overflow<nuw> : i64
  %1 = llvm.shl %arg54, %arg55 overflow<nuw> : i64
  %2 = llvm.add %0, %1 overflow<nuw> : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def lift (f : Fin n → Fin m) (M : NFA' n) : NFA' m where
  σ := _
  M := M.M.lift f

def runBvMbaPreprocess (g : MVarId) : MetaM (Option MVarId) := do
  let simpName := `bv_mba_preprocess
  let some ext ← (getSimpExtension? simpName)
    | throwError m!"[bv_mba] Error: {simpName} simp attribute not found!"
  let theorems ← ext.getTheorems
  let some ext ← (Simp.getSimprocExtension? simpName)
    | throwError m!"[bv_nnf] Error: {simpName}} simp attribute not found!"
  let simprocs ← ext.getSimprocs
  let config : Simp.Config := { Simp.neutralConfig with
    failIfUnchanged   := false,
  }
  let ctx ← Simp.mkContext (config := config)
    (simpTheorems := #[theorems])
    (congrTheorems := ← Meta.getSimpCongrTheorems)
  match ← simpGoal g ctx (simprocs := #[simprocs]) with
  | (none, _) => return none
  | (some (_newHyps, g'), _) => pure g'

def mkCarryAssignCircuitLeN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
    let ixs := List.range (n + 1) |>.attach
    let circs := ixs.map fun ⟨i, hi⟩ =>
      mkCarryAssignCircuitN p i |>.map (fun v => v.castLe (by admit /- proof elided -/
      ))
    Circuit.bigOr circs

def pr51551_neg1_after := [llvm|
{
^0(%arg4 : i32, %arg5 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.and %arg5, %0 : i32
  %5 = llvm.or disjoint %4, %1 : i32
  %6 = llvm.mul %5, %arg4 : i32
  %7 = llvm.and %6, %2 : i32
  %8 = llvm.icmp "eq" %7, %3 : i32
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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 parseComFromFile (fileName : String) :
    IO (Option (Σ (Γ' : Ctxt LLVM.Ty) (eff : EffectKind) (ty : List LLVM.Ty), Com LLVM Γ' eff ty)) :=
  Com.parseFromFile LLVM fileName

def test_eq1_before := [llvm|
{
^0(%arg10 : i32, %arg11 : i16):
  %0 = llvm.trunc %arg10 overflow<nsw> : i32 to i8
  %1 = llvm.trunc %arg11 overflow<nsw> : i16 to i8
  %2 = llvm.icmp "eq" %0, %1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def ashr_mul_times_5_div_4_before := [llvm|
{
^0(%arg16 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mul %arg16, %0 overflow<nsw,nuw> : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (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 and_xor_or2_after := [llvm|
{
^0(%arg670 : i64, %arg671 : i64, %arg672 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg671 : i64
  %2 = llvm.udiv %0, %arg672 : i64
  %3 = llvm.or %2, %1 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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) -> ()
}
]

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

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

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

structure NonNegFlag where
  nneg : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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

def lshr_and_add_after := [llvm|
{
^0(%arg57 : i8, %arg58 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(96 : i8) : i8
  %3 = llvm.srem %arg57, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg58, %2 : i8
  %6 = llvm.add %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def p2_scalar_shifted_urem_by_const_after := [llvm|
{
^0(%arg16 : i32, %arg17 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg16, %0 : i32
  %4 = llvm.shl %3, %arg17 overflow<nuw> : i32
  %5 = llvm.urem %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

@[simp_denote]
def llvm_urem_64 : Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 64), .llvm (.bitvec 64)]⟩
  .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry (%x: i64, %y: i64 ):
    %1 = llvm.urem    %x, %y : i64
    llvm.return %1 : i64
  }]

def negative_not_power_of_two_logical_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.icmp "sgt" %arg6, %0 : i32
  %5 = llvm.add %arg6, %1 : i32
  %6 = llvm.icmp "ult" %5, %2 : i32
  %7 = "llvm.select"(%4, %6, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

Nat.reduceEqDiff in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Nat

def fork (a : Γ.Var (.tokenstream)) : Expr (DC) Γ .pure (.tokenstream2) :=
  Expr.mk
    (op := .fork)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

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) -> ()
}
]

structure AllocState where
  nextFreeBlock : Nat
  deriving Inhabited

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

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

def or_not_and_commute2_after := [llvm|
{
^0(%arg531 : i32, %arg532 : i32, %arg533 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg532 : i32
  %3 = llvm.xor %arg533, %2 : i32
  %4 = llvm.xor %arg531, %1 : i32
  %5 = llvm.and %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def or_eq_with_one_bit_diff_constants2_before := [llvm|
{
^0(%arg362 : i32):
  %0 = llvm.mlir.constant(97 : i32) : i32
  %1 = llvm.mlir.constant(65 : i32) : i32
  %2 = llvm.icmp "eq" %arg362, %0 : i32
  %3 = llvm.icmp "eq" %arg362, %1 : i32
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def PR23309_after := [llvm|
{
^0(%arg53 : i32, %arg54 : i32):
  %0 = llvm.sub %arg53, %arg54 : i32
  %1 = llvm.trunc %0 : i32 to i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def propDict2 : AttrDict 0 := [mlir_attr_dict| <{foo = "bar", baz = "quux" }>]

noncomputable def to_prop (f : Bool → Bool → Bool) (p1 p2 : Prop) : Prop :=
  f (@Decidable.decide p1 (Classical.propDecidable _)) (@Decidable.decide p2 (Classical.propDecidable _))

def alive_AndOrXor_2647_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%a : _, %b : _):
  %v1 = llvm.and %a, %b
  %v2 = llvm.xor %a, %b
  %v3 = llvm.xor %v1, %v2
  llvm.return %v3
}]

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

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

private def rgn3 : Region φ :=
  [mlir_region|  {
      "std.return"(%x0) : (i42) -> ()
  }]

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

def not_mul_of_pow2_after := [llvm|
{
^0(%arg77 : i32, %arg78 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(1530 : i32) : i32
  %2 = llvm.and %arg77, %0 : i32
  %3 = llvm.zext %arg78 : i8 to i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def and_not_or_or_not_or_xor_commute5_after := [llvm|
{
^0(%arg310 : i32, %arg311 : i32, %arg312 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg311, %arg312 : i32
  %2 = llvm.xor %arg311, %arg312 : i32
  %3 = llvm.or %2, %arg310 : i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.xor %4, %0 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

IO.FS.Mode in Init.System.IO

def not_cond_before := [llvm|
{
^0(%arg24 : i1, %arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg24, %0 : i1
  %2 = "llvm.select"(%1, %arg25, %arg26) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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 t0_after := [llvm|
{
^0(%arg30 : i1, %arg31 : i8, %arg32 : i8, %arg33 : i8, %arg34 : i8):
  %0 = llvm.icmp "ne" %arg31, %arg32 : i8
  %1 = llvm.and %0, %arg30 : i1
  %2 = "llvm.select"(%1, %arg34, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def canonicalize_icmp_ugt_1 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 1 : i64
      %1 = llvm.icmp.ugt %c, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 1 : i64
      %1 = llvm.icmp.ult %x, %c : i64
      llvm.return %1 : i1
  }]

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

def test_lshr__exact_is_safe_before := [llvm|
{
^0(%arg60 : i32, %arg61 : 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 %arg60, %0 : i32
  %4 = llvm.lshr %3, %1 : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg61, %5 : i64
  %8 = "llvm.select"(%6, %arg61, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

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

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

def icmp_eq_select_after := [llvm|
{
^0(%arg3 : i1, %arg4 : i32, %arg5 : i32):
  %0 = llvm.icmp "eq" %arg4, %arg5 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def or_logic_or_logic_and_7_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i1, %arg32 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg31, %arg30 : i1
  %3 = "llvm.select"(%arg30, %0, %arg32) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

private def test_simple2 := [RV64_com| {
  ^bb0(%e1 : !i64, %e2 : !i64 ):
  %1 = add %e1, %e2 : !i64
  %2 = sub %1, %1 : !i64
       ret %2  : !i64
}]

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

def Factor.toExpr (f : Factor) : Expr :=
  match f with
  | .var i => mkApp (mkConst ``Factor.var) (mkNatLit i)
  | .xor i j => mkApp2 (mkConst ``Factor.xor) i.toExpr j.toExpr
  | .and i j => mkApp2 (mkConst ``Factor.and) i.toExpr j.toExpr
  | .or i j => mkApp2 (mkConst ``Factor.or) i.toExpr j.toExpr
  | .not x => mkApp (mkConst ``Factor.not) x.toExpr

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) -> ()
}
]

structure NonNegFlag where
  nneg : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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 lshr_xor_or_good_mask_before := [llvm|
{
^0(%arg108 : i8, %arg109 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.lshr %arg108, %0 : i8
  %3 = llvm.lshr %arg109, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def add_positive_low_bound_reject_test: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_positive_low_bound_reject_llvm
  rhs := add_positive_low_bound_reject_riscv

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

def ashrslt_01_14_after := [llvm|
{
^0(%arg255 : i4):
  %0 = llvm.mlir.constant(-4 : i4) : i4
  %1 = llvm.icmp "slt" %arg255, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def match_signed_before := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(64) : i64
  %2 = llvm.mlir.constant(19136) : i64
  %3 = llvm.mlir.constant(9) : i64
  %4 = llvm.srem %arg15, %0 : i64
  %5 = llvm.sdiv %arg15, %0 : i64
  %6 = llvm.srem %5, %1 : i64
  %7 = llvm.sdiv %arg15, %2 : i64
  %8 = llvm.srem %7, %3 : i64
  %9 = llvm.mul %6, %0 : i64
  %10 = llvm.add %4, %9 : i64
  %11 = llvm.mul %8, %2 : i64
  %12 = llvm.add %10, %11 : i64
  "llvm.return"(%12) : (i64) -> ()
}
]

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 ripple_nsw4_after := [llvm|
{
^0(%arg17 : i16, %arg18 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg18, %0 : i16
  %3 = llvm.and %arg17, %1 : i16
  %4 = llvm.add %3, %2 overflow<nsw,nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def RawCNFA.addFinal (m : RawCNFA A) (s : State) : RawCNFA A :=
  { m with finals := m.finals.insert s }

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 sext_xor_sub_1_before := [llvm|
{
^0(%arg26 : i64, %arg27 : i1):
  %0 = llvm.sext %arg27 : i1 to i64
  %1 = llvm.xor %0, %arg26 : i64
  %2 = llvm.sub %1, %0 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def Config.default : Config := {}

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 eq_umin4_before := [llvm|
{
^0(%arg54 : i32, %arg55 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg54, %0 : i32
  %2 = llvm.icmp "ult" %arg55, %1 : i32
  %3 = "llvm.select"(%2, %arg55, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "eq" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def factorize3_after := [llvm|
{
^0(%arg5 : i32, %arg6 : i32, %arg7 : i32):
  %0 = llvm.or %arg5, %arg7 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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) -> ()
}
]

instance (priority := low) : Monad (pure.toMonad m) :=

def icmp_sgt1_before := [llvm|
{
^0(%arg24 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.shl %arg24, %0 overflow<nsw> : i8
  %3 = llvm.icmp "sgt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def test11_before := [llvm|
{
^0(%arg197 : i8):
  %0 = llvm.mlir.constant(12 : i8) : i8
  %1 = llvm.mlir.constant(4 : i8) : i8
  %2 = llvm.or %arg197, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def ashr_lshr_inv2_after := [llvm|
{
^0(%arg99 : i32, %arg100 : i32):
  %0 = llvm.ashr %arg99, %arg100 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def udiv_c_i32_before := [llvm|
{
^0(%arg6 : i8):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.zext %arg6 : i8 to i32
  %2 = llvm.udiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def parseExprs (lhsExpr rhsExpr : Expr) (width : Nat): ParseExprM (Option ParsedBVLogicalExpr)  := do
  let some lhsRes ← toBVExpr lhsExpr width | throwError "Could not extract lhs: {lhsExpr}"

  let state ← get
  let lhs: ParsedBVExpr := {bvExpr := lhsRes.bvExpr, width := lhsRes.width, symVars := state.symVarToVal, inputVars := state.inputVarIdToVariable}

  let some rhsRes ← toBVExpr rhsExpr width | throwError "Could not extract rhs: {rhsExpr}"
  let state ← get

  let rhsInputVars := state.inputVarIdToVariable.filter fun k _ => !lhs.inputVars.contains k
  let rhsSymVars := state.symVarToVal.filter fun k _ => !lhs.symVars.contains k

  let rhs: ParsedBVExpr := {bvExpr := rhsRes.bvExpr, width := rhsRes.width, symVars := rhsSymVars, inputVars := rhsInputVars}

  trace[Generalize] m! "lhs width: {lhsRes.width}; rhs width: {rhsRes.width}"
  if h : lhsRes.width = rhsRes.width then
    let rhsExpr := h ▸ rhsRes.bvExpr
    let bvLogicalExpr := BoolExpr.literal (GenBVPred.bin lhsRes.bvExpr BVBinPred.eq rhsExpr)
    trace[Generalize] m! "BVLogicalExpr: {bvLogicalExpr}"

    return some {lhs := lhs, rhs := rhs, state := state, logicalExpr := bvLogicalExpr}

  return none

noncomputable def complete (M : NFA' n) : NFA' n where
  σ := _
  M := M.M.complete

def ashr_and_or_disjoint_after := [llvm|
{
^0(%arg41 : i8, %arg42 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(52 : i8) : i8
  %3 = llvm.srem %arg41, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg42, %2 : i8
  %6 = llvm.or disjoint %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

def ashr_bitwidth_mask_before := [llvm|
{
^0(%arg127 : i8, %arg128 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg127, %0 : i8
  %2 = llvm.and %1, %arg128 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

Finset.range in Mathlib.Data.Finset.Range

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 or_signbit_ashr_after := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-256 : i32) : i32
  %2 = llvm.lshr %arg5, %0 : i32
  %3 = llvm.or %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def shl_sub_lshr_reverse_before := [llvm|
{
^0(%arg136 : i32, %arg137 : i32, %arg138 : i32):
  %0 = llvm.shl %arg136, %arg137 overflow<nuw> : i32
  %1 = llvm.sub %arg138, %0 overflow<nsw,nuw> : i32
  %2 = llvm.lshr exact %1, %arg137 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def returnTypes  := Signature.returnTypes ∘ s.signature

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

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

def narrow_zext_xor_before := [llvm|
{
^0(%arg46 : i16, %arg47 : i32):
  %0 = llvm.zext %arg46 : i16 to i32
  %1 = llvm.xor %0, %arg47 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def select_neg1_0 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1):
      %t = llvm.mlir.constant (-1) : i64
      %f = llvm.mlir.constant (0) : i64
      %0 = llvm.select %c, %t, %f : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1):
      %0 = llvm.sext %c: i1 to i64
      llvm.return %0 : i64
  }]

def test0_before := [llvm|
{
^0(%arg123 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.xor %arg123, %0 : i32
  %3 = llvm.icmp "sgt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def test12_before := [llvm|
{
^0(%arg76 : i32, %arg77 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.zext %arg76 : i32 to i128
  %2 = llvm.zext %arg77 : i32 to i128
  %3 = llvm.and %2, %0 : i128
  %4 = llvm.lshr %1, %3 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def ugt_and_min_logical_after := [llvm|
{
^0(%arg334 : i8, %arg335 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 test_and1_after := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg53, %0 : i32
  %2 = llvm.icmp "ult" %arg52, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def lowmask_add_zext_commute_before := [llvm|
{
^0(%arg233 : i16, %arg234 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mul %arg234, %arg234 : i32
  %2 = llvm.zext %arg233 : i16 to i32
  %3 = llvm.add %1, %2 : i32
  %4 = llvm.and %3, %0 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def positive_samevar_shlnuw_ashrexact_after := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  "llvm.return"(%arg32) : (i8) -> ()
}
]

def BasicBlock.WellTyped : UnTyped.BasicBlock Op VarName → RegionType Ty → Prop
  | ⟨_, args, prog⟩, ⟨argTys, retTy⟩ =>
      args.length = argTys.length ∧ Body.WellTyped (args.zip argTys) prog retTy

abbrev BitVecs.empty : BitVecs n := ⟨0, List.Vector.replicate n .nil⟩

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

def src_is_mask_p2_m1_after := [llvm|
{
^0(%arg90 : i8, %arg91 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(123 : i8) : i8
  %3 = llvm.shl %0, %arg91 : i8
  %4 = llvm.add %3, %1 : i8
  %5 = llvm.xor %arg90, %2 : i8
  %6 = llvm.icmp "ugt" %5, %4 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def and_not_or_commute2_before := [llvm|
{
^0(%arg475 : i32, %arg476 : i32, %arg477 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg476 : i32
  %3 = llvm.and %arg475, %2 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %4, %arg477 : i32
  %6 = llvm.and %arg475, %arg477 : i32
  %7 = llvm.xor %6, %1 : i32
  %8 = llvm.or %2, %7 : i32
  %9 = llvm.and %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

instance {d : Dialect} [DialectSignature d] {t} {Γ : Ctxt d.Ty} {Γ' : DerivedCtxt Γ} :
    Coe (Expr d Γ eff t) (Expr d Γ'.ctxt eff t) where
  coe e := e.changeVars Γ'.diff.toHom

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

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

def not_match_inconsistent_values_after := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(29) : i64
  %2 = llvm.mlir.constant(63) : i64
  %3 = llvm.urem %arg12, %0 : i64
  %4 = llvm.udiv %arg12, %1 : i64
  %5 = llvm.and %4, %2 : i64
  %6 = llvm.mul %5, %0 overflow<nsw,nuw> : i64
  %7 = llvm.add %3, %6 overflow<nsw,nuw> : i64
  "llvm.return"(%7) : (i64) -> ()
}
]

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

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

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

def foo1_or_signbit_lshr_without_shifting_signbit_both_sides_after := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.shl %arg100, %arg101 : i32
  %2 = llvm.shl %arg100, %arg102 : i32
  %3 = llvm.and %1, %2 : i32
  %4 = llvm.icmp "slt" %3, %0 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def test46_after := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.and %arg200, %arg199 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def llvm_sdiv_lower_riscv_no_flag_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := sdiv_llvm_no_exact_64
  rhs := sdiv_riscv_64

def zext_zext_eq_after := [llvm|
{
^0(%arg80 : i8, %arg81 : i8):
  %0 = llvm.icmp "eq" %arg80, %arg81 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def not_or_or_and_not_and_and_commute1_and_after := [llvm|
{
^0(%arg205 : i32, %arg206 : i32, %arg207 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg205, %0 : i32
  %2 = llvm.xor %arg207, %arg206 : i32
  %3 = llvm.or %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def or_and1_commuted_before := [llvm|
{
^0(%arg135 : i1, %arg136 : i1, %arg137 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg136, %0 : i1
  %2 = llvm.and %arg137, %1 : i1
  %3 = "llvm.select"(%2, %arg135, %arg136) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def t10_almost_highest_bit_after := [llvm|
{
^0(%arg22 : i32, %arg23 : i64, %arg24 : i32):
  %0 = llvm.mlir.constant(64 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.sub %0, %arg24 : i32
  %4 = llvm.shl %arg22, %3 : i32
  %5 = llvm.add %arg24, %1 : i32
  %6 = llvm.zext nneg %5 : i32 to i64
  %7 = llvm.lshr %arg23, %6 : i64
  %8 = llvm.trunc %7 : i64 to i32
  %9 = llvm.and %4, %8 : i32
  %10 = llvm.icmp "ne" %9, %2 : i32
  "llvm.return"(%10) : (i1) -> ()
}
]

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

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

def lshr_C1_add_A_C2_i32_before := [llvm|
{
^0(%arg76 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.mlir.constant(6 : i32) : i32
  %3 = llvm.and %arg76, %0 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.shl %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

def test1_after := [llvm|
{
^0(%arg8 : i17, %arg9 : i17):
  %0 = llvm.mlir.constant(7 : i17) : i17
  %1 = llvm.and %arg8, %0 : i17
  "llvm.return"(%1) : (i17) -> ()
}
]

def urem_i8_after := [llvm|
{
^0(%arg33 : i8, %arg34 : i8):
  %0 = llvm.urem %arg33, %arg34 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

def shl_sub_after := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.shl %arg12, %0 : i8
  %3 = llvm.shl %arg13, %1 : i8
  %4 = llvm.sub %2, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def lshr_pow2_ult_equal_constants_before := [llvm|
{
^0(%arg61 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.lshr %0, %arg61 : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def mkRewrite {Γ ty}
  (rw : PeepholeRewrite LLVMPlusRiscV Γ ty) :
  Σ Γ ty, PeepholeRewrite LLVMPlusRiscV Γ ty :=
  ⟨_, _, rw⟩

def icmp_select_var_pred_uge_after := [llvm|
{
^0(%arg65 : i8, %arg66 : i8, %arg67 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.add %arg67, %0 overflow<nuw> : i8
  %4 = llvm.icmp "ne" %arg65, %1 : i8
  %5 = llvm.icmp "uge" %arg66, %3 : i8
  %6 = "llvm.select"(%4, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

def icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_before := [llvm|
{
^0(%arg43 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(2147483647 : i32) : i32
  %2 = llvm.icmp "ult" %arg43, %0 : i32
  %3 = llvm.and %arg43, %1 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def test95_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(40 : i8) : i8
  %3 = llvm.trunc %arg0 : i32 to i8
  %4 = llvm.lshr %3, %0 : i8
  %5 = llvm.and %4, %1 : i8
  %6 = llvm.or %5, %2 : i8
  %7 = llvm.zext %6 : i8 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def test_logical_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.icmp "eq" %arg0, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

instance : DecidableNFA (NFA'.autMsbSet).M :=

def not_and_and_or_not_or_or_commute2_or_after := [llvm|
{
^0(%arg247 : i32, %arg248 : i32, %arg249 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg249, %arg248 : i32
  %2 = llvm.or %1, %arg247 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def redundant_binop_in_equality_XPlusYNeX : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.add %x, %y : i64
      %1 = llvm.icmp.ne %0, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.mlir.constant (0) : i64
      %1 = llvm.icmp.ne %y, %0 : i64
      llvm.return %1 : i1
  }]

def hoist_ashr_ahead_of_sext_2_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.sext %arg1 : i8 to i32
  %2 = llvm.ashr %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def test_shl__all_are_safe_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(60 : i32) : i32
  %2 = llvm.shl %arg84, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg85, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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) -> ()
}
]

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

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

def liftComb {argTys : List Comb.Ty} {outTy : Comb.Ty}
    (f : HVector toType argTys → ⟦outTy⟧) :
    HVector toType (liftTy <$> argTys) → ⟦liftTy outTy⟧ := fun args =>
  let B := fun
    | .stream (.bitvec w) => BitVec w
    | _ => BitVec 0
  have h := by admit /- proof elided -/

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

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

@[nospecialize]
def toAIGAux {α : Type}
    [DecidableEq α] [Fintype α] [Hashable α] (c : Circuit α) (aig : AIG α) :
    ToAIGAuxEntrypoint aig c :=
  match c with
  | .fals => {
      out := aig,
      ref := aig.mkConstCached false,
      href := by admit /- proof elided -/

def src_is_mask_zext_after := [llvm|
{
^0(%arg131 : i16, %arg132 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i16) : i16
  %2 = llvm.lshr %0, %arg132 : i8
  %3 = llvm.zext %2 : i8 to i16
  %4 = llvm.xor %arg131, %1 : i16
  %5 = llvm.icmp "ule" %4, %3 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def or_xor_commute4_before := [llvm|
{
^0(%arg160 : i32, %arg161 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.udiv %0, %arg160 : i32
  %2 = llvm.udiv %0, %arg161 : i32
  %3 = llvm.or %1, %2 : i32
  %4 = llvm.xor %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test4_before := [llvm|
{
^0(%arg305 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg305, %0 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def shl_add_lshr_comm_after := [llvm|
{
^0(%arg151 : i32, %arg152 : i32, %arg153 : i32):
  %0 = llvm.mul %arg153, %arg153 : i32
  %1 = llvm.lshr %0, %arg152 : i32
  %2 = llvm.add %1, %arg151 overflow<nuw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def add_select_not_sext_before := [llvm|
{
^0(%arg26 : i1):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = "llvm.select"(%arg26, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %4 = llvm.xor %arg26, %2 : i1
  %5 = llvm.sext %4 : i1 to i64
  %6 = llvm.add %3, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

def GLobalISelPostLegalizerCombiner :
    List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  redundant_binop_in_equality)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  PostLegalizerCombiner_LLVMIR_64)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  PostLegalizerCombiner_LLVMIR_32)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  canonicalize_icmp)
  ++
  List.map (fun ⟨_,y⟩ => mkRewrite (RISCVPeepholeRewriteToRiscvPeephole y))
  PostLegalizerCombiner_RISCV

@[simp_denote]
def add_multiuse_riscv_i64 :=
  [LV| {
    ^entry (%x: i64):
    %0 = "li"() {imm = -1 : !i64} : (!i64) -> (!i64)
    %1 = slli %0, 40 : !i64
    %2 = addi %1, 1 : !i64
    %a0  = "builtin.unrealized_conversion_cast" (%x) : (i64) -> (!i64)
    %3 = add %a0, %2 : !i64
    %4 = and %3, %2 : !i64
    %5 = "builtin.unrealized_conversion_cast" (%4) : (!i64) -> (i64)
    llvm.return %5 : i64
  }]

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 main3_after := [llvm|
{
^0(%arg155 : i32):
  %0 = llvm.mlir.constant(55 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg155, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  %4 = llvm.zext %3 : i1 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def llvm_sext_lower_riscv_i32_to_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32)] :=
  {lhs:= sext_llvm_i32_to_64, rhs:= sext_riscv_i32_to_64}

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

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

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

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

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

def NFA.autWidthLang (wp : WidthPredicate) (n : Nat) : Language (BitVec 0) := { bvs  | wp.final? n bvs.length }

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

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

def bitwise_and_bitwise_and_icmps_comm2_after := [llvm|
{
^0(%arg238 : i8, %arg239 : i8, %arg240 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg239, %0 : i8
  %3 = llvm.shl %1, %arg240 overflow<nuw> : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.and %arg238, %4 : i8
  %6 = llvm.icmp "eq" %5, %4 : i8
  %7 = llvm.and %6, %2 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

instance : Hashable Empty where
  hash x := x.elim

def test7_before := [llvm|
{
^0(%arg0 : i1023):
  %0 = llvm.mlir.constant(70368744177663 : i1023) : i1023
  %1 = llvm.mlir.constant(703687463 : i1023) : i1023
  %2 = llvm.or %arg0, %0 : i1023
  %3 = llvm.xor %2, %1 : i1023
  "llvm.return"(%3) : (i1023) -> ()
}
]

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

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

def no_shift_no_xor_multiuse_cmp_with_xor_before := [llvm|
{
^0(%arg104 : i32, %arg105 : i32, %arg106 : i32, %arg107 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg104, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.xor %arg105, %0 : i32
  %5 = "llvm.select"(%3, %arg105, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = "llvm.select"(%3, %arg106, %arg107) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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 hoist_ashr_ahead_of_sext_1_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.sext %arg3 : i8 to i32
  %2 = llvm.ashr %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def and_not_or_commute8_after := [llvm|
{
^0(%arg457 : i32, %arg458 : i32, %arg459 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg457 : i32
  %3 = llvm.sdiv %0, %arg458 : i32
  %4 = llvm.xor %3, %arg459 : i32
  %5 = llvm.and %4, %2 : i32
  %6 = llvm.xor %5, %1 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

def alive_AddSub_1152_src   :=
[llvm()| {
^bb0(%y : i1, %x : i1):
  %v1 = llvm.add %x, %y : i1
  llvm.return %v1 : i1
}]

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

Fin.elim0 in Init.Data.Fin.Basic

def lshr_shl_pow2_const_xor_before := [llvm|
{
^0(%arg59 : i16):
  %0 = llvm.mlir.constant(256 : i16) : i16
  %1 = llvm.mlir.constant(2 : i16) : i16
  %2 = llvm.mlir.constant(8 : i16) : i16
  %3 = llvm.lshr %0, %arg59 : i16
  %4 = llvm.shl %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  %6 = llvm.xor %5, %2 : i16
  "llvm.return"(%6) : (i16) -> ()
}
]

def add_mask_ashr28_non_pow2_i32_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(28 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.ashr %arg1, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def Predicate.quote (p : Predicate) : Expr :=
  match p with
  | .width .eq n => mkApp2 (mkConst ``Predicate.width) (mkConst ``WidthPredicate.eq) (mkNatLit n)
  | .width .neq n => mkApp2 (mkConst ``Predicate.width) (mkConst ``WidthPredicate.neq) (mkNatLit n)
  | .width .lt n => mkApp2 (mkConst ``Predicate.width) (mkConst ``WidthPredicate.lt) (mkNatLit n)
  | .width .le n => mkApp2 (mkConst ``Predicate.width) (mkConst ``WidthPredicate.le) (mkNatLit n)
  | .width .gt n => mkApp2 (mkConst ``Predicate.width) (mkConst ``WidthPredicate.gt) (mkNatLit n)
  | .width .ge n => mkApp2 (mkConst ``Predicate.width) (mkConst ``WidthPredicate.ge) (mkNatLit n)
  | .binary .eq a b => mkApp2 (mkConstBin ``BinaryPredicate.eq) (Term.quote a) (Term.quote b)
  | .binary .neq a b => mkApp2 (mkConstBin ``BinaryPredicate.neq) (Term.quote a) (Term.quote b)
  | .binary .ult a b => mkApp2 (mkConstBin ``BinaryPredicate.ult) (Term.quote a) (Term.quote b)
  | .binary .ule a b => mkApp2 (mkConstBin ``BinaryPredicate.ule) (Term.quote a) (Term.quote b)
  | .binary .slt a b => mkApp2 (mkConstBin ``BinaryPredicate.slt) (Term.quote a) (Term.quote b)
  | .binary .sle a b => mkApp2 (mkConstBin ``BinaryPredicate.sle) (Term.quote a) (Term.quote b)
  | land p q => mkApp2 (mkConst ``Predicate.land) (Predicate.quote p) (Predicate.quote q)
  | lor p q => mkApp2 (mkConst ``Predicate.lor) (Predicate.quote p) (Predicate.quote q)

def clear_to_clear_decomposebittest_after := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.and %arg12, %0 : i8
  %3 = llvm.or disjoint %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def uge_sext_after := [llvm|
{
^0(%arg134 : i1, %arg135 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg135, %0 : i8
  %2 = llvm.or %1, %arg134 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

@[simp, reducible]
def Op.outTy : Op  → Ty
  | .li _ => Ty.bv
  | .mulh => Ty.bv
  | .mulhu => Ty.bv
  | .mulhsu => Ty.bv
  | .divu => Ty.bv
  | .remuw => Ty.bv
  | .remu =>  Ty.bv
  | .addiw (_imm : BitVec 12) => Ty.bv
  | .lui (_imm : BitVec 20) => Ty.bv
  | .auipc (_imm : BitVec 20) => Ty.bv
  | .slliw (_shamt : BitVec 5) => Ty.bv
  | .srliw (_shamt : BitVec 5) => Ty.bv
  | .sraiw (_shamt : BitVec 5) => Ty.bv
  | .slli (_shamt : BitVec 6) => Ty.bv
  | .srli (_shamt : BitVec 6) => Ty.bv
  | .srai (_shamt : BitVec 6) => Ty.bv
  | .addw => Ty.bv
  | .subw => Ty.bv
  | .sllw => Ty.bv
  | .srlw => Ty.bv
  | .sraw => Ty.bv
  | .add => Ty.bv
  | .slt => Ty.bv
  | .sltu => Ty.bv
  | .and => Ty.bv
  | .or => Ty.bv
  | .xor => Ty.bv
  | .sll => Ty.bv
  | .srl => Ty.bv
  | .sub => Ty.bv
  | .sra => Ty.bv
  | .remw  => Ty.bv
  | .rem => Ty.bv
  | .mul => Ty.bv
  | .mulw => Ty.bv
  | .div => Ty.bv
  | .divw => Ty.bv
  | .divuw => Ty.bv
  | .addi (_imm : BitVec 12) => Ty.bv
  | .slti (_imm : BitVec 12) => Ty.bv
  | .sltiu (_imm : BitVec 12) => Ty.bv
  | .andi (_imm : BitVec 12) => Ty.bv
  | .ori (_imm : BitVec 12) => Ty.bv
  | .xori (_imm : BitVec 12) => Ty.bv
  | .bclr => Ty.bv
  | .bext => Ty.bv
  | .binv => Ty.bv
  | .bset => Ty.bv
  | .bclri (_shamt : BitVec 6) => Ty.bv
  | .bexti (_shamt : BitVec 6) => Ty.bv
  | .binvi (_shamt : BitVec 6) => Ty.bv
  | .bseti (_shamt : BitVec 6) => Ty.bv
  | adduw => Ty.bv
  | .sh1adduw => Ty.bv
  | .sh2adduw => Ty.bv
  | .sh3adduw => Ty.bv
  | .sh1add => Ty.bv
  | .sh2add => Ty.bv
  | .sh3add => Ty.bv
  | .slliuw (_shamt : BitVec 6) => Ty.bv
  | .andn =>  Ty.bv
  | .orn =>  Ty.bv
  | .xnor =>  Ty.bv
  | .clz => Ty.bv
  | .clzw => Ty.bv
  | .ctz => Ty.bv
  | .ctzw => Ty.bv
  | .max =>  Ty.bv
  | .maxu =>  Ty.bv
  | .min  =>  Ty.bv
  | .minu  =>  Ty.bv
  | .sextb => Ty.bv
  | .sexth => Ty.bv
  | .zexth => Ty.bv
  | .rol => Ty.bv
  | .rolw => Ty.bv
  | .ror => Ty.bv
  | .rori (_shamt : BitVec 6) => Ty.bv
  | .roriw (_shamt : BitVec 5) => Ty.bv
  | .rorw => Ty.bv
  | .pack => Ty.bv
  | .packh => Ty.bv
  | .packw => Ty.bv
  | .mv => Ty.bv
  | .not => Ty.bv
  | .neg => Ty.bv
  | .negw => Ty.bv
  | .sextw => Ty.bv
  | .zextb => Ty.bv
  | .zextw => Ty.bv
  | .seqz => Ty.bv
  | .snez => Ty.bv
  | .sltz => Ty.bv
  | .sgtz => Ty.bv

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

def lshr_shl_pow2_const_overflow_after := [llvm|
{
^0(%arg57 : i16):
  %0 = llvm.mlir.constant(0 : i16) : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

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

inductive Op
| fst
| snd
| pair (w : Nat)
| fstVal (w : Nat)
| fstValPure (w : Nat)
| sndVal (w : Nat)
| sndValPure (w : Nat)
| fstVal' (w : Nat)
| sndVal' (w : Nat)
| tokVal' (w : Nat)
| fork
| forkVal
| join
| merge
| mux
| muxVal
| cMerge
| branch
| source
| sourceOnes
| sink
| supp
| not
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

def test7_before := [llvm|
{
^0(%arg96 : i64):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg96 : i64 to i128
  %2 = llvm.lshr %1, %0 : i128
  %3 = llvm.trunc %2 : i128 to i92
  "llvm.return"(%3) : (i92) -> ()
}
]

partial def deductiveSearch (expr: FpExpr w) (constants: Std.HashMap Nat FpExprWrapper)
      (target: FpExprWrapper) (depth: Nat) (parent: Nat) : TermElabM (List (FpExpr target.width)) := do
  return []

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

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

def rhs : Com Simple (Ctxt.ofList [.int]) .pure [.int] :=
  [simple_com| {
    ^bb0(%x : i32):
      "return" (%x) : (i32) -> ()
  }]

def scalar_i8_shl_ule_const_before := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.shl %arg12, %0 : i8
  %3 = llvm.icmp "ule" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def t0_before := [llvm|
{
^0(%arg17 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.lshr %arg17, %0 : i8
  %2 = llvm.trunc %1 : i8 to i4
  %3 = llvm.sext %2 : i4 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def shift_no_xor_multiuse_cmp_with_xor_after := [llvm|
{
^0(%arg116 : i32, %arg117 : i32, %arg118 : i32, %arg119 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg116, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  %4 = llvm.shl %2, %0 overflow<nsw,nuw> : i32
  %5 = llvm.xor %arg117, %4 : i32
  %6 = "llvm.select"(%3, %arg118, %arg119) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

def sub_dec_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.add %arg4, %0 : i8
  %2 = llvm.sub %1, %arg5 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

def sub_0xffffffffff_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := sub_0xffffffffff_llvm_i64
  rhs :=  sub_0xffffffffff_riscv_i64

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

IntCast in Init.Data.Int.Basic

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 slt_swap_or_not_max_after := [llvm|
{
^0(%arg54 : i8, %arg55 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "ne" %arg54, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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 lshr_ne_msb_low_last_zero_before := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.lshr %0, %arg174 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def test4_before := [llvm|
{
^0(%arg4 : i67, %arg5 : i67):
  %0 = llvm.mlir.constant(66 : i67) : i67
  %1 = llvm.mlir.constant(2 : i67) : i67
  %2 = llvm.lshr %arg5, %0 : i67
  %3 = llvm.or %arg4, %2 : i67
  %4 = llvm.and %3, %1 : i67
  "llvm.return"(%4) : (i67) -> ()
}
]

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

def andcond.100.inv.inner.cond.in.outer.cond_before := [llvm|
{
^0(%arg55 : i1, %arg56 : i1, %arg57 : i8, %arg58 : i8, %arg59 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg55, %0 : i1
  %3 = "llvm.select"(%2, %arg56, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg55, %arg57, %arg58) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = "llvm.select"(%3, %arg59, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_logical_before := [llvm|
{
^0(%arg35 : i32):
  %0 = llvm.mlir.constant(12 : 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(false) : i1
  %5 = llvm.and %arg35, %0 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %arg35, %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 alive_Select_1105_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%Y : _, %X : _):
  %v1 = llvm.copy %Y
  llvm.return %v1
}]

def DCFork := [DC_com| {
  ^entry(%0 : !ValueStream_8):
    %unpack12 = "DC.unpack" (%0) : (!ValueStream_8) -> (!ValueTokenStream_8)
    %unpack1 = "DC.fstVal" (%unpack12) : (!ValueTokenStream_8) -> (!ValueStream_8)
    %unpack2 = "DC.sndVal" (%unpack12) : (!ValueTokenStream_8) -> (!TokenStream)
    %fork12 = "DC.fork" (%unpack2) : (!TokenStream) -> (!TokenStream2)
    %fork1 = "DC.fst" (%fork12) : (!TokenStream2) -> (!TokenStream)
    %fork2 = "DC.snd" (%fork12) : (!TokenStream2) -> (!TokenStream)
    %pack1 = "DC.pack" (%unpack1, %fork1) : (!ValueStream_8, !TokenStream) -> (!ValueStream_8)
    %pack2 = "DC.pack" (%unpack1, %fork2) : (!ValueStream_8, !TokenStream) -> (!ValueStream_8)
    %pack12 = "DC.pair" (%pack1, %pack2) : (!ValueStream_8, !ValueStream_8) -> (!ValueStream2_8)
    "return" (%pack12) : (!ValueStream2_8) -> ()
  }]

def slt_to_ult_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.xor %arg36, %0 : i8
  %2 = llvm.xor %arg37, %0 : i8
  %3 = llvm.icmp "slt" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def shl_bad_sub_i64_after := [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 overflow<nuw> : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def lshr_lshr_pow2_const_negative_nopow2_1_after := [llvm|
{
^0(%arg63 : i16):
  %0 = llvm.mlir.constant(31 : i16) : i16
  %1 = llvm.mlir.constant(4 : i16) : i16
  %2 = llvm.lshr %0, %arg63 : i16
  %3 = llvm.and %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

def shrink_and_after := [llvm|
{
^0(%arg9 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.and %arg9, %0 : i64
  %2 = llvm.trunc %1 overflow<nsw,nuw> : i64 to i31
  "llvm.return"(%2) : (i31) -> ()
}
]

def bools_logical_commute3_and2_after := [llvm|
{
^0(%arg69 : i1, %arg70 : i1, %arg71 : i1):
  %0 = "llvm.select"(%arg71, %arg70, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def input2 : Stream (BitVec 8) := ofList [none, some 3, some 17, some 42, none]

def addi_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := addi_llvm_i64
  rhs := addi_riscv_i64

def or_xor_tree_0110_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32, %arg29 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg27, %0 : i32
  %2 = llvm.mul %arg28, %0 : i32
  %3 = llvm.mul %arg29, %0 : i32
  %4 = llvm.xor %1, %2 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def alive_AddSub_1202_tgt :=
[sllvm| {
^bb0(%x : i64, %C : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %x, %v1 : i64
  %v3 = llvm.mlir.constant 1 : i64
  %v4 = llvm.sub %C, %v3 : i64
  %v5 = llvm.sub %v4, %x : i64
  llvm.return %v5 : i64
}]

def bools_logical_after := [llvm|
{
^0(%arg48 : i1, %arg49 : i1, %arg50 : i1):
  %0 = "llvm.select"(%arg50, %arg49, %arg48) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def shift_xor_multiuse_cmp_or_before := [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 "ne" %1, %3 : i32
  %5 = llvm.or %arg37, %2 : i32
  %6 = "llvm.select"(%4, %arg37, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg38, %arg39) <{"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 lshr_and_or_disjoint_after := [llvm|
{
^0(%arg43 : i8, %arg44 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(52 : i8) : i8
  %3 = llvm.srem %arg43, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg44, %2 : i8
  %6 = llvm.or disjoint %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

def fold_sext_to_and_wrong7_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.sext %arg3 : i8 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

@[simp_denote]
def zext_riscv_1_to_16 := [LV| {
  ^entry (%arg: i1):
    %0 = "builtin.unrealized_conversion_cast"(%arg) : (i1) -> !i64
    %1 = andi %0, 1 : !i64
    %res = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i16)
    llvm.return %res : i16
  }]

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

def ZMod.toInt_zero_iff_zero (x : ZMod q) : x = 0 ↔ x.toInt = 0 :=

def or_and_not_not_commute7_after := [llvm|
{
^0(%arg404 : i32, %arg405 : i32, %arg406 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg406, %arg405 : i32
  %2 = llvm.or %1, %arg404 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def neg_mask2_lshr_after := [llvm|
{
^0(%arg14 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.lshr %arg14, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.sub %2, %4 overflow<nsw> : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def bools_logical_commute0_after := [llvm|
{
^0(%arg108 : i1, %arg109 : i1, %arg110 : i1):
  %0 = "llvm.select"(%arg110, %arg109, %arg108) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def nestedAttrDict0 : AttrDict 0 := [mlir_attr_dict| {foo = {bar = "baz"} }]

Lean.TSyntax in Init.Prelude

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) -> ()
}
]

Lean.Parser.Tactic.trace in Mathlib.Tactic.Trace

def smear_set_bit_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.shl %arg6, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def sext_sub_const_before := [llvm|
{
^0(%arg25 : i1):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.sext %arg25 : i1 to i64
  %2 = llvm.sub %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

@[simp_llvm_option]
def trunc {w: Nat} (w': Nat) (x: IntW w) (noWrapFlags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w' := do
  let x' <- x
  if noWrapFlags.nsw ∧ ((x'.truncate w').signExtend w ≠ x') then
    .poison
  else if noWrapFlags.nuw ∧ ((x'.truncate w').zeroExtend w ≠ x') then
    .poison
  else
    trunc? w' x'

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

@[simp_denote]
def add_riscv_i64 :=
  [LV| {
    ^entry (%arg0: i64, %arg1: i64):
    %a = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!i64)
    %b = "builtin.unrealized_conversion_cast" (%arg1) : (i64) -> (!i64)
    %0 = add %a, %b : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

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 gt_signed_to_large_unsigned_before := [llvm|
{
^0(%arg41 : i8):
  %0 = llvm.mlir.constant(1024 : i32) : i32
  %1 = llvm.sext %arg41 : i8 to i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

abbrev VarSet (Γ : Ctxt Ty) : Type :=
  Finset (Σ t, Γ.Var t)

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) -> ()
}
]

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

def and_to_xor3_after := [llvm|
{
^0(%arg115 : i32, %arg116 : i32):
  %0 = llvm.xor %arg115, %arg116 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

Algebra in Mathlib.Algebra.Algebra.Defs

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

def or_test2_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.shl %arg0, %0 : i8
  %3 = llvm.or %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

@[reducible]
def tests : List ConcreteCliTest := llvmTests!

def and_orn_cmp_3_before := [llvm|
{
^0(%arg185 : i72, %arg186 : i72, %arg187 : i72):
  %0 = llvm.mlir.constant(42 : i72) : i72
  %1 = llvm.icmp "ugt" %arg185, %arg186 : i72
  %2 = llvm.icmp "ule" %arg185, %arg186 : i72
  %3 = llvm.icmp "ugt" %arg187, %0 : i72
  %4 = llvm.or %2, %3 : i1
  %5 = llvm.and %1, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

def and_sequence_10_lhs (w : Nat)   :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _):
  %v1 = llvm.and %Z, %C1
  %v2 = llvm.and %v1, %C1
  %v3 = llvm.and %v2, %C1
  %v4 = llvm.and %v3, %C1
  %v5 = llvm.and %v4, %C1
  %v6 = llvm.and %v5, %C1
  %v7 = llvm.and %v6, %C1
  %v8 = llvm.and %v7, %C1
  %v9 = llvm.and %v8, %C1
  %v10 = llvm.and %v9, %C1
  llvm.return %v10
}]

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

def test_op_op_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32, %arg22 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "sgt" %arg20, %0 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.icmp "sgt" %arg21, %0 : i32
  %4 = llvm.sext %3 : i1 to i32
  %5 = llvm.icmp "sgt" %arg22, %0 : i32
  %6 = "llvm.select"(%5, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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 t0_before := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.shl %arg12, %0 : i8
  %2 = llvm.ashr %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def srem_common_dividend_defined_cond_before := [llvm|
{
^0(%arg21 : i1, %arg22 : i5, %arg23 : i5, %arg24 : i5):
  %0 = llvm.srem %arg22, %arg23 : i5
  %1 = llvm.srem %arg22, %arg24 : i5
  %2 = "llvm.select"(%arg21, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

Polynomial.coeff in Mathlib.Algebra.Polynomial.Basic

Lean.Parser.ParserContext in Lean.Parser.Types
</all_available_defs>

<all_available_lemmas>
List.nodup_singleton in Mathlib.Data.List.Nodup
BitVec.eq_of_getLsbD_eq in Init.Data.BitVec.Bootstrap
BitVec.getLsbD_append in Init.Data.BitVec.Lemmas
BitVec.ofBool_eq_iff_eq in Init.Data.BitVec.Lemmas
Function.LeftInverse.injective in Init.Data.Function
BitVec.cons_msb_setWidth in Init.Data.BitVec.Bootstrap
BitVec.setWidth_cons in Init.Data.BitVec.Lemmas
List.foldl_cons in Init.Data.List.Basic
and_self in Init.SimpLemmas
and_true in Init.SimpLemmas
or_true in Init.SimpLemmas

@[ext]
theorem ext {x y : BitStream} (h : ∀ i, x i = y i) : x = y

theorem XorZextXor_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ^^^ 3#3) ^^^ 12#5 = zeroExtend 5 x ^^^ 15#5

theorem sext_zext_ne_known_nonneg_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬6#8 = 0 → ofBool (signExtend 32 x_1 != zeroExtend 32 (x / 6#8)) = ofBool (x_1 != x / 6#8)

theorem logical_or_bitwise_or_icmps_comm2_proof : logical_or_bitwise_or_icmps_comm2_before ⊑ logical_or_bitwise_or_icmps_comm2_after

theorem add_select_not_sext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (sext 64 (LLVM.xor e (const? 1 1))) ⊑
    select e (const? 64 64) (const? 64 0)

theorem n12_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 ^^^ -1#32) + x + 2#32 = x + (x_1 ^^^ -1#32) + 2#32

theorem prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

theorem slt_0_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (truncate 8 x <ₛ 0#8) = ofBool (x &&& 128#32 != 0#32)

theorem select_icmp_ne_0_and_1073741824_and_not_8_proof : select_icmp_ne_0_and_1073741824_and_not_8_before ⊑ select_icmp_ne_0_and_1073741824_and_not_8_after

theorem lt_unsigned_to_large_unsigned_proof : lt_unsigned_to_large_unsigned_before ⊑ lt_unsigned_to_large_unsigned_after

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

theorem ashrslt_02_07_exact_proof : ashrslt_02_07_exact_before ⊑ ashrslt_02_07_exact_after

theorem t5_thm.extracted_1._7 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 32),
  x_1 = 1#1 → ¬x = 1#1 → ¬64#32 = 0 → ¬6#32 ≥ ↑32 → x_2 / 64#32 = x_2 >>> 6#32

theorem lshr_pow2_ult_equal_constants_proof : lshr_pow2_ult_equal_constants_before ⊑ lshr_pow2_ult_equal_constants_after

theorem test19_commutative0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32 ∨ x ≥ ↑32 ∨ (1#32 <<< x_1 &&& 1#32 <<< x) + 1#32 <<< x = 0) →
    True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨
        x_1 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 →
      False

theorem masked_icmps_mask_notallzeros_bmask_mixed_3_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 15#32 != 0#32) = 1#1 → ofBool (x &&& 7#32 == 0#32) = ofBool (x &&& 15#32 == 8#32)

theorem eval_sext_multi_use_in_one_inst_thm (e : IntW 32) :
  sext 32
      (LLVM.or
        (mul (LLVM.and (trunc 16 e) (const? 16 14)) (LLVM.and (trunc 16 e) (const? 16 14))
          { «nsw» := true, «nuw» := true })
        (const? 16 (-32768))) ⊑
    sext 32
      (LLVM.or
        (mul (LLVM.and (trunc 16 e) (const? 16 14)) (LLVM.and (trunc 16 e) (const? 16 14))
          { «nsw» := true, «nuw» := true })
        (const? 16 (-32768)) { «disjoint» := true })

theorem in_constant_mone_vary_proof : in_constant_mone_vary_before ⊑ in_constant_mone_vary_after

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 <ᵤ x) &&& ofBool (x <ᵤ x_1) = 0#1

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

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

@[simp]
theorem MatchVar.liftM_bind_eq_some_iff (x? : Option α)
    (f : α → MatchVarM Δ Γ β) :
    ((liftM x? >>= f) mapIn = some mapOut)
    ↔ ( ∃ h : x?.isSome,
        f (x?.get h) mapIn = some mapOut )

theorem add_smin_simplify_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow (BitVec.ofInt 32 (-3)) = true) →
    ¬ofBool (x + BitVec.ofInt 32 (-3) <ₛ 2147483644#32) = 1#1 → 2147483644#32 = x + BitVec.ofInt 32 (-3)

theorem lshrugt_03_08_proof : lshrugt_03_08_before ⊑ lshrugt_03_08_after

theorem icmp_eq_and_pow2_shl_pow2_negative2_proof : icmp_eq_and_pow2_shl_pow2_negative2_before ⊑ icmp_eq_and_pow2_shl_pow2_negative2_after

theorem test_zext2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem positive_biggershl_lshrexact_proof : positive_biggershl_lshrexact_before ⊑ positive_biggershl_lshrexact_after

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 n12_proof : n12_before ⊑ n12_after

theorem p0_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (shl (const? 8 1) e_1) e ⊑ icmp IntPred.ne (lshr e e_1) (const? 8 0)

theorem ashrslt_01_07_exact_proof : ashrslt_01_07_exact_before ⊑ ashrslt_01_07_exact_after

theorem e_1617 :
    7 * ( ~~~b &&& (a ^^^ c)) - 1 * ( ~~~b ||| (a ^^^ c)) - 2 * (c ^^^  ~~~(a |||  ~~~b)) - 11 * (c &&&  ~~~(a &&& b)) - 7 * (a ^^^ ( ~~~b &&& c)) + 1 * (b ||| (a ^^^ c)) + 1 * (b ^^^  ~~~(a ||| (b &&& c))) + 3 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (a &&&  ~~~b) + 3 * ( ~~~a &&& (b ^^^ c)) - 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 3 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 7 * (b ^^^ c) - 3 *  ~~~(a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 14 * ( ~~~a &&& ( ~~~b &&& c)) + 10 * ( ~~~a &&& (b &&& c)) + 20 * (a &&& ( ~~~b &&& c)) + 7 * (a &&& (b &&& c)) =  - 9 *  ~~~(a ||| ( ~~~b ||| c))

theorem masked_icmps_mask_notallzeros_bmask_mixed_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 12#32 != 0#32) = 1#1 → ofBool (x &&& 7#32 == 1#32) = ofBool (x &&& 15#32 == 9#32)

theorem uadd_sat_flipped_wrong_bounds_proof : uadd_sat_flipped_wrong_bounds_before ⊑ uadd_sat_flipped_wrong_bounds_after

theorem zext_zext_ule_op0_wide_proof : zext_zext_ule_op0_wide_before ⊑ zext_zext_ule_op0_wide_after

theorem test_ashr_exact__exact_is_safe_proof : test_ashr_exact__exact_is_safe_before ⊑ test_ashr_exact__exact_is_safe_after

theorem test1_thm (e e_1 : IntW 32) :
  zext 32 (LLVM.xor (icmp IntPred.slt e_1 (const? 32 0)) (icmp IntPred.sgt e (const? 32 (-1)))) ⊑
    zext 32 (icmp IntPred.sgt (LLVM.xor e_1 e) (const? 32 (-1)))

theorem positive_biggerlshr_shlnuwnsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(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) →
    ¬3#8 ≥ ↑8 → x >>> 6#8 <<< 3#8 = x >>> 3#8 &&& 24#8

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

theorem e_1808 :
    5 *  ~~~(a ^^^ b) + 3 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * ((a ^^^ b) ||| (a ^^^ c)) + 5 * ((a ||| b) &&& (b ^^^ c)) - 1 * (a ||| c) + 1 * (c |||  ~~~(a ||| b)) - 7 * (a ||| (b ^^^ c)) - 2 * (a &&&  ~~~b) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 7 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 *  ~~~(a &&&  ~~~a) - 11 * ((a &&& b) |||  ~~~(b ||| c)) - 2 * (b ||| (a &&&  ~~~c)) + 7 * (c ^^^ (a ||| (b &&& c))) - 2 *  ~~~(a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a ||| ( ~~~b ||| c))) - 2 * (b ^^^ (a ||| c)) + 5 * ( ~~~c &&&  ~~~(a ^^^ b)) - 3 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 2 * (a |||  ~~~b) - 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * (b ^^^ (a &&& (b ||| c))) - 3 * (c ^^^  ~~~(a &&& (b ||| c))) - 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 7 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 1 *  ~~~( ~~~a &&& (b ^^^ c)) - 3 * (c ||| (a &&& b)) + 1 * (b ^^^ (a &&&  ~~~c)) - 2 * ((a &&& c) |||  ~~~(b ||| c)) - 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 * (b ^^^ (a ||| (b ^^^ c))) + 13 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) + 32 *  ~~~( ~~~a ||| (b ||| c)) + 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 23 * ( ~~~a &&& (b &&& c)) + 28 * (a &&& ( ~~~b &&& c)) + 17 * (a &&& (b &&& c)) =  - 7 * ( ~~~a &&& ( ~~~b &&& c))

theorem exact_lshr_eq_exactdiv_proof : exact_lshr_eq_exactdiv_before ⊑ exact_lshr_eq_exactdiv_after

theorem icmp_select_var_select_proof : icmp_select_var_select_before ⊑ icmp_select_var_select_after

theorem add_1_proof : add_1_before ⊑ add_1_after

theorem lshrugt_02_14_exact_proof : lshrugt_02_14_exact_before ⊑ lshrugt_02_14_exact_after

theorem test_add__nsw_is_safe_proof : test_add__nsw_is_safe_before ⊑ test_add__nsw_is_safe_after

theorem fold_sext_to_and3_proof : fold_sext_to_and3_before ⊑ fold_sext_to_and3_after

theorem bools_multi_uses2_logical_thm.extracted_1._23 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → x_1 = 1#1 → ¬x = 1#1 → ¬True → x_1 + x = 0#1

theorem not_add_eq_not_sub :
    ~~~ (x + y) = ~~~ x - y

theorem fold_sext_to_and_wrong9_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (sext 32 e) (const? 32 128)) (const? 32 1) ⊑ const? 1 1

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 AvoidCollision_cast_setWidth (h : v = v') (x : BitVec w) :
    (x.setWidth v).cast h = x.setWidth v'

theorem shl_nsw_add_negative_invalid_constant3_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ (2#4 <<< (x + BitVec.ofInt 4 (-8))).sshiftRight' (x + BitVec.ofInt 4 (-8)) ≠ 2#4 ∨
        x + BitVec.ofInt 4 (-8) ≥ ↑4) →
    True ∧ (2#4 <<< (x ^^^ BitVec.ofInt 4 (-8))).sshiftRight' (x ^^^ BitVec.ofInt 4 (-8)) ≠ 2#4 ∨
        x ^^^ BitVec.ofInt 4 (-8) ≥ ↑4 →
      False

theorem shl_and_lshr_comm_proof : shl_and_lshr_comm_before ⊑ shl_and_lshr_comm_after

theorem main1_proof : main1_before ⊑ main1_after

theorem not_xor_to_or_not3_proof : not_xor_to_or_not3_before ⊑ not_xor_to_or_not3_after

theorem test19_proof : test19_before ⊑ test19_after

theorem main7e_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ¬ofBool (x_4 &&& x_3 &&& x_2 == x_4 &&& x_3) &&& ofBool (x_1 &&& x &&& x_2 == x_1 &&& x) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x_2 &&& (x_4 &&& x_3 ||| x_1 &&& x) != x_4 &&& x_3 ||| x_1 &&& x))

theorem positive_biggershl_shlnuwnsw_proof : positive_biggershl_shlnuwnsw_before ⊑ positive_biggershl_shlnuwnsw_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 t10_constants_proof : t10_constants_before ⊑ t10_constants_after

theorem sdiv_ult_smin_proof : sdiv_ult_smin_before ⊑ sdiv_ult_smin_after

theorem trunc_shl_shl_var_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(x ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬(x ≥ ↑64 ∨ 2#32 ≥ ↑32) → truncate 32 (x_1 <<< x <<< 2#64) = truncate 32 (x_1 <<< x) <<< 2#32

theorem udiv_shl_mul_nuw_swap_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑5 ∨ True ∧ x.umulOverflow x_2 = true ∨ x * x_2 = 0) →
    ¬(True ∧ 1#5 <<< x_1 >>> x_1 ≠ 1#5 ∨ x_1 ≥ ↑5 ∨ x = 0) → x_2 <<< x_1 / (x * x_2) = 1#5 <<< x_1 / x

theorem test_logical_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (255#32 <ᵤ x) = 1#1 → 1#1 = ofBool (255#32 <ᵤ x)

theorem test4_proof : test4_before ⊑ test4_after

theorem same_signbit_wrong_type_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 →
    ofBool (x_1 >>> 7#8 != zeroExtend 8 (ofBool (-1#32 <ₛ x))) = ofBool (x_1 <ₛ 0#8) ^^^ ofBool (-1#32 <ₛ x)

theorem test54_proof : test54_before ⊑ test54_after

@[simp] theorem HVector.denote_cons
    {t : _ × _} {ts : RegionSignature _}
    (a : Com d t.1 .impure t.2) (as : Regions _ ts) :
    HVector.denote (.cons a as) = .cons (a.denote) (as.denote)

@[simp]
lemma bitVecToFinFun_inj [FinEnum ar] : Function.Injective (bitVecToFinFun (ar := ar))

theorem xor_logic_and_or1_proof : xor_logic_and_or1_before ⊑ xor_logic_and_or1_after

theorem t3_c0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), 42#8 - x_1 - x = 42#8 - (x_1 + x)

theorem test_mul__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 268435457)) (const? 32 268435456)) (const? 32 (-1879048192))
      (mul (LLVM.and e (const? 32 268435457)) (const? 32 9)) ⊑
    mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := false, «nuw» := true }

theorem test5_commuted_x_y_thm (e e_1 : IntW 64) :
  LLVM.or (LLVM.xor e_1 e) (LLVM.xor e (const? 64 (-1))) ⊑ LLVM.xor (LLVM.and e_1 e) (const? 64 (-1))

theorem shl_nsw_add_nsw_nuw_proof : shl_nsw_add_nsw_nuw_before ⊑ shl_nsw_add_nsw_nuw_after

theorem select_xor_inv_icmp_proof : select_xor_inv_icmp_before ⊑ select_xor_inv_icmp_after

theorem t5_proof : t5_before ⊑ t5_after

theorem ule_or_not_min_commute_logical_proof : ule_or_not_min_commute_logical_before ⊑ ule_or_not_min_commute_logical_after

theorem shift_no_xor_multiuse_or_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1#32 == 0#32) = 1#1 → 1#32 ≥ ↑32 → False

theorem positive_biggerashr_shlnuwnsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(6#8 ≥ ↑8 ∨
        True ∧ (x.sshiftRight' 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x.sshiftRight' 6#8 ∨
          True ∧ x.sshiftRight' 6#8 <<< 3#8 >>> 3#8 ≠ x.sshiftRight' 6#8 ∨ 3#8 ≥ ↑8) →
    ¬3#8 ≥ ↑8 → x.sshiftRight' 6#8 <<< 3#8 = x.sshiftRight' 3#8 &&& BitVec.ofInt 8 (-8)

theorem mul_of_pow2_commute_proof : mul_of_pow2_commute_before ⊑ mul_of_pow2_commute_after

theorem and_consts_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and (const? 32 4) e) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (LLVM.and (const? 32 8) e) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 12)) (const? 32 12)

theorem not_not_cmp_proof : not_not_cmp_before ⊑ not_not_cmp_after

theorem trunc_shl_ashr_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (ashr e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (ashr e_1 e)) (const? 32 2)

theorem mkStateUniqueCircuitN_eq_false_iff {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity]
  (p : FSM arity) (n : Nat)
  {env : Vars p.α arity n → Bool} :
  ((mkStateUniqueCircuitN p n).eval env = false) ↔
  (∀ (i : Nat) (hi : i < n), ∃ (s : p.α), env (Vars.stateN s i) ≠ env (Vars.stateN s n))

theorem demorgan_nor_use2b_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x * 23#8 == 0 || 8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && x * 23#8 == -1) = true →
    (x * 23#8 == 0 || 8 != 1 && x_1 &&& (x ^^^ -1#8) == intMin 8 && x * 23#8 == -1) = true → False

theorem t1_sshr_proof : t1_sshr_before ⊑ t1_sshr_after

theorem one_side_fold_slt_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1), ¬x_1 = 1#1 → ofBool (x <ₛ x) = 0#1

theorem zext_nneg_i1_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬(True ∧ x.msb = true) → zeroExtend 32 x = 0#32

theorem or_wrong_const1_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ofBool (truncate 8 x != 127#8) ||

theorem test3_proof : test3_before ⊑ test3_after

theorem no_shift_no_xor_multiuse_or_proof : no_shift_no_xor_multiuse_or_before ⊑ no_shift_no_xor_multiuse_or_after

theorem sext_multiuse_proof : sext_multiuse_before ⊑ sext_multiuse_after

theorem lshr_and_sub_proof : lshr_and_sub_before ⊑ lshr_and_sub_after

theorem lshr_add_and_shl_thm (e e_1 : IntW 32) :
  shl (add e_1 (LLVM.and (lshr e (const? 32 5)) (const? 32 127))) (const? 32 5) ⊑
    add (LLVM.and e (const? 32 4064)) (shl e_1 (const? 32 5))

theorem p_constmask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& 65280#32 &&& (x &&& BitVec.ofInt 32 (-65281)) != 0) = true → False

theorem udiv1_thm (e e_1 : IntW 32) : mul (LLVM.udiv e_1 e { «exact» := true }) e ⊑ e_1

theorem and_signbit_select_shl_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x &&& BitVec.ofInt 32 (-65536)) <<< 8#32 = x <<< 8#32 &&& BitVec.ofInt 32 (-16777216)

theorem lshrult_03_02_exact_proof : lshrult_03_02_exact_before ⊑ lshrult_03_02_exact_after

@[simp, grind=] lemma Ctxt.getElem?_delete_eq_none_iff {i : Nat} {vs : DeleteRange Γ} :
    (Γ.delete vs)[i]? = none ↔ Γ.length ≤ i + vs.num

theorem test_zext_nneg_thm (e : IntW 64) (e_1 : IntW 32) (e_2 : IntW 64) :
  sub (add e_2 (const? 64 (-5))) (add (zext 64 (LLVM.xor e_1 (const? 32 (-1))) { «nneg» := true }) e) ⊑
    add (add e_2 (const? 64 (-4))) (sub (sext 64 e_1) e)

theorem e_1580 :
     - 1 * ( ~~~a &&& (b ^^^ c)) - 2 * b + 3 * (c ^^^  ~~~(a |||  ~~~b)) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 2 * ((a &&& b) ^^^ (b ||| c)) - 2 * (c ^^^ (a ||| (b ||| c))) + 11 * (a ^^^ b) - 3 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 11 * (a ^^^ (b ^^^ c)) + 2 *  ~~~(a ||| (b ||| c)) - 22 *  ~~~( ~~~a ||| (b ||| c)) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 16 * ( ~~~a &&& ( ~~~b &&& c)) - 10 * ( ~~~a &&& (b &&& c)) - 14 * (a &&& ( ~~~b &&& c)) - 13 * (a &&& (b &&& c)) = 19 *  ~~~(a ||| ( ~~~b ||| c)) - 1 * (c ^^^ (a &&& ( ~~~b ||| c)))

theorem sub_select_sext_thm (e : IntW 64) (e_1 : IntW 1) :
  sub (select e_1 (const? 64 64) e) (sext 64 e_1) ⊑ select e_1 (const? 64 65) e

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

theorem zext_sext_add_icmp_slt_minus1_proof : zext_sext_add_icmp_slt_minus1_before ⊑ zext_sext_add_icmp_slt_minus1_after

theorem ripple_nsw1_proof : ripple_nsw1_before ⊑ ripple_nsw1_after

theorem ashrslt_01_12_proof : ashrslt_01_12_before ⊑ ashrslt_01_12_after

theorem t4_ugt_slt_65536_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x_1) = 1#1 → ¬ofBool (65535#32 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → x_1 = x

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    ¬ofBool (BitVec.ofInt 64 (-2) <ₛ x) = 1#1 → x >>> 62#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = 0#64

theorem shl_nsw_nuw_poison_constant_fold_thm (e : IntW 8) (e_1 : IntW 1) :
  shl (const? 8 16) (select e_1 (const? 8 3) e) { «nsw» := true, «nuw» := true } ⊑
    select e_1 (const? 8 (-128)) (shl (const? 8 16) e { «nsw» := true, «nuw» := true })

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

theorem alive_AndOrXor_2264 : alive_AndOrXor_2264_src ⊑ alive_AndOrXor_2264_tgt

theorem not_invert_signbit_splat_mask1_proof : not_invert_signbit_splat_mask1_before ⊑ not_invert_signbit_splat_mask1_after

theorem test66_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬ofBool (x &&& 4294967296#64 != 0#64) = 1#1 → ¬ofBool (x &&& 4294967296#64 == 0#64) = 1#1 → 42#32 = 40#32

theorem test3_proof : test3_before ⊑ test3_after

@[simp] theorem Hom.castDomain_rfl {h : Δ = Δ} {f : Γ.Hom Δ} :
    (f.castCodomain h) = f

theorem test4_logical_proof : test4_logical_before ⊑ test4_logical_after

theorem test91_proof : test91_before ⊑ test91_after

theorem zext_lshr_proof : zext_lshr_before ⊑ zext_lshr_after

theorem scalar_i32_signbit_shl_and_eq_X_is_constant1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → ofBool (BitVec.ofInt 32 (-2147483648) <<< x &&& 12345#32 == 0#32) = 1#1

theorem test_proof : test_before ⊑ test_after

theorem lshr_exact_add_nuw_proof : lshr_exact_add_nuw_before ⊑ lshr_exact_add_nuw_after

theorem or_xor_tree_1010_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 * 42#32 ^^^ x_1 * 42#32 ^^^ x * 42#32 ||

theorem e_2319 :
    11 * (e |||  ~~~f) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~d ||| (e ||| f)) - 2 * (f ||| (d &&&  ~~~e)) - 7 * (e ^^^ (d &&&  ~~~f)) + 4 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * (d ||| (e &&& f)) + 2 * ( ~~~d ||| (e &&& f)) - 1 * (e ^^^ (d &&& (e ||| f))) - 1 * (f &&&  ~~~(d ^^^ e)) + 3 *  ~~~(d ^^^ f) - 7 * ((d &&& f) ||| (e &&&  ~~~f)) + 7 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * ( ~~~e ||| (d ^^^ f)) + 2 * ( ~~~e |||  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& (e &&& f))) - 3 *  ~~~(e &&& f) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * (e ^^^ (d ||| (e ^^^ f))) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) - 11 * (d &&& ( ~~~e ||| f)) + 1 * (f ^^^ (d ||| (e &&& f))) + 2 * (d &&&  ~~~f) + 7 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * (e |||  ~~~(d ^^^ f)) - 6 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ^^^ f) + 5 *  ~~~(d ||| (e ^^^ f)) - 2 * (e ^^^  ~~~(d ||| f)) - 6 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (d ||| ( ~~~e &&& f)) + 5 * ( ~~~f ||| (d ^^^ e)) - 3 * (e ^^^  ~~~(d ||| (e &&& f))) + 3 * ( ~~~d &&& (e ||| f)) - 1 * (f ^^^ ( ~~~d &&& (e ||| f))) + 5 * (d ^^^ ( ~~~e ||| f)) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * (e &&& (d ||| f)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e ^^^ (d ||| (e &&& f))) - 2 *  ~~~(d ^^^ (e ||| f)) + 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 7 * ( ~~~d ||| ( ~~~e &&& f)) + 2 * (d ||| e) + 5 *  ~~~(d ||| f) + 11 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 52 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) - 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 33 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) - 32 * (d &&& (e &&& f)) = 1 * d - 7 * (f ^^^  ~~~(d ||| e))

theorem test_sub__all_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 255#32 == 6#32) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-254)).ssubOverflow (x &&& 255#32) = true ∨
          True ∧ (BitVec.ofInt 32 (-254)).usubOverflow (x &&& 255#32) = true) →
      BitVec.ofInt 32 (-260) = BitVec.ofInt 32 (-254) - (x &&& 255#32)

theorem sdiv_icmp6_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.sdiv e (const? 64 (-5)) { «exact» := true }) (const? 64 (-1)) ⊑
    icmp IntPred.eq e (const? 64 5)

theorem test_shl_nuw_nsw__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 1073741822#32 == 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 syncMap3_flip23 {f : α → β → γ → δ} :
  syncMap₃ f xs ys zs = syncMap₃ (fun x z y => f x y z) xs zs ys

theorem scalar_i32_shl_and_negC_ne_proof : scalar_i32_shl_and_negC_ne_before ⊑ scalar_i32_shl_and_negC_ne_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 e_778 :
    2 * z + 1 * (z ^^^ t) - 5 *  ~~~(z &&& t) - 3 * (z &&&  ~~~t) - 7 * (z &&& t) =  - 5 *  ~~~(z &&&  ~~~z) + 1 *  ~~~(z |||  ~~~t)

theorem commutativity_mult' 
  (hppot : ppot &&& (ppot - 1) = 0)
  (hqpot : qpot &&& (qpot - 1) = 0)
  (hrpot : rpot &&& (rpot - 1) = 0)
  (hspot : spot &&& (spot - 1) = 0)
  (htpot : tpot &&& (tpot - 1) = 0)
  (hupot : upot &&& (upot - 1) = 0)
  (hpmask : pmask = ppot - 1)
  (hqmask : qmask = qpot - 1)
  (hrmask : rmask = rpot - 1)
  (hsmask : smask = spot - 1)
  (htmask : tmask = tpot - 1)
  (humask : umask = upot - 1) :
  (bw' rmask (mulMax' (bw' pmask a') pmask (bw' qmask b') qmask)) =
  (bw' rmask (mulMax' (bw' qmask b') qmask (bw' pmask a') pmask))

theorem test_invert_demorgan_logical_and_thm.extracted_1._3 : ∀ (x x_1 : BitVec 64),
  ofBool (x_1 == 27#64) = 1#1 →
    ofBool (x_1 != 27#64) = 1#1 →
      (ofBool (x_1 == 0#64) ||| ofBool (x == 0#64)) ^^^ 1#1 = ofBool (x_1 != 0#64) &&& 1#1

theorem or_and_shifts2_proof : or_and_shifts2_before ⊑ or_and_shifts2_after

theorem select_lshr_icmp_const_reordered_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 32#32) = 1#1 → ¬5#32 ≥ ↑32 → 0#32 = x >>> 5#32

@[simp] theorem Hom.append_appendInl (f : Γ.Hom Δ) (v : ζ.Var t) :
    (f.append (ζ := ζ)) v.appendInl = v.appendInl

theorem shl_add_nsw_proof : shl_add_nsw_before ⊑ shl_add_nsw_after

theorem hoist_ashr_ahead_of_sext_2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬8#32 ≥ ↑32 → ¬7#8 ≥ ↑8 → (signExtend 32 x).sshiftRight' 8#32 = signExtend 32 (x.sshiftRight' 7#8)

theorem ashrslt_01_00_proof : ashrslt_01_00_before ⊑ ashrslt_01_00_after

theorem or_xor_xor_normal_binops_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.xor (LLVM.xor e_2 e_1) (LLVM.and (LLVM.xor e_2 e_1) (LLVM.xor e e_1)))
      (LLVM.xor (LLVM.xor e e_1) (LLVM.and (LLVM.xor e_2 e_1) (LLVM.xor e e_1))) ⊑
    LLVM.xor e_2 e

theorem canonicalize_logic_first_and0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  x + 48#8 &&& BitVec.ofInt 8 (-10) = (x &&& BitVec.ofInt 8 (-10)) + 48#8

@[simp]
lemma reduce_accepts {M : NFA' n} : M.reduce.accepts = M.accepts

theorem and_not_or_proof : and_not_or_before ⊑ and_not_or_after

theorem icmp_ne_and1_lshr_pow2_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (lshr (const? 32 8) e) (const? 32 1)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 3))

theorem and_or3_commuted_thm.extracted_1._7 : ∀ (x x_1 : BitVec 1) (x_2 x_3 : BitVec 32),
  ¬ofBool (x_3 == x_2) &&& x_1 = 1#1 → x_1 = 1#1 → ¬ofBool (x_3 != x_2) = 1#1 → x_1 = x

@[bv_multi_width_normalize] theorem false_imp_eq (p : Prop) : (False → p) = True

@[simp]
theorem BitVec.intCast_eq_ofInt : ((i : Int) : BitVec w) = BitVec.ofInt w i

theorem sub_eq_mul_and_not_sub_xor (x y : BitVec w):
    x - y = 2 * (x &&& ~~~ y) - (x ^^^ y)

theorem t2_ashr_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.sshiftRight' (signExtend 32 x) = x_1.sshiftRight' (zeroExtend 32 x)

@[simp]
theorem Eqn.denote_cons {w : Nat}
    (t : Term) (ts : List Term) (env : Env w) :
    Eqn.denote (t :: ts) env = t.denote env + Eqn.denote ts env

theorem or_not_xor_common_op_commute5_proof : or_not_xor_common_op_commute5_before ⊑ or_not_xor_common_op_commute5_after

theorem fold_add_udiv_urem_without_noundef_proof : fold_add_udiv_urem_without_noundef_before ⊑ fold_add_udiv_urem_without_noundef_after

theorem test4_proof : test4_before ⊑ test4_after

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

theorem uge_sext_thm (e : IntW 8) (e_1 : IntW 1) :
  icmp IntPred.uge (sext 8 e_1) e ⊑ LLVM.or (icmp IntPred.eq e (const? 8 0)) e_1

theorem andn_or_cmp_2_proof : andn_or_cmp_2_before ⊑ andn_or_cmp_2_after

theorem icmp_shl_nsw_sge0_proof : icmp_shl_nsw_sge0_before ⊑ icmp_shl_nsw_sge0_after

@[simp]
theorem Factor.denote_width_zero  (f : Factor) (env : Env 0) : f.denote env = 0

theorem add_signbit_select_shl_proof : add_signbit_select_shl_before ⊑ add_signbit_select_shl_after

theorem src_srem_shl_demand_max_mask_hit_demand_proof : src_srem_shl_demand_max_mask_hit_demand_before ⊑ src_srem_shl_demand_max_mask_hit_demand_after

theorem add_mask_ashr27_i32_thm (e : IntW 32) :
  add (LLVM.and (ashr e (const? 32 27)) (const? 32 8)) (ashr e (const? 32 27)) ⊑
    add (LLVM.and (ashr e (const? 32 27)) (const? 32 8)) (ashr e (const? 32 27))
      { «nsw» := true, «nuw» := false }

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem test11_thm (e : IntW 32) :
  urem (mul (LLVM.and e (const? 32 (-2))) (const? 32 2)) (const? 32 4) ⊑ const? 32 0

theorem eq_smax1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ₛ x_1) = 1#1 → ofBool (x_1 == x_1) = ofBool (x ≤ₛ x_1)

theorem zext_nneg_flag_drop_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬(True ∧ (x_1 &&& 127#8).msb = true) →
    zeroExtend 16 (x_1 &&& 127#8) ||

private theorem not_gt_eq_le (A B : BitVec w) : (¬ (A >ₛ B)) = (A ≤ₛ B)

theorem foo1_and_signbit_lshr_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and (shl (const? 32 1) e_2) e_1) (const? 32 0))
      (icmp IntPred.eq (LLVM.and (lshr (const? 32 (-2147483648)) e) e_1) (const? 32 0)) ⊑
    icmp IntPred.ne
      (LLVM.and e_1
        (LLVM.or (shl (const? 32 1) e_2 { «nsw» := false, «nuw» := true })
          (lshr (const? 32 (-2147483648)) e { «exact» := true })))
      (LLVM.or (shl (const? 32 1) e_2 { «nsw» := false, «nuw» := true })
        (lshr (const? 32 (-2147483648)) e { «exact» := true }))

theorem negative_not_power_of_two_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (-1#32 <ₛ x) = 1#1 → 0#1 = ofBool (x == 0#32)

theorem test_mul_nuw__none_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq e (const? 32 805306368)) (const? 32 (-1342177280))
      (mul e (const? 32 9) { «nsw» := false, «nuw» := true }) ⊑
    mul e (const? 32 9)

theorem test65_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (x &&& 16#64 != 0#64) = 1#1 → ofBool (x &&& 16#64 == 0#64) = 1#1 → 40#32 = 42#32

theorem e_662 :
    1 * y + 7 * (x ^^^ y) + 5 *  ~~~x + 3 * (x |||  ~~~y) - 1 *  ~~~(x &&& y) - 1 * (x ||| y) - 1 * x + 4 *  ~~~y - 5 *  ~~~(x ^^^ y) + 5 *  ~~~(x ||| y) = 11 *  ~~~(x &&&  ~~~x) - 14 * (x &&& y)

theorem eq_irregular_bit_widths_proof : eq_irregular_bit_widths_before ⊑ eq_irregular_bit_widths_after

theorem not_or_or_and_not_and_and_commute2_and_proof : not_or_or_and_not_and_and_commute2_and_before ⊑ not_or_or_and_not_and_and_commute2_and_after

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

theorem demorgan_nor_proof : demorgan_nor_before ⊑ demorgan_nor_after

theorem neg_nsw_sgt_0_proof : neg_nsw_sgt_0_before ⊑ neg_nsw_sgt_0_after

theorem not_false_not_proof : not_false_not_before ⊑ not_false_not_after

theorem fold_sext_to_and_wrong5_proof : fold_sext_to_and_wrong5_before ⊑ fold_sext_to_and_wrong5_after

theorem test10b_proof : test10b_before ⊑ test10b_after

theorem main4_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) = 1#1 → 0#1 = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 != 55#32))

theorem main3_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 == 0#32) = 1#1 →
    ofBool (x &&& 48#32 == 0#32) = 1#1 → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 != 0#32))

theorem test93_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬64#96 ≥ ↑96 → ¬31#32 ≥ ↑32 → truncate 32 (signExtend 96 x >>> 64#96) = x.sshiftRight' 31#32

theorem substitute_constant_and_eq_eq_proof : substitute_constant_and_eq_eq_before ⊑ substitute_constant_and_eq_eq_after

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

theorem test_sub_0_Y_eq_0_proof : test_sub_0_Y_eq_0_before ⊑ test_sub_0_Y_eq_0_after

theorem foo1_and_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨
          x_1 ≥ ↑32 ∨
            True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨
              x ≥ ↑32 ∨ True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32) →
      ofBool (x_2 * x_2 &&& 1#32 <<< x_1 == 0#32) ||

theorem HVector.map_eq_map_of_matchArg
    {lets : Lets d Γ_in eff Γ_out}
    {matchLets : Lets d Δ_in .pure Δ_out}
    {ma : Mapping Δ_in Γ_out}
    {l : List d.Ty} {args₁ : HVector _ l} {args₂ : HVector _ l}
    (mapOut : MatchArgResult lets matchLets args₁ args₂ ma)
    (f₁ f₂ : (t : d.Ty) → Var _ t → ⟦t⟧)
    (hf : ∀ {t v₁ v₂},
      (mapOut' : MatchVarResult lets v₁ matchLets v₂ ma)
      → mapOut'.val = mapOut.val
      → f₂ t v₂ = f₁ t v₁) :
    HVector.map f₂ args₂ = HVector.map f₁ args₁

theorem addsub_combine_constants_thm (e e_1 : IntW 7) :
  add (add e_1 (const? 7 42)) (sub (const? 7 10) e) { «nsw» := true, «nuw» := false } ⊑
    add (sub e_1 e) (const? 7 52)

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 123), x ^^^ x = 0#123

theorem addhshlhsdivhscalar0_proof : addhshlhsdivhscalar0_before ⊑ addhshlhsdivhscalar0_after

theorem shl_add_and_proof : shl_add_and_before ⊑ shl_add_and_after

theorem neg_slt_0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (0#8 - x <ₛ 0#8) = ofBool (-1#8 <ₛ x + -1#8)

theorem zext_add_scalar_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 32 x + 42#32 = 42#32

theorem signed_sign_bit_extract_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (x.sshiftRight' 31#32 != 0#32) = ofBool (x <ₛ 0#32)

theorem test_sext1_proof : test_sext1_before ⊑ test_sext1_after

theorem in_constant_6_vary_invmask_proof : in_constant_6_vary_invmask_before ⊑ in_constant_6_vary_invmask_after

theorem scalar_i32_shl_and_signbit_eq_X_is_constant1_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl (const? 32 12345) e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.sgt (shl (const? 32 12345) e) (const? 32 (-1))

theorem syncMap₃_eq_syncMap₃
    (hxs : xs ~ xs') (hys : ys ~ ys') (hzs : zs ~ zs') :
    syncMap₃ f xs ys zs ~ syncMap₃ f xs' ys' zs'

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

theorem or_eq_with_one_bit_diff_constants1_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x == 50#32) = 1#1 → ofBool (x == 51#32) = ofBool (x &&& BitVec.ofInt 32 (-2) == 50#32)

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    ofBool (BitVec.ofInt 64 (-2) <ₛ x) = 1#1 →
      x >>> 62#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = x >>> 62#64 &&& 1#64

theorem no_shift_xor_multiuse_cmp_or_thm.extracted_1._1 : ∀ (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 and_or2_commuted_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 &&& (x_1 ^^^ 1#1) = 1#1 → x_2 = 1#1 → x_1 = 1#1 → x_2 = 1#1

theorem allOnes_xor_eq_not (x : BitVec w) : allOnes w ^^^ x = ~~~x

theorem addhshlhsdivhscalar0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-4) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-4) == -1) = true ∨ 2#8 ≥ ↑8) →
    (4#8 == 0 || 8 != 1 && x == intMin 8 && 4#8 == -1) = true → False

theorem do_not_add_annotation_to_existing_instr_thm (e e_1 : IntW 32) : add (const? 32 0) (add e_1 e) ⊑ add e_1 e

theorem slt_zero_ne_ne_b_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬31#32 ≥ ↑32 →
    ofBool (zeroExtend 32 (ofBool (x_1 != x)) != x_1 >>> 31#32) = ofBool (x_1 <ₛ 0#32) ^^^ ofBool (x_1 != x)

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem e_1592 :
     - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) + 11 * (b ^^^ (a ||| (b &&& c))) - 6 * (b ^^^  ~~~(a |||  ~~~c)) + 1 * (c |||  ~~~(a ^^^ b)) + 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 11 * (b ^^^ ( ~~~a ||| (b ||| c))) - 6 * (c |||  ~~~(a ||| b)) + 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 6 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 1 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 2 * (c ^^^ (a &&& (b ||| c))) + 11 * (b ^^^  ~~~(a &&& (b &&& c))) - 11 * (a &&& b) - 16 *  ~~~(a ||| ( ~~~b ||| c)) - 27 *  ~~~( ~~~a ||| (b ||| c)) + 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) = 8 * ( ~~~a &&& (b &&& c))

theorem main14_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.sge (trunc 16 e) (const? 16 0)) (icmp IntPred.sge (trunc 8 e) (const? 8 0))
        (const? 1 0))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 32896)) (const? 32 0)) (const? 32 2) (const? 32 1)

theorem add_nsw_const_const_sub_proof : add_nsw_const_const_sub_before ⊑ add_nsw_const_const_sub_after

theorem ashrslt_03_03_proof : ashrslt_03_03_before ⊑ ashrslt_03_03_after

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

theorem positive_samevar_shlnuw_ashrexact_proof : positive_samevar_shlnuw_ashrexact_before ⊑ positive_samevar_shlnuw_ashrexact_after

theorem add_and_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) + (x_1 ||| x) = x_1 + x

theorem bools2_logical_commute0_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → x = x_1

theorem PR1817_2_logical_thm (e : IntW 32) :
  select (icmp IntPred.slt e (const? 32 10)) (const? 1 1) (icmp IntPred.ult e (const? 32 10)) ⊑
    icmp IntPred.slt e (const? 32 10)

theorem e_15 :
     - 5 * y + 1 *  ~~~x + 11 *  ~~~(x ^^^ y) + 4 *  ~~~(x |||  ~~~y) = 6 * (x &&& y) + 12 *  ~~~(x ||| y)

theorem sextinreg2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  24#32 ≥ ↑32 ∨ True ∧ x <<< 24#32 >>> 24#32 <<< 24#32 ≠ x <<< 24#32 ∨ 24#32 ≥ ↑32 → False

theorem test_or4_logical_proof : test_or4_logical_before ⊑ test_or4_logical_after

theorem main10_logical_thm.extracted_1._1 : ∀ (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 → 1#32 = 2#32

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

theorem dont_narrow_zext_ashr_keep_trunc_thm (e e_1 : IntW 8) :
  trunc 8 (ashr (add (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 1)) ⊑
    trunc 8 (lshr (add (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 1))

theorem not_sub_eq_sub_sub_one :
    ~~~ (x - y) = y - x - 1

theorem ashr_ult_13_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬1#4 ≥ ↑4 → ofBool (x.sshiftRight' 1#4 <ᵤ BitVec.ofInt 4 (-3)) = ofBool (x <ᵤ BitVec.ofInt 4 (-6))

theorem trunc_shl_nuw_31_i32_i64_proof : trunc_shl_nuw_31_i32_i64_before ⊑ trunc_shl_nuw_31_i32_i64_after

theorem uge_or_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == -1#8) ||

theorem e_2434 :
    1 * (d ||| f) - 2 *  ~~~(d ||| f) - 7 * (f &&&  ~~~(d &&&  ~~~e)) + 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 7 * (f ^^^  ~~~(d ||| (e &&& f))) - 7 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 11 *  ~~~(d &&&  ~~~e) - 3 * (d &&&  ~~~e) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (f &&&  ~~~(d ^^^ e)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 4 *  ~~~(d ^^^ (e &&& f)) - 3 * (e ^^^ (d ||| f)) + 11 * (d |||  ~~~e) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * (e ^^^ (d ||| ( ~~~e ||| f))) + 3 * (d ||| ( ~~~e &&& f)) + 4 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * (f ^^^  ~~~(d &&& (e ||| f))) - 6 *  ~~~(d ^^^ (e ^^^ f)) + 11 * (d &&& ( ~~~e ||| f)) + 1 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 7 * ((d &&& e) |||  ~~~(e ^^^ f)) + 3 * (e &&& f) - 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&& f) |||  ~~~(e ||| f)) - 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 3 * (d ^^^ e) + 7 * (f ^^^  ~~~(d &&& e)) + 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * (d &&& (e ^^^ f)) - 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 5 * ( ~~~f &&&  ~~~(d ^^^ e)) - 7 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 11 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (e ^^^  ~~~(d |||  ~~~f)) + 3 * (d ||| ( ~~~e ||| f)) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 11 *  ~~~(e |||  ~~~f) + 7 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 *  ~~~(d &&&  ~~~d) - 2 * (e ^^^  ~~~(d ||| f)) - 1 * e + 2 *  ~~~(d &&& f) - 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 6 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 *  ~~~(e &&& f) + 2 * (e &&&  ~~~(d &&& f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 11 * (e |||  ~~~f) + 5 *  ~~~(d &&& (e ^^^ f)) - 1 * d + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 7 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (d ||| (e &&& f)) - 29 *  ~~~(d ||| (e ||| f)) + 25 *  ~~~(d ||| ( ~~~e ||| f)) - 33 *  ~~~( ~~~d ||| (e ||| f)) - 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 15 * ( ~~~d &&& ( ~~~e &&& f)) + 13 * ( ~~~d &&& (e &&& f)) - 23 * (d &&& ( ~~~e &&& f)) - 27 * (d &&& (e &&& f)) = 1 * (d ^^^ ( ~~~e &&& f)) + 6 * (e ^^^ ( ~~~d ||| (e ||| f)))

theorem e_578 :
     - 11 *  ~~~(x ^^^ y) + 11 * (x ||| y) - 3 *  ~~~(x &&&  ~~~y) + 5 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) + 11 *  ~~~(x &&&  ~~~x) - 5 *  ~~~(x ||| y) - 24 *  ~~~(x |||  ~~~y) - 30 * (x &&&  ~~~y) = 15 * (x &&& y) - 2 * y

theorem test3_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.and (LLVM.xor e_1 (const? 32 (-1))) (LLVM.xor e (const? 32 (-1)))) (const? 32 (-1)) ⊑
    LLVM.or e_1 e

theorem ne_umin2_proof : ne_umin2_before ⊑ ne_umin2_after

theorem Predicate.evalEq_iff_not_evalNeq (a b : BitStream) :
    ∀ (w : Nat), evalEq a b w ↔ ¬ (evalNeq a b w)

theorem no_shift_xor_multiuse_cmp_thm (e e_1 e_2 e_3 : IntW 32) :
  mul (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2 (LLVM.or e_2 (const? 32 4096)))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul (LLVM.or e_2 (LLVM.xor (LLVM.and e_3 (const? 32 4096)) (const? 32 4096)))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

theorem t7_ugt_sgt_neg1_thm.extracted_1._15 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x_2) = 1#1 → ¬ofBool (65535#32 <ₛ x_2) = 1#1 → ofBool (x_2 <ₛ 0#32) = 1#1 → x_2 = x

theorem bools_logical_thm.extracted_1._18 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ^^^ 1#1 = 1#1 → ¬x_2 = 1#1 → ¬0#1 = 1#1 → 0#1 = x_1

theorem icmp_ne_sext_slt_allones_nofold_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.slt e (const? 32 (-1)))) e ⊑
    icmp IntPred.ne e (sext 32 (icmp IntPred.slt e (const? 32 (-1))))

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

theorem p0_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.and (LLVM.xor (shl (const? 8 (-1)) e_1) (const? 8 (-1))) e) e ⊑
    icmp IntPred.ne (lshr e e_1) (const? 8 0)

theorem lshr_lshr_pow2_const_negative_nopow2_1_thm (e : IntW 16) :
  LLVM.and (lshr (lshr (const? 16 2047) e) (const? 16 6)) (const? 16 4) ⊑
    LLVM.and (lshr (const? 16 31) e) (const? 16 4)

theorem alive_AddSub_1156  (w : Nat)   : alive_AddSub_1156_src w  ⊑ alive_AddSub_1156_tgt w

theorem ashr_lshr_exact_ashr_only_proof : ashr_lshr_exact_ashr_only_before ⊑ ashr_lshr_exact_ashr_only_after

theorem ashr_lshr_shift_amt_mismatch_proof : ashr_lshr_shift_amt_mismatch_before ⊑ ashr_lshr_shift_amt_mismatch_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 e_1595 :
     - 1 *  ~~~(a &&& ( ~~~b &&& c)) - 11 * (a &&& (b ||| c)) - 6 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) + 5 * b + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a &&& b) + 3 * (c ^^^ (a ||| b)) + 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 2 * (a ||| (b ||| c)) + 2 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 7 * (b &&& (a ||| c)) + 8 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~( ~~~a ||| (b ||| c)) - 3 * ( ~~~a &&& ( ~~~b &&& c)) + 7 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 15 * (a &&& (b &&& c)) =  - 13 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem icmp_select_var_pred_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) = 1#1 → ofBool (x_1 != 0#8) = 1#1 → False

theorem sext_multiuse_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ (zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8))).saddOverflow (BitVec.ofInt 7 (-8)) = true ∨
        (zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8)) + BitVec.ofInt 7 (-8) == 0 ||
              7 != 1 && zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8)) == intMin 7 &&
                zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8)) + BitVec.ofInt 7 (-8) == -1) =
            true ∨
          (x ^^^ BitVec.ofInt 4 (-8) == 0 ||
              4 != 1 &&
                  truncate 4
                      ((zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8))).sdiv
                        (zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8)) + BitVec.ofInt 7 (-8))) ==
                    intMin 4 &&
                x ^^^ BitVec.ofInt 4 (-8) == -1) =
            true) →
    (signExtend 7 x == 0 || 7 != 1 && zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8)) == intMin 7 && signExtend 7 x == -1) =
          true ∨
        (x ^^^ BitVec.ofInt 4 (-8) == 0 ||
            4 != 1 && truncate 4 ((zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8))).sdiv (signExtend 7 x)) == intMin 4 &&
              x ^^^ BitVec.ofInt 4 (-8) == -1) =
          true →
      False

theorem xor_sext_sext_proof : xor_sext_sext_before ⊑ xor_sext_sext_after

theorem negate_add_with_single_negatible_operand_thm.extracted_1._1 : ∀ (x : BitVec 8),
  0#8 - (x + 42#8) = BitVec.ofInt 8 (-42) - x

theorem test5_thm (e : IntW 1) : zext 32 (zext 8 e) ⊑ zext 32 e

theorem sge_or_max_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.sge e_1 e) (icmp IntPred.eq e_1 (const? 8 127)) ⊑ icmp IntPred.sge e_1 e

theorem or_ashr_not_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (ashr e_2 e_1) (LLVM.xor (ashr e e_1) (const? 8 (-1))) ⊑
    ashr (LLVM.or e_2 (LLVM.xor e (const? 8 (-1)))) e_1

theorem xor_andn_commute4_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x_1 = 0) →
    ¬(x_1 = 0 ∨ x = 0) → 42#32 / x_1 ^^^ 42#32 / x &&& (42#32 / x_1 ^^^ -1#32) = 42#32 / x_1 ||

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail0_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail0_after

theorem slt_swap_or_not_max_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.sgt e_1 e) (icmp IntPred.ne e (const? 8 127)) ⊑
    icmp IntPred.ne e (const? 8 127)

theorem or_ashr_not_proof : or_ashr_not_before ⊑ or_ashr_not_after

theorem e_240 :
    1 *  ~~~(x ^^^ y) - 1 *  ~~~(x &&&  ~~~x) + 1 * (x ||| y) + 5 * x + 3 *  ~~~(x ||| y) - 5 * (x &&&  ~~~y) - 6 * (x &&& y) = 3 *  ~~~x - 3 *  ~~~(x |||  ~~~y)

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

theorem trunc_signed_nsw_zext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(True ∧ signExtend 32 (truncate 16 x_1) ≠ x_1) →
    ofBool (truncate 16 x_1 <ₛ zeroExtend 16 x) = ofBool (x_1 <ₛ zeroExtend 32 x)

theorem icmp_eq_x_invertable_y2_todo_thm (e : IntW 8) (e_1 : IntW 1) :
  icmp IntPred.eq (select e_1 (const? 8 7) (const? 8 24)) (LLVM.and e (select e_1 (const? 8 7) (const? 8 24))) ⊑
    icmp IntPred.eq (LLVM.or e (select e_1 (const? 8 (-8)) (const? 8 (-25)))) (const? 8 (-1))

theorem PR28476_logical_proof : PR28476_logical_before ⊑ PR28476_logical_after

theorem e_835 :
     - 2 *  ~~~(z &&& t) - 1 * (z |||  ~~~t) - 1 * z + 2 *  ~~~(z |||  ~~~t) + 2 * (z &&& t) =  - 3 *  ~~~(z ||| t) - 4 * (z &&&  ~~~t)

theorem addhshlhsdivhscalar1_thm.extracted_1._1 : ∀ (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 → False

theorem or_xor_common_op_commute7_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor e_2 e_1) (LLVM.or e e_1) ⊑ LLVM.or (LLVM.or e e_1) e_2

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 12#32 ≥ ↑32) → ofBool (x <<< 12#32 >>> 12#32 != 0#32) = ofBool (x &&& 1048575#32 != 0#32)

theorem test55_thm (e : IntW 32) :
  sext 64 (LLVM.and (LLVM.or (trunc 16 e) (const? 16 (-32574))) (const? 16 (-25350))) ⊑
    sext 64 (LLVM.or (LLVM.and (trunc 16 e) (const? 16 7224)) (const? 16 (-32574)) { «disjoint» := true })

theorem sdiv_icmp5_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.sdiv e (const? 64 (-5)) { «exact» := true }) (const? 64 1) ⊑
    icmp IntPred.eq e (const? 64 (-5))

theorem logical_and_logical_and_icmps_comm2_proof : logical_and_logical_and_icmps_comm2_before ⊑ logical_and_logical_and_icmps_comm2_after

theorem test23_proof : test23_before ⊑ test23_after

theorem a_false_implies_b_false2_proof : a_false_implies_b_false2_before ⊑ a_false_implies_b_false2_after

theorem gt_signed_to_small_unsigned_proof : gt_signed_to_small_unsigned_before ⊑ gt_signed_to_small_unsigned_after

theorem sge_or_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.eq e_1 (const? 8 127)) (icmp IntPred.sge e_1 e) ⊑ icmp IntPred.sge e_1 e

theorem lshrult_01_01_exact_proof : lshrult_01_01_exact_before ⊑ lshrult_01_01_exact_after

theorem xor_of_icmps_to_ne_thm (e : IntW 64) :
  LLVM.xor (icmp IntPred.sgt e (const? 64 4)) (icmp IntPred.slt e (const? 64 6)) ⊑
    icmp IntPred.ne e (const? 64 5)

theorem srem_common_divisor_defined_cond_thm.extracted_1._1 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ (x_1 == 0 || 5 != 1 && x == intMin 5 && x_1 == -1) = true) → x_2 = 1#1 → False

theorem lowmask_add_zext_commute_thm (e : IntW 16) (e_1 : IntW 32) :
  LLVM.and (add (mul e_1 e_1) (zext 32 e)) (const? 32 65535) ⊑ zext 32 (add e (trunc 16 (mul e_1 e_1)))

theorem shl_add_add_proof : shl_add_add_before ⊑ shl_add_add_after

theorem test59_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(4#32 ≥ ↑32 ∨ 4#32 ≥ ↑32) →
    True ∧ (zeroExtend 32 x <<< 4#32).sshiftRight' 4#32 ≠ zeroExtend 32 x ∨
        True ∧ zeroExtend 32 x <<< 4#32 >>> 4#32 ≠ zeroExtend 32 x ∨
          4#32 ≥ ↑32 ∨
            4#8 ≥ ↑8 ∨
              True ∧ (x_1 >>> 4#8).msb = true ∨
                True ∧ (zeroExtend 32 x <<< 4#32 &&& 48#32 &&& zeroExtend 32 (x_1 >>> 4#8) != 0) = true ∨
                  True ∧ (zeroExtend 32 x <<< 4#32 &&& 48#32 ||| zeroExtend 32 (x_1 >>> 4#8)).msb = true →
      False

theorem lshr_ne_both_equal_proof : lshr_ne_both_equal_before ⊑ lshr_ne_both_equal_after

theorem sub_2_thm (e e_1 : IntW 8) (e_2 : IntW 1) (e_3 : IntW 8) :
  LLVM.xor (sub e_3 (select e_2 (LLVM.xor e_1 (const? 8 (-1))) (LLVM.xor e (const? 8 123)))) (const? 8 (-1)) ⊑
    sub (const? 8 (-2)) (add (select e_2 e_1 (LLVM.xor e (const? 8 (-124)))) e_3)

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_after

theorem udiv_illegal_type_thm.extracted_1._1 : ∀ (x x_1 : BitVec 9), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem signExtend_eq (x : BitVec w) : x.signExtend w = x  := sorry

--

theorem shl_or_lshr_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑32 ∨ x_1 ≥ ↑32) → x_1 ≥ ↑32 → False

theorem test4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) &&& ofBool (-1#32 <ₛ x) = ofBool (-1#32 <ₛ x_1 ||| x)

theorem main4_logical_proof : main4_logical_before ⊑ main4_logical_after

theorem and_logic_and_logic_or_4_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 &&& x_1 = 1#1 → x_1 = 1#1 → ¬x_2 = 1#1 → 1#1 = x

theorem t0_commutative_thm.extracted_1._11 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 x_3 : BitVec 8),
  ¬ofBool (x_3 == x_2) = 1#1 → ofBool (x_3 != x_2) = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → False

@[simp]
theorem Factor.reflect_zero_of_denote_zero {w : Nat} {f : Factor} {xs : Env w} (h : f.denote xs = 0) :
    f.reflect xs = 0#w

theorem test10_proof : test10_before ⊑ test10_after

theorem lsb_mask_sign_zext_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (x + -1#32 &&& (x ^^^ -1#32)) >>> 31#32 = zeroExtend 32 (ofBool (x == 0#32))

theorem substitute_constant_and_ne_ugt_swap_logical_proof : substitute_constant_and_ne_ugt_swap_logical_before ⊑ substitute_constant_and_ne_ugt_swap_logical_after

theorem in_constant_6_vary_invmask_proof : in_constant_6_vary_invmask_before ⊑ in_constant_6_vary_invmask_after

theorem shl_xor_xor_no_const_thm (e e_1 e_2 e_3 : IntW 8) :
  LLVM.xor (shl e_3 e_2) (LLVM.xor (shl e_1 e_2) e) ⊑ LLVM.xor (shl (LLVM.xor e_1 e_3) e_2) e

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

theorem trunc_lshr_thm (e : IntW 8) :
  LLVM.and (trunc 6 (lshr e (const? 8 2))) (const? 6 14) ⊑
    LLVM.and (lshr (trunc 6 e) (const? 6 2)) (const? 6 14)

theorem icmp_ne_sext_ne_otherwise_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x != 2#32)) != x) = ofBool (x != -1#32)

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x ≤ₛ 126#8) = ofBool (x != 127#8)

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 pr51551_demand3bits_thm (e e_1 : IntW 32) :
  LLVM.and (mul (LLVM.or (LLVM.and e_1 (const? 32 (-7))) (const? 32 1)) e { «nsw» := true, «nuw» := false })
      (const? 32 7) ⊑
    LLVM.and e (const? 32 7)

theorem masked_or_allzeroes_notoptimised_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.eq (LLVM.and e (const? 32 39)) (const? 32 0)) ⊑
    LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 0))
      (icmp IntPred.eq (LLVM.and e (const? 32 39)) (const? 32 0))

theorem splat_mul_unknown_lz_proof : splat_mul_unknown_lz_before ⊑ splat_mul_unknown_lz_after

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

theorem test29_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 10#32 ^^^ 123#32 = 113#32

theorem foo1_and_signbit_lshr_without_shifting_signbit_proof : foo1_and_signbit_lshr_without_shifting_signbit_before ⊑ foo1_and_signbit_lshr_without_shifting_signbit_after

theorem main7g_logical_proof : main7g_logical_before ⊑ main7g_logical_after

theorem trunc_shl_shl_infloop_proof : trunc_shl_shl_infloop_before ⊑ trunc_shl_shl_infloop_after

theorem reassoc_x2_mul_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.umulOverflow 5#32 = true ∨
        True ∧ x.umulOverflow 9#32 = true ∨ True ∧ (x_1 * 5#32).umulOverflow (x * 9#32) = true) →
    True ∧ (x_1 * x).umulOverflow 45#32 = true → False

theorem src_is_mask_const_sle_thm (e : IntW 8) :
  icmp IntPred.sle (LLVM.and (LLVM.xor e (const? 8 123)) (const? 8 31)) (LLVM.xor e (const? 8 123)) ⊑
    icmp IntPred.sgt e (const? 8 (-1))

theorem e_2194 :
     - 3 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 11 * (f ^^^ (d ||| (e &&& f))) + 3 * (d &&& ( ~~~e ||| f)) + 2 * (d ^^^ (e &&& f)) - 11 *  ~~~(d |||  ~~~e) - 2 * ((d &&& e) ||| (e ^^^ f)) - 5 * (e ^^^ (d &&& (e ||| f))) - 1 * ( ~~~e ||| (d ^^^ f)) + 2 * (e &&&  ~~~(d &&& f)) - 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 5 * (d ||| e) - 2 * d + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) + 3 * e - 1 * (e |||  ~~~(d |||  ~~~f)) + 1 * (e ||| (d &&&  ~~~f)) - 7 * (e ^^^  ~~~(d &&&  ~~~f)) - 11 * (f ^^^ (d ||| e)) - 7 * ( ~~~d &&& ( ~~~e ||| f)) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 3 * (f ^^^ (d &&& e)) - 2 * (f &&& (d ^^^ e)) + 11 * (e ^^^ (d &&& f)) - 1 * f - 6 * (e ^^^ (d ||| (e &&& f))) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 *  ~~~(d &&&  ~~~e) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) + 2 * (e |||  ~~~(d ||| f)) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 7 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 *  ~~~(d ^^^ (e ||| f)) + 1 *  ~~~(e ^^^ f) + 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 11 * (e &&&  ~~~(d ^^^ f)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (d ^^^ ( ~~~e ||| f)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (f ^^^  ~~~(d ||| (e &&& f))) + 13 *  ~~~(d ||| (e ||| f)) + 34 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) - 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 30 * ( ~~~d &&& ( ~~~e &&& f)) + 3 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) = 2 *  ~~~(d ^^^ ( ~~~e &&& f)) + 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f)))

theorem and_orn_cmp_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32),
  ofBool (x_1 <ₛ x_2) = 1#1 → x = 1#1 → 1#1 = x

theorem eq_iff_coeff_eq [hqgt1 : Fact (q > 1)] (a b : R q n) :
    a = b ↔ Polynomial.coeff a.representative = Polynomial.coeff b.representative

theorem not_or_or_and_no_and_commute1_proof : not_or_or_and_no_and_commute1_before ⊑ not_or_or_and_no_and_commute1_after

theorem bools_multi_uses2_logical_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → x = 1#1 → ¬True → 0#1 + 0#1 = 0#1 ^^^ 0#1

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 shl_add_log_may_cause_poison_pr62175_with_nuw_proof : shl_add_log_may_cause_poison_pr62175_with_nuw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nuw_after

theorem invert_both_cmp_operands_sub_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool ((x_1 ^^^ -1#32) - x <ᵤ 42#32) = ofBool (BitVec.ofInt 32 (-43) <ᵤ x_1 + x)

theorem positive_biggershl_shlnsw_lshrexact_proof : positive_biggershl_shlnsw_lshrexact_before ⊑ positive_biggershl_shlnsw_lshrexact_after

theorem shl_xor_xor_good_mask_proof : shl_xor_xor_good_mask_before ⊑ shl_xor_xor_good_mask_after

theorem bv_AndOrXor_2486 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.xor (LLVM.add e e_1) (LLVM.const? w (-1)) ⊑ LLVM.sub (LLVM.sub (LLVM.const? w (-1)) e_1) e

theorem fold_select_trunc_nsw_false_proof : fold_select_trunc_nsw_false_before ⊑ fold_select_trunc_nsw_false_after

@[simp]
theorem mkIndHypCircuitNoCycleBreaking_eval_eq_false_iff
    {circs : KInductionCircuits fsm n}
    (env : Vars fsm.α arity (n + 2) → Bool) :
    ((mkIndHypCircuitNoCycleBreaking circs).eval env = false) ↔
    ((mkSuccCarryAndOutsAssignPrecond circs).eval env = false → (mkPostcondIndHypNoCycleBreaking circs).eval env = false)

theorem sub_shl_same_amount_partial_nsw2_proof : sub_shl_same_amount_partial_nsw2_before ⊑ sub_shl_same_amount_partial_nsw2_after

theorem test15_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(27#32 ≥ ↑32 ∨ 31#32 ≥ ↑32) → signExtend 32 (ofBool (x &&& 16#32 != 0#32)) = (x <<< 27#32).sshiftRight' 31#32

theorem sle_and_min_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sle e_1 e) (icmp IntPred.eq e_1 (const? 8 (-128))) (const? 1 0) ⊑
    icmp IntPred.eq e_1 (const? 8 (-128))

theorem ashrsgt_03_12_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 3) { «exact» := true }) (const? 4 (-4)) ⊑ const? 1 1

theorem fold_sext_to_and_wrong2_proof : fold_sext_to_and_wrong2_before ⊑ fold_sext_to_and_wrong2_after

theorem test12_proof : test12_before ⊑ test12_after

theorem select_xor_icmp_bad_3_proof : select_xor_icmp_bad_3_before ⊑ select_xor_icmp_bad_3_after

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

theorem shift_no_xor_multiuse_cmp_with_xor_proof : shift_no_xor_multiuse_cmp_with_xor_before ⊑ shift_no_xor_multiuse_cmp_with_xor_after

theorem uge_swap_and_max_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == -1#8) &&& ofBool (x ≤ᵤ x_1) = ofBool (x_1 == -1#8)

theorem trunc_shl_33_i32_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬33#64 ≥ ↑64 → truncate 32 (x <<< 33#64) = 0#32

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (0#8).ssubOverflow x = true) → ofBool (x <ₛ 0#8 - x) = ofBool (x <ₛ 0#8)

theorem ashrsgt_01_05_proof : ashrsgt_01_05_before ⊑ ashrsgt_01_05_after

theorem test4_thm (e : IntW 49) : add (LLVM.and e (const? 49 (-2))) (const? 49 1) ⊑ LLVM.or e (const? 49 1)

theorem test2_proof : test2_before ⊑ test2_after

theorem or_xor_common_op_commute0_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.or e_2 e_1) (LLVM.xor e_2 e) ⊑ LLVM.or (LLVM.or e_2 e_1) e

theorem or_and_or_pat7_proof : or_and_or_pat7_before ⊑ or_and_or_pat7_after

theorem same_signbit_wrong_type_signed_thm (e : IntW 32) (e_1 : IntW 8) :
  icmp IntPred.ne (ashr e_1 (const? 8 7)) (sext 8 (icmp IntPred.sgt e (const? 32 (-1)))) ⊑
    LLVM.xor (icmp IntPred.slt e_1 (const? 8 0)) (icmp IntPred.sgt e (const? 32 (-1)))

theorem test8_proof : test8_before ⊑ test8_after

theorem neg_test_icmp_non_equality_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 <ₛ 0#32) = 1#1 → ¬2#32 ≥ ↑32 → 0#32 = x <<< 2#32

theorem trunc_sel_smaller_sext_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 32 42#16 = 42#32

theorem test44_thm.extracted_1._1 : ∀ (x : BitVec 8), True ∧ (zeroExtend 16 x ||| 1234#16).msb = true → False

theorem test3i_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(29#32 ≥ ↑32 ∨ 29#32 ≥ ↑32) →
    zeroExtend 32 (ofBool (x_1 >>> 29#32 ||| 35#32 == x >>> 29#32 ||| 35#32)) =
      zeroExtend 32 (ofBool (-1#32 <ₛ x_1 ^^^ x))

theorem lshrugt_03_12_exact_proof : lshrugt_03_12_exact_before ⊑ lshrugt_03_12_exact_after

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem exact_ashr_ne_proof : exact_ashr_ne_before ⊑ exact_ashr_ne_after

theorem test10_proof : test10_before ⊑ test10_after

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

theorem masked_bit_set_nonzero_cmp_proof : masked_bit_set_nonzero_cmp_before ⊑ masked_bit_set_nonzero_cmp_after

theorem shl_lshr_demand4_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ 3#8 ≥ ↑8) → x ≥ ↑8 ∨ 3#8 ≥ ↑8 ∨ True ∧ (44#8 <<< x >>> 3#8 &&& BitVec.ofInt 8 (-32) != 0) = true → False

theorem scalar_i32_shl_and_signbit_eq_X_is_constant2_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 31)

theorem test3_proof : test3_before ⊑ test3_after

theorem ule_swap_or_not_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x ≤ᵤ x_1) = 1#1 → ofBool (x != 0#8) = 1#1

theorem main6_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 3))
        (icmp IntPred.eq (LLVM.and e (const? 32 48)) (const? 32 16)) (const? 1 0))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 55)) (const? 32 19))

theorem reassoc_x2_add_nuw_thm (e e_1 : IntW 32) :
  add (add e_1 (const? 32 4) { «nsw» := false, «nuw» := true }) (add e (const? 32 8) { «nsw» := false, «nuw» := true })
      { «nsw» := false, «nuw» := true } ⊑
    add (add e_1 e { «nsw» := false, «nuw» := true }) (const? 32 12) { «nsw» := false, «nuw» := true }

theorem n9_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    62#64 ≥ ↑64 ∨
        True ∧ signExtend 64 (truncate 32 (x >>> 62#64)) ≠ x >>> 62#64 ∨
          True ∧ zeroExtend 64 (truncate 32 (x >>> 62#64)) ≠ x >>> 62#64 ∨
            True ∧ (0#32).ssubOverflow (truncate 32 (x >>> 62#64)) = true →
      False

theorem lor_land_right2_proof : lor_land_right2_before ⊑ lor_land_right2_after

theorem e_1832 :
    1 * (c ^^^ ( ~~~a ||| (b ||| c))) - 6 *  ~~~(a |||  ~~~c) + 4 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 3 *  ~~~c + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) + 7 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) + 7 * ((a |||  ~~~b) &&& (b ^^^ c)) - 11 *  ~~~(a ^^^ ( ~~~b ||| c)) - 7 * ( ~~~a &&& (b ||| c)) + 11 * (b &&&  ~~~c) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 4 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 11 *  ~~~(a ||| b) - 11 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 7 * (c ^^^  ~~~(a |||  ~~~b)) + 4 * (c ||| (a &&& b)) - 1 * ((a ^^^ b) ||| (a ^^^ c)) - 2 * (c ^^^ (a &&&  ~~~b)) + 2 *  ~~~(a ||| c) - 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 7 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 3 *  ~~~(a ^^^ b) + 11 * (c &&& (a ||| b)) - 5 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 4 * (c ^^^ ( ~~~a ||| (b &&& c))) - 5 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~( ~~~a &&& (b &&& c)) - 7 * (b ^^^ (a &&& (b ^^^ c))) + 7 * (b |||  ~~~(a ||| c)) - 3 * ( ~~~c &&& (a ^^^ b)) - 7 *  ~~~(b ^^^ c) - 6 *  ~~~(a ||| (b ||| c)) + 4 *  ~~~(a ||| ( ~~~b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) - 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 7 * ( ~~~a &&& ( ~~~b &&& c)) + 4 * (a &&& ( ~~~b &&& c)) + 4 * (a &&& (b &&& c)) = 1 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c)))

theorem trunc_lshr_big_mask_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬2#8 ≥ ↑8 → 2#8 ≥ ↑8 ∨ True ∧ zeroExtend 8 (truncate 6 (x >>> 2#8)) ≠ x >>> 2#8 → False

theorem slt_to_ugt_proof : slt_to_ugt_before ⊑ slt_to_ugt_after

theorem main7a_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 == x_2) &&& ofBool (x &&& x_1 == x) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x_1 &&& (x_2 ||| x) != x_2 ||| x))

theorem test_shl_nuw_nsw__none_are_safe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    ¬(True ∧ ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& BitVec.ofInt 32 (-2) ∨
          True ∧ (x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32 >>> 2#32 ≠ x_1 &&& BitVec.ofInt 32 (-2) ∨
            2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 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 →
        False

theorem icmp_eq_mul_nsw_nonequal_commuted_proof : icmp_eq_mul_nsw_nonequal_commuted_before ⊑ icmp_eq_mul_nsw_nonequal_commuted_after

theorem e_793 :
     - 7 *  ~~~(z &&&  ~~~t) - 5 *  ~~~(z &&& t) + 5 *  ~~~(z ||| t) + 12 *  ~~~(z |||  ~~~t) + 5 * (z &&&  ~~~t) =  - 7 *  ~~~(z ^^^ t)

theorem bitwise_or_bitwise_or_icmps_comm1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(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 == 0#8) ||

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 or_xor_common_op_commute7_proof : or_xor_common_op_commute7_before ⊑ or_xor_common_op_commute7_after

theorem main5e_like_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_2 &&& x == x_2) = 1#1 → 1#32 = zeroExtend 32 1#1

theorem basic_com_add_thm (e e_1 : IntW 8) :
  LLVM.xor (add e_1 (LLVM.xor e (const? 8 (-1)))) (const? 8 (-1)) ⊑ sub e e_1

theorem ashr_sgt_exact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8) → ofBool (10#8 <ₛ x.sshiftRight' 3#8) = ofBool (80#8 <ₛ x)

@[simp] theorem eval_trueUptoExcluding (n : Nat) {env : Fin 0 → BitStream} :
    (trueUptoExcluding n).eval env = fun i => decide (i < n)

theorem zext_sext_sgt_known_nonneg_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (zext 32 (LLVM.udiv (const? 8 127) e_1)) (sext 32 e) ⊑
    icmp IntPred.sgt (LLVM.udiv (const? 8 127) e_1) e

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

theorem trunc_sandwich_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(28#32 ≥ ↑32 ∨ 2#12 ≥ ↑12) →
    ¬(30#32 ≥ ↑32 ∨
          True ∧ signExtend 32 (truncate 12 (x >>> 30#32)) ≠ x >>> 30#32 ∨
            True ∧ zeroExtend 32 (truncate 12 (x >>> 30#32)) ≠ x >>> 30#32) →
      truncate 12 (x >>> 28#32) >>> 2#12 = truncate 12 (x >>> 30#32)

theorem e_1649 :
     - 1 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) + 1 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 2 * c + 2 * (a &&& b) + 1 * (a ||| ( ~~~b ||| c)) + 7 * (a ^^^ ( ~~~b ||| c)) + 2 * (c ||| (a &&& b)) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * (a ^^^ (b &&& c)) - 3 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 6 * ( ~~~b ||| (a ^^^ c)) + 2 * b + 11 * (a ^^^ (b ||| c)) - 2 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 *  ~~~(a &&& (b ^^^ c)) + 11 *  ~~~(a ||| (b ||| c)) - 12 *  ~~~(a ||| ( ~~~b ||| c)) + 6 *  ~~~( ~~~a ||| (b ||| c)) - 13 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 8 * ( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) =  - 4 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 * (a &&& (b &&& c))

theorem t0_ult_slt_65536_proof : t0_ult_slt_65536_before ⊑ t0_ult_slt_65536_after

theorem and_not_or_or_not_or_xor_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ((x_2 ||| x_1) ^^^ -1#32) &&& x ||

theorem PR42691_9_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 13)) (icmp IntPred.ne e (const? 32 2147483647)) ⊑
    icmp IntPred.ult (add e (const? 32 (-14))) (const? 32 2147483633)

theorem main11_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) ||

theorem land_lor_left1_proof : land_lor_left1_before ⊑ land_lor_left1_after

theorem e_1421 :
    3 *  ~~~z + 2 * (z ^^^ t) + 1 * z + 7 *  ~~~(z &&& t) + 1 *  ~~~t + 1 *  ~~~(z ^^^ t) - 5 *  ~~~(z ||| t) - 13 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) + 4 * (z &&& t) = 7 * (z |||  ~~~t) - 1 * t

theorem ult_192_proof : ult_192_before ⊑ ult_192_after

theorem f2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ₛ 0#32) = 1#1 →
    ¬x ≥ ↑32 → zeroExtend 32 (ofBool ((7#32).sshiftRight' x <ₛ x_1)) = zeroExtend 32 (ofBool (7#32 >>> x <ₛ x_1))

theorem lshrult_02_04_exact_proof : lshrult_02_04_exact_before ⊑ lshrult_02_04_exact_after

theorem ult_umin3_thm (e e_1 : IntW 32) :
  icmp IntPred.ugt (add e_1 (const? 32 3))
      (select (icmp IntPred.ult (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.ult e (add e_1 (const? 32 3))

theorem PR42691_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ₛ 0#32) = 1#1 → 1#1 = ofBool (2147483646#32 <ᵤ 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 udiv400_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2#32 ≥ ↑32 ∨ 100#32 = 0) → ¬400#32 = 0 → x >>> 2#32 / 100#32 = x / 400#32

theorem slt_smin1_proof : slt_smin1_before ⊑ slt_smin1_after

theorem lshr_not_nneg2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8 &&& BitVec.ofInt 8 (-128) != 0) = true → False

theorem not_or_or_and_not_and_and_commute1_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (LLVM.or (LLVM.or (LLVM.xor e_2 (const? 32 (-1))) e_1) e)
      (LLVM.xor (LLVM.and (LLVM.and e_2 e_1) e) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.xor e e_1) (LLVM.xor e_2 (const? 32 (-1)))

theorem positive_biggershl_shlnuwnsw_lshrexact_proof : positive_biggershl_shlnuwnsw_lshrexact_before ⊑ positive_biggershl_shlnuwnsw_lshrexact_after

theorem negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_thm (e : IntW 8) :
  icmp IntPred.eq (ashr e (const? 8 1) { «exact» := true }) (const? 8 5) ⊑
    icmp IntPred.eq e (const? 8 10)

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬1#64 ≥ ↑64 → ofBool (0#64 <ᵤ x >>> 1#64) = ofBool (1#64 <ᵤ x)

theorem and_min_7_7_proof : and_min_7_7_before ⊑ and_min_7_7_after

theorem e_224 :
    5 * (x |||  ~~~y) + 7 *  ~~~(x ^^^ y) - 5 * x - 17 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) - 12 * (x &&& y) =  - 5 *  ~~~(x &&&  ~~~x)

theorem ripple_nsw4_proof : ripple_nsw4_before ⊑ ripple_nsw4_after

theorem t4_ugt_slt_128_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (143#32 <ᵤ x + 16#32) = 1#1 →
    ofBool (127#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → False

theorem n4_thm (e : IntW 16) :
  LLVM.and (shl (zext 32 e) (const? 32 16)) (const? 32 (-1073741824)) ⊑
    LLVM.and (shl (zext 32 e) (const? 32 16) { «nsw» := false, «nuw» := true }) (const? 32 (-1073741824))

theorem test8_thm (e : IntW 999) : LLVM.and e (const? 999 0) ⊑ const? 999 0

theorem sel_false_val_is_a_masked_shl_of_true_val1_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 15#32 == 0#32) = 1#1 →
    ¬(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 ∨ zeroExtend 64 ((x_1 &&& 15#32) <<< 2#32) ≥ ↑64) →
      2#32 ≥ ↑32 ∨ True ∧ (x_1 <<< 2#32 &&& 60#32).msb = true ∨ zeroExtend 64 (x_1 <<< 2#32 &&& 60#32) ≥ ↑64 → False

theorem shl_add_and_fail_mismatch_shift_proof : shl_add_and_fail_mismatch_shift_before ⊑ shl_add_and_fail_mismatch_shift_after

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

theorem eval_bigOr_eq_decide
    (cs : List (Circuit α)) (env : α → Bool):
    (Circuit.bigOr cs).eval env = decide (∃ c ∈ cs, c.eval env = true)

theorem sgt_positive_multip_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 5#8 = true) → ofBool (21#8 <ₛ x * 5#8) = ofBool (4#8 <ₛ x)

theorem neg_or_ashr_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (0#32 - x ||| x).sshiftRight' 31#32 = signExtend 32 (ofBool (x != 0#32))

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

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

theorem scalar_i32_shl_and_signbit_eq_nonzero_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 32 (-2147483648))) (const? 32 1) ⊑ const? 1 0

theorem xor_logic_and_logic_or4_proof : xor_logic_and_logic_or4_before ⊑ xor_logic_and_logic_or4_after

theorem mul_two :
  (bw r (mulMax (bw p a) (bw 2 (2#2))))  =
  (bw r ((bw p a) <<< 1))

theorem ne_rem_zero_nonuw_proof : ne_rem_zero_nonuw_before ⊑ ne_rem_zero_nonuw_after

theorem main8_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 != 0#32) = 1#1 →
    ofBool (x &&& 192#32 == 0#32) = 1#1 → ofBool (truncate 8 x <ₛ 0#8) = 1#1 → 2#32 = 1#32

theorem test2_proof : test2_before ⊑ test2_after

theorem and1_lshr1_is_cmp_eq_0_multiuse_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    x ≥ ↑8 ∨
        True ∧ (1#8 >>> x <<< 1#8).sshiftRight' 1#8 ≠ 1#8 >>> x ∨
          True ∧ 1#8 >>> x <<< 1#8 >>> 1#8 ≠ 1#8 >>> x ∨ 1#8 ≥ ↑8 →
      False

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 → True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64 → False

theorem e_526 :
    1 *  ~~~(x ^^^ y) - 1 * y + 11 *  ~~~(x &&&  ~~~y) + 11 *  ~~~(x &&& y) + 2 *  ~~~y - 25 *  ~~~(x ||| y) - 23 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) - 6 * (x &&& y) =  - 2 * (x ||| y) + 7 * x

theorem ashr_ult_15_proof : ashr_ult_15_before ⊑ ashr_ult_15_after

theorem and_logic_and_logic_or_5_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬0#1 = 1#1 → x_2 &&& x = 0#1

theorem bad_add1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ (1#32 <<< x).uaddOverflow 1#32 = true → False

theorem icmp_sgt9_proof : icmp_sgt9_before ⊑ icmp_sgt9_after

theorem fake_sext_thm (e : IntW 3) :
  lshr (sext 18 e) (const? 18 17) ⊑ zext 18 (lshr e (const? 3 2)) { «nneg» := true }

theorem ripple_nsw5_thm (e e_1 : IntW 16) :
  add (LLVM.or e_1 (const? 16 (-21845))) (LLVM.or e (const? 16 (-10923))) ⊑
    add (LLVM.or e_1 (const? 16 (-21845))) (LLVM.or e (const? 16 (-10923))) { «nsw» := true, «nuw» := false }

theorem uge_or_not_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x ≤ᵤ x_1) ||

theorem negative_not_power_of_two_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#32 <ₛ x) = 1#1 → ofBool (x + 255#32 <ᵤ 256#32) = ofBool (x == 0#32)

theorem e_2311 :
    1 *  ~~~(d &&& e) - 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| (e ||| f)) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * (f &&& (d ||| e)) - 6 * (d ^^^ e) + 4 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 2 * ( ~~~e &&& (d ^^^ f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (e &&&  ~~~(d &&& f)) - 1 *  ~~~(d ^^^ (e ||| f)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) + 11 * (d &&& (e ||| f)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 3 * ( ~~~e ||| (d ^^^ f)) - 7 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 *  ~~~(e &&&  ~~~f) + 1 * (e &&& f) + 7 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 7 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 1 * d - 2 *  ~~~( ~~~d &&& (e &&& f)) - 1 * (d ^^^ (e ||| f)) + 4 * (d ^^^ f) - 2 * (f ^^^ (d ||| (e &&& f))) + 5 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (e ||| (d &&& f)) - 6 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * (f ^^^ (d &&&  ~~~e)) - 11 * (e &&& (d ^^^ f)) - 1 * e - 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 2 * (f ^^^ (d |||  ~~~e)) - 2 * ( ~~~d ||| ( ~~~e ||| f)) + 5 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * ( ~~~d &&& ( ~~~e ||| f)) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * (f |||  ~~~(d ^^^ e)) - 1 * (d ||| ( ~~~e ||| f)) + 3 * ((d &&& f) ||| (e &&&  ~~~f)) + 11 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 3 *  ~~~(d &&& f) - 11 * (e ^^^ ( ~~~d ||| (e ||| f))) - 2 *  ~~~(d |||  ~~~f) + 1 *  ~~~(d &&& (e ^^^ f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 6 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * (e ^^^ (d &&& f)) + 23 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 34 *  ~~~( ~~~d ||| (e ||| f)) + 3 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e &&& f)) + 11 * ( ~~~d &&& (e &&& f)) + 3 * (d &&& ( ~~~e &&& f)) + 1 * (d &&& (e &&& f)) = 6 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 11 * ((d &&& e) ^^^ (e |||  ~~~f))

theorem or_and_or_pat6_proof : or_and_or_pat6_before ⊑ or_and_or_pat6_after

theorem and_xor_or6_proof : and_xor_or6_before ⊑ and_xor_or6_after

theorem scalar_i32_shl_and_negC_eq_X_is_constant1_proof : scalar_i32_shl_and_negC_eq_X_is_constant1_before ⊑ scalar_i32_shl_and_negC_eq_X_is_constant1_after

theorem i_proof : i_before ⊑ i_after

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

theorem or_and3_commuted_thm (e e_1 : IntW 1) (e_2 e_3 : IntW 32) :
  select (LLVM.or (icmp IntPred.eq e_3 e_2) e_1) e_1 e ⊑
    select e_1 (const? 1 1) (select (icmp IntPred.ne e_3 e_2) e (const? 1 0))

theorem lshrugt_01_03_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 1#4 <<< 1#4 ≠ x ∨ 1#4 ≥ ↑4) → ofBool (3#4 <ᵤ x >>> 1#4) = ofBool (6#4 <ᵤ x)

theorem test_sext_zext_proof : test_sext_zext_before ⊑ test_sext_zext_after

theorem exactly_one_set_signbit_proof : exactly_one_set_signbit_before ⊑ exactly_one_set_signbit_after

theorem e_2412 :
     - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d ^^^ e) &&& (d ^^^ f)) + 11 * (f ^^^ (d ||| ( ~~~e &&& f))) - 3 *  ~~~(d ^^^ (e &&& f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 3 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 * (e |||  ~~~(d ||| f)) + 1 * (f ^^^  ~~~(d |||  ~~~e)) - 1 *  ~~~(d ^^^ (e ||| f)) + 4 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * (d ||| ( ~~~e &&& f)) + 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d ||| e)) + 7 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * (d &&& f) + 2 *  ~~~(d &&& ( ~~~e &&& f)) - 1 *  ~~~(d &&& ( ~~~e ||| f)) - 2 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 * (f |||  ~~~(d ||| e)) - 6 * (d ^^^ ( ~~~e &&& f)) - 11 * (f ^^^ (d ||| (e ||| f))) + 2 * (e ^^^  ~~~(d &&& (e ||| f))) + 3 *  ~~~(d &&& (e &&& f)) + 1 *  ~~~(d |||  ~~~e) + 1 * (d ||| e) + 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 7 *  ~~~(e &&& f) + 3 * (d |||  ~~~f) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 11 * (e &&&  ~~~f) - 5 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (e |||  ~~~(d |||  ~~~f)) - 7 * (e ^^^ (d ||| (e ||| f))) + 1 *  ~~~(d &&& f) - 7 * (e &&& (d ||| f)) - 1 * (f ^^^ (d ||| e)) - 1 * (e &&&  ~~~(d &&&  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 *  ~~~( ~~~d &&& (e ||| f)) - 5 * (e ^^^ (d &&& (e ||| f))) - 5 * ( ~~~d ||| (e ||| f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 2 * (f |||  ~~~(d |||  ~~~e)) - 1 * (e &&&  ~~~(d ^^^ f)) + 1 * (f ^^^ (d |||  ~~~e)) + 2 * ((d &&& f) |||  ~~~(e ||| f)) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 2 * (e &&& (d ^^^ f)) - 11 * (e ^^^ ( ~~~d ||| (e &&& f))) + 3 * (d &&& ( ~~~e ||| f)) - 7 * (d ||| (e &&& f)) - 6 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 6 *  ~~~(e &&&  ~~~f) - 2 * (d &&& (e ||| f)) + 5 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 4 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~(d ||| ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ||| f)) - 13 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 5 * ( ~~~d &&& ( ~~~e &&& f)) - 16 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) =  - 4 *  ~~~(e ||| f) - 7 * ((d &&& e) |||  ~~~(e ^^^ f))

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 simplify_and_common_op_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  ((x_2 ||| x_1 ||| x) ^^^ -1#4) &&& x_1 = 0#4

theorem wide_source_matching_signbits_proof : wide_source_matching_signbits_before ⊑ wide_source_matching_signbits_after

theorem sext_multi_uses_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 1) (x_2 : BitVec 64),
  ¬x_1 = 1#1 → x_2 * signExtend 64 x_1 + ((x ^^^ signExtend 64 x_1) - signExtend 64 x_1) = x

theorem zext_sext_sgt_known_nonneg_proof : zext_sext_sgt_known_nonneg_before ⊑ zext_sext_sgt_known_nonneg_after

theorem xor_sge_thm (e e_1 : IntW 8) :
  icmp IntPred.sge (mul e_1 e_1) (LLVM.xor (LLVM.or e (const? 8 (-128))) (mul e_1 e_1)) ⊑
    icmp IntPred.slt (LLVM.xor (LLVM.or e (const? 8 (-128))) (mul e_1 e_1)) (mul e_1 e_1)

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 t4_const_after_fold_lshr_shl_ne_proof : t4_const_after_fold_lshr_shl_ne_before ⊑ t4_const_after_fold_lshr_shl_ne_after

theorem testi64i32_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(31#32 ≥ ↑32 ∨ 32#64 ≥ ↑64) →
    ofBool ((truncate 32 x).sshiftRight' 31#32 == truncate 32 (x >>> 32#64)) =
      ofBool (x + 2147483648#64 <ᵤ 4294967296#64)

theorem test_eq_0_and_15_add_1_thm (e : IntW 8) :
  icmp IntPred.eq (LLVM.and (add e (const? 8 1)) (const? 8 15)) (const? 8 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 8 15)) (const? 8 15)

theorem ugt_rem_zero_proof : ugt_rem_zero_before ⊑ ugt_rem_zero_after

theorem tryFactorization_xor_ashr_ashr_thm (e : IntW 32) :
  LLVM.xor (ashr (const? 32 (-3)) e) (ashr (const? 32 (-5)) e) ⊑ lshr (const? 32 6) e

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

theorem positive_samevar_proof : positive_samevar_before ⊑ positive_samevar_after

theorem tryFactorization_xor_lshr_ashr_thm (e : IntW 32) :
  LLVM.xor (lshr (const? 32 5) e) (ashr (const? 32 (-3)) e) ⊑ ashr (const? 32 (-8)) e

@[simp]
theorem Expr.op_mk {Γ : Ctxt d.Ty} {ty} {eff : EffectKind} (op : d.Op)
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op))
    (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).op = op

theorem allOnes_sub_eq_xor (x :BitVec w) : (allOnes w) - x = x ^^^ (allOnes w)

theorem and_nosignbit_lshr_proof : and_nosignbit_lshr_before ⊑ and_nosignbit_lshr_after

theorem eq_umax1_proof : eq_umax1_before ⊑ eq_umax1_after

@[simp]
lemma step_cast {M : NFA α σ} (h : σ = ς) (q q' : σ): (h ▸ q') ∈ (h ▸ M).step (h ▸ q) a ↔ q' ∈  M.step q a

theorem sge_or_not_max_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.sge e_1 e) (icmp IntPred.ne e_1 (const? 8 127)) ⊑ const? 1 1

@[simp] lemma eval_or (x : Bool → BitStream) : or.eval x = (x true) ||

theorem e_1126 :
     - 3 *  ~~~z - 2 *  ~~~(z &&& t) + 2 * (z ^^^ t) + 3 * (z |||  ~~~t) + 2 *  ~~~(z ||| t) - 2 *  ~~~(z |||  ~~~t) - 8 * (z &&&  ~~~t) - 8 * (z &&& t) =  - 5 * (z ||| t)

theorem e_2042 :
     - 7 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~( ~~~d &&& (e ||| f)) + 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 11 * (e ||| (d &&&  ~~~f)) + 3 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 *  ~~~(d ||| (e ^^^ f)) + 3 *  ~~~f - 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 1 * (e &&& f) - 11 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 7 * ( ~~~d &&& (e ||| f)) + 1 * (f &&& (d ^^^ e)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 3 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 3 * ( ~~~d &&& ( ~~~e ||| f)) + 2 * (d ^^^ f) + 11 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 5 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * (d ||| f) + 7 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 3 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 2 *  ~~~(d &&& f) + 4 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * (d &&& (e ^^^ f)) - 4 *  ~~~(d ||| (e ||| f)) + 19 *  ~~~(d ||| ( ~~~e ||| f)) + 29 *  ~~~( ~~~d ||| (e ||| f)) + 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 8 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) + 9 * (d &&& (e &&& f)) = 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f)))

theorem e_790 :
     - 1 * (z ||| t) - 7 *  ~~~(z ^^^ t) + 4 *  ~~~(z ||| t) - 2 * (z &&&  ~~~t) + 8 * (z &&& t) =  - 1 *  ~~~(z |||  ~~~t) - 3 *  ~~~t

theorem not_lt_is_geq {a b: Nat} (NOT_LT: ¬ (a < b)): a >= b

theorem t0_proof : t0_before ⊑ t0_after

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

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → 46#599 ≥ ↑599 → False

theorem and_or_not_not_commute7_proof : and_or_not_not_commute7_before ⊑ and_or_not_not_commute7_after

theorem eq_smax3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ₛ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 == x_1 + 3#32) = ofBool (x ≤ₛ x_1 + 3#32)

theorem ashr_ne_both_equal_proof : ashr_ne_both_equal_before ⊑ ashr_ne_both_equal_after

theorem a_false_implies_b_false2_comm_proof : a_false_implies_b_false2_comm_before ⊑ a_false_implies_b_false2_comm_after

theorem or_def {α : Type _} (c d : Circuit α) :
  (c ||| d) = Circuit.simplifyOr c d

theorem f_var1_commutative_and_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == 0#32) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& (x_1 ||| 1#32) != 0#32))

theorem main3f_like_logical_thm.extracted_1._11 : ∀ (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 → 0#32 = zeroExtend 32 0#1

theorem main7c_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_2 &&& x_1) &&& ofBool (x * 42#32 == x * 42#32 &&& x_1) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x_1 &&& (x_2 ||| x * 42#32) != x_2 ||| x * 42#32))

theorem or_xor_tree_1111_proof : or_xor_tree_1111_before ⊑ or_xor_tree_1111_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 lor_land_left1_proof : lor_land_left1_before ⊑ lor_land_left1_after

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

theorem sub_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a - c) ≈ʷ (b - d)

theorem t1_thm (e : IntW 8) (e_1 : IntW 1) :
  LLVM.xor (add (sext 8 e_1) e) (sext 8 e_1) ⊑ select e_1 (sub (const? 8 0) e) e

theorem not_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → -1#999 = signExtend 999 (x ^^^ 1#1)

theorem select_icmp_eq_and_1_0_lshr_fv_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 &&& 1#8 == 0#8) = 1#1 → ¬(1#8 ≥ ↑8 ∨ x_1 <<< 1#8 &&& 2#8 ≥ ↑8) → x = x >>> (x_1 <<< 1#8 &&& 2#8)

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

@[simp] theorem dropUntil_last   : dropUntil (cons ty Γ) (Var.last Γ ty) = Γ

theorem icmp_select_implied_cond_ne_proof : icmp_select_implied_cond_ne_before ⊑ icmp_select_implied_cond_ne_after

theorem main7c_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_2 &&& x_1) &&& ofBool (x * 42#32 == x * 42#32 &&& x_1) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x_1 &&& (x_2 ||| x * 42#32) != x_2 ||| x * 42#32))

theorem land_band_left1_proof : land_band_left1_before ⊑ land_band_left1_after

theorem trunc_lshr_trunc_outofrange_proof : trunc_lshr_trunc_outofrange_before ⊑ trunc_lshr_trunc_outofrange_after

theorem e_601 :
     - 1 *  ~~~(x ^^^ y) - 1 *  ~~~x + 4 * y + 5 * x - 5 * (x |||  ~~~y) - 11 *  ~~~(x &&&  ~~~x) + 25 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 17 * (x &&&  ~~~y) + 8 * (x &&& y) = 7 *  ~~~y - 1 * (x ^^^ y)

theorem sdiv_common_divisor_defined_cond_proof : sdiv_common_divisor_defined_cond_before ⊑ sdiv_common_divisor_defined_cond_after

theorem uge_to_slt_thm (e : IntW 8) :
  icmp IntPred.uge (LLVM.xor e (const? 8 127)) (const? 8 15) ⊑ icmp IntPred.slt e (const? 8 113)

theorem t0_commutative_thm.extracted_1._18 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8),
  ¬ofBool (x_4 == x_3) = 1#1 → ¬ofBool (x_4 != x_3) = 1#1 → ¬0#1 = 1#1 → ¬x_2 = 1#1 → x = x_1

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 447),
  True ∧ (x_1 &&& 70368744177664#447 &&& (x &&& 70368744177663#447) != 0) = true → False

theorem or_xor_commute4_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.udiv (const? 32 42) e_1) (LLVM.or (LLVM.udiv (const? 32 42) e) (LLVM.udiv (const? 32 42) e_1)) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e) (LLVM.xor (LLVM.udiv (const? 32 42) e_1) (const? 32 (-1)))

theorem f_var1_proof : f_var1_before ⊑ f_var1_after

theorem test69_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 128#32 != 0#32) = 1#1 → 6#32 ≥ ↑32 → False

theorem test17_proof : test17_before ⊑ test17_after

theorem test_and1_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x_1) = 1#1 → ofBool (-1#32 <ₛ x_1) = 1#1 → 0#1 = ofBool (x_1 <ₛ x &&& 2147483647#32)

theorem not_xor_to_or_not4_thm (e e_1 e_2 : IntW 3) :
  LLVM.xor (LLVM.xor (LLVM.and e_2 e_1) (LLVM.or e e_2)) (const? 3 (-1)) ⊑
    LLVM.or (LLVM.and e_2 e_1) (LLVM.xor (LLVM.or e e_2) (const? 3 (-1)))

theorem ult_umin1_proof : ult_umin1_before ⊑ ult_umin1_after

theorem trunc_sel_equal_sext_thm.extracted_1._4 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 32 42#16 = 42#32

theorem lt_signed_to_small_unsigned_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x <ᵤ 17#32) = ofBool (x <ᵤ 17#8)

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 n10_wrong_pred2_proof : n10_wrong_pred2_before ⊑ n10_wrong_pred2_after

theorem test2_logical_proof : test2_logical_before ⊑ test2_logical_after

theorem e_821 :
     - 1 * (z ^^^ t) + 1 * (z |||  ~~~t) - 7 * t - 1 *  ~~~(z ||| t) + 6 * (z &&& t) =  - 8 *  ~~~(z |||  ~~~t)

theorem t17_nocse_mismatching_x_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x_1 ≥ ↑8 ∨ x ≥ ↑8) →
    ¬(True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ True ∧ ((-1#8) <<< x_1).sshiftRight' x_1 ≠ -1#8 ∨ x_1 ≥ ↑8) →
      1#8 <<< x_1 + -1#8 ||

theorem t4_proof : t4_before ⊑ t4_after

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 add_shl_same_amount_proof : add_shl_same_amount_before ⊑ add_shl_same_amount_after

theorem and_logic_and_logic_or_5_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → ¬0#1 = 1#1 → x_1 &&& x = 0#1

theorem test3_proof : test3_before ⊑ test3_after

theorem add_eq_xor_add_mul_and_3 (x y : BitVec w) :
    x + y = (x ^^^ y) + (x &&& y) * 2#w

theorem shl_and_lshr_comm_proof : shl_and_lshr_comm_before ⊑ shl_and_lshr_comm_after

theorem bv_276_2 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.udiv e_1 e) (LLVM.sub (LLVM.const? 5 0) e) ⊑ LLVM.sub (LLVM.urem e_1 e) e_1

theorem sub_zext_trunc_lshr_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    16#32 ≥ ↑32 ∨ 31#32 ≥ ↑32 ∨ True ∧ ((truncate 32 x <<< 16#32).sshiftRight' 31#32).saddOverflow 10#32 = true →
      False

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

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

theorem main8_proof : main8_before ⊑ main8_after

theorem test12_proof : test12_before ⊑ test12_after

theorem test_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ zeroExtend 32 x_1) = ofBool (x <ᵤ x_1)

theorem e_2381 :
     - 2 *  ~~~(d &&&  ~~~d) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 7 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 3 * (f ^^^ (d ||| (e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 11 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 11 * ((d &&& e) |||  ~~~(e ||| f)) - 2 * (e ^^^ (d ||| f)) - 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * (f &&&  ~~~(d ^^^ e)) + 4 * (e &&& (d ||| f)) + 1 *  ~~~(d ^^^ (e ||| f)) - 1 * (d ||| ( ~~~e ||| f)) - 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 3 * (f &&& (d ^^^ e)) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) - 3 * (e |||  ~~~f) + 3 *  ~~~(d &&& ( ~~~e ||| f)) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 *  ~~~(d &&& e) - 7 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(e &&& f) + 2 *  ~~~(d |||  ~~~e) + 5 * (d |||  ~~~f) + 4 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 2 * ( ~~~d ||| (e ^^^ f)) + 3 *  ~~~(d &&& f) - 6 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 *  ~~~(e ^^^ f) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * (d &&& (e ||| f)) - 5 * (e ^^^ (d &&& ( ~~~e ||| f))) - 6 * ( ~~~d ||| ( ~~~e ||| f)) + 2 * ( ~~~d ||| (e &&& f)) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) - 2 * (d ^^^ e) - 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * (f ||| (d &&& e)) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 4 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (d ^^^ (e &&& f)) + 1 *  ~~~e - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 11 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 3 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 29 *  ~~~(d ||| (e ||| f)) + 35 *  ~~~(d ||| ( ~~~e ||| f)) + 42 *  ~~~( ~~~d ||| (e ||| f)) + 6 * ( ~~~d &&& ( ~~~e &&& f)) + 30 * ( ~~~d &&& (e &&& f)) + 40 * (d &&& ( ~~~e &&& f)) + 6 * (d &&& (e &&& f)) =  - 34 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 5 * (d &&&  ~~~e)

theorem test_shl__all_are_safe_proof : test_shl__all_are_safe_before ⊑ test_shl__all_are_safe_after

theorem main7b_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == x &&& x_1) = 1#1 → ¬ofBool (x_1 != x &&& x_1) = 1#1 → 0#1 = 1#1 → False

theorem positive_sameconst_shlnsw_lshrexact_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8 ∨ True ∧ (x >>> 3#8 <<< 3#8).sshiftRight' 3#8 ≠ x >>> 3#8 ∨ 3#8 ≥ ↑8) →
    x >>> 3#8 <<< 3#8 = x

theorem pr33078_4_thm (e : IntW 3) :
  trunc 8 (lshr (sext 16 e) (const? 16 13)) ⊑
    trunc 8 (lshr (sext 16 e) (const? 16 13)) { «nsw» := true, «nuw» := true }

theorem ashr_lowmask_proof : ashr_lowmask_before ⊑ ashr_lowmask_after

theorem t2_thm (e : IntW 64) : sub (const? 64 0) (ashr e (const? 64 63)) ⊑ lshr e (const? 64 63)

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

theorem n11_wrong_pred3_proof : n11_wrong_pred3_before ⊑ n11_wrong_pred3_after

theorem bools_logical_thm.extracted_1._17 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ^^^ 1#1 = 1#1 → ¬x_2 = 1#1 → 0#1 = 1#1 → 1#1 = x_1

theorem shl_trunc_bigger_shl_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(4#32 ≥ ↑32 ∨ 2#8 ≥ ↑8) → 6#8 ≥ ↑8 → False

theorem sel_sext_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1), ¬x_1 = 1#1 → signExtend 64 42#32 = 42#64

theorem lowmask_add_2_proof : lowmask_add_2_before ⊑ lowmask_add_2_after

theorem t4_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (0#8).ssubOverflow x = true) → ofBool (x <ᵤ 0#8 - x) = ofBool (0#8 <ₛ x)

theorem test52_thm.extracted_1._1 : ∀ (x : BitVec 64),
  True ∧ (truncate 16 x &&& 7224#16 &&& BitVec.ofInt 16 (-32574) != 0) = true → False

theorem udiv_common_divisor_defined_cond_proof : udiv_common_divisor_defined_cond_before ⊑ udiv_common_divisor_defined_cond_after

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

theorem select_icmp_sgt_not_smin_proof : select_icmp_sgt_not_smin_before ⊑ select_icmp_sgt_not_smin_after

theorem icmp_select_var_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_2 = 0 → ofBool (x_1 == 0#8) = 1#1 → ofBool (42#8 / x_2 == 42#8 / x_2) = 1#1

theorem neg_nsw_sgt_n1_proof : neg_nsw_sgt_n1_before ⊑ neg_nsw_sgt_n1_after

theorem foo1_or_commuted_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32) →
    True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨
        x_1 ≥ ↑32 ∨
          True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨
            x ≥ ↑32 ∨ True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 →
      False

theorem e_1254 :
    1 *  ~~~(z ^^^ t) - 6 *  ~~~(z &&&  ~~~z) - 1 *  ~~~(z &&&  ~~~t) - 2 * (z ^^^ t) - 7 * t + 17 *  ~~~(z ||| t) + 5 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) + 13 * (z &&& t) = 11 * (z |||  ~~~t) - 11 * (z ||| t)

theorem sdiv_exact_eq_0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smod x ≠ 0 ∨ (x == 0 || 8 != 1 && x_1 == intMin 8 && x == -1) = true) →
    ofBool (x_1.sdiv x == 0#8) = ofBool (x_1 == 0#8)

theorem bools2_logical_commute1_thm.extracted_1._16 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → ¬0#1 = 1#1 → x = x_2

theorem lshrugt_02_09_exact_proof : lshrugt_02_09_exact_before ⊑ lshrugt_02_09_exact_after

theorem lor_land_right2_thm (e e_1 : IntW 1) : select e_1 (select e (const? 1 1) e_1) (const? 1 0) ⊑ e_1

theorem neg_nsw_slt_n1_proof : neg_nsw_slt_n1_before ⊑ neg_nsw_slt_n1_after

theorem foo1_and_signbit_lshr_without_shifting_signbit_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_2 ≥ ↑32 ∨ x ≥ ↑32) → True ∧ 1#32 <<< x_2 >>> x_2 ≠ 1#32 ∨ x_2 ≥ ↑32 ∨ x ≥ ↑32 → False

theorem icmp_equality_test_commute_icmp2_proof : icmp_equality_test_commute_icmp2_before ⊑ icmp_equality_test_commute_icmp2_after

theorem shl_add_and_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬(4#32 ≥ ↑32 ∨ 4#32 ≥ ↑32) → 4#32 ≥ ↑32 → False

theorem t6_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (0#8).ssubOverflow x = true) → ofBool (0#8 - x <ᵤ x) = ofBool (x <ₛ 0#8)

theorem ugt_and_min_commute_proof : ugt_and_min_commute_before ⊑ ugt_and_min_commute_after

theorem e_1876 :
     - 2 *  ~~~(a &&& b) + 2 * (c ||| (a &&&  ~~~b)) - 6 * ( ~~~a &&& (b ||| c)) - 1 * ( ~~~a ||| (b &&& c)) - 5 * (b ^^^ (a &&& c)) - 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 2 *  ~~~c + 1 * ((a &&& b) ^^^ (b ||| c)) + 7 * (a ||| (b ||| c)) + 4 * (a ^^^ c) - 3 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 7 *  ~~~(a &&&  ~~~c) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a ||| (b ^^^ c)) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) + 1 * (b ^^^ (a ||| (b ^^^ c))) + 1 *  ~~~(a ||| ( ~~~b &&& c)) + 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 * (b ^^^  ~~~(a ||| c)) - 1 * (c ||| (a ^^^ b)) - 2 * ( ~~~c ||| (a ^^^ b)) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) + 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 4 * (b ^^^ (a &&& ( ~~~b ||| c))) - 7 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 1 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 * ((a ^^^ b) ||| (a ^^^ c)) - 6 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 7 *  ~~~(a |||  ~~~b) - 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 3 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 5 *  ~~~(a ^^^ c) - 1 * (c &&& (a ||| b)) + 2 * ((a ^^^ b) &&& (a ^^^ c)) + 2 *  ~~~( ~~~a &&& (b ^^^ c)) + 1 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * (c ^^^ (a ||| b)) + 15 *  ~~~(a ||| (b ||| c)) + 40 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) - 5 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 20 * ( ~~~a &&& (b &&& c)) + 22 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) =  - 1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 4 * (b ^^^  ~~~(a &&& (b ||| c)))

theorem shl_lshr_demand3_proof : shl_lshr_demand3_before ⊑ shl_lshr_demand3_after

theorem test_proof : test_before ⊑ test_after

theorem src_srem_shl_demand_max_mask_hit_demand_thm (e : IntW 32) :
  LLVM.and (shl (LLVM.srem e (const? 32 4)) (const? 32 1)) (const? 32 (-4)) ⊑
    LLVM.and (shl (LLVM.srem e (const? 32 4)) (const? 32 1) { «nsw» := true, «nuw» := false }) (const? 32 (-4))

@[simp] lemma eval_borrow (x : Bool → BitStream) : borrow.eval x = (x true).borrow (x false)

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬16#32 ≥ ↑32 →
    zeroExtend 32 x <<< 16#32 &&& BitVec.ofInt 32 (-2147483648) = signExtend 32 x &&& BitVec.ofInt 32 (-2147483648)

theorem in_constant_mone_vary_invmask_proof : in_constant_mone_vary_invmask_before ⊑ in_constant_mone_vary_invmask_after

theorem main_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(6#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) → 5#8 ≥ ↑8 ∨ True ∧ ((truncate 8 x ^^^ -1#8) <<< 5#8 &&& 64#8).msb = true → False

theorem or_xor_tree_0000_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 * 42#32 ^^^ x_1 * 42#32 ||

theorem test5_proof : test5_before ⊑ test5_after

theorem ashr_mul_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬8#20 ≥ ↑20 →
    ¬(True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 8#16 ≥ ↑16) →
      truncate 16 ((signExtend 20 x_1 * signExtend 20 x).sshiftRight' 8#20) =
        (signExtend 16 x_1 * signExtend 16 x).sshiftRight' 8#16

theorem bools_multi_uses2_logical_thm.extracted_1._32 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → ¬0#1 = 1#1 → x = 1#1 → 0#1 + x = 0#1 ^^^ x

theorem invert_both_cmp_operands_sub_proof : invert_both_cmp_operands_sub_before ⊑ invert_both_cmp_operands_sub_after

theorem not_signbit_alt_xor_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → (x ^^^ BitVec.ofInt 8 (-2)) >>> 7#8 = zeroExtend 8 (ofBool (-1#8 <ₛ x))

theorem ashr_lshr_cst_thm (e : IntW 32) :
  select (icmp IntPred.slt e (const? 32 1)) (ashr e (const? 32 8) { «exact» := true }) (lshr e (const? 32 8)) ⊑
    ashr e (const? 32 8)

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

theorem sgt_3_impliesF_eq_2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ofBool (3#8 <ₛ x) = 1#1 → ¬ofBool (x <ₛ 4#8) = 1#1 → ofBool (2#8 == x) = 0#1

@[simp, simp_denote]
theorem liftEffect_pure_impure [Pure m] (hle : pure ≤ impure) :
    liftEffect hle (α := α) (m := m) = Pure.pure

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 0#32) &&& ofBool (x <ᵤ 14#32) = ofBool (x + -1#32 <ᵤ 13#32)

theorem uge_and_max_commute_proof : uge_and_max_commute_before ⊑ uge_and_max_commute_after

theorem e_488 :
    11 * (x ||| y) + 3 *  ~~~(x ^^^ y) + 1 * (x ^^^ y) - 3 * y + 3 *  ~~~(x &&&  ~~~y) + 11 * x - 10 *  ~~~(x ||| y) - 16 *  ~~~(x |||  ~~~y) - 25 * (x &&& y) = 23 * (x &&&  ~~~y) - 4 *  ~~~x

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

theorem C0zero_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 10#8 <ᵤ 0#8) = 1#1 → ofBool (x <ₛ BitVec.ofInt 8 (-10)) = 1#1 → False

theorem positive_biggerashr_shlnsw_ashrexact_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x >>> 6#8 <<< 6#8 ≠ x ∨
        6#8 ≥ ↑8 ∨ True ∧ (x.sshiftRight' 6#8 <<< 3#8).sshiftRight' 3#8 ≠ x.sshiftRight' 6#8 ∨ 3#8 ≥ ↑8) →
    ¬(True ∧ x >>> 3#8 <<< 3#8 ≠ x ∨ 3#8 ≥ ↑8) → x.sshiftRight' 6#8 <<< 3#8 = x.sshiftRight' 3#8

theorem test_shl_nuw_nsw__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 neg_neg : a = - - a

theorem shl_add_add_thm (e e_1 : IntW 8) :
  add (shl e_1 (const? 8 2)) (add (shl e (const? 8 2)) (const? 8 48)) ⊑
    add (shl (add e e_1) (const? 8 2)) (const? 8 48)

theorem test15f_proof : test15f_before ⊑ test15f_after

theorem not_or_or_and_no_and_commute1_or_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (LLVM.or (LLVM.or e_2 e_1) (LLVM.xor e (const? 32 (-1)))) (LLVM.xor (LLVM.and e_1 e) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.and e_2 (LLVM.xor e_1 (const? 32 (-1)))) (LLVM.xor e (const? 32 (-1)))

theorem tryFactorization_add_nuw_mul_proof : tryFactorization_add_nuw_mul_before ⊑ tryFactorization_add_nuw_mul_after

theorem lt_unsigned_to_large_signed_thm (e : IntW 8) : icmp IntPred.slt (zext 32 e) (const? 32 1024) ⊑ const? 1 1

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_1688 :
     - 3 * (c ^^^  ~~~(a &&& b)) - 3 * (c ^^^ (a &&&  ~~~b)) + 2 * (b ^^^  ~~~(a ||| c)) + 2 * (b |||  ~~~c) + 1 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 5 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 7 *  ~~~( ~~~a &&& (b &&& c)) - 11 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 * (c &&& (a ^^^ b)) - 2 * (b ^^^  ~~~(a &&& (b &&& c))) + 4 *  ~~~( ~~~a ||| (b &&& c)) + 3 * (a &&& b) - 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 11 * (a ^^^ (b &&& c)) - 5 * ( ~~~b &&&  ~~~(a ^^^ c)) - 11 *  ~~~(a &&& (b ^^^ c)) - 3 *  ~~~(a &&& (b &&& c)) - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 *  ~~~b + 7 *  ~~~(a &&&  ~~~a) + 20 *  ~~~(a ||| (b ||| c)) + 22 *  ~~~(a ||| ( ~~~b ||| c)) + 17 *  ~~~( ~~~a ||| (b ||| c)) - 2 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 31 * ( ~~~a &&& ( ~~~b &&& c)) + 12 * ( ~~~a &&& (b &&& c)) - 4 * (a &&& ( ~~~b &&& c)) + 22 * (a &&& (b &&& c)) = 5 * (c ^^^  ~~~(a &&& (b &&& c)))

theorem and_nosignbit_shl_proof : and_nosignbit_shl_before ⊑ and_nosignbit_shl_after

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

theorem n2_proof : n2_before ⊑ n2_after

theorem e_740 :
    7 * (x |||  ~~~y) - 3 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x &&&  ~~~x) - 11 * x - 1 *  ~~~y + 3 * y + 2 * (x ||| y) - 7 *  ~~~x + 5 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) =  - 3 * (x &&& y)

theorem ashrslt_03_09_exact_proof : ashrslt_03_09_exact_before ⊑ ashrslt_03_09_exact_after

theorem select_icmp_ne_0_and_4096_xor_32_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 4096#32) = 1#1 → ¬7#32 ≥ ↑32 → x = x_1 >>> 7#32 &&& 32#32 ^^^ x ^^^ 32#32

theorem e_1842 :
    7 * (b ^^^ (a &&& ( ~~~b ||| c))) + 5 * (b |||  ~~~(a |||  ~~~c)) + 1 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 7 * (b ^^^ (a ||| c)) + 4 *  ~~~(b |||  ~~~c) - 11 * (c ^^^  ~~~(a ||| b)) + 3 * ((a ^^^ b) ||| (a ^^^ c)) - 2 * (b ^^^ (a |||  ~~~c)) - 1 * ( ~~~b &&& (a ^^^ c)) - 7 * (b ^^^  ~~~(a |||  ~~~c)) - 5 * (c ^^^ (a ||| ( ~~~b ||| c))) + 5 * (c ^^^  ~~~(a &&&  ~~~b)) + 11 * (b ||| (a &&&  ~~~c)) + 11 *  ~~~(a ^^^ b) - 5 *  ~~~(a ^^^ ( ~~~b ||| c)) - 6 *  ~~~(a ^^^ ( ~~~b &&& c)) - 5 * (a |||  ~~~c) + 1 * (a &&& (b ^^^ c)) - 3 * (a ^^^ (b ^^^ c)) + 11 * (b &&& (a ||| c)) - 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 2 * (c ||| (a &&&  ~~~b)) - 2 *  ~~~(a ^^^ (b ||| c)) - 7 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 11 * ((a &&& b) ^^^ (b ||| c)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 2 * c - 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 6 * (b ^^^  ~~~(a &&& (b &&& c))) + 2 * (b ^^^ (a ||| (b ^^^ c))) - 6 *  ~~~( ~~~a &&& (b ^^^ c)) + 3 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 4 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 3 *  ~~~( ~~~a &&& (b ||| c)) + 31 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) + 15 *  ~~~( ~~~a ||| (b ||| c)) - 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 9 * ( ~~~a &&& ( ~~~b &&& c)) - 1 * ( ~~~a &&& (b &&& c)) + 26 * (a &&& ( ~~~b &&& c)) + 1 * (a &&& (b &&& c)) =  - 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c))

theorem andcond.100.inv.inner.cond.in.outer.cond_proof : andcond.100.inv.inner.cond.in.outer.cond_before ⊑ andcond.100.inv.inner.cond.in.outer.cond_after

theorem e_1232 :
    7 *  ~~~(z ^^^ t) - 3 * (z |||  ~~~t) - 6 * (z ||| t) - 2 *  ~~~(z &&&  ~~~z) - 11 *  ~~~z + 7 * t + 9 *  ~~~(z ||| t) + 12 *  ~~~(z |||  ~~~t) + 13 * (z &&&  ~~~t) = 1 * (z &&& t) + 2 * z

theorem gt_unsigned_to_large_signed_proof : gt_unsigned_to_large_signed_before ⊑ gt_unsigned_to_large_signed_after

theorem fold_icmp_shl_nuw_c2_precondition2_proof : fold_icmp_shl_nuw_c2_precondition2_before ⊑ fold_icmp_shl_nuw_c2_precondition2_after

theorem eval_eq_zero_of_mkIndHypCycleBreaking_eval_eq_false_of_mkSafetyCircuit_eval_eq_false
    (circs : KInductionCircuits fsm K)
    (hCircs : circs.IsLawful)
    (hSafety : ∀ (env : _), (mkSafetyCircuit circs).eval env = false)
    (hIndHyp : ∀ (env : _), (mkIndHypCycleBreaking circs).eval env = false) :
    (∀ (envBitstream : _), fsm.eval envBitstream = BitStream.zero)

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

theorem add_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → (x_1 ^^^ -1#8) + x ^^^ -1#8 = x_1 - x

theorem test_lshr__exact_is_unsafe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 63#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 → False

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

theorem test13_proof : test13_before ⊑ test13_after

theorem positive_biggerShl_shlnuw_proof : positive_biggerShl_shlnuw_before ⊑ positive_biggerShl_shlnuw_after

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 lshrugt_01_04_proof : lshrugt_01_04_before ⊑ lshrugt_01_04_after

theorem or_signbit_select_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬8#32 ≥ ↑32 → (x ||| BitVec.ofInt 32 (-65536)) >>> 8#32 = x >>> 8#32 ||

theorem alive_AndOrXor_2367  (w : Nat)   : alive_AndOrXor_2367_src w  ⊑ alive_AndOrXor_2367_tgt w

theorem test3_proof : test3_before ⊑ test3_after

@[simp] lemma eval_scanAnd_true_iff (x : Unit → BitStream) (n : Nat) : scanAnd.eval x n = true ↔ (∀ (i : Nat), (hi : i ≤ n) → x () i = true)

theorem lshrugt_02_13_proof : lshrugt_02_13_before ⊑ lshrugt_02_13_after

theorem sub_ashr_and_i8_thm (e e_1 : IntW 8) :
  LLVM.and (ashr (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 8 7)) e ⊑
    select (icmp IntPred.slt e_1 e) e (const? 8 0)

theorem bv_AndOrXor_2617 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.and e (LLVM.xor e_1 (LLVM.const? w (-1)))) (LLVM.and (LLVM.xor e (LLVM.const? w (-1))) e_1) ⊑
        LLVM.xor e e_1

theorem demorgan_and_apint5_thm (e e_1 : IntW 47) :
  LLVM.and (LLVM.xor e_1 (const? 47 (-1))) (LLVM.xor e (const? 47 (-1))) ⊑
    LLVM.xor (LLVM.or e_1 e) (const? 47 (-1))

theorem negative_trunc_not_arg_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x_1) = 1#1 →
    ofBool (x_1 &&& 128#32 == 0#32) = 1#1 → 0#1 = ofBool (x + 128#32 <ᵤ 256#32)

theorem lshr_or_proof : lshr_or_before ⊑ lshr_or_after

theorem test_srem_canonicalize_op0_thm.extracted_1._1 : ∀ (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.srem x) = true →
      False

theorem t0_commutative_proof : t0_commutative_before ⊑ t0_commutative_after

theorem scalar_i8_lshr_and_negC_eq_not_negatedPowerOf2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x ≥ ↑8 → ofBool (x_1 >>> x &&& BitVec.ofInt 8 (-3) == 0#8) = ofBool (x_1 &&& BitVec.ofInt 8 (-3) <<< x == 0#8)

theorem ashrsgt_03_02_exact_proof : ashrsgt_03_02_exact_before ⊑ ashrsgt_03_02_exact_after

theorem ashrsgt_02_08_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 2)) (const? 4 (-8)) ⊑ const? 1 1

theorem ashr_ugt_6_thm (e : IntW 4) :
  icmp IntPred.ugt (ashr e (const? 4 1)) (const? 4 6) ⊑ icmp IntPred.slt e (const? 4 0)

theorem icmp_sgt6_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 16) ⊑
    icmp IntPred.sgt e (const? 8 8)

theorem gt_unsigned_to_small_signed_proof : gt_unsigned_to_small_signed_before ⊑ gt_unsigned_to_small_signed_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_6_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 8))
      (icmp IntPred.ne (LLVM.and e (const? 32 12)) (const? 32 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 8)

theorem and_two_ranges_to_mask_and_range_different_sizes_proof : and_two_ranges_to_mask_and_range_different_sizes_before ⊑ and_two_ranges_to_mask_and_range_different_sizes_after

theorem and_lshr_and_proof : and_lshr_and_before ⊑ and_lshr_and_after

theorem e_438 :
    7 * (x |||  ~~~y) - 5 *  ~~~x + 3 * x - 1 *  ~~~(x ^^^ y) - 11 * (x ||| y) - 2 *  ~~~(x ||| y) + 16 *  ~~~(x |||  ~~~y) + 2 * (x &&& y) =  - 1 *  ~~~y

theorem main5c_like_logical_proof : main5c_like_logical_before ⊑ main5c_like_logical_after

theorem demorgan_and_apint1_proof : demorgan_and_apint1_before ⊑ demorgan_and_apint1_after

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

theorem BitVec.add_getElem_zero {x y : BitVec w} (hw : 0 < w) : (x + y)[0] =
    ((x[0] ^^ y[0]))

theorem e_1388 :
     - 3 * (z ||| t) + 2 * (z ^^^ t) + 3 * t - 2 *  ~~~(z ^^^ t) + 4 *  ~~~(z &&&  ~~~z) + 11 *  ~~~t + 1 * z + 1 * (z |||  ~~~t) - 6 *  ~~~(z |||  ~~~t) - 16 * (z &&&  ~~~t) = 4 * (z &&& t) + 14 *  ~~~(z ||| t)

theorem t1_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ x ≥ ↑16) → ¬15#16 - x ≥ ↑16 → 1#16 <<< x + -1#16 ||

theorem test1_proof : test1_before ⊑ test1_after

@[simp] lemma NFA'.autSignedCmp_σ (cmp : RelationOrdering) : (NFA'.autSignedCmp cmp).σ = NFA.signedCmpState

theorem uge_umin4_thm (e e_1 : IntW 32) :
  icmp IntPred.ule (add e_1 (const? 32 3))
      (select (icmp IntPred.ult e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    icmp IntPred.uge e (add e_1 (const? 32 3))

theorem PR42691_2_proof : PR42691_2_before ⊑ PR42691_2_after

theorem main3c_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 0#32) ||

theorem trunc_unsigned_both_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 x_1) ≠ x_1 ∨
        True ∧ zeroExtend 16 (truncate 8 x_1) ≠ x_1 ∨
          True ∧ signExtend 16 (truncate 8 x) ≠ x ∨ True ∧ zeroExtend 16 (truncate 8 x) ≠ x) →
    ofBool (truncate 8 x_1 <ᵤ truncate 8 x) = ofBool (x_1 <ᵤ x)

theorem eq_nsw_rem_zero_thm (e : IntW 8) :
  icmp IntPred.eq (mul e (const? 8 (-5)) { «nsw» := true, «nuw» := false }) (const? 8 20) ⊑
    icmp IntPred.eq e (const? 8 (-4))

theorem main7c_logical_thm.extracted_1._6 : ∀ (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 → ¬ofBool (x == x &&& x_1) = 1#1 → 1#32 = zeroExtend 32 1#1

theorem ashrslt_03_11_exact_proof : ashrslt_03_11_exact_before ⊑ ashrslt_03_11_exact_after

theorem icmp_sle3_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 (-16)) ⊑
    icmp IntPred.slt e (const? 8 (-7))

theorem AvoidCollision_getLsbD_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
    getLsbD (setWidth m x) i = (decide (i < m) && getLsbD x i)

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

theorem cmpne_xor_cst1_proof : cmpne_xor_cst1_before ⊑ cmpne_xor_cst1_after

theorem trunc_shl_zext_32_thm (e : IntW 32) :
  zext 32 (shl (trunc 16 e) (const? 16 4)) ⊑ LLVM.and (shl e (const? 32 4)) (const? 32 65520)

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

theorem masked_and_notA_slightly_optimized_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (8#32 ≤ᵤ x) = 1#1 → 0#1 = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

theorem carryWith_congrEnv {p : FSM arity}
    {carryState : p.α → Bool} {x y : arity → BitStream} {n : Nat}
    (h : ∀ a i, i < n → x a i = y a i) :
    p.carryWith carryState x n = p.carryWith carryState y n

theorem eq_smax2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ₛ x_1) = 1#1 → ofBool (x == x) = ofBool (x_1 ≤ₛ x)

theorem lshrult_02_00_proof : lshrult_02_00_before ⊑ lshrult_02_00_after

theorem shl_and_lshr_proof : shl_and_lshr_before ⊑ shl_and_lshr_after

theorem n0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_2 ≥ ↑8 → True ∧ ((-1#8) <<< x_2).sshiftRight' x_2 ≠ -1#8 ∨ x_2 ≥ ↑8 → False

theorem lshr_eq_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 (-128)) e) (const? 8 1) ⊑ icmp IntPred.eq e (const? 8 7)

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 8), x - BitVec.ofInt 8 (-42) = x + 42#8

theorem icmp_mul_nsw_sgt_proof : icmp_mul_nsw_sgt_before ⊑ icmp_mul_nsw_sgt_after

theorem e_2251 :
     - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 11 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * (e ^^^  ~~~(d &&&  ~~~f)) - 6 * ((d &&& e) ||| (e ^^^ f)) - 7 * ( ~~~f ||| (d ^^^ e)) + 5 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * (d ^^^ f) + 7 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~(e &&& f) + 1 *  ~~~(e &&&  ~~~f) - 1 * (f ^^^ (d &&&  ~~~e)) - 11 * (e ^^^ (d ||| (e &&& f))) - 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e &&&  ~~~(d &&& f)) - 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 7 * (f ^^^ (d ||| e)) + 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 *  ~~~(e ||| f) + 5 * (e ^^^ (d &&&  ~~~f)) + 7 * (f ^^^  ~~~(d &&& (e ||| f))) - 6 * (e &&&  ~~~(d &&&  ~~~f)) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 5 * (f &&&  ~~~(d ^^^ e)) - 7 * ( ~~~d &&& (e ||| f)) - 5 * (e ||| (d &&&  ~~~f)) - 3 *  ~~~(d |||  ~~~e) + 5 *  ~~~(d &&& ( ~~~e ||| f)) + 5 * f - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (d ||| (e ^^^ f)) - 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 *  ~~~( ~~~d &&& (e ||| f)) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) + 4 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^ (d &&& f)) - 1 * (f ^^^  ~~~(d ||| e)) + 1 * (d ^^^ ( ~~~e ||| f)) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (f &&& (d ||| e)) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (f &&& (d ^^^ e)) + 7 * (f ^^^ (d ||| (e &&& f))) + 11 * (e ^^^ (d ||| (e ^^^ f))) - 12 *  ~~~(d ||| (e ||| f)) + 26 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 2 * ( ~~~d &&& ( ~~~e &&& f)) - 12 * ( ~~~d &&& (e &&& f)) - 16 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) = 1 * d - 4 *  ~~~( ~~~d &&& (e ^^^ f))

theorem zext_add_scalar_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → zeroExtend 32 x + 42#32 = 42#32

theorem test9_proof : test9_before ⊑ test9_after

theorem select_2_thm.extracted_1._10 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → x ^^^ 45#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-46)

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

theorem alive_AddSub_1560 : alive_AddSub_1560_src ⊑ alive_AddSub_1560_tgt

theorem signed_sign_bit_extract_trunc_proof : signed_sign_bit_extract_trunc_before ⊑ signed_sign_bit_extract_trunc_after

theorem test_const_shr_and_1_ne_0_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.and (lshr (const? 32 42) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and (shl (const? 32 1) e { «nsw» := false, «nuw» := true }) (const? 32 42))
      (const? 32 0)

theorem icmp_eq_sext_ne_zero_thm (e : IntW 32) :
  icmp IntPred.eq (sext 32 (icmp IntPred.ne e (const? 32 0))) e ⊑
    icmp IntPred.ult (add e (const? 32 1)) (const? 32 2)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_after

theorem or_not_and_wrong_c_proof : or_not_and_wrong_c_before ⊑ or_not_and_wrong_c_after

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

theorem trunc_lshr_zext_thm (e : IntW 8) : trunc 8 (lshr (zext 32 e) (const? 32 6)) ⊑ lshr e (const? 8 6)

theorem demo (x y : BitVec 8) : (0#8 - x ||| y) + y = (y ||| 0#8 - x) + y

theorem xor_decide (p q : Prop) [dp : Decidable p] [Decidable q] :
    (decide p).xor (decide q) = decide (p ≠ q)

theorem negtest_near_pow2_cmpval_isnt_close_to_pow2_proof : negtest_near_pow2_cmpval_isnt_close_to_pow2_before ⊑ negtest_near_pow2_cmpval_isnt_close_to_pow2_after

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

theorem n9_proof : n9_before ⊑ n9_after

theorem eq_rem_zero_nonuw_thm (e : IntW 8) :
  icmp IntPred.eq (mul e (const? 8 5)) (const? 8 20) ⊑ icmp IntPred.eq e (const? 8 4)

@[simp]
theorem Eqn.numVars_cons : Eqn.numVars (t :: es) = max t.numVars (Eqn.numVars es)

theorem sext_sub_proof : sext_sub_before ⊑ sext_sub_after

theorem sle_swap_or_min_commute_proof : sle_swap_or_min_commute_before ⊑ sle_swap_or_min_commute_after

theorem sle_or_min_proof : sle_or_min_before ⊑ sle_or_min_after

theorem udiv_i8_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem trunc_shl_shl_var_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(x ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬(x ≥ ↑64 ∨ 2#32 ≥ ↑32) → truncate 32 (x_1 <<< x <<< 2#64) = truncate 32 (x_1 <<< x) <<< 2#32

theorem sgt_3_impliesF_eq_2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ofBool (3#8 <ₛ x_1) = 1#1 → ofBool (x_1 <ₛ 4#8) = 1#1 → ofBool (2#8 == x_1) = ofBool (x == x_1)

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem icmp_ne_sext_ne_zero_proof : icmp_ne_sext_ne_zero_before ⊑ icmp_ne_sext_ne_zero_after

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

theorem icmp_mul_nsw_sle_proof : icmp_mul_nsw_sle_before ⊑ icmp_mul_nsw_sle_after

theorem smear_sign_and_widen_proof : smear_sign_and_widen_before ⊑ smear_sign_and_widen_after

theorem demorgan_nor_use2c_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬((x_1 ^^^ -1#8 ||| x) * 23#8 == 0 ||
          8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && (x_1 ^^^ -1#8 ||| x) * 23#8 == -1) =
        true →
    ((x ||| x_1 ^^^ -1#8) * 23#8 == 0 ||
          8 != 1 && (x ||| x_1 ^^^ -1#8) ^^^ -1#8 == intMin 8 && (x ||| x_1 ^^^ -1#8) * 23#8 == -1) =
        true →
      False

theorem alive_290__292 : alive_290__292_src ⊑ alive_290__292_tgt

theorem test25_thm.extracted_1._1 : ∀ (x x_1 : BitVec 37),
  ¬(17#37 ≥ ↑37 ∨ 17#37 ≥ ↑37 ∨ 17#37 ≥ ↑37) →
    (x_1 >>> 17#37 + x >>> 17#37) <<< 17#37 = x + (x_1 &&& BitVec.ofInt 37 (-131072)) &&& BitVec.ofInt 37 (-131072)

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 not_match_inconsistent_values_thm (e : IntW 64) :
  add (urem e (const? 64 299)) (mul (urem (LLVM.udiv e (const? 64 29)) (const? 64 64)) (const? 64 299)) ⊑
    add (urem e (const? 64 299))
      (mul (LLVM.and (LLVM.udiv e (const? 64 29)) (const? 64 63)) (const? 64 299) { «nsw» := true, «nuw» := true })
      { «nsw» := true, «nuw» := true }

theorem select_xor_inv_icmp_proof : select_xor_inv_icmp_before ⊑ select_xor_inv_icmp_after

theorem t0_proof : t0_before ⊑ t0_after

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

theorem t0_const_after_fold_lshr_shl_ne_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 x_2 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + -1#32) ≥ ↑64) →
    ¬(31#32 ≥ ↑32 ∨ True ∧ (x_2 >>> 31#32).msb = true) →
      ofBool (x_2 >>> (32#32 - x_1) &&& truncate 32 (x <<< zeroExtend 64 (x_1 + -1#32)) != 0#32) =
        ofBool (x &&& zeroExtend 64 (x_2 >>> 31#32) != 0#64)

theorem t2_commutative_proof : t2_commutative_before ⊑ t2_commutative_after

theorem test_sdiv_canonicalize_op0_exact_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨
        True ∧ (0#32 - x_1).smod x ≠ 0 ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    ¬(True ∧ x_1.smod x ≠ 0 ∨
          (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 e_313 :
     - 1 * (x |||  ~~~y) + 7 * y + 7 *  ~~~y - 5 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) - 6 * (x &&& y) = 1 *  ~~~(x &&& y)

@[simp] lemma eval_fsmCarry'' (x : Bool → BitStream) :
    (fsmCarry'' initCarry).eval x =
      (BitStream.carry' initCarry (x true) (x false))

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

theorem test_shl__nuw_is_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(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)))

omit [LawfulBEq A] [Fintype S] [DecidableEq S] in
lemma processOneElem_mem_states (st : worklist.St A S) (final : S → Bool) (a : A) (sa : S) (s : State) :
    s ∈ (processOneElem A S final s st (a, sa)).m.states →
    s ∈ st.m.states ∨ s = st.m.stateMax

theorem icmp_eq_sext_eq_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == 0#32)) == x) = 0#1

theorem ashrsgt_02_12_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2) { «exact» := true }) (const? 4 (-4)) ⊑ const? 1 1

theorem icmp_eq_and_pow2_lshr_pow2_case2_proof : icmp_eq_and_pow2_lshr_pow2_case2_before ⊑ icmp_eq_and_pow2_lshr_pow2_case2_after

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

theorem add_shl_same_amount_partial_nuw2_proof : add_shl_same_amount_partial_nuw2_before ⊑ add_shl_same_amount_partial_nuw2_after

theorem or_logic_or_logic_and_6_thm.extracted_1._9 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

theorem p_commutative4_proof : p_commutative4_before ⊑ p_commutative4_after

theorem and_orn_xor_thm (e e_1 : IntW 4) :
  LLVM.and (LLVM.or (LLVM.xor e_1 (const? 4 (-1))) e) (LLVM.xor e_1 e) ⊑
    LLVM.and e (LLVM.xor e_1 (const? 4 (-1)))

theorem sub_1_proof : sub_1_before ⊑ sub_1_after

theorem positive_biggershl_shlnuw_proof : positive_biggershl_shlnuw_before ⊑ positive_biggershl_shlnuw_after

theorem n2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-128) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-128) == -1) = true →
    x.sdiv (BitVec.ofInt 8 (-128)) = zeroExtend 8 (ofBool (x == BitVec.ofInt 8 (-128)))

theorem test_with_3_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → 3#32 <<< x &&& 1#32 = zeroExtend 32 (ofBool (x == 0#32))

theorem pv_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.and (lshr (const? 8 (-1)) e_1) e) e ⊑
    icmp IntPred.ugt e (lshr (const? 8 (-1)) e_1)

theorem ashr_lshr_shift_wrong_pred_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ≤ₛ 0#32) = 1#1 → ¬x ≥ ↑32 → ¬ofBool (x_1 <ₛ 1#32) = 1#1 → x_1 >>> x = x_1.sshiftRight' x

theorem ashrslt_03_05_exact_proof : ashrslt_03_05_exact_before ⊑ ashrslt_03_05_exact_after

theorem not_or_or_and_no_and_commute2_proof : not_or_or_and_no_and_commute2_before ⊑ not_or_or_and_no_and_commute2_after

theorem test_or_eq_different_operands_proof : test_or_eq_different_operands_before ⊑ test_or_eq_different_operands_after

theorem n15_variable_shamts_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 64),
  ¬(x_2 ≥ ↑64 ∨ x ≥ ↑32) →
    ¬(x ≥ ↑32 ∨ x_2 ≥ ↑64) →
      ofBool (truncate 32 (x_3 <<< x_2) &&& x_1 >>> x != 0#32) =
        ofBool (x_1 >>> x &&& truncate 32 (x_3 <<< x_2) != 0#32)

theorem e_50 :
    2 *  ~~~y + 1 *  ~~~(x &&&  ~~~x) - 3 * (x ^^^ y) + 8 *  ~~~(x ||| y) + 10 * (x &&& y) = 11 *  ~~~(x &&&  ~~~y) - 13 *  ~~~(x |||  ~~~y)

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

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_4_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_4_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_4_logical_after

theorem e_328 :
     - 1 *  ~~~x - 2 * (x ||| y) - 6 *  ~~~y + 7 * (x ^^^ y) - 3 *  ~~~(x ^^^ y) + 10 *  ~~~(x ||| y) + 1 * (x &&&  ~~~y) + 5 * (x &&& y) = 4 *  ~~~(x |||  ~~~y)

theorem signbit_splat_mask_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ¬ofBool (x_1 <ₛ 0#8) = 1#1 → signExtend 16 (x_1.sshiftRight' 7#8) &&& x = 0#16

theorem test94_thm.extracted_1._1 : ∀ (x : BitVec 32),
  signExtend 64 (signExtend 8 (ofBool (x == BitVec.ofInt 32 (-2))) ^^^ -1#8) =
    signExtend 64 (ofBool (x != BitVec.ofInt 32 (-2)))

theorem select_icmp_eq_pow2_flipped_thm (e : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e (const? 8 4)) (const? 8 0)) (LLVM.xor e (const? 8 4)) e ⊑
    LLVM.or e (const? 8 4)

theorem alive_constant_fold_100: forall (w : Nat), TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt w (0)) %v0
  dsl_ret %v1
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v000 := unit: ;
  %v001 := op:const (Bitvec.ofInt w (0)) %v000;
  %v100 := pair:%v001 %v001;
  %v101 := op:add w %v100;
  %v110 := pair:%v101 %v001;
  %v111 := op:add w %v110;
  %v120 := pair:%v111 %v001;
  %v121 := op:add w %v120;
  %v130 := pair:%v121 %v001;
  %v131 := op:add w %v130;
  %v140 := pair:%v131 %v001;
  %v141 := op:add w %v140;
  %v150 := pair:%v141 %v001;
  %v151 := op:add w %v150;
  %v160 := pair:%v151 %v001;
  %v161 := op:add w %v160;
  %v170 := pair:%v161 %v001;
  %v171 := op:add w %v170;
  %v180 := pair:%v171 %v001;
  %v181 := op:add w %v180;
  %v190 := pair:%v181 %v001;
  %v191 := op:add w %v190;
  %v200 := pair:%v191 %v001;
  %v201 := op:add w %v200;
  %v210 := pair:%v201 %v001;
  %v211 := op:add w %v210;
  %v220 := pair:%v211 %v001;
  %v221 := op:add w %v220;
  %v230 := pair:%v221 %v001;
  %v231 := op:add w %v230;
  %v240 := pair:%v231 %v001;
  %v241 := op:add w %v240;
  %v250 := pair:%v241 %v001;
  %v251 := op:add w %v250;
  %v260 := pair:%v251 %v001;
  %v261 := op:add w %v260;
  %v270 := pair:%v261 %v001;
  %v271 := op:add w %v270;
  %v280 := pair:%v271 %v001;
  %v281 := op:add w %v280;
  %v290 := pair:%v281 %v001;
  %v291 := op:add w %v290;
  %v300 := pair:%v291 %v001;
  %v301 := op:add w %v300;
  %v310 := pair:%v301 %v001;
  %v311 := op:add w %v310;
  %v320 := pair:%v311 %v001;
  %v321 := op:add w %v320;
  %v330 := pair:%v321 %v001;
  %v331 := op:add w %v330;
  %v340 := pair:%v331 %v001;
  %v341 := op:add w %v340;
  %v350 := pair:%v341 %v001;
  %v351 := op:add w %v350;
  %v360 := pair:%v351 %v001;
  %v361 := op:add w %v360;
  %v370 := pair:%v361 %v001;
  %v371 := op:add w %v370;
  %v380 := pair:%v371 %v001;
  %v381 := op:add w %v380;
  %v390 := pair:%v381 %v001;
  %v391 := op:add w %v390;
  %v400 := pair:%v391 %v001;
  %v401 := op:add w %v400;
  %v410 := pair:%v401 %v001;
  %v411 := op:add w %v410;
  %v420 := pair:%v411 %v001;
  %v421 := op:add w %v420;
  %v430 := pair:%v421 %v001;
  %v431 := op:add w %v430;
  %v440 := pair:%v431 %v001;
  %v441 := op:add w %v440;
  %v450 := pair:%v441 %v001;
  %v451 := op:add w %v450;
  %v460 := pair:%v451 %v001;
  %v461 := op:add w %v460;
  %v470 := pair:%v461 %v001;
  %v471 := op:add w %v470;
  %v480 := pair:%v471 %v001;
  %v481 := op:add w %v480;
  %v490 := pair:%v481 %v001;
  %v491 := op:add w %v490;
  %v500 := pair:%v491 %v001;
  %v501 := op:add w %v500;
  %v510 := pair:%v501 %v001;
  %v511 := op:add w %v510;
  %v520 := pair:%v511 %v001;
  %v521 := op:add w %v520;
  %v530 := pair:%v521 %v001;
  %v531 := op:add w %v530;
  %v540 := pair:%v531 %v001;
  %v541 := op:add w %v540;
  %v550 := pair:%v541 %v001;
  %v551 := op:add w %v550;
  %v560 := pair:%v551 %v001;
  %v561 := op:add w %v560;
  %v570 := pair:%v561 %v001;
  %v571 := op:add w %v570;
  %v580 := pair:%v571 %v001;
  %v581 := op:add w %v580;
  %v590 := pair:%v581 %v001;
  %v591 := op:add w %v590;
  %v600 := pair:%v591 %v001;
  %v601 := op:add w %v600;
  %v610 := pair:%v601 %v001;
  %v611 := op:add w %v610;
  %v620 := pair:%v611 %v001;
  %v621 := op:add w %v620;
  %v630 := pair:%v621 %v001;
  %v631 := op:add w %v630;
  %v640 := pair:%v631 %v001;
  %v641 := op:add w %v640;
  %v650 := pair:%v641 %v001;
  %v651 := op:add w %v650;
  %v660 := pair:%v651 %v001;
  %v661 := op:add w %v660;
  %v670 := pair:%v661 %v001;
  %v671 := op:add w %v670;
  %v680 := pair:%v671 %v001;
  %v681 := op:add w %v680;
  %v690 := pair:%v681 %v001;
  %v691 := op:add w %v690;
  %v700 := pair:%v691 %v001;
  %v701 := op:add w %v700;
  %v710 := pair:%v701 %v001;
  %v711 := op:add w %v710;
  %v720 := pair:%v711 %v001;
  %v721 := op:add w %v720;
  %v730 := pair:%v721 %v001;
  %v731 := op:add w %v730;
  %v740 := pair:%v731 %v001;
  %v741 := op:add w %v740;
  %v750 := pair:%v741 %v001;
  %v751 := op:add w %v750;
  %v760 := pair:%v751 %v001;
  %v761 := op:add w %v760;
  %v770 := pair:%v761 %v001;
  %v771 := op:add w %v770;
  %v780 := pair:%v771 %v001;
  %v781 := op:add w %v780;
  %v790 := pair:%v781 %v001;
  %v791 := op:add w %v790;
  %v800 := pair:%v791 %v001;
  %v801 := op:add w %v800;
  %v810 := pair:%v801 %v001;
  %v811 := op:add w %v810;
  %v820 := pair:%v811 %v001;
  %v821 := op:add w %v820;
  %v830 := pair:%v821 %v001;
  %v831 := op:add w %v830;
  %v840 := pair:%v831 %v001;
  %v841 := op:add w %v840;
  %v850 := pair:%v841 %v001;
  %v851 := op:add w %v850;
  %v860 := pair:%v851 %v001;
  %v861 := op:add w %v860;
  %v870 := pair:%v861 %v001;
  %v871 := op:add w %v870;
  %v880 := pair:%v871 %v001;
  %v881 := op:add w %v880;
  %v890 := pair:%v881 %v001;
  %v891 := op:add w %v890;
  %v900 := pair:%v891 %v001;
  %v901 := op:add w %v900;
  %v910 := pair:%v901 %v001;
  %v911 := op:add w %v910;
  %v920 := pair:%v911 %v001;
  %v921 := op:add w %v920;
  %v930 := pair:%v921 %v001;
  %v931 := op:add w %v930;
  %v940 := pair:%v931 %v001;
  %v941 := op:add w %v940;
  %v950 := pair:%v941 %v001;
  %v951 := op:add w %v950;
  %v960 := pair:%v951 %v001;
  %v961 := op:add w %v960;
  %v970 := pair:%v961 %v001;
  %v971 := op:add w %v970;
  %v980 := pair:%v971 %v001;
  %v981 := op:add w %v980;
  %v990 := pair:%v981 %v001;
  %v991 := op:add w %v990
  dsl_ret %v991
  ]

theorem n15_variable_shamts_proof : n15_variable_shamts_before ⊑ n15_variable_shamts_after

theorem t0_proof : t0_before ⊑ t0_after

theorem neg_mask_const_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ (1000#32).ssubOverflow (signExtend 32 x) = true ∨
        15#16 ≥ ↑16 ∨ True ∧ (0#32).ssubOverflow (zeroExtend 32 (x >>> 15#16)) = true) →
    ofBool (x <ₛ 0#16) = 1#1 →
      ¬(True ∧ (1000#32).ssubOverflow (signExtend 32 x) = true) →
        1000#32 - signExtend 32 x &&& 0#32 - zeroExtend 32 (x >>> 15#16) = 1000#32 - signExtend 32 x

theorem test14_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.saddOverflow 1#32 = true ∨
        True ∧ (x_1 + 1#32).saddOverflow ((x ||| BitVec.ofInt 32 (-1431655767)) ^^^ 1431655766#32) = true) →
    x_1 + 1#32 + ((x ||| BitVec.ofInt 32 (-1431655767)) ^^^ 1431655766#32) = x_1 - (x &&& 1431655766#32)

theorem lt_signed_to_small_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x <ₛ BitVec.ofInt 32 (-17)) = ofBool (x <ₛ BitVec.ofInt 8 (-17))

theorem select_add_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64) (x_2 : BitVec 1), ¬x_2 = 1#1 → x_1 = x_1 + 0#64

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

theorem ugt_or_not_min_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 0#8) = 1#1 → 1#1 = ofBool (x_1 != 0#8)

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 eq_smax2_proof : eq_smax2_before ⊑ eq_smax2_after

theorem BitVec.eq_iff_sub_zero (x y : BitVec w) : x = y ↔ x - y = 0

theorem main3f_like_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != 0#32) ||

theorem and_logic_and_logic_or_1_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.and e_2 e_1) (const? 1 1) (select e_2 e (const? 1 0)) ⊑
    select e_2 (select e_1 (const? 1 1) e) (const? 1 0)

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

theorem select_icmp_ne_0_and_8_and_not_1073741824_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ¬ofBool (0#8 != x_1 &&& 8#8) = 1#1 → ¬ofBool (x_1 &&& 8#8 == 0#8) = 1#1 → x &&& BitVec.ofInt 32 (-1073741825) = x

@[grind =, simp]
lemma createSink_finals [LawfulBEq A] {m : RawCNFA A} : m.createSink.2.finals = m.finals

theorem slt_zero_eq_ne_0_proof : slt_zero_eq_ne_0_before ⊑ slt_zero_eq_ne_0_after

theorem test9_logical_proof : test9_logical_before ⊑ test9_logical_after

theorem ashrsgt_03_10_proof : ashrsgt_03_10_before ⊑ ashrsgt_03_10_after

theorem add_shl_same_amount_partial_nsw2_thm (e e_1 e_2 : IntW 6) :
  add (shl e_2 e_1) (shl e e_1 { «nsw» := true, «nuw» := false }) { «nsw» := true, «nuw» := false } ⊑
    shl (add e_2 e) e_1

theorem ashr_ugt_4_proof : ashr_ugt_4_before ⊑ ashr_ugt_4_after

theorem icmp_power2_and_icmp_shifted_mask_1073741824_1073741823_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ult e (const? 32 1073741824))
      (icmp IntPred.ne (LLVM.and e (const? 32 1073741823)) (const? 32 1073741823)) ⊑
    icmp IntPred.ult e (const? 32 1073741823)

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

theorem n2_badmask_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.or (LLVM.and e_3 e_2) (LLVM.and (LLVM.xor e_1 (const? 32 (-1))) e) ⊑
    LLVM.or (LLVM.and e_3 e_2) (LLVM.and e (LLVM.xor e_1 (const? 32 (-1))))

theorem foo2_thm (e e_1 : IntW 1) : mul e_1 e ⊑ LLVM.and e_1 e

theorem lshrult_02_01_exact_proof : lshrult_02_01_exact_before ⊑ lshrult_02_01_exact_after

theorem test1_proof : test1_before ⊑ test1_after

theorem main4b_proof : main4b_before ⊑ main4b_after

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

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

theorem ofBitVecZextMsb_EqualUpTo_ofBitVecSext
  (x : BitVec w) :
  EqualUpTo (w + 1)
    (BitStream.ofBitVecZextMsb x)
    (BitStream.concat false (BitStream.ofBitVecSext x))

theorem e_640 :
     - 7 * y + 1 *  ~~~y + 4 *  ~~~(x &&& y) - 7 *  ~~~x - 11 * (x ^^^ y) - 1 * (x ||| y) - 1 *  ~~~(x ||| y) + 22 *  ~~~(x |||  ~~~y) + 7 * (x &&&  ~~~y) + 5 * (x &&& y) =  - 3 *  ~~~(x ^^^ y)

theorem appendInl_toCons {v : Var Γ t} :
    v.toCons (t':=t').appendInl (Δ := Δ) = v.appendInl.toCons

theorem not_xor_to_or_not1_proof : not_xor_to_or_not1_before ⊑ not_xor_to_or_not1_after

theorem ashrslt_01_00_exact_proof : ashrslt_01_00_exact_before ⊑ ashrslt_01_00_exact_after

theorem test7_logical_proof : test7_logical_before ⊑ test7_logical_after

theorem and_or_not_not_commute2_proof : and_or_not_not_commute2_before ⊑ and_or_not_not_commute2_after

@[simp]
theorem BitStream.ofProp_eq_negOne_iff (p : Prop) :
    (BitStream.ofProp p = .negOne) ↔ p

theorem shl_shl_proof : shl_shl_before ⊑ shl_shl_after

@[simp]
theorem R.coeff_fromPoly (p : (ZMod q)[X]) :
    R.coeff (R.fromPoly (q := q) (n := n) p) = Polynomial.coeff (p %ₘ (f q n))

theorem or_or_logic_and_2_proof : or_or_logic_and_2_before ⊑ or_or_logic_and_2_after

theorem test_sext_zext_thm (e : IntW 16) : sext 64 (zext 32 e) ⊑ zext 64 e

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

@[simp] theorem xor_eq : (x ^^^ y) i = (xor (x i) (y i))

theorem xor_or_thm (e : IntW 8) :
  LLVM.or (LLVM.xor e (const? 8 32)) (const? 8 7) ⊑ LLVM.xor (LLVM.and e (const? 8 (-8))) (const? 8 39)

theorem bitwise_and_logical_and_icmps_comm1_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))
      (select (icmp IntPred.eq e (const? 8 42)) (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0))
        (const? 1 0)) ⊑
    select (icmp IntPred.eq e (const? 8 42))
      (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)))
      (const? 1 0)

theorem e_1995 :
     - 1 *  ~~~(a &&& (b ||| c)) + 1 * (b ^^^  ~~~(a &&&  ~~~c)) - 2 *  ~~~b + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 6 * (a &&& (b ||| c)) + 4 * (a ^^^ (b ||| c)) - 1 * (c ^^^  ~~~(a &&& b)) - 6 * (b ^^^ (a &&& (b ||| c))) + 1 *  ~~~(a ||| (b &&& c)) + 11 * ( ~~~b &&&  ~~~(a ^^^ c)) - 11 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 *  ~~~(a &&&  ~~~a) - 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 11 * (b ^^^ (a &&&  ~~~c)) + 7 * (c ^^^  ~~~(a ||| (b &&& c))) - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 11 * (b &&&  ~~~c) + 1 * ((a &&& b) |||  ~~~(b ||| c)) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 2 *  ~~~(b |||  ~~~c) + 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 2 * (a ||| b) + 1 *  ~~~(a ^^^ b) - 2 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 1 * ( ~~~a ||| ( ~~~b &&& c)) - 2 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 7 * (c &&& (a ^^^ b)) + 2 * (a ||| ( ~~~b &&& c)) - 5 *  ~~~a + 2 * ( ~~~b ||| (a ^^^ c)) + 5 * (a &&& b) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 7 * ( ~~~a &&& (b ||| c)) + 3 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 5 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 1 * (a ^^^ c) - 1 * (b |||  ~~~(a ||| c)) - 2 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 1 * (c ^^^  ~~~(a &&&  ~~~b)) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 1 * (b ||| (a &&&  ~~~c)) + 3 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 7 * (c ^^^  ~~~(a &&& (b ||| c))) + 4 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 2 * (b |||  ~~~(a ^^^ c)) - 6 * (a &&& ( ~~~b ||| c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) - 2 *  ~~~(a ^^^ ( ~~~b ||| c)) + 6 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 16 * ( ~~~a &&& (b &&& c)) + 30 * (a &&& ( ~~~b &&& c)) + 18 * (a &&& (b &&& c)) =  - 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c)))

theorem nonexact_ashr_eq_exactdiv_proof : nonexact_ashr_eq_exactdiv_before ⊑ nonexact_ashr_eq_exactdiv_after

theorem lshr_16_add_known_16_leading_zeroes_proof : lshr_16_add_known_16_leading_zeroes_before ⊑ lshr_16_add_known_16_leading_zeroes_after

theorem test15d_proof : test15d_before ⊑ test15d_after

theorem shl_bad_sub_i32_thm (e : IntW 32) :
  shl (const? 32 1) (sub (const? 32 32) e) ⊑
    shl (const? 32 1) (sub (const? 32 32) e) { «nsw» := false, «nuw» := true }

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

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

theorem lshr_shl_demand1_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ 3#8 ≥ ↑8) → x ≥ ↑8 → False

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 e_2255 :
     - 5 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 *  ~~~(d ^^^ e) - 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * ((d &&& e) |||  ~~~(e ||| f)) - 3 * (e ^^^ f) + 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(d &&& f) + 1 * (d ||| (e &&& f)) - 11 * (d ^^^ (e ^^^ f)) - 6 * (f ^^^ ( ~~~d ||| (e ||| f))) - 11 * (e ^^^ (d &&& f)) + 5 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (f ^^^ (d &&& (e ||| f))) + 3 * ( ~~~e ||| (d ^^^ f)) + 11 * ( ~~~d ||| (e ||| f)) + 5 * (d ||| f) - 6 *  ~~~(e ||| f) + 7 * ((d &&& f) |||  ~~~(e ||| f)) - 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 2 * (d ||| (e ||| f)) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 5 * f - 7 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * (d &&& (e ^^^ f)) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 4 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 4 * (e ^^^ (d ||| f)) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 *  ~~~(d ^^^ (e ||| f)) - 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 11 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f ||| (d &&&  ~~~e)) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (d &&&  ~~~f) - 2 *  ~~~(d &&&  ~~~e) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * (f &&& (d ^^^ e)) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e |||  ~~~(d ||| f)) - 6 * (d ^^^ (e ||| f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 5 * (e ^^^ (d ||| (e ^^^ f))) - 1 * ((d &&& e) ^^^ (e ||| f)) - 5 *  ~~~(d ||| (e ||| f)) + 29 *  ~~~(d ||| ( ~~~e ||| f)) - 7 *  ~~~( ~~~d ||| (e ||| f)) + 30 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 29 * ( ~~~d &&& ( ~~~e &&& f)) + 18 * ( ~~~d &&& (e &&& f)) + 5 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) =  - 1 * ( ~~~d ||| ( ~~~e ||| f))

theorem main14_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (0#16 ≤ₛ truncate 16 x) = 1#1 →
    ofBool (x &&& 32896#32 == 0#32) = 1#1 → ¬ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 1#32 = 2#32

theorem e_1301 :
    4 * (z |||  ~~~t) - 1 *  ~~~z + 1 *  ~~~(z &&& t) + 11 *  ~~~t - 3 *  ~~~(z ^^^ t) - 10 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) - 14 * (z &&&  ~~~t) + 1 * (z &&& t) = 2 *  ~~~(z &&&  ~~~z)

theorem udiv_shl_pair1_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 >>> x ≠ x_2 ∨ x ≥ ↑32 ∨ x_2 <<< x = 0) →
    True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32 → False

theorem test5_proof : test5_before ⊑ test5_after

theorem ne_nuw_rem_nz_thm (e : IntW 8) :
  icmp IntPred.ne (mul e (const? 8 5) { «nsw» := false, «nuw» := true }) (const? 8 (-30)) ⊑ const? 1 1

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 select_sub_icmp_bad_2_proof : select_sub_icmp_bad_2_before ⊑ select_sub_icmp_bad_2_after

theorem ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

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

@[grind =, simp, aesop 50% unsafe]
lemma states_addManyTrans (m : RawCNFA A) (as : List A) (s1 s2 : State) :
    (m.addManyTrans as s1 s2).states = m.states

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 test19a_proof : test19a_before ⊑ test19a_after

theorem icmp_eq_sext_ne_allones_proof : icmp_eq_sext_ne_allones_before ⊑ icmp_eq_sext_ne_allones_after
</all_available_lemmas>

<local_ctx>
import Batteries.Data.Fin.Basic

import Batteries.Data.Fin.Lemmas

import Blase.SingleWidth.Defs

import Blase.AutoStructs.Constructions

import Blase.AutoStructs.Defs

import Blase.AutoStructs.FiniteStateMachine

import Mathlib.Tactic.Ring

import Mathlib.Data.Nat.Size -- TODO: remove and get rid of shiftLeft_eq_mul_pow use

import Mathlib.Data.BitVec

import Mathlib.Tactic.FinCases

open Fin.NatCast

open Mathlib

section fsm

abbrev Alphabet (arity: Type) [FinEnum arity] := BitVec (FinEnum.card arity + 1)

variable {arity : Type} [FinEnum arity]

def finFunToBitVec [fe : FinEnum carry] (c : carry → Bool) : BitVec (FinEnum.card carry) :=
  BitVec.ofFn fun i => c (fe.equiv.invFun i)

def bitVecToFinFun [FinEnum ar] (bv : BitVec $ FinEnum.card ar) : ar → Bool :=
  fun c => bv[FinEnum.equiv.toFun c]

def NFA.ofFSM (p : FSM arity) : NFA (Alphabet arity) (p.α → Bool) where
  start := { q | q = p.initCarry }
  accept := ⊤
  step s a := {s' |
    let (s'', b) := p.nextBit s (bitVecToFinFun (a.truncate $ FinEnum.card arity))
    s' = s'' ∧ a.msb = b }

open BitStream in

def CNFA.ofFSM (p : FSM arity) : CNFA (FinEnum.card arity + 1) :=
  worklistRun (BitVec (FinEnum.card p.α))
    (fun _ => true)
    #[finFunToBitVec p.initCarry]
    (by admit /- proof elided -/
    )
    f
  where
</local_ctx>

<target_theorem>
@[simp]
lemma CNFA.ofFSM.f_spec {p : FSM arity} {s s' : BitVec (FinEnum.card p.α)} :
    (a, s') ∈ f p s ↔ bitVecToFinFun s' ∈ (NFA.ofFSM p).step (bitVecToFinFun s) a :=
</target_theorem>

