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>
BitVec in Init.Prelude
Fin in Init.Prelude
NFA in Mathlib.Computability.NFA
NFA.accept in Mathlib.Computability.NFA
NFA.start in Mathlib.Computability.NFA
NFA.step in Mathlib.Computability.NFA
Bool in Init.Prelude
Nat in Init.Prelude
BitVec.iunfoldr in Init.Data.BitVec.Folds
List in Init.Prelude
List.Vector in Mathlib.Data.Vector.Defs
Vector in Init.Data.Vector.Basic
Vector.ofFn in Init.Data.Vector.Basic
List.getLast in Init.Data.List.Basic
List.reverseRecOn in Mathlib.Data.List.Induction
NFA.stepSet in Mathlib.Computability.NFA

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

@[simp]
def _root_.Set.proj (f : Fin n → Fin m) (bvs : Set (BitVecs m)) : Set (BitVecs n) :=
  BitVecs.transport f '' bvs

def revertBvHyps (g : MVarId) : MetaM MVarId := do
  let (_, g) ← g.revert (← g.getNondepPropHyps)
  return g

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

Prod in Init.Prelude

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

scoped instance : Refinement (BitVec w) := .ofEq

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

def mul16_low_miss_shift_amount_before := [llvm|
{
^0(%arg4 : i16, %arg5 : i16):
  %0 = llvm.mlir.constant(127 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.and %arg4, %0 : i16
  %3 = llvm.lshr %arg4, %1 : i16
  %4 = llvm.and %arg5, %0 : i16
  %5 = llvm.lshr %arg5, %1 : i16
  %6 = llvm.mul %5, %2 : i16
  %7 = llvm.mul %4, %3 : i16
  %8 = llvm.mul %4, %2 : i16
  %9 = llvm.add %6, %7 : i16
  %10 = llvm.shl %9, %1 : i16
  %11 = llvm.add %10, %8 : i16
  "llvm.return"(%11) : (i16) -> ()
}
]

def no_masks_with_logical_or2_before := [llvm|
{
^0(%arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(63 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ne" %arg7, %0 : i32
  %4 = llvm.icmp "ne" %arg8, %1 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.icmp "ne" %arg9, %0 : i32
  %7 = llvm.or %5, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def test_sub_nuw__nsw_is_safe_before := [llvm|
{
^0(%arg22 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(-2147483647 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.or %arg22, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.sub %0, %3 overflow<nuw> : i32
  %6 = "llvm.select"(%4, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

IO.FS.Mode in Init.System.IO

def a_true_implies_b_false_before := [llvm|
{
^0(%arg24 : i8, %arg25 : i1, %arg26 : i1):
  %0 = llvm.mlir.constant(20 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "ugt" %arg24, %0 : i8
  %4 = llvm.icmp "ult" %arg24, %1 : i8
  %5 = "llvm.select"(%4, %arg25, %arg26) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = "llvm.select"(%3, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def not_and_and_not_commute1_after := [llvm|
{
^0(%arg561 : i32, %arg562 : i32, %arg563 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg562, %arg563 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %arg561, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def icmp_sle10_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.shl %arg3, %0 overflow<nsw> : i8
  %3 = llvm.icmp "sle" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

BitVec.shiftConcat in Init.Data.BitVec.Basic

def test_before := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(4294967294) : i64
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.or %arg0, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.srem %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def not_xor_to_or_not1_after := [llvm|
{
^0(%arg39 : i3, %arg40 : i3, %arg41 : i3):
  %0 = llvm.mlir.constant(-1 : i3) : i3
  %1 = llvm.or %arg40, %arg41 : i3
  %2 = llvm.and %arg39, %arg41 : i3
  %3 = llvm.xor %1, %0 : i3
  %4 = llvm.or %2, %3 : i3
  "llvm.return"(%4) : (i3) -> ()
}
]

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

def printPrefix (x : BitStream) : Nat → String
  | 0   => "0b"
  | n+1 =>
    let h := if x.head then "1" else "0"
    let t := x.tail.printPrefix n
    t ++ h

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

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

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

def icmp_ne_riscv_eq_icmp_ne_llvm_32_pseudo : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_neq_llvm_32, rhs:= icmp_ne_riscv_32_pseudo}

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 test4_after := [llvm|
{
^0(%arg193 : i32, %arg194 : i32):
  %0 = llvm.icmp "slt" %arg193, %arg194 : i32
  %1 = llvm.zext %0 : i1 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def mul_of_sdiv_fail_ub_before := [llvm|
{
^0(%arg1 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(-6 : i8) : i8
  %2 = llvm.sdiv exact %arg1, %0 : i8
  %3 = llvm.mul %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

def 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 add_hi_and_lo_negone_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_hi_and_lo_negone_llvm_i64
  rhs := add_hi_and_lo_negone_riscv_i64

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

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

def sub_ashr_or_i16_before := [llvm|
{
^0(%arg37 : i16, %arg38 : i16):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.sub %arg38, %arg37 overflow<nsw> : i16
  %2 = llvm.ashr %1, %0 : i16
  %3 = llvm.or %2, %arg37 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

def test11f_before := [llvm|
{
^0(%arg91 : i32, %arg92 : i32, %arg93 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mul %arg92, %arg93 : i32
  %2 = llvm.xor %1, %arg91 : i32
  %3 = llvm.xor %arg91, %0 : i32
  %4 = llvm.xor %1, %3 : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (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) -> ()
}
]

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

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

def p_after := [llvm|
{
^0(%arg60 : i32, %arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg60, %arg62 : i32
  %2 = llvm.xor %arg62, %0 : i32
  %3 = llvm.and %arg61, %2 : i32
  %4 = llvm.or disjoint %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def lshr_16_add_zext_basic_multiuse_after := [llvm|
{
^0(%arg31 : i16, %arg32 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.zext %arg31 : i16 to i32
  %2 = llvm.zext %arg32 : i16 to i32
  %3 = llvm.add %1, %2 overflow<nsw,nuw> : i32
  %4 = llvm.lshr %3, %0 : i32
  %5 = llvm.or %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

def substitute_constant_and_eq_eq_after := [llvm|
{
^0(%arg322 : i8, %arg323 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.icmp "eq" %arg322, %0 : i8
  %2 = llvm.icmp "eq" %arg323, %0 : i8
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (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 irc_constants_AMinusC1MinusC2_1_0 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (1) : i64
      %c2 = llvm.mlir.constant (0) : i64
      %0 = llvm.sub %a, %c1 : i64
      %1 = llvm.sub %0, %c2 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (1) : i64
      %c2 = llvm.mlir.constant (0) : i64
      %0 = llvm.add %c1, %c2 : i64
      %1 = llvm.sub %a, %0 : i64
      llvm.return %1 : i64
  }]

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 trunc_sel_equal_sext_after := [llvm|
{
^0(%arg77 : i32, %arg78 : i1):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.shl %arg77, %0 : i32
  %3 = llvm.ashr exact %2, %0 : i32
  %4 = "llvm.select"(%arg78, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test5_commuted_x_y_before := [llvm|
{
^0(%arg220 : i64, %arg221 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.xor %arg221, %arg220 : i64
  %2 = llvm.xor %arg220, %0 : i64
  %3 = llvm.or %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

BitVec.iunfoldr in Init.Data.BitVec.Folds

def test47_before := [llvm|
{
^0(%arg139 : i8):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.sext %arg139 : i8 to i32
  %2 = llvm.or %1, %0 : i32
  %3 = llvm.zext %2 : i32 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def NFA'.autSignedCmp (cmp: RelationOrdering) : NFA' 2 :=
  ⟨_, NFA.autSignedCmp cmp⟩

def xor_ugt_2_after := [llvm|
{
^0(%arg13 : i8, %arg14 : i8, %arg15 : i8):
  %0 = llvm.mlir.constant(63 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.add %arg13, %arg15 : i8
  %3 = llvm.and %arg14, %0 : i8
  %4 = llvm.or disjoint %3, %1 : i8
  %5 = llvm.xor %2, %4 : i8
  %6 = llvm.icmp "ugt" %2, %5 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

def Com.parseFromFile (d : Dialect)
    [DialectSignature d] [TransformTy d 0] [TransformExpr d 0] [TransformReturn d 0]
    (fileName : String) :
    IO (Option (Σ (Γ' : Ctxt d.Ty) (eff : EffectKind) (ty : List d.Ty), Com d Γ' eff ty)) := do
  parseRegionFromFile fileName fun region =>
    let res := mkCom (d:= d) region
    match res with
    | Except.error e => Except.error s!"Error:\n{reprStr e}"
    | Except.ok res => Except.ok res

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

def mkWidthFSM (wcard : Nat) (tcard : Nat) (bcard : Nat) (ncard icard : Nat) (pcard : Nat) (w : Nondep.WidthExpr) :
    (NatFSM wcard tcard bcard ncard icard pcard w) :=
  match w with
  | .const nat => {
      toFsm := (FSM.trueUptoExcluding nat).map Fin.elim0
    }
  | .var wnat =>
    if h : wnat < wcard then
      { toFsm :=
        composeUnaryAux FSM.scanAnd (FSM.var' (StateSpace.widthVar ⟨wnat, h⟩))
        
      }
    else
      { toFsm := FSM.zero' } 
  | .min v w =>
      { toFsm :=
        (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm &&& (mkWidthFSM wcard tcard bcard ncard icard pcard w).toFsm
      }
  | .max v w =>
        { toFsm :=
        (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm ||| (mkWidthFSM wcard tcard bcard ncard icard pcard w).toFsm
      }
  | .addK v k =>
    { toFsm :=
        composeUnaryAux (FSM.repeatN true k)  (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm
    }
  | .kadd k v =>
    { toFsm :=
        composeUnaryAux (FSM.repeatN true k)  (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm
    }

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

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

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

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

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

def or_or_and_pat8_after := [llvm|
{
^0(%arg46 : i8, %arg47 : i8, %arg48 : i8, %arg49 : i8):
  %0 = llvm.or %arg49, %arg46 : i8
  %1 = llvm.and %0, %arg47 : i8
  %2 = llvm.or %1, %arg48 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def c_1_0_0_after := [llvm|
{
^0(%arg20 : i4, %arg21 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.and %arg20, %0 : i4
  %3 = llvm.and %arg21, %1 : i4
  %4 = llvm.or disjoint %2, %3 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

@[simps]
def proj (M: NFA (BitVec n1) σ) (f : Fin n2 → Fin n1) : NFA (BitVec n2) σ where
  start := M.start
  accept := M.accept
  step q a := { q' | ∃ a', a'.transport f = a ∧ q' ∈ M.step q a' }

def c_1_0_0_after := [llvm|
{
^0(%arg20 : i4, %arg21 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.and %arg20, %0 : i4
  %3 = llvm.and %arg21, %1 : i4
  %4 = llvm.or disjoint %2, %3 : i4
  "llvm.return"(%4) : (i4) -> ()
}
]

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

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

BitVec.smod in Init.Data.BitVec.Basic

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

def andcond.010.inv.inner.cond.in.inner.sel_after := [llvm|
{
^0(%arg65 : i1, %arg66 : i1, %arg67 : i1, %arg68 : i1, %arg69 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg66, %arg69, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = "llvm.select"(%arg65, %1, %arg68) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def shrMax (a : BitVec v) (b : BitVec w) : BitVec (max v w) :=
    a.signExtend (max v w) >>> b.signExtend (max v w)

def ripple_nsw3_after := [llvm|
{
^0(%arg19 : i16, %arg20 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg20, %0 : i16
  %3 = llvm.and %arg19, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw,nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

Poly in Mathlib.NumberTheory.Dioph

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

def test2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32):
  %0 = llvm.xor %arg7, %arg6 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

def ripple_nsw2_before := [llvm|
{
^0(%arg21 : i16, %arg22 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(-16385 : i16) : i16
  %2 = llvm.and %arg22, %0 : i16
  %3 = llvm.and %arg21, %1 : i16
  %4 = llvm.add %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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 and_or_not_not_commute6_after := [llvm|
{
^0(%arg357 : i32, %arg358 : i32, %arg359 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg358 : i32
  %3 = llvm.or %arg359, %2 : i32
  %4 = llvm.and %3, %arg357 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def zero_sign_bit_after := [llvm|
{
^0(%arg31 : i16):
  %0 = llvm.mlir.constant(32767 : i16) : i16
  %1 = llvm.mlir.constant(512 : i16) : i16
  %2 = llvm.and %arg31, %0 : i16
  %3 = llvm.add %2, %1 overflow<nuw> : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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

def andn_or_cmp_2_after := [llvm|
{
^0(%arg170 : i16, %arg171 : i16, %arg172 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.icmp "slt" %arg170, %arg171 : i16
  %2 = llvm.icmp "ugt" %arg172, %0 : i16
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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 Tensor2d'.transpose (t : Tensor2d' α) : Tensor2d' α where
  dim₀ := t.dim₁
  dim₁ := t.dim₀
  mat := t.mat.transpose

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 List.product (l₁ : List α) (l₂ : List β) : List (α × β) := l₁.flatMap fun a => l₂.map (Prod.mk a)

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

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

def 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 ule_swap_or_not_min_commute_before := [llvm|
{
^0(%arg260 : i8, %arg261 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "uge" %arg261, %arg260 : i8
  %2 = llvm.icmp "ne" %arg260, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def inter (M N : NFA' n) : NFA' n := ⟨_, M.M.inter N.M⟩

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 test_mul_nuw__all_are_safe_after := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg14, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def or_and_shifts2_before := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(896 : i32) : i32
  %2 = llvm.mlir.constant(4 : i32) : i32
  %3 = llvm.mlir.constant(7 : i32) : i32
  %4 = llvm.shl %arg13, %0 : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.lshr %arg13, %2 : i32
  %7 = llvm.and %6, %3 : i32
  %8 = llvm.or %5, %7 : i32
  "llvm.return"(%8) : (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) -> ()
}
]

Complement in Init.Prelude

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

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

def fold_xor_zext_icmp_after := [llvm|
{
^0(%arg91 : i64, %arg92 : i64, %arg93 : i64):
  %0 = llvm.icmp "sgt" %arg91, %arg92 : i64
  %1 = llvm.icmp "slt" %arg91, %arg93 : i64
  %2 = llvm.xor %0, %1 : i1
  %3 = llvm.zext %2 : i1 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

Function.LeftInverse in Init.Data.Function

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

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

def and_sext_multiuse_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "sgt" %arg0, %arg1 : i32
  %2 = llvm.add %arg2, %arg3 : i32
  %3 = "llvm.select"(%1, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

@[simp_denote]
def ctxtTransformToLLVM  (Γ : Ctxt LLVMPlusRiscV.Ty) :=
  Ctxt.map  (fun ty  =>
    match ty with
    | .llvm someLLVMTy => someLLVMTy
    | .riscv _  => .bitvec 999
  ) Γ

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

def sext_zext_apint1_before := [llvm|
{
^0(%arg86 : i77):
  %0 = llvm.zext %arg86 : i77 to i533
  %1 = llvm.sext %0 : i533 to i1024
  "llvm.return"(%1) : (i1024) -> ()
}
]

def Lets.vars : Lets d Γ_in eff Γ_out → Var Γ_out t → VarSet Γ_in
  | .nil, v => VarSet.ofVar v
  | .var lets e, v => by admit /- proof elided -/
      | right v => exact lets.vars v
      | left _ => exact lets.varsOfVec e.args

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

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

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

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

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

def t1_otherbitwidth_after := [llvm|
{
^0(%arg11 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.and %arg11, %0 : i16
  %3 = llvm.sub %1, %2 overflow<nsw> : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

def t15_before := [llvm|
{
^0(%arg198 : i32, %arg199 : i32):
  %0 = llvm.shl %arg198, %arg199 overflow<nuw> : i32
  %1 = llvm.udiv %0, %arg198 : i32
  "llvm.return"(%1) : (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 trunc_shl_33_i32_i64_after := [llvm|
{
^0(%arg48 : i64):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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 throwUBIf [Pure m] (p : Prop) [Decidable p] : m Unit :=
  if p then HasUB.throwUB else pure ()

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

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

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

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

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

def different_size_zext_zext_ne_commute_before := [llvm|
{
^0(%arg20 : i7, %arg21 : i4):
  %0 = llvm.zext %arg20 : i7 to i25
  %1 = llvm.zext %arg21 : i4 to i25
  %2 = llvm.icmp "ne" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def llvm_udiv_lower_riscv_no_flag_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs := udiv_llvm_no_exact_32, rhs := udiv_riscv_32, correct :=
  by admit /- proof elided -/

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

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

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

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

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

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

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

def elim0 {α : Sort u} (i : Inputs ι 0) : α :=
  i.ix.elim0

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

def sltiu_test: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16)] where
  lhs := sltiu_llvm
  rhs := sltiu_riscv

def src_x_and_nmask_sge_after := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg18 overflow<nsw> : i8
  %2 = llvm.icmp "sle" %1, %arg17 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def t4_before := [llvm|
{
^0(%arg210 : i8, %arg211 : i1):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.mlir.constant(44 : i8) : i8
  %2 = "llvm.select"(%arg211, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %arg210, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg3 : i33):
  %0 = llvm.mlir.constant(4095 : i33) : i33
  %1 = llvm.and %arg3, %0 : i33
  "llvm.return"(%1) : (i33) -> ()
}
]

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

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

structure BitVecs (n : Nat) where
  w : Nat
  bvs : List.Vector (BitVec w) n

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

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

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

def narrow_sext_xor_before := [llvm|
{
^0(%arg48 : i16, %arg49 : i32):
  %0 = llvm.sext %arg48 : i16 to i32
  %1 = llvm.xor %0, %arg49 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

abbrev Width.concrete : Nat → Width φ := ConcreteOrMVar.concrete

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

def positive_samevar_shlnsw_ashrexact_after := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  "llvm.return"(%arg37) : (i8) -> ()
}
]

def sge_swap_or_max_logical_before := [llvm|
{
^0(%arg180 : i8, %arg181 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "sle" %arg181, %arg180 : i8
  %3 = llvm.icmp "eq" %arg180, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

@[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 llvm_shl_lower_riscv_nsw_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := shl_llvm_nsw_32
  rhs := shl_riscv_32

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

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

@[simp]
def WidthExpr.ofDep_kadd {wcard : Nat} {v : MultiWidth.WidthExpr wcard} {k : Nat} :
    (WidthExpr.ofDep (MultiWidth.WidthExpr.kadd k v)) =
    (.kadd k (.ofDep v)) := rfl

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

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

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

def positive_biggerlshr_lshrexact_before := [llvm|
{
^0(%arg40 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.lshr exact %arg40, %0 : i8
  %3 = llvm.shl %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

@[simp_llvm]
def neg? {w : Nat} (x : BitVec w) : IntW w := do
  .value <| (-.) x

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

def mul16_low_before := [llvm|
{
^0(%arg24 : i16, %arg25 : i16):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.and %arg24, %0 : i16
  %3 = llvm.lshr %arg24, %1 : i16
  %4 = llvm.and %arg25, %0 : i16
  %5 = llvm.lshr %arg25, %1 : i16
  %6 = llvm.mul %5, %2 : i16
  %7 = llvm.mul %4, %3 : i16
  %8 = llvm.mul %4, %2 : i16
  %9 = llvm.add %6, %7 : i16
  %10 = llvm.shl %9, %1 : i16
  %11 = llvm.add %10, %8 : i16
  "llvm.return"(%11) : (i16) -> ()
}
]

inductive ExpTy where
  | isl : ISL.Ty → ExpTy
  | regFile

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

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

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

def select_exact_lshr_icmp_const_after := [llvm|
{
^0(%arg146 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.lshr %arg146, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

Lean.Elab.WF.paramLet in Lean.Elab.PreDefinition.WF.Preprocess

def TermBinop.termGadget (t : TermBinop) : CNFA 3 :=
  match t with
  | .and => FSM.ofTerm (.and (.var 0) (.var 1)) |> CNFA.ofFSM
  | .or => FSM.ofTerm (.or (.var 0) (.var 1)) |> CNFA.ofFSM
  | .xor => FSM.ofTerm (.xor (.var 0) (.var 1)) |> CNFA.ofFSM
  | .add => FSM.ofTerm (.add (.var 0) (.var 1)) |> CNFA.ofFSM
  | .sub => FSM.ofTerm (.sub (.var 0) (.var 1)) |> CNFA.ofFSM

def src_is_mask_and_fail_mixed_after := [llvm|
{
^0(%arg119 : i8, %arg120 : i8, %arg121 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(-124 : i8) : i8
  %3 = llvm.ashr %0, %arg120 : i8
  %4 = llvm.lshr %1, %arg121 : i8
  %5 = llvm.and %3, %4 : i8
  %6 = llvm.xor %arg119, %2 : i8
  %7 = llvm.or %5, %6 : i8
  %8 = llvm.icmp "eq" %7, %1 : i8
  "llvm.return"(%8) : (i1) -> ()
}
]

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

@[simp]
def Env.get_ofEnvFin (envFin : EnvFin w n) (i : Fin n) :
    (Env.ofEnvFin envFin)[i] = envFin i :=

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

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

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

def and_or3_before := [llvm|
{
^0(%arg168 : i1, %arg169 : i1, %arg170 : i32, %arg171 : i32):
  %0 = llvm.icmp "eq" %arg170, %arg171 : i32
  %1 = llvm.and %arg169, %0 : i1
  %2 = "llvm.select"(%1, %arg168, %arg169) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

structure Item where
 name : String
 tac : Syntax

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

def scalar1_before := [llvm|
{
^0(%arg30 : i4, %arg31 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.xor %arg30, %arg31 : i4
  %2 = llvm.and %1, %0 : i4
  %3 = llvm.xor %2, %arg31 : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

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

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

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

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

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

@[simp_llvm_option]
def sdiv {w : Nat} (x y : IntW w) (flag : ExactFlag := {exact := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.exact ∧ x'.smod y' ≠ 0 then
    .poison
  else
    sdiv? x' y'

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

Std.HashMap.union in Std.Data.HashMap.Basic

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

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

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

def ne_210_after := [llvm|
{
^0(%arg76 : i32, %arg77 : i32):
  %0 = llvm.trunc %arg76 : i32 to i24
  %1 = llvm.trunc %arg77 : i32 to i24
  %2 = llvm.icmp "ne" %0, %1 : i24
  "llvm.return"(%2) : (i1) -> ()
}
]

instance : LawfulGetElem (Ctxt Ty) Nat Ty (fun as i => i < as.length) where
  getElem?_def Γ i _ := by admit /- proof elided -/

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

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

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

@[simp]
def Env.getLsb_eq_of_width_one (env : List (BitVec 1)) : Env.getLsb env = env :=

def shl_add_add_no_const_after := [llvm|
{
^0(%arg122 : i8, %arg123 : i8, %arg124 : i8, %arg125 : i8):
  %0 = llvm.add %arg123, %arg122 : i8
  %1 = llvm.shl %0, %arg124 : i8
  %2 = llvm.add %1, %arg125 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

@[simp_denote]
def add32_sext_accept_llvm := [LV| {
  ^entry (%a: i32):
  %0 = llvm.mlir.constant (2999) : i32
  %1 = llvm.add %a, %0 : i32
  llvm.return %1 : i32
}]

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

def positive_different_trunc_both_logical_after := [llvm|
{
^0(%arg36 : i32):
  %0 = llvm.mlir.constant(16384 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(128 : i16) : i16
  %3 = llvm.mlir.constant(256 : i16) : i16
  %4 = llvm.mlir.constant(false) : i1
  %5 = llvm.and %arg36, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.trunc %arg36 : i32 to i16
  %8 = llvm.add %7, %2 : i16
  %9 = llvm.icmp "ult" %8, %3 : i16
  %10 = "llvm.select"(%6, %9, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%10) : (i1) -> ()
}
]

@[tactic bvAutomataFragmentWidthLegal]
def evalBvAutomataFragmentIllegalWidth : Tactic := fun
| `(tactic| bv_automata_fragment_width_legal) => do
  let g ← getMainGoal
  g.withContext do
    let ws ← findExprBitwidths (← g.getType)
    let ws := ws.toArray
    if h0: ws.size = 0 then throwError m!"found no bitvector in the target: {indentD (← g.getType)}"
    else if hgt: ws.size > 1 then
      let (w1, wExample1) := ws[0]
      let (w2, wExample2) := ws[1]
      let mExample := m!"{w1} → {wExample1}; {w2} → {wExample2}"
      throwError m!"found multiple bitvector widths in the target: {indentD mExample}"
    else
      return ()
| _ => throwUnsupportedSyntax

RV64.div in RISCV.Instructions

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

def shl_and_and_before := [llvm|
{
^0(%arg172 : i8, %arg173 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(88 : i8) : i8
  %2 = llvm.shl %arg172, %0 : i8
  %3 = llvm.shl %arg173, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.and %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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 icmp_eq_sext_eq_otherwise_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg15, %0 : i32
  "llvm.return"(%1) : (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 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 and_min_7_7_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.and %arg2, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

Lean.Name.mkSimple in Init.Prelude

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

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

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

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

def or_nosignbit_select_ashr_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(8388352 : i32) : i32
  %2 = llvm.ashr %arg8, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = "llvm.select"(%arg9, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

instance : ToString (Expr d Γ eff t) where toString expr := s!"{expr.print}"

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

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

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

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

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

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

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

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

HEq in Init.Prelude

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

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

def slt_zero_slt_i1_fail_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg5 : i1 to i32
  %2 = llvm.lshr %arg4, %0 : i32
  %3 = llvm.icmp "slt" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

@[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'

Fin.clamp in Batteries.Data.Fin.Basic

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 t4_after := [llvm|
{
^0(%arg210 : i8, %arg211 : i1):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(-44 : i8) : i8
  %2 = "llvm.select"(%arg211, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.add %2, %arg210 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

def 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_09_before := [llvm|
{
^0(%arg228 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.ashr %arg228, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def BoolBinaryRelationKind.toSmtLib : BoolBinaryRelationKind → SexprPBV.BoolBinaryRelationKind
| .eq => .eq

@[simp, simp_denote]
def coe_toMonad [Pure m] {eff : EffectKind} : eff.toMonad m α → m α :=
  liftEffect (le_impure eff)

def irc_constants_C2MinusAPlusC1_2_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 lshrugt_01_14_exact_before := [llvm|
{
^0(%arg207 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.lshr exact %arg207, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def or_xor_tree_0111_after := [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.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

instance : Lean.ToExpr RegIndex := inherit

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

def udiv_shl_mul_nuw_exact_after := [llvm|
{
^0(%arg142 : i5, %arg143 : i5, %arg144 : i5):
  %0 = llvm.mlir.constant(1 : i5) : i5
  %1 = llvm.shl %0, %arg144 overflow<nuw> : i5
  %2 = llvm.udiv exact %1, %arg143 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

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

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

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

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

def test3_apint_after := [llvm|
{
^0(%arg43 : i47, %arg44 : i47):
  %0 = llvm.or %arg43, %arg44 : i47
  "llvm.return"(%0) : (i47) -> ()
}
]

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

def dec_mask_commute_neg_i32_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.sdiv %0, %arg6 : i32
  %4 = llvm.sub %1, %3 : i32
  %5 = llvm.and %3, %4 : i32
  %6 = llvm.add %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def test9_before := [llvm|
{
^0(%arg111 : i32, %arg112 : i32):
  %0 = llvm.and %arg111, %arg112 : i32
  %1 = llvm.xor %arg111, %arg112 : i32
  %2 = llvm.xor %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def Tensor2d'.extract (δ₀ δ₁ : Index) (sz₀ sz₁ : Index) (t : Tensor2d' α) : (Tensor2d' α) :=
  if SZ0 : δ₀ + sz₀ ≤ t.dim₀ then
    if SZ1 : δ₁ + sz₁ ≤ t.dim₁ then
      {
        dim₀ := sz₀,
        dim₁ := sz₁,
        mat := Matrix.of fun (ix₀ : Fin sz₀) (ix₁ : Fin sz₁) =>
          have INBOUNDS0 : δ₀ + ix₀ < t.dim₀ := by admit /- proof elided -/

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

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

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

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

def llvm_const_lower_riscv_li_6 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_6, rhs:= liRiscv_6,
   correct := by admit /- proof elided -/

def and_not_or_wrong_b_before := [llvm|
{
^0(%arg428 : i32, %arg429 : i32, %arg430 : i32, %arg431 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg428, %arg429 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %2, %arg430 : i32
  %4 = llvm.and %arg428, %arg430 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.or %5, %arg431 : i32
  %7 = llvm.and %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

def different_size_sext_sext_sgt_after := [llvm|
{
^0(%arg14 : i7, %arg15 : i4):
  %0 = llvm.sext %arg15 : i4 to i7
  %1 = llvm.icmp "sgt" %arg14, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def parseAndGeneralize
  [H : HydrableParseAndGeneralize parsedExpr genPred genExpr]
  (cfg : MedusaSynthGeneralizeConfig)
  (hExpr : Expr) (context: GeneralizeContext): TermElabM MessageData := do
    let targetWidth := 8
    let timeoutMs := 300000

    match_expr hExpr with
    | Eq w lhsExpr rhsExpr =>

          let some width ← H.getWidth w  | throwError m! "Could not determine the rewrite width from {w}"
          let startTime ← Core.liftIOCore IO.monoMsNow

          \n Input expression: {hExpr} has generalization: {pretty}"
                          | GeneralizeContext.Tactic _name =>
                            match cfg.output with
                            | .thmStmt =>
                              let name := Name.mkSimple "foo"
                              pure m! "{H.prettifyAsTheorem name res allVariables widthVals}"
                            | .sexpr =>
                              throwError (H.prettifyAsSexpr res allVariables) widthVals|> format
            | none => throwError m! "Could not generalize {bvLogicalExpr}"
    | _ => throwError m!"The top level constructor is not an equality predicate in {hExpr}"

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

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

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

def State.setMapping (e x : Expr) : GenM Unit := do
  let s ← get
  let m ← s.mapping.insert e x
  set {s with mapping := m}

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

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

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

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

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

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

HAnd.hAnd in Init.Prelude

def ashrsgt_02_08_exact_after := [llvm|
{
^0(%arg77 : i4):
  %0 = llvm.mlir.constant(true) : 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) -> ()
}
]

@[simp_denote]
def slt_riscv_i64 :=
  [LV| {
    ^entry (%arg0: i64, %arg1: i64):
    %a = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!i64)
    %b = "builtin.unrealized_conversion_cast" (%arg1) : (i64) -> (!i64)
    %2 = slt %a, %b : !i64
    %3 = "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i64)
    llvm.return %3 : i64
  }]

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

def both_before := [llvm|
{
^0(%arg9 : i8, %arg10 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg9 : i8
  %2 = llvm.shl %0, %arg10 : i8
  %3 = llvm.icmp "ugt" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

@[simp_denote]
def add_positive_low_bound_accept_llvm := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (2048) : i32
    %1 = llvm.add %0, %a : i32
    llvm.return %1 :i32
  }]

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

def one_sdiv { w : Nat} {a : BitVec w} (ha0 : a ≠ 0) (ha1 : a ≠ 1)
    (hao : a ≠ allOnes w) :
    BitVec.sdiv (1#w) a = 0#w :=

def no_masks_with_logical_or2_after := [llvm|
{
^0(%arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(63 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ne" %arg8, %0 : i32
  %4 = llvm.and %arg7, %arg9 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = "llvm.select"(%5, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def cmpne_xor_cst1_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.xor %arg20, %0 : i32
  %2 = llvm.icmp "ne" %1, %arg21 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def test15g_before := [llvm|
{
^0(%arg21 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.mlir.constant(-9 : i32) : i32
  %4 = llvm.and %arg21, %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 ult_to_slt_after := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.icmp "slt" %arg32, %arg33 : i8
  "llvm.return"(%0) : (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 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 test7_after := [llvm|
{
^0(%arg81 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.lshr %arg81, %0 : i64
  %2 = llvm.zext nneg %1 : i64 to i92
  "llvm.return"(%2) : (i92) -> ()
}
]

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

def zext_sext_sgt_known_nonneg_after := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.udiv %0, %arg24 : i8
  %2 = llvm.icmp "sgt" %1, %arg25 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def atZero (f : LoopBody t) : t → t := fun v => f 0 v

@[simp_riscv]
def not_pseudo (rs1_val : BitVec 64) : BitVec 64 :=
  RV64.xori (-1) rs1_val

def xor_common_op_commute2_before := [llvm|
{
^0(%arg204 : i8, %arg205 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.xor %arg204, %0 : i8
  %2 = llvm.xor %1, %arg205 : i8
  %3 = llvm.or %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def test13_before := [llvm|
{
^0(%arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(-1431655767 : i32) : i32
  %1 = llvm.mlir.constant(1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.or %arg44, %0 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %arg45, %2 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

def select_riscv_select_llvm_32 : LLVMPeepholeRewriteRefine 32
  [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 1)] where
  lhs := select_llvm_32
  rhs := select_riscv_32

@[simp_denote]
def srem {Γ : Ctxt _} (w : ℕ) (l r : Nat)
    (lp : (Γ[l]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      )
    (rp : (Γ[r]? = some (InstCombine.MTy.bitvec (ConcreteOrMVar.concrete w)))
      := by admit /- proof elided -/
      ) :
    Expr InstCombine.LLVM Γ .pure (LLVM.Ty.bitvec w) :=
  Expr.mk
    (op := InstCombine.MOp.srem w)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := rfl)
    (args := .cons ⟨l, lp⟩ <| .cons ⟨r, rp⟩ .nil)
    (regArgs := .nil)

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

def ashr_2_add_zext_basic_before := [llvm|
{
^0(%arg35 : i1, %arg36 : i1):
  %0 = llvm.mlir.constant(1 : i2) : i2
  %1 = llvm.zext %arg35 : i1 to i2
  %2 = llvm.zext %arg36 : i1 to i2
  %3 = llvm.add %1, %2 : i2
  %4 = llvm.ashr %3, %0 : i2
  "llvm.return"(%4) : (i2) -> ()
}
]

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

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

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

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

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

partial def balancedBracketsFnAux (startPos: String.Pos.Raw)
  (i: String.Pos.Raw)
  (bs: List Bracket) (ctx: ParserContext) (s: ParserState): ParserState :=
  if ctx.atEnd i
  then s.mkError "found EOF"
  else
  match ctx.get i with
  
  | '(' => balancedBracketsFnAux startPos (ctx.next i) (Bracket.Round::bs) ctx s
  | '[' => balancedBracketsFnAux startPos (ctx.next i) (Bracket.Square::bs) ctx s
  | '<' => balancedBracketsFnAux startPos (ctx.next i) (Bracket.Angle::bs) ctx s
  | '{' => balancedBracketsFnAux startPos (ctx.next i) (Bracket.Curly::bs) ctx s
  
  | ')' => consumeCloseBracket Bracket.Round startPos i bs ctx s
  | ']' => consumeCloseBracket Bracket.Square startPos i bs ctx s
  | '>' => consumeCloseBracket Bracket.Angle startPos i bs ctx s
  | '}' => consumeCloseBracket Bracket.Curly startPos i bs ctx s
  | _c => balancedBracketsFnAux startPos (ctx.next i) bs ctx s

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

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

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

def not_signbit_splat_mask1_after := [llvm|
{
^0(%arg109 : i8, %arg110 : i16):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg109, %0 : i8
  %2 = llvm.zext %1 : i8 to i16
  %3 = llvm.and %arg110, %2 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

def bools_after := [llvm|
{
^0(%arg51 : i1, %arg52 : i1, %arg53 : i1):
  %0 = "llvm.select"(%arg53, %arg52, %arg51) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def mulo_by_2_unsigned : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (2) : i64
      %0 = llvm.mul %x, %c overflow<nuw> : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %0 = llvm.add %x, %x overflow<nuw> : i64
      llvm.return %0 : i64
  }]

def composeQuinaryAux' (p : FSM (Fin 5)) (q₀ q₁ q₂ q₃ q₄: FSM α) : FSM α :=
  p.compose (α)
    (λ _ => α)
    (λ _ i => i)
    (λ v =>
      v.cases q₀ fun v =>
        v.cases q₁ fun v =>
          v.cases q₂ fun v =>
            v.cases q₃ fun v =>
              v.cases q₄ fun v => v.elim0)

def and_zext_eq_zero_before := [llvm|
{
^0(%arg28 : i32, %arg29 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "eq" %arg28, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.lshr %arg28, %arg29 : i32
  %5 = llvm.xor %4, %1 : i32
  %6 = llvm.and %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def test22_before := [llvm|
{
^0(%arg189 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.xor %arg189, %0 : i1
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.xor %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def xor_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := xor_llvm_i32
  rhs := xor_riscv_i32

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

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 test_invert_demorgan_or3_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.mlir.constant(178206 : i32) : i32
  %1 = llvm.mlir.constant(-196608 : i32) : i32
  %2 = llvm.mlir.constant(-1506 : i32) : i32
  %3 = llvm.mlir.constant(-917760 : i32) : i32
  %4 = llvm.mlir.constant(-716213 : i32) : i32
  %5 = llvm.mlir.constant(-1114112 : i32) : i32
  %6 = llvm.mlir.constant(-196112 : i32) : i32
  %7 = llvm.icmp "ne" %arg13, %0 : i32
  %8 = llvm.add %arg14, %1 : i32
  %9 = llvm.icmp "ult" %8, %2 : i32
  %10 = llvm.add %arg14, %3 : i32
  %11 = llvm.icmp "ult" %10, %4 : i32
  %12 = llvm.add %arg14, %5 : i32
  %13 = llvm.icmp "ult" %12, %6 : i32
  %14 = llvm.and %7, %9 : i1
  %15 = llvm.and %14, %11 : i1
  %16 = llvm.and %15, %13 : i1
  "llvm.return"(%16) : (i1) -> ()
}
]

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

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

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

def or_or_and_pat4_before := [llvm|
{
^0(%arg62 : i8, %arg63 : i8, %arg64 : i8, %arg65 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg64 : i8
  %2 = llvm.and %arg62, %arg63 : i8
  %3 = llvm.and %arg65, %arg63 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def foldConstraints (expr: BoolExpr α) (constraints: List (BoolExpr α)) (op: Gate) : BoolExpr α :=
    match constraints with
    | [] => expr
    | x :: xs =>
      foldConstraints (BoolExpr.gate op expr x) xs op

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

BitVec.cons in Init.Data.BitVec.Basic

def test_invert_demorgan_logical_or_after := [llvm|
{
^0(%arg11 : i64, %arg12 : i64):
  %0 = llvm.mlir.constant(27) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "ne" %arg11, %0 : i64
  %4 = llvm.icmp "ne" %arg12, %1 : i64
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = llvm.icmp "ne" %arg11, %1 : i64
  %7 = llvm.and %6, %5 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

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

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

def OrSextSext : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := [LV| {
    ^entry (%x: i32, %y: i32):
      %0 = llvm.sext %x : i32 to i64
      %1 = llvm.sext %y : i32 to i64
      %2 = llvm.or %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i32, %y: i32):
      %0 = llvm.or %x, %y : i32
      %1 = llvm.sext %0 : i32 to i64
      llvm.return %1 : i64
  }]

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

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

def 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 select_constants_and_icmp_eq0_common_bit_before := [llvm|
{
^0(%arg40 : i1, %arg41 : i1):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = "llvm.select"(%arg40, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = "llvm.select"(%arg41, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %5 = llvm.and %3, %4 : i8
  %6 = llvm.icmp "eq" %5, %2 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

String.intercalate in Init.Data.String.Defs

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

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

def nonempty [DecidableEq α] (c : Circuit α) : Bool :=
  (nonemptyAux c c.vars rfl).1

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

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

def test_ne_0_and_15_add_3_before := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.add %arg2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.icmp "ne" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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 or_not_and_commute8_after := [llvm|
{
^0(%arg513 : i32, %arg514 : i32, %arg515 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg513 : i32
  %3 = llvm.sdiv %0, %arg514 : i32
  %4 = llvm.xor %3, %arg515 : i32
  %5 = llvm.xor %2, %1 : i32
  %6 = llvm.and %4, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

def add_nuw_const_const_sub_before := [llvm|
{
^0(%arg55 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-127 : i8) : i8
  %2 = llvm.add %arg55, %0 overflow<nuw> : i8
  %3 = llvm.sub %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def shl_xor_before := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(16 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(3 : i8) : i8
  %3 = llvm.shl %0, %arg22 : i8
  %4 = llvm.add %arg22, %1 : i8
  %5 = llvm.shl %2, %4 : i8
  %6 = llvm.xor %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def test11_after := [llvm|
{
^0(%arg184 : i32, %arg185 : i32):
  %0 = llvm.and %arg185, %arg184 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def mul_may_overflow_before := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(4294967295 : i34) : i34
  %1 = llvm.zext %arg8 : i32 to i34
  %2 = llvm.zext %arg9 : i32 to i34
  %3 = llvm.mul %1, %2 : i34
  %4 = llvm.icmp "ule" %3, %0 : i34
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def resNames : List SSAVal :=
  op.res.map Prod.fst

def appendInl (v : Γ.Var t) : (Γ ++ Δ).Var t :=
  ⟨v.val, by admit /- proof elided -/
  ⟩

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

def scalar_i16_shl_and_negC_eq_before := [llvm|
{
^0(%arg33 : i16, %arg34 : i16):
  %0 = llvm.mlir.constant(-128 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.shl %arg33, %arg34 : i16
  %3 = llvm.and %2, %0 : i16
  %4 = llvm.icmp "eq" %3, %1 : i16
  "llvm.return"(%4) : (i1) -> ()
}
]

def ashrsgt_02_02_exact_before := [llvm|
{
^0(%arg83 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.ashr exact %arg83, %0 : i4
  %2 = llvm.icmp "sgt" %1, %0 : i4
  "llvm.return"(%2) : (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 bools_logical_commute0_and2_after := [llvm|
{
^0(%arg102 : i1, %arg103 : i1, %arg104 : i1):
  %0 = "llvm.select"(%arg104, %arg103, %arg102) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

def a_after := [llvm|
{
^0(%arg48 : i1, %arg49 : i1):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.sext %arg49 : i1 to i32
  %3 = "llvm.select"(%arg48, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.add %3, %2 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def sltu_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := sltu_llvm_i32
  rhs := sltu_riscv_i32

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

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

@[simp_denote]
def sltu_riscv :=
  [LV| {
    ^entry (%arg0: i16, %arg1: i16):
    %a0 = "builtin.unrealized_conversion_cast" (%arg0) : (i16) -> (!i64)
    %a1 = "builtin.unrealized_conversion_cast" (%arg1) : (i16) -> (!i64)
    %0 = li (149595403036) : !i64 
    %1 = "lui" (%0) {imm = 16 : !i64} : (!i64) -> (!i64)
    %2 = "addi" (%1) {imm = -1 : !i64} : (!i64) -> (!i64)
    %3 = and %2, %a1 : !i64
    %4 = and %2, %a0 : !i64
    %5 = sltu %4, %3 : !i64
    %6 = "builtin.unrealized_conversion_cast" (%5) : (!i64) -> (i16)
    llvm.return %6 :i16
  }]

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

def rhs := [poly q, n, hq | {
^bb0(%a : !R):
  return %a : !R

}]

def shl_or_lshr_comm_after := [llvm|
{
^0(%arg106 : i32, %arg107 : i32, %arg108 : i32):
  %0 = llvm.lshr %arg108, %arg107 : i32
  %1 = llvm.or %0, %arg106 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def a_or_b_const_before := [llvm|
{
^0(%arg10 : i32, %arg11 : i32, %arg12 : i32):
  %0 = llvm.icmp "eq" %arg10, %arg12 : i32
  %1 = llvm.icmp "ne" %arg11, %arg12 : i32
  %2 = llvm.and %0, %1 : i1
  %3 = llvm.icmp "ne" %arg10, %arg12 : i32
  %4 = llvm.icmp "eq" %arg11, %arg12 : i32
  %5 = llvm.and %3, %4 : i1
  %6 = llvm.or %2, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def sdiv_exact_eq_9_no_of_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(9 : i8) : i8
  %2 = llvm.and %arg9, %0 : i8
  %3 = llvm.mul %2, %1 overflow<nsw,nuw> : i8
  %4 = llvm.icmp "eq" %3, %arg8 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def t9_highest_bit_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i64, %arg27 : i32):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.zext %arg25 : i32 to i64
  %3 = llvm.lshr %arg26, %0 : i64
  %4 = llvm.and %3, %2 : i64
  %5 = llvm.icmp "ne" %4, %1 : i64
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

structure RawCNFA.SimulFun (m : RawCNFA A) (M : NFA A Q) (f : m.states ≃ Q)  where
  accept {q} : ((f.invFun q).val ∈ m.finals ↔ q ∈ M.accept)
  initial {q} : q ∈ M.start ↔ (f.invFun q).val ∈ m.initials
  trans_match {a q q'} : q' ∈ M.step q a ↔ (f.invFun q').val ∈ m.tr (f.invFun q) a

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

partial def collectWidthExpr (state : CollectState) (e : Expr) :
    SolverM (MultiWidth.Nondep.WidthExpr × CollectState) := do
  if let some v ← getNatValue? e then
    return (.const v, state)
  else
    match_expr e with
    | Nat.succ n =>
      let (we, state) ← collectWidthExpr state n
      return (.addK we 1, state)
    | min nat _inst x y =>
      match_expr nat with
      | Nat =>
        let (wx, state) ← collectWidthExpr state x
        let (wy, state) ← collectWidthExpr state y
        return (.min wx wy, state)
      | _ => mkAtom
    | max nat _inst x y =>
      match_expr nat with
      | Nat =>
        let (wx, state) ← collectWidthExpr state x
        let (wy, state) ← collectWidthExpr state y
        return (.max wx wy, state)
      | _ => mkAtom
    | HAdd.hAdd _nat0 _nat1 _nat2 _inst a b =>
      match_expr _nat0 with
      | Nat =>
        match_expr _nat1 with
        | Nat =>
          match_expr _nat2 with
          | Nat => do
            if let some a ← getNatValue? a then
              let (wb, state) ← collectWidthExpr state b
              return (.kadd a wb, state)
            else
              let (wa, state) ← collectWidthExpr state a
              if let some b ← getNatValue? b then
                return (.addK wa b, state)
              else
                mkAtom
          | _ => mkAtom
        | _ => mkAtom
      | _ => mkAtom
    | _ => mkAtom
    where
      mkAtom := do
        let (we, state) ← collectWidthAtom state e
        return (we, state)

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

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

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

def neg (x : BitStream) : BitStream :=
  fun n => (negAux x n).1

def twoway_clamp_lt_after := [llvm|
{
^0(%arg15 : i32):
  %0 = llvm.mlir.constant(13767 : i32) : i32
  %1 = llvm.mlir.constant(13768 : i32) : i32
  %2 = llvm.icmp "sgt" %arg15, %0 : i32
  %3 = "llvm.select"(%2, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

instance : HydrableGetInputWidth where
  getWidth := Fp.getWidth

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

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

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

partial def deductiveSearch (expr: GenBVExpr w) (constants: Std.HashMap Nat BVExpr.PackedBitVec)
      (target: BVExpr.PackedBitVec) (depth: Nat) (parent: Nat) : TermElabM (List (GenBVExpr target.w)) := do

    let updatePackedBVWidth (orig : BVExpr.PackedBitVec) (newWidth: Nat) : BVExpr.PackedBitVec :=
        if orig.w < newWidth then
            if orig.bv < 0 then
             {bv := orig.bv.signExtend newWidth, w := newWidth}
            else {bv := orig.bv.zeroExtend newWidth, w := newWidth}
        else if orig.w > newWidth then
            {bv := orig.bv.truncate newWidth, w := newWidth}
        else
            orig

    match depth with
      | 0 => return []
      | _ =>
            let mut res : List (GenBVExpr target.w) := []

            for (constId, constVal) in constants.toArray do
              let newVar : GenBVExpr target.w := GenBVExpr.var constId

              if constVal == target then
                res := newVar :: res
                continue

              if constId == parent then 
                continue

              if target.bv == 0 then
                res := GenBVExpr.const 0 :: res

              let newConstVal := (updatePackedBVWidth constVal target.w)
              let h : newConstVal.w = target.w := sorry

              let constBv := h ▸ newConstVal.bv
              
              if BitVec.not constBv == target.bv then
                res := GenBVExpr.un BVUnOp.not newVar :: res

              
              let addRes ← deductiveSearch expr constants {bv := target.bv - constBv} (depth-1) constId
              res := res ++ addRes.map (λ resExpr => GenBVExpr.bin newVar BVBinOp.add resExpr)

              
              let subRes ← deductiveSearch expr constants {bv := constBv - target.bv} (depth-1) constId
              res := res ++ subRes.map (λ resExpr => GenBVExpr.bin newVar BVBinOp.add (negate resExpr))

              
              let subRes' ← deductiveSearch expr constants {bv := target.bv + constBv}  (depth-1) constId
              res := res ++ subRes'.map (λ resExpr => GenBVExpr.bin (resExpr) BVBinOp.add (negate newVar))

              
              if (BitVec.srem target.bv constBv) == 0 && (BitVec.sdiv target.bv constBv != 0) then
                let mulRes ← deductiveSearch expr constants {bv := BitVec.sdiv target.bv constBv} (depth - 1) constId
                res := res ++ mulRes.map (λ resExpr => GenBVExpr.bin newVar BVBinOp.mul resExpr)

              
              if target.bv != 0 && (BitVec.umod constBv target.bv) == 0 then
                let divRes ← deductiveSearch expr constants {bv := BitVec.udiv constBv target.bv} (depth - 1) constId
                res := res ++ divRes.map (λ resExpr => GenBVExpr.bin newVar BVBinOp.udiv resExpr)

            return res

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

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

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

def XorAndAnd : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64, %z: i64):
      %0 = llvm.and %x, %z : i64
      %1 = llvm.and %y, %z : i64
      %2 = llvm.xor %0, %1 : i64
      llvm.return %2 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64, %z: i64):
      %0 = llvm.xor %x, %y : i64
      %1 = llvm.and %0, %z : i64
      llvm.return %1 : i64
  }]

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

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

def eq_21_comm_and_before := [llvm|
{
^0(%arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg122, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg122, %1 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg123, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg123, %1 : i32
  %9 = llvm.trunc %8 : i32 to i8
  %10 = llvm.icmp "eq" %3, %7 : i8
  %11 = llvm.icmp "eq" %5, %9 : i8
  %12 = llvm.and %10, %11 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

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 or_not_and_commute1_after := [llvm|
{
^0(%arg534 : i32, %arg535 : i32, %arg536 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg535 : i32
  %3 = llvm.xor %2, %arg536 : i32
  %4 = llvm.xor %arg534, %1 : i32
  %5 = llvm.and %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def alive_AndOrXor_2627_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%a : _, %c : _, %b : _):
  %v1 = llvm.mlir.constant -1
  %v2 = llvm.xor %a, %v1
  %v3 = llvm.and %v2, %b
  %v4 = llvm.xor %a, %c
  %v5 = llvm.or %a, %b
  %v6 = llvm.xor %v3, %c
  llvm.return %v6
}]

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

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

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

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

def or_and_or_pat8_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8, %arg12 : i8, %arg13 : i8):
  %0 = llvm.or %arg13, %arg10 : i8
  %1 = llvm.and %0, %arg11 : i8
  %2 = llvm.or %1, %arg12 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def or_zext_zext_after := [llvm|
{
^0(%arg56 : i8, %arg57 : i4):
  %0 = llvm.zext %arg57 : i4 to i8
  %1 = llvm.or %arg56, %0 : i8
  %2 = llvm.zext %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def or_xor_common_op_commute5_after := [llvm|
{
^0(%arg120 : i8, %arg121 : i8, %arg122 : i8):
  %0 = llvm.or %arg121, %arg120 : i8
  %1 = llvm.or %0, %arg122 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def EqualUpTo (w : Nat) (x y : BitStream) : Prop :=
  ∀ i < w, x i = y i

def udiv_illegal_type_before := [llvm|
{
^0(%arg23 : i9, %arg24 : i9):
  %0 = llvm.zext %arg23 : i9 to i32
  %1 = llvm.zext %arg24 : i9 to i32
  %2 = llvm.udiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def wrongimm2_before := [llvm|
{
^0(%arg4 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.lshr %arg4, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.trunc %arg4 : i16 to i8
  %5 = llvm.ashr %4, %1 : i8
  %6 = llvm.icmp "eq" %5, %3 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

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 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 uge_umin1_before := [llvm|
{
^0(%arg52 : i32, %arg53 : i32):
  %0 = llvm.icmp "ult" %arg52, %arg53 : i32
  %1 = "llvm.select"(%0, %arg52, %arg53) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "uge" %1, %arg52 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

Lean.ofReduceBool in Init.Core

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 ult_rem_zero_before := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(21 : i8) : i8
  %2 = llvm.mul %arg174, %0 overflow<nuw> : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def select_bittest_to_sub_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.and %arg4, %0 : i32
  %3 = llvm.sub %1, %2 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

def add_smin_simplify2_before := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(-3 : i32) : i32
  %1 = llvm.mlir.constant(2147483645 : i32) : i32
  %2 = llvm.add %arg33, %0 overflow<nsw> : i32
  %3 = llvm.icmp "slt" %2, %1 : i32
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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 uadd_sat_flipped_wrong_bounds_after := [llvm|
{
^0(%arg96 : i32):
  %0 = llvm.mlir.constant(-13 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.icmp "ugt" %arg96, %0 : i32
  %4 = llvm.add %arg96, %1 : i32
  %5 = "llvm.select"(%3, %2, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def AttrEntry.destructure {φ} : AttrEntry φ → String × AttrValue φ
  | .mk name value => (name,value)

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

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

def or_or_and_complex_after := [llvm|
{
^0(%arg82 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.mlir.constant(71777214294589695) : i64
  %2 = llvm.mlir.constant(-71777214294589696) : i64
  %3 = llvm.lshr %arg82, %0 : i64
  %4 = llvm.shl %arg82, %0 : i64
  %5 = llvm.and %3, %1 : i64
  %6 = llvm.and %4, %2 : i64
  %7 = llvm.or disjoint %5, %6 : i64
  "llvm.return"(%7) : (i64) -> ()
}
]

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

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

def or_logic_or_logic_and_2_before := [llvm|
{
^0(%arg45 : i1, %arg46 : i1, %arg47 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg45, %arg46 : i1
  %3 = "llvm.select"(%arg47, %0, %arg45) <{"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 t9_ashr_exact_flag_preservation_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.ashr exact %arg25, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

instance {test : ConcreteCliTest} : ToString (toType test.ty) where
  toString :=
    match test.ty with
    | bitvec w => inferInstanceAs (ToString (PoisonOr <| BitVec w)) |>.toString

def ugt_swap_and_not_min_commute_before := [llvm|
{
^0(%arg66 : i8, %arg67 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ult" %arg67, %arg66 : i8
  %2 = llvm.icmp "ne" %arg66, %0 : i8
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def testi64i32_after := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.mlir.constant(-128 : i32) : i32
  %3 = llvm.icmp "sgt" %arg8, %0 : i64
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

structure State where
   
  mapping : DiscrTree Expr
  invMapping : Std.HashMap Expr Expr
  deriving Inhabited

Int.instAdd in Init.Data.Int.Basic

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

def ashr_lshr_exact_lshr_only_before := [llvm|
{
^0(%arg127 : i32, %arg128 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "sgt" %arg127, %0 : i32
  %2 = llvm.lshr exact %arg127, %arg128 : i32
  %3 = llvm.ashr %arg127, %arg128 : i32
  %4 = "llvm.select"(%1, %2, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

NFA in Mathlib.Computability.NFA

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

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

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

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

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

instance {cmp} : Fintype (NFA'.autSignedCmp cmp).σ :=

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

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

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

def no_shift_xor_multiuse_xor_after := [llvm|
{
^0(%arg132 : i32, %arg133 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg132, %0 : i32
  %2 = llvm.xor %arg133, %0 : i32
  %3 = llvm.xor %1, %arg133 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.mul %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

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

def mapOpt {α β : Type} (s : Stream α) (f : α → (Option β)) : Stream β :=
  fun i => (s i).bind f

def t0_const_after_fold_lshr_shl_ne_before := [llvm|
{
^0(%arg43 : i32, %arg44 : i64, %arg45 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.sub %0, %arg45 : i32
  %4 = llvm.lshr %arg43, %3 : i32
  %5 = llvm.add %arg45, %1 : i32
  %6 = llvm.zext %5 : i32 to i64
  %7 = llvm.shl %arg44, %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 select_t_cond : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.select %c, %t, %0 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%c: i1, %t: i64):
      %0 = llvm.sext %c: i1 to i64
      %1 = llvm.freeze %t : i64
      %2 = llvm.and %0, %1 : i64
      llvm.return %2 : i64
  }]

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

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

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

def source : TokenStream :=
  Stream.corec () fun () => (some (), ())

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

def select_icmp_eq_and_4096_0_xor_4096_after := [llvm|
{
^0(%arg221 : i32, %arg222 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg221, %0 : i32
  %2 = llvm.xor %arg222, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def one_side_fold_eq_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i32, %arg27 : i32, %arg28 : i1):
  %0 = "llvm.select"(%arg28, %arg25, %arg27) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %1 = "llvm.select"(%arg28, %arg26, %arg27) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %2 = llvm.icmp "eq" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def sle_swap_or_min_after := [llvm|
{
^0(%arg150 : i8, %arg151 : i8):
  %0 = llvm.icmp "sge" %arg151, %arg150 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def test2_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i1):
  %0 = llvm.and %arg30, %arg31 : i1
  %1 = llvm.and %0, %arg30 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

inductive ExTy
  | nat
  | bool
  deriving DecidableEq

noncomputable def R.leadingTerm {q n} (a : R q n) : R q n :=
  let deg? := Polynomial.degree a.representative
  match deg? with
    | .none => 0
    | .some deg =>  R.monomial (a.coeff deg) deg

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

def ConcreteCliTest.printSignature (test : ConcreteCliTest) : String :=
  s!"{test.context.toList.reverse} → {test.ty}"

def test13_after := [llvm|
{
^0(%arg0 : i1024):
  %0 = llvm.mlir.constant(1016 : i1024) : i1024
  %1 = llvm.lshr %arg0, %0 : i1024
  "llvm.return"(%1) : (i1024) -> ()
}
]

def test86_after := [llvm|
{
^0(%arg59 : i16):
  %0 = llvm.mlir.constant(4 : i16) : i16
  %1 = llvm.ashr %arg59, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

def product (accept? : Prop → Prop → Prop) (M : NFA α σ) (N : NFA α ς) : NFA α (σ × ς) where
  step := fun (q₁, q₂) a => { (q₁', q₂') | (q₁' ∈ M.step q₁ a) ∧ (q₂' ∈ N.step q₂ a) }
  start := { (q₁, q₂) | (q₁ ∈ M.start) ∧ (q₂ ∈ N.start) }
  accept := { (q₁, q₂) | accept? (q₁ ∈ M.accept) (q₂ ∈ N.accept) }

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

def test_or_eq_a_b_after := [llvm|
{
^0(%arg36 : i1, %arg37 : i8, %arg38 : i8):
  %0 = "llvm.select"(%arg36, %arg37, %arg38) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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 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 select_icmp_slt_zero_smin_before := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.icmp "slt" %arg7, %0 : i8
  %3 = llvm.xor %arg7, %1 : i8
  %4 = "llvm.select"(%2, %arg7, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def test_invert_demorgan_or3_before := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.mlir.constant(178206 : i32) : i32
  %1 = llvm.mlir.constant(-195102 : i32) : i32
  %2 = llvm.mlir.constant(1506 : i32) : i32
  %3 = llvm.mlir.constant(-201547 : i32) : i32
  %4 = llvm.mlir.constant(716213 : i32) : i32
  %5 = llvm.mlir.constant(-918000 : i32) : i32
  %6 = llvm.mlir.constant(196112 : i32) : i32
  %7 = llvm.mlir.constant(true) : i1
  %8 = llvm.icmp "eq" %arg13, %0 : i32
  %9 = llvm.add %arg14, %1 : i32
  %10 = llvm.icmp "ult" %9, %2 : i32
  %11 = llvm.add %arg14, %3 : i32
  %12 = llvm.icmp "ult" %11, %4 : i32
  %13 = llvm.add %arg14, %5 : i32
  %14 = llvm.icmp "ult" %13, %6 : i32
  %15 = llvm.or %8, %10 : i1
  %16 = llvm.or %15, %12 : i1
  %17 = llvm.or %16, %14 : i1
  %18 = llvm.xor %17, %7 : i1
  "llvm.return"(%18) : (i1) -> ()
}
]

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

def eq_smin1_after := [llvm|
{
^0(%arg87 : i32, %arg88 : i32):
  %0 = llvm.icmp "sle" %arg87, %arg88 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

RV64.sub in RISCV.Instructions

def scalar_i8_lshr_and_signbit_eq_after := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.lshr %arg35, %arg36 : i8
  %2 = llvm.icmp "sgt" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def rhs : Com ScfArith ⟨[  .int,  .int,   .nat,   t]⟩ .impure t :=
   
  Com.letPure (axpy ⟨1, by admit /- proof elided -/
  ⟩ ⟨2, by admit /- proof elided -/
  ⟩ ⟨0, by admit /- proof elided -/
  ⟩) <|
   
  Com.letPure (neg ⟨2, rfl⟩) <|
  Com.var (for_ (t := t)
                        ⟨  2, rfl⟩
                        ⟨  3, rfl⟩
                        ⟨  4, rfl⟩
                        ⟨  5, rfl⟩  rgn) <|
  Com.rets [⟨0, rfl⟩]ₕ

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 scalar_i32_lshr_and_negC_eq_nonzero_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

def llvm_const_lower_riscv_li_2 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_2, rhs:= liRiscv_2,
   correct := by admit /- proof elided -/

def llvm_add_lower_riscv_nuw_flag_16 : LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16)] where
  lhs:= add_llvm_nuw_flags_16
  rhs:= add_riscv_16

def merge (x y : TokenStream) : ValueStream (BitVec 1) :=
  Stream.corec (β := TokenStream × TokenStream) (x, y) fun ⟨x, y⟩ =>
    match x 0, y 0 with
    | some _, some _ => (some 1, (x.tail, y))
    | some _, none => (some 1, (x.tail, y.tail))
    | none, some _ => (some 0, (x.tail, y.tail))
    | none, none => (none, (x.tail, y.tail))

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

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

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

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

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

@[simp_denote]
def shl_llvm_64 := [LV| {
  ^entry (%x: i64, %y: i64):
    %1 = llvm.shl %x, %y : i64
    llvm.return %1 : i64
  }]

def scalar0_before := [llvm|
{
^0(%arg32 : i4, %arg33 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.xor %arg32, %arg33 : i4
  %2 = llvm.and %1, %0 : i4
  %3 = llvm.xor %2, %arg33 : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

@[simp_sllvm]
def LLVM.IntW.canBe (x : LLVM.IntW w) (y : BitVec w) : Bool :=
  x = .poison ∨ x = .value y

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

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

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

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

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

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

def Expr.mkToFSM (self : Expr) : MetaM Expr :=
  mkAppM ``FSMPredicateSolution.toFSM #[self]

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

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

def test14_after := [llvm|
{
^0(%arg36 : i1, %arg37 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg36, %arg37 : i1
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def same_signbit_wrong_type_signed_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i32):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.ashr %arg14, %0 : i8
  %3 = llvm.icmp "sgt" %arg15, %1 : i32
  %4 = llvm.sext %3 : i1 to i8
  %5 = llvm.icmp "ne" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def attr3Unit : AttrEntry 0 := [mlir_attr_entry| sym_name]

def or_xor_tree_1101_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg6, %0 : i32
  %2 = llvm.mul %arg7, %0 : i32
  %3 = llvm.mul %arg8, %0 : i32
  %4 = llvm.xor %2, %1 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (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 a_or_b_before := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg15, %0 : i32
  %2 = llvm.icmp "ne" %arg16, %0 : i32
  %3 = llvm.and %1, %2 : i1
  %4 = llvm.icmp "ne" %arg15, %0 : i32
  %5 = llvm.icmp "eq" %arg16, %0 : i32
  %6 = llvm.and %4, %5 : i1
  %7 = llvm.or %3, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

def add_shl_moreOneUse_sh3add_no_ZBA_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_shl_moreOneUse_sh3add
  rhs := add_shl_moreOneUse_sh3add_riscv_no_ZBA

def test67_before := [llvm|
{
^0(%arg113 : i1, %arg114 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.mlir.constant(-16777216 : i32) : i32
  %3 = llvm.mlir.constant(0 : i8) : i8
  %4 = llvm.zext %arg113 : i1 to i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %arg114, %5 : i32
  %7 = llvm.shl %6, %1 overflow<nsw,nuw> : i32
  %8 = llvm.xor %7, %2 : i32
  %9 = llvm.ashr exact %8, %1 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.icmp "eq" %10, %3 : i8
  "llvm.return"(%11) : (i1) -> ()
}
]

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

def test3_before := [llvm|
{
^0(%arg6 : i49, %arg7 : i49):
  %0 = llvm.mlir.constant(1 : i49) : i49
  %1 = llvm.shl %arg7, %0 : i49
  %2 = llvm.or %arg6, %1 : i49
  %3 = llvm.and %2, %0 : i49
  "llvm.return"(%3) : (i49) -> ()
}
]

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

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

def testi16i8_com_before := [llvm|
{
^0(%arg11 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.lshr %arg11, %0 : i16
  %3 = llvm.trunc %2 : i16 to i8
  %4 = llvm.trunc %arg11 : i16 to i8
  %5 = llvm.ashr %4, %1 : i8
  %6 = llvm.icmp "eq" %3, %5 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def or_and3_commuted_after := [llvm|
{
^0(%arg100 : i1, %arg101 : i1, %arg102 : i32, %arg103 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ne" %arg102, %arg103 : i32
  %3 = "llvm.select"(%2, %arg101, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg100, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def trunc_shl_nuw_31_i32_i64_before := [llvm|
{
^0(%arg56 : i64):
  %0 = llvm.mlir.constant(31) : i64
  %1 = llvm.shl %arg56, %0 overflow<nuw> : i64
  %2 = llvm.trunc %1 : i64 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

noncomputable def R.toTensor' {q n} (a : R q n) : List Int :=
  let t := a.toTensor
  t ++ List.replicate (2^n - t.length + 1) 0

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

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

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

elab "[simple_com| " reg:mlir_region "]" : term => SSA.elabIntoCom' reg (Simple)

def xor_nosignbit_shl_after := [llvm|
{
^0(%arg18 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg18, %0 : i32
  %3 = llvm.xor %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def multiuse2_before := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mlir.constant(24 : i32) : i32
  %4 = llvm.mlir.constant(96 : i32) : i32
  %5 = llvm.and %arg10, %0 : i32
  %6 = llvm.shl %5, %1 overflow<nsw,nuw> : i32
  %7 = llvm.shl %5, %2 overflow<nsw,nuw> : i32
  %8 = llvm.and %arg10, %3 : i32
  %9 = llvm.shl %8, %1 overflow<nsw,nuw> : i32
  %10 = llvm.shl %8, %2 overflow<nsw,nuw> : i32
  %11 = llvm.and %arg10, %4 : i32
  %12 = llvm.shl %11, %1 overflow<nsw,nuw> : i32
  %13 = llvm.shl %11, %2 overflow<nsw,nuw> : i32
  %14 = llvm.or %6, %9 : i32
  %15 = llvm.or %12, %14 : i32
  %16 = llvm.or %13, %10 : i32
  %17 = llvm.or %7, %16 : i32
  %18 = llvm.or %15, %17 : i32
  "llvm.return"(%18) : (i32) -> ()
}
]

noncomputable def nonesUntilSome (x : Stream α) (not_stuck : x ≠ stuck α) : Nat :=
  prop.choose
where
  prop : ∃ i, (x.drop i).head.isSome ∧ ∀ j < i, x.get j = none := by admit /- proof elided -/

def fold_add_udiv_urem_without_noundef_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.udiv %arg4, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  %4 = llvm.urem %arg4, %0 : i32
  %5 = llvm.or disjoint %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def add_or_and_commutative_before := [llvm|
{
^0(%arg17 : i32, %arg18 : i32):
  %0 = llvm.or %arg17, %arg18 : i32
  %1 = llvm.and %arg18, %arg17 : i32
  %2 = llvm.add %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def udiv_i32_before := [llvm|
{
^0(%arg29 : i8, %arg30 : i8):
  %0 = llvm.zext %arg29 : i8 to i32
  %1 = llvm.zext %arg30 : i8 to i32
  %2 = llvm.udiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def mul8_low_A0_B0_before := [llvm|
{
^0(%arg60 : i8, %arg61 : i8):
  %0 = llvm.mlir.constant(15 : i8) : i8
  %1 = llvm.mlir.constant(4 : i8) : i8
  %2 = llvm.and %arg60, %0 : i8
  %3 = llvm.lshr %arg60, %1 : i8
  %4 = llvm.and %arg61, %0 : i8
  %5 = llvm.lshr %arg61, %1 : i8
  %6 = llvm.mul %5, %arg60 : i8
  %7 = llvm.mul %3, %arg61 : i8
  %8 = llvm.mul %4, %2 : i8
  %9 = llvm.add %6, %7 : i8
  %10 = llvm.shl %9, %1 : i8
  %11 = llvm.add %10, %8 : i8
  "llvm.return"(%11) : (i8) -> ()
}
]

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

def test68_xor_after := [llvm|
{
^0(%arg162 : i32, %arg163 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.lshr %arg162, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %arg163, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def alive_AddSub_1176_tgt :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.mlir.constant 0 : i64
  %v2 = llvm.sub %v1, %b : i64
  %v3 = llvm.sub %a, %b : i64
  llvm.return %v3 : i64
}]
</all_available_defs>

<all_available_lemmas>
List.append_inj_left' in Init.Data.List.Lemmas
List.append_inj_right' in Init.Data.List.Lemmas
List.dropLast_concat_getLast in Init.Data.List.Lemmas
List.map_append in Init.Data.List.Lemmas
List.map_cons in Init.Data.List.Basic
List.map_dropLast in Init.Data.List.Lemmas
List.map_nil in Init.Data.List.Basic
Set.ext in Mathlib.Data.Set.Defs
Set.mem_iUnion in Mathlib.Order.SetNotation
exists_prop in Init.PropLemmas

theorem List.getElem_append_left{α : Type u_1} {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.length) :\n(l₁ ++ l₂)[i] = l₁[i]

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

theorem not_mul_of_bool_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  True ∧ (x_1 &&& 3#32).smulOverflow (zeroExtend 32 x) = true ∨
      True ∧ (x_1 &&& 3#32).umulOverflow (zeroExtend 32 x) = true →
    False

theorem ashrslt_01_07_proof : ashrslt_01_07_before ⊑ ashrslt_01_07_after

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

theorem test9_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741824#32 != 0#32) = 1#1 →
    ofBool (-1#32 <ₛ x) = ofBool (x &&& BitVec.ofInt 32 (-1073741824) == 1073741824#32)

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

theorem trunc_unsigned_nsw_sext_proof : trunc_unsigned_nsw_sext_before ⊑ trunc_unsigned_nsw_sext_after

theorem icmp_select_var_select_thm.extracted_1._12 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (x_1 == 0#8) = 1#1 ∧ x_2 = 1#1 → ofBool (x_1 == 0#8) = 1#1 → True → ofBool (x == x_1) = 1#1

theorem test17_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬x = 0 → 1#32 % x = zeroExtend 32 (ofBool (x != 1#32))

@[simp]
theorem scanOr_zero (s : BitStream) : scanOr s 0 = s 0

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

theorem t13_x_is_one_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (1#32 <<< (32#32 - x_1) &&& truncate 32 (x >>> zeroExtend 64 (x_1 + BitVec.ofInt 32 (-16))) != 0#32) =
      ofBool (x &&& 65536#64 != 0#64)

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

theorem lshrult_01_12_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 1)) (const? 4 (-4)) ⊑ const? 1 1

lemma CNFA.canonicalSimul (m : CNFA n) : m.m.Simul m.toNFA {(s, s') | s = s'.val} ⊤ ∅

theorem select_zext_or_eq_ult_add_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-3))) (const? 32 2)) (const? 32 1)
      (zext 32 (icmp IntPred.eq e (const? 32 5))) ⊑
    zext 32 (icmp IntPred.ult (add e (const? 32 (-3))) (const? 32 3))

@[bv_automata_nnf] theorem not_eq_eq {α : Sort u} (a b : α) : (¬ (a = b)) = (a ≠ b)

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

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 test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 <ᵤ x) &&& ofBool (x <ᵤ x_1) = 0#1

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

theorem positive_sameconst_shlnuwnsw_thm (e : IntW 8) :
  shl (ashr e (const? 8 3)) (const? 8 3) { «nsw» := true, «nuw» := true } ⊑ LLVM.and e (const? 8 (-8))

theorem t7_proof : t7_before ⊑ t7_after

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

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

theorem bv_InstCombineShift__497 :
    ∀ (e e_1 e_2 : LLVM.IntW w), LLVM.lshr (LLVM.xor e e_2) e_1 ⊑ LLVM.xor (LLVM.lshr e e_1) (LLVM.lshr e_2 e_1)

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem e_2220 :
    11 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 5 * (f ||| (d &&&  ~~~e)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 6 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 6 * (d ^^^ ( ~~~e ||| f)) - 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 5 *  ~~~(d ^^^ e) - 6 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (d ||| ( ~~~e &&& f)) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 5 * (e |||  ~~~(d ||| f)) - 3 * (f &&& (d |||  ~~~e)) + 1 * ((d &&& e) ^^^ (e ||| f)) - 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * (d &&& f) + 3 * d + 2 *  ~~~(d ^^^ (e ^^^ f)) - 1 * (f ^^^ (d &&&  ~~~e)) - 11 * (f ^^^ (d &&& ( ~~~e ||| f))) + 2 *  ~~~(d &&&  ~~~d) + 2 * (f &&&  ~~~(d &&&  ~~~e)) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~(d ||| (e &&& f))) + 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 11 * ((d &&& e) ^^^ (e |||  ~~~f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (f &&& (d ||| e)) - 1 * (e &&& (d |||  ~~~f)) - 2 *  ~~~(d ^^^ ( ~~~e ||| f)) + 2 * (e ^^^ (d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * (f ||| (d ^^^ e)) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 3 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 * (d |||  ~~~f) + 2 * (d ^^^ (e ||| f)) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 5 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 7 * (d ^^^ ( ~~~e &&& f)) - 31 *  ~~~(d ||| (e ||| f)) - 10 *  ~~~(d ||| ( ~~~e ||| f)) - 17 *  ~~~( ~~~d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 13 * ( ~~~d &&& ( ~~~e &&& f)) + 34 * ( ~~~d &&& (e &&& f)) - 14 * (d &&& ( ~~~e &&& f)) - 32 * (d &&& (e &&& f)) =  - 1 * (e ^^^ (d &&& ( ~~~e ||| f)))

theorem test6_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬32#128 ≥ ↑128 →
    ¬(32#64 ≥ ↑64 ∨ True ∧ zeroExtend 64 (truncate 32 (x >>> 32#64)) ≠ x >>> 32#64) →
      truncate 32 (zeroExtend 128 x >>> 32#128) = truncate 32 (x >>> 32#64)

theorem not_add_thm (e : IntW 32) :
  LLVM.xor (add e (const? 32 123)) (const? 32 (-1)) ⊑ sub (const? 32 (-124)) e

theorem test25_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(BitVec.ofInt 32 (-2147483648) == 0 || 32 != 1 && x == intMin 32 && BitVec.ofInt 32 (-2147483648) == -1) = true →
    ofBool (x.srem (BitVec.ofInt 32 (-2147483648)) != 0#32) = ofBool (x &&& 2147483647#32 != 0#32)

theorem samesign_inverted_different_sign_bittest1_proof : samesign_inverted_different_sign_bittest1_before ⊑ samesign_inverted_different_sign_bittest1_after

theorem icmp_ule_64_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(True ∧ x <<< 64#128 >>> 64#128 ≠ x ∨ 64#128 ≥ ↑128) →
    ofBool (x <<< 64#128 ≤ᵤ 18446744073709551615#128) = ofBool (x == 0#128)

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

theorem nonexact_lshr_ne_noexactlog_proof : nonexact_lshr_ne_noexactlog_before ⊑ nonexact_lshr_ne_noexactlog_after

theorem mul_select_zext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → 1#64 * zeroExtend 64 x_1 = 0#64

theorem trunc_ashr_trunc_outofrange_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬25#32 ≥ ↑32 →
    25#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 8 ((truncate 32 x).sshiftRight' 25#32)) ≠ (truncate 32 x).sshiftRight' 25#32 →
      False

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

@[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)

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

theorem test_shift_and_cmp_changed4_thm (e : IntW 8) :
  icmp IntPred.slt (LLVM.and (lshr e (const? 8 5)) (const? 8 (-64))) (const? 8 32) ⊑ const? 1 1

theorem ule_swap_or_not_min_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x ≤ᵤ x_1) ||

theorem foo1_proof : foo1_before ⊑ foo1_after

theorem icmp_sle4_proof : icmp_sle4_before ⊑ icmp_sle4_after

theorem and_and_logic_or_1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 &&& x = 1#1 → ¬x = 1#1 → False

theorem PR30273_three_bools_proof : PR30273_three_bools_before ⊑ PR30273_three_bools_after

theorem uge_swap_or_not_max_proof : uge_swap_or_not_max_before ⊑ uge_swap_or_not_max_after

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

@[simp] theorem subAux_eq_BitVec_carry (a b : BitStream) (w i : Nat) (hi : i < w) :
    (a.subAux b i).2 = !(BitVec.carry (i + 1) (a.toBitVec w) ((~~~b).toBitVec w) true)

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 test29_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 10#32 ^^^ 123#32 = 113#32

theorem and_xor_or2_proof : and_xor_or2_before ⊑ and_xor_or2_after

theorem relabelNat_unsat_iff' {aig : AIG α} {hidx1} {hidx2} :
    (aig.relabelNat).UnsatAt idx invert hidx1 ↔ aig.UnsatAt idx invert hidx2

theorem or_eq_with_diff_one_signed_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq e (const? 32 0)) (icmp IntPred.eq e (const? 32 (-1))) ⊑
    icmp IntPred.ult (add e (const? 32 1)) (const? 32 2)

theorem e_2306 :
    5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * (e &&&  ~~~(d ^^^ f)) - 11 * ((d &&& e) |||  ~~~(e ||| f)) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * (e ^^^ (d ||| (e ||| f))) - 5 *  ~~~(d &&&  ~~~f) + 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 11 *  ~~~e + 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 7 * (d ||| (e &&& f)) - 11 * (d ||| f) + 4 * (e ||| (d &&& f)) + 5 *  ~~~f + 1 * (e ||| (d &&&  ~~~f)) - 2 *  ~~~(d &&& f) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 7 * ((d ^^^ e) ||| (d ^^^ f)) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (d ^^^ (e ||| f)) - 7 * (d ||| ( ~~~e ||| f)) - 5 * (e ^^^  ~~~(d &&& (e &&& f))) - 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (e |||  ~~~(d ||| f)) + 5 *  ~~~(d &&& (e ||| f)) - 11 * (e ||| (d ^^^ f)) + 4 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 5 *  ~~~(d &&&  ~~~e) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 3 * e + 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 5 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (e ^^^ (d &&&  ~~~f)) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * (f ^^^ (d &&&  ~~~e)) + 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~f &&&  ~~~(d ^^^ e)) - 5 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * (e ^^^  ~~~(d &&& f)) + 4 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * (d &&& ( ~~~e ||| f)) - 3 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 2 * (d &&& (e ||| f)) - 1 * (e &&& f) + 3 *  ~~~(d &&& ( ~~~e ||| f)) - 7 * (e &&&  ~~~(d &&& f)) - 3 * (f |||  ~~~(d |||  ~~~e)) - 5 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 *  ~~~(e |||  ~~~f) + 1 * (e ^^^ f) - 6 *  ~~~(d ^^^ f) + 6 *  ~~~(d ||| (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e ||| f)) + 30 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 40 * ( ~~~d &&& ( ~~~e &&& f)) - 12 * ( ~~~d &&& (e &&& f)) + 35 * (d &&& ( ~~~e &&& f)) + 19 * (d &&& (e &&& f)) =  - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 1 * (d |||  ~~~e)

theorem n0_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor (shl (const? 8 1) e_1) (const? 8 (-1))) e ⊑
    icmp IntPred.ugt e (LLVM.xor (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 (-1)))

theorem sub_zext_trunc_lshr_thm (e : IntW 64) :
  sub (const? 32 10) (zext 32 (trunc 1 (lshr e (const? 64 15)))) ⊑
    add (ashr (shl (trunc 32 e) (const? 32 16)) (const? 32 31)) (const? 32 10)
      { «nsw» := true, «nuw» := false }

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

theorem icmp_slt_0_or_icmp_sgt_0_i64_proof : icmp_slt_0_or_icmp_sgt_0_i64_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_after

theorem positive_biggershl_shlnsw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ True ∧ (x.sshiftRight' 3#8 <<< 6#8).sshiftRight' 6#8 ≠ x.sshiftRight' 3#8 ∨ 6#8 ≥ ↑8) →
    True ∧ (x <<< 3#8).sshiftRight' 3#8 ≠ x ∨ 3#8 ≥ ↑8 → False

theorem test7_thm (e : IntW 32) :
  icmp IntPred.ugt (LLVM.udiv (const? 32 8) e) (const? 32 8) ⊑ const? 1 0

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 main5_like_logical_thm (e e_1 : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e_1 (const? 32 7)) (const? 32 7))
        (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 7)) (const? 1 0))
      (const? 32 0) (const? 32 1) ⊑
    zext 32
      (select (icmp IntPred.ne (LLVM.and e_1 (const? 32 7)) (const? 32 7)) (const? 1 1)
        (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 7)))

theorem sext_zext_ult_known_nonneg_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬6#8 ≥ ↑8 → ofBool (signExtend 32 x_1 <ᵤ zeroExtend 32 (x >>> 6#8)) = ofBool (x_1 <ᵤ x >>> 6#8)

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

theorem land_bor_left1_proof : land_bor_left1_before ⊑ land_bor_left1_after

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

theorem e_1518 :
     - 1 * (a ^^^ (b ^^^ c)) - 1 * (b ^^^ (a &&& (b ||| c))) + 1 *  ~~~(a ||| (b &&& c)) + 3 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& (b &&& c)) - 2 * (a &&& (b &&& c)) = 2 * (a &&& ( ~~~b &&& c))

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

theorem badimm2_thm (e : IntW 16) :
  select (icmp IntPred.eq (ashr (trunc 8 e) (const? 8 6)) (trunc 8 (lshr e (const? 16 8)))) (trunc 8 e)
      (LLVM.xor (trunc 8 (ashr e (const? 16 15))) (const? 8 127)) ⊑
    select
      (icmp IntPred.eq (ashr (trunc 8 e) (const? 8 6))
        (trunc 8 (lshr e (const? 16 8)) { «nsw» := false, «nuw» := true }))
      (trunc 8 e) (select (icmp IntPred.sgt e (const? 16 (-1))) (const? 8 127) (const? 8 (-128)))

theorem PR42691_3_logical_thm (e : IntW 32) :
  select (icmp IntPred.sge e (const? 32 0)) (const? 1 1) (icmp IntPred.eq e (const? 32 (-2147483648))) ⊑
    icmp IntPred.ult e (const? 32 (-2147483647))

theorem udiv_i32_c_multiuse_proof : udiv_i32_c_multiuse_before ⊑ udiv_i32_c_multiuse_after

theorem e_331 :
     - 6 *  ~~~x + 2 * (x |||  ~~~y) - 3 * x + 2 * (x ||| y) - 10 *  ~~~(x ||| y) - 10 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) - 15 * (x &&& y) =  - 3 *  ~~~(x &&&  ~~~x) - 11 *  ~~~(x &&&  ~~~y)

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 test14_proof : test14_before ⊑ test14_after

theorem icmp_mul_nsw_slt_proof : icmp_mul_nsw_slt_before ⊑ icmp_mul_nsw_slt_after

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

theorem ashrsgt_02_02_exact_proof : ashrsgt_02_02_exact_before ⊑ ashrsgt_02_02_exact_after

theorem and_logic_and_logic_or_7_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬0#1 = 1#1 → x &&& x_2 = 0#1

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

theorem test7_proof : test7_before ⊑ test7_after

theorem or_eq_with_one_bit_diff_constants2_proof : or_eq_with_one_bit_diff_constants2_before ⊑ or_eq_with_one_bit_diff_constants2_after

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

theorem alive_Select_704 : forall (w : Nat) (A B : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (B) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp slt  w %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v1;
  %v8 := op:icmp sge  w %v7;
  %v9 := triple:%v8 %v6 %v1;
  %v10 := op:select 1 %v9
  dsl_ret %v10
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (B) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp slt  1 %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v1;
  %v8 := op:icmp sge  1 %v7;
  %v9 := op:copy 1 %v1
  dsl_ret %v9
  ]

@[grind ., simp]
lemma RawCNFA.stateMax_nin_states (m : RawCNFA A) : ¬(m.stateMax ∈ m.states)

theorem select_zext_different_condition_proof : select_zext_different_condition_before ⊑ select_zext_different_condition_after

theorem foo1_and_commuted_proof : foo1_and_commuted_before ⊑ foo1_and_commuted_after

theorem AvoidCollision_setWidth_one_eq_ofBool_getLsb_zero (x : BitVec w) :
    x.setWidth 1 = BitVec.ofBool (x.getLsbD 0)

theorem test3_proof : test3_before ⊑ test3_after

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

theorem band_lor_right2_thm (e e_1 : IntW 1) : select e_1 (const? 1 1) (LLVM.and e e_1) ⊑ e_1

theorem zext_zext_eq_proof : zext_zext_eq_before ⊑ zext_zext_eq_after

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

theorem test_proof : test_before ⊑ test_after

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

theorem test_negative_nuw_and_signed_pred_proof : test_negative_nuw_and_signed_pred_before ⊑ test_negative_nuw_and_signed_pred_after

theorem test19a_thm (e : IntW 39) :
  icmp IntPred.eq (ashr e (const? 39 2)) (const? 39 (-1)) ⊑ icmp IntPred.ugt e (const? 39 (-5))

theorem test_thm.extracted_1._2 : ∀ (x : BitVec 1) (x_1 : BitVec 64),
  x = 1#1 →
    ¬(4#64 ≥ ↑64 ∨
          3#64 ≥ ↑64 ∨
            True ∧ (x_1 >>> 4#64).saddOverflow (x_1 >>> 3#64) = true ∨
              True ∧ (x_1 >>> 4#64).uaddOverflow (x_1 >>> 3#64) = true) →
      ¬(16#64 = 0 ∨ 8#64 = 0) → x_1 / 16#64 + x_1 / 8#64 = x_1 >>> 4#64 + x_1 >>> 3#64

theorem select_replace_nested_no_simplify_proof : select_replace_nested_no_simplify_before ⊑ select_replace_nested_no_simplify_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    ¬(62#64 ≥ ↑64 ∨ 63#64 ≥ ↑64) →
      x.sshiftRight' 62#64 ||

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

theorem test_proof : test_before ⊑ test_after

theorem test_ne_0_and_15_add_3_proof : test_ne_0_and_15_add_3_before ⊑ test_ne_0_and_15_add_3_after

theorem eq_commuted_proof : eq_commuted_before ⊑ eq_commuted_after

theorem sle_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 test9_thm (e : IntW 8) :
  icmp IntPred.eq (LLVM.xor e (const? 8 123)) (const? 8 34) ⊑ icmp IntPred.eq e (const? 8 89)

theorem t7_thm.extracted_1._3 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬x_1 = 1#1 → ¬x ≥ ↑8 → True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

theorem sext_true_val_must_be_all_ones_thm (e : IntW 1) :
  select e (sext 32 e) (const? 32 42) ⊑ select e (const? 32 (-1)) (const? 32 42)

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 e_1445 :
    4 * (z ^^^ t) + 5 * (z ||| t) - 1 *  ~~~(z &&& t) + 2 *  ~~~(z &&&  ~~~t) + 3 *  ~~~t - 5 *  ~~~(z &&&  ~~~z) + 1 *  ~~~(z ^^^ t) - 4 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) - 3 * (z &&& t) = 1 *  ~~~z - 1 *  ~~~(z ||| t)

theorem sub_sext_mask1_trunc_lshr_thm (e : IntW 64) :
  sub (const? 32 10) (sext 32 (LLVM.and (trunc 8 (lshr e (const? 64 15))) (const? 8 1))) ⊑
    zext 32
      (add (trunc 8 (ashr (shl e (const? 64 48)) (const? 64 63)) { «nsw» := true, «nuw» := false }) (const? 8 10)
        { «nsw» := true, «nuw» := false })

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 14#32 == 0#32) = 1#1 →
    ofBool (x &&& 3#32 != 1#32) = ofBool (x &&& 14#32 == 0#32) ||

@[simp]
lemma bitVecToFinFun_linv [FinEnum ar] (bv : BitVec $ FinEnum.card ar) :
    finFunToBitVec (bitVecToFinFun bv) = bv

theorem shl_C1_add_A_C2_i32_thm (e : IntW 16) :
  shl (const? 32 6) (add (zext 32 e) (const? 32 5)) ⊑ shl (const? 32 192) (zext 32 e { «nneg» := true })

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

theorem xor_icmp_true_signed_commuted_proof : xor_icmp_true_signed_commuted_before ⊑ xor_icmp_true_signed_commuted_after

@[simp] theorem negAux_succ (x : BitStream) (n : Nat) : x.negAux (n + 1) =
    let borrow

theorem and_or3_thm (e : IntW 1) (e_1 e_2 : IntW 32) (e_3 : IntW 1) :
  select (LLVM.and e_3 (icmp IntPred.eq e_2 e_1)) e e_3 ⊑
    select e_3 (select (icmp IntPred.ne e_2 e_1) (const? 1 1) e) (const? 1 0)

theorem e_434 :
     - 5 * y + 4 *  ~~~(x &&& y) - 2 * (x ^^^ y) - 3 * x - 9 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 3 * (x &&& y) =  - 5 *  ~~~(x ^^^ y)

theorem test_and4_proof : test_and4_before ⊑ test_and4_after

theorem test_or1_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.slt e_1 (const? 32 0)) (icmp IntPred.sge e_1 (LLVM.and e (const? 32 2147483647))) ⊑
    icmp IntPred.uge e_1 (LLVM.and e (const? 32 2147483647))

theorem or_ugt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ᵤ x_1 ||| x) = ofBool (x_1 ||| x != x_1)

theorem zext_sext_add_icmp_slt_1_type_not_i1_thm (e : IntW 1) (e_1 : IntW 2) :
  icmp IntPred.slt (add (zext 8 e_1) (sext 8 e)) (const? 8 1) ⊑
    icmp IntPred.slt (add (zext 8 e_1) (sext 8 e) { «nsw» := true, «nuw» := false }) (const? 8 1)

theorem ult_swap_or_not_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) ||

theorem test1_proof : test1_before ⊑ test1_after

theorem select_icmp_ne_0_and_32_xor_4096_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 32))) e (LLVM.xor e (const? 32 4096)) ⊑
    LLVM.xor (LLVM.xor (LLVM.and (shl e_1 (const? 32 7)) (const? 32 4096)) e) (const? 32 4096)

theorem and_ashr_not_proof : and_ashr_not_before ⊑ and_ashr_not_after

theorem lshrult_02_15_exact_proof : lshrult_02_15_exact_before ⊑ lshrult_02_15_exact_after

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

theorem isMonotone_matchVarArg_aux (lets : Lets d Γ_in eff Γ_out) :
    (
     ∀  (Δ_out : Ctxt d.Ty)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out) (l : List d.Ty)
        (argsl : HVector Γ_out.Var l) (argsr : HVector Δ_out.Var l),
        (matchArg lets matchLets argsl argsr).IsMonotone
    )
    ∧ (
      ∀ (Δ_out : Ctxt d.Ty) (t : d.Ty) (v : Γ_out.Var t)
        (matchLets : Lets d Δ_in EffectKind.pure Δ_out)
        (w : Var Δ_out t),
        (matchVar lets v matchLets w).IsMonotone
    )

theorem select_constants_and_icmp_eq0_common_bit_thm (e e_1 : IntW 1) :
  icmp IntPred.eq (LLVM.and (select e_1 (const? 8 2) (const? 8 3)) (select e (const? 8 2) (const? 8 3)))
      (const? 8 0) ⊑
    const? 1 0

theorem test_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 34)) (icmp IntPred.sgt e (const? 32 (-1))) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.ne e (const? 32 34)) (icmp IntPred.sgt e (const? 32 (-1)))

theorem test_ashr__exact_is_safe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2147483588))) (const? 32 0)) e
      (ashr e (zext 64 (ashr (LLVM.and e_1 (const? 32 (-2147483588))) (const? 32 2)))) ⊑
    ashr e (zext 64 (LLVM.and (ashr e_1 (const? 32 2)) (const? 32 (-536870897))) { «nneg» := true })

theorem evalWith_succ_eq_evalWith_delta' (p : FSM arity) (carryState : p.α → Bool)
      (x : arity → BitStream) :
  p.evalWith carryState x (n + 1) =
  p.evalWith (p.delta' carryState (fun s => x s 0)) (fun s i => x s (i + 1)) n

theorem e_1068 :
    1 * (z ^^^ t) + 4 *  ~~~(z &&& t) + 11 * (z |||  ~~~t) - 2 *  ~~~(z &&&  ~~~t) + 3 *  ~~~(z |||  ~~~t) - 3 * (z &&&  ~~~t) - 3 * (z &&& t) = 6 *  ~~~(z &&&  ~~~z) + 7 *  ~~~t

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32) → (zeroExtend 32 x <<< 16#32).sshiftRight' 16#32 = signExtend 32 x

theorem ashr_ult_4_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 4) ⊑ icmp IntPred.sgt e (const? 4 (-1))

theorem udiv_shl_mul_nuw_exact_thm (e e_1 e_2 : IntW 5) :
  LLVM.udiv (shl e_2 e_1 { «nsw» := false, «nuw» := true }) (mul e_2 e { «nsw» := false, «nuw» := true })
      { «exact» := true } ⊑
    LLVM.udiv (shl (const? 5 1) e_1 { «nsw» := false, «nuw» := true }) e { «exact» := true }

theorem sgt_swap_or_not_min_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 (-128))) (const? 1 1) (icmp IntPred.slt e e_1) ⊑
    icmp IntPred.ne e_1 (const? 8 (-128))

theorem select_of_symmetric_selects_thm.extracted_1._8 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 1),
  ¬x_3 = 1#1 → ¬x_2 = 1#1 → x_2 ^^^ x_3 = 1#1 → x_1 = x

theorem test_sub_0_Y_ne_0_thm (e : IntW 8) :
  icmp IntPred.ne (sub (const? 8 0) e) (const? 8 0) ⊑ icmp IntPred.ne e (const? 8 0)

theorem e_1109 :
    1 *  ~~~(z &&&  ~~~z) - 6 *  ~~~z + 4 * (z ||| t) + 11 * (z |||  ~~~t) + 11 * z - 6 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) - 27 * (z &&& t) = 27 * (z &&&  ~~~t)

theorem alive_AddSub_1164  (w : Nat)   : alive_AddSub_1164_src w  ⊑ alive_AddSub_1164_tgt w

theorem t0_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 <ᵤ x_1 - x) = ofBool (x_1 <ᵤ x)

theorem lshrult_03_11_proof : lshrult_03_11_before ⊑ lshrult_03_11_after

theorem e_1572 :
     - 3 *  ~~~(a ^^^ c) - 3 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 2 * (b ^^^  ~~~(a ||| (b &&& c))) + 7 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 3 *  ~~~(a |||  ~~~c) - 1 * ( ~~~b ||| (a ^^^ c)) - 3 * (c ||| (a &&&  ~~~b)) - 1 * (c ^^^ (a ||| (b &&& c))) - 5 * (a ^^^ ( ~~~b &&& c)) + 5 *  ~~~(a ||| (b ||| c)) - 1 *  ~~~(a ||| ( ~~~b ||| c)) + 3 *  ~~~( ~~~a ||| (b ||| c)) - 5 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 4 * ( ~~~a &&& ( ~~~b &&& c)) + 5 * ( ~~~a &&& (b &&& c)) + 4 * (a &&& ( ~~~b &&& c)) =  - 3 * (a ||| (b &&& c)) - 2 * (a &&& (b &&& c))

theorem gt_unsigned_to_small_signed_thm (e : IntW 8) :
  icmp IntPred.sgt (zext 32 e) (const? 32 17) ⊑ icmp IntPred.ugt e (const? 8 17)

theorem select_shl_icmp_bad_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 1#32) = 1#1 → ¬x_1 ≥ ↑32 → 1#32 ≥ ↑32 → 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)))

@[simp]
lemma bv_to_set_shift (x s : Nat) :
    (s ∈ bv_to_set (1#w <<< x)) ↔ (s = x ∧ x < w)

theorem not_neg_eq_sub_one (x : BitVec w) :
    ~~~ (- x) = x - 1

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

theorem scalar_i8_shl_and_negC_eq_proof : scalar_i8_shl_and_negC_eq_before ⊑ scalar_i8_shl_and_negC_eq_after

theorem sle_swap_or_not_min_logical_proof : sle_swap_or_not_min_logical_before ⊑ sle_swap_or_not_min_logical_after

theorem src_is_mask_const_slt_proof : src_is_mask_const_slt_before ⊑ src_is_mask_const_slt_after

theorem positive_biggershl_shlnsw_proof : positive_biggershl_shlnsw_before ⊑ positive_biggershl_shlnsw_after

theorem t0_ult_slt_65536_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ 65536#32) = 1#1 → ofBool (x_1 <ₛ 65536#32) = 1#1 → ofBool (65535#32 <ₛ x_1) = 1#1 → False

theorem icmp_slt_0_and_icmp_ne_neg2_i32_fail_proof : icmp_slt_0_and_icmp_ne_neg2_i32_fail_before ⊑ icmp_slt_0_and_icmp_ne_neg2_i32_fail_after

theorem sext_sext_ne_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (sext 32 e_1) (sext 32 e) ⊑ icmp IntPred.ne e_1 e

theorem t0_lshr_proof : t0_lshr_before ⊑ t0_lshr_after

theorem select1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 = 1#1 → zeroExtend 32 (truncate 8 x_2) = x_2 &&& 255#32

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

theorem test4_logical_proof : test4_logical_before ⊑ test4_logical_after

theorem xor_icmp_invalid_range_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == 0#8) ^^^ ofBool (x != 4#8) = ofBool (x &&& BitVec.ofInt 8 (-5) != 0#8)

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 sub_to_xor_and_commuted_proof : sub_to_xor_and_commuted_before ⊑ sub_to_xor_and_commuted_after

theorem icmp_sle6_proof : icmp_sle6_before ⊑ icmp_sle6_after

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 32), x &&& 0#32 = 0#32

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

private theorem BitVec.signExtend_slt_signExtend_of_slt {x y : BitVec w}
    {N : Nat} (hN : w ≤ N)
    (h : x.slt y) : (x.signExtend N).slt (y.signExtend N)

theorem sub_shl_same_amount_partial_nuw1_proof : sub_shl_same_amount_partial_nuw1_before ⊑ sub_shl_same_amount_partial_nuw1_after

theorem corec₂_eq_val (x : Stream α):
  (corec₂ x fun x => Id.run (x 0, x 0, tail x)) = (corec₂ x fun x => Id.run (x 0, x 0, x.tail))

theorem narrow_sext_or_proof : narrow_sext_or_before ⊑ narrow_sext_or_after

theorem select_ashr_icmp_bad_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 1#32) = 1#1 → ¬x_1 ≥ ↑32 → 1#32 ≥ ↑32 → False

lemma complete_stepSet_sink {M : NFA α σ} :
    .inr () ∈ S → .inr () ∈ M.complete.stepSet S a

theorem e_2450 :
     - 1 * (e &&& (d ^^^ f)) - 1 * (f ^^^ (d ||| e)) + 1 * ( ~~~e ||| (d ^^^ f)) + 5 * (e &&& (d |||  ~~~f)) - 11 *  ~~~(d ^^^ f) - 3 * ((d &&& e) ^^^ (e |||  ~~~f)) + 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 3 * ( ~~~d ||| (e &&& f)) + 5 * (f |||  ~~~(d ||| e)) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 11 * ( ~~~d ||| (e ||| f)) - 6 * (e ^^^  ~~~(d ||| f)) + 11 *  ~~~( ~~~d &&& (e ||| f)) - 5 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 6 * (e |||  ~~~(d ^^^ f)) + 1 * (f ||| (d ^^^ e)) + 4 * (f ^^^ (d ||| ( ~~~e ||| f))) + 2 * (e &&& (d ||| f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 5 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 * (e |||  ~~~(d |||  ~~~f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * (e |||  ~~~f) + 3 *  ~~~(d |||  ~~~f) - 1 * (f ^^^ (d ||| (e &&& f))) - 7 * (d ^^^ (e &&& f)) + 2 * ((d &&& e) ||| (e ^^^ f)) + 7 * (e ^^^  ~~~(d &&& (e &&& f))) + 11 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (d ||| f) - 11 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 5 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * (d ||| ( ~~~e &&& f)) + 1 * (d |||  ~~~f) - 11 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 * (e ^^^ (d ||| (e ||| f))) - 6 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * f + 2 * (f &&& (d ^^^ e)) + 7 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 5 *  ~~~(d ^^^ (e &&& f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 *  ~~~(e &&& f) - 1 *  ~~~(d &&& ( ~~~e ||| f)) - 7 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 2 *  ~~~d - 1 * ((d &&& e) |||  ~~~(e ||| f)) - 1 * (d &&& (e ^^^ f)) - 7 * (d &&&  ~~~e) + 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 4 * (e ^^^ (d ||| f)) - 6 *  ~~~(d ||| ( ~~~e &&& f)) - 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 5 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 3 * (d |||  ~~~e) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 7 * ( ~~~d &&& (e ||| f)) - 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 21 *  ~~~(d ||| (e ||| f)) - 3 *  ~~~(d ||| ( ~~~e ||| f)) - 16 *  ~~~( ~~~d ||| (e ||| f)) + 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 46 * ( ~~~d &&& ( ~~~e &&& f)) + 11 * ( ~~~d &&& (e &&& f)) - 10 * (d &&& ( ~~~e &&& f)) - 29 * (d &&& (e &&& f)) =  - 4 * ((d |||  ~~~e) &&& (e ^^^ f))

theorem test14_proof : test14_before ⊑ test14_after

theorem and_not_xor_common_op_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 ^^^ x ^^^ -1#32) &&& x = x &&& x_1

theorem test18a_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& BitVec.ofInt 8 (-2) == 0#8) = ofBool (x <ᵤ 2#8)

theorem src_x_and_nmask_sge_thm (e e_1 : IntW 8) :
  icmp IntPred.sge (LLVM.and e_1 (shl (const? 8 (-1)) e)) (shl (const? 8 (-1)) e) ⊑
    icmp IntPred.sle (shl (const? 8 (-1)) e { «nsw» := true, «nuw» := false }) e_1

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

theorem mul_selectp2_x_non_const_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  mul (select e_2 (const? 8 2) (shl (const? 8 1) e_1)) e ⊑ shl e (select e_2 (const? 8 1) e_1)

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

@[bv_automata_preprocess] theorem BitVec.zero_mul (x : BitVec w) : 0#w * x = 0#w

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

theorem p_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 &&& x_1 &&& (x &&& (x_1 ^^^ -1#32)) != 0) = true) →
    x_2 &&& x_1 ||

theorem uge_swap_or_not_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 ≤ᵤ x) ||

theorem shl_lshr_pow2_const_negative_overflow1_proof : shl_lshr_pow2_const_negative_overflow1_before ⊑ shl_lshr_pow2_const_negative_overflow1_after

theorem sub_shl_same_amount_thm (e e_1 e_2 : IntW 6) : sub (shl e_2 e_1) (shl e e_1) ⊑ shl (sub e_2 e) e_1

theorem bools_multi_uses2_logical_thm.extracted_1._15 : ∀ (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 + x = 0#1

theorem bools_multi_uses1_logical_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → x = 1#1 → False

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

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 t14_and_with_const0_proof : t14_and_with_const0_before ⊑ t14_and_with_const0_after

theorem ashrsgt_02_09_exact_proof : ashrsgt_02_09_exact_before ⊑ ashrsgt_02_09_exact_after

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

theorem sle_swap_or_min_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.sge e_1 e) (icmp IntPred.eq e (const? 8 (-128))) ⊑
    icmp IntPred.sge e_1 e

theorem not_and_and_or_not_or_or_commute2_and_proof : not_and_and_or_not_or_or_commute2_and_before ⊑ not_and_and_or_not_or_or_commute2_and_after

theorem bools_multi_uses1_logical_thm.extracted_1._9 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → ¬0#1 = 1#1 → 0#1 ^^^ 0#1 = x ^^^ 0#1

theorem bv_283 :
    ∀ (e e_1 : LLVM.IntW 1), LLVM.mul e_1 e ⊑ LLVM.and e_1 e

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 test2_logical_proof : test2_logical_before ⊑ test2_logical_after

theorem xor_signbit_lshr_proof : xor_signbit_lshr_before ⊑ xor_signbit_lshr_after

theorem testi16i8_thm (e : IntW 16) :
  icmp IntPred.eq (ashr (trunc 8 e) (const? 8 7)) (trunc 8 (lshr e (const? 16 8))) ⊑
    icmp IntPred.ult (add e (const? 16 128)) (const? 16 256)

theorem test_invert_demorgan_logical_or_thm (e e_1 : IntW 64) :
  LLVM.xor
      (LLVM.or (icmp IntPred.eq e_1 (const? 64 0))
        (select (icmp IntPred.eq e_1 (const? 64 27)) (const? 1 1) (icmp IntPred.eq e (const? 64 0))))
      (const? 1 1) ⊑
    LLVM.and (icmp IntPred.ne e_1 (const? 64 0))
      (select (icmp IntPred.ne e_1 (const? 64 27)) (icmp IntPred.ne e (const? 64 0)) (const? 1 0))

theorem and_ne_with_diff_one_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 40#32) &&& ofBool (x != 39#32) = ofBool (x + BitVec.ofInt 32 (-41) <ᵤ BitVec.ofInt 32 (-2))

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

theorem uge_umin4_proof : uge_umin4_before ⊑ uge_umin4_after

theorem sdiv_x_by_const_cmp_x_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(13#32 == 0 || 32 != 1 && x == intMin 32 && 13#32 == -1) = true → ofBool (x.sdiv 13#32 == x) = ofBool (x == 0#32)

theorem not_true_not_proof : not_true_not_before ⊑ not_true_not_after

theorem ne_shift_in_zeros_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.ne (trunc 24 (lshr e_1 (const? 32 16))) (trunc 24 (lshr e (const? 32 16))))
      (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8)))) ⊑
    icmp IntPred.ugt (LLVM.xor e_1 e) (const? 32 255)

theorem ashr_lowmask_proof : ashr_lowmask_before ⊑ ashr_lowmask_after

theorem main7e_logical_thm.extracted_1._15 : ∀ (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 → 0#32 = zeroExtend 32 (ofBool (x_1 &&& x &&& x_2 != x_1 &&& x))

theorem ashr_ult_11_proof : ashr_ult_11_before ⊑ ashr_ult_11_after

theorem ashrslt_02_05_proof : ashrslt_02_05_before ⊑ ashrslt_02_05_after

theorem test58_proof : test58_before ⊑ test58_after

@[grind ., simp]
lemma RawCNFA.states_lt (m : RawCNFA A) s : s ∈ m.states → s < m.stateMax

theorem test_ult_thm (e : IntW 16) (e_1 : IntW 32) :
  icmp IntPred.ult (trunc 8 e_1 { «nsw» := true, «nuw» := false }) (trunc 8 e { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.ult e_1 (sext 32 e)

theorem main3e_like_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& x == 0#32) = 1#1 → ofBool (x_1 &&& x != 0#32) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬8#32 ≥ ↑32 → 7#8 ≥ ↑8 → False

theorem scalar_i32_lshr_and_signbit_eq_proof : scalar_i32_lshr_and_signbit_eq_before ⊑ scalar_i32_lshr_and_signbit_eq_after

theorem demorgan_nor_use2ac_proof : demorgan_nor_use2ac_before ⊑ demorgan_nor_use2ac_after

theorem PR44545_proof : PR44545_before ⊑ PR44545_after

theorem ult_or_not_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ult e_1 e) (const? 1 1) (icmp IntPred.ne e_1 (const? 8 (-1))) ⊑
    icmp IntPred.ne e_1 (const? 8 (-1))

theorem select_constants_and_icmp_ne0_proof : select_constants_and_icmp_ne0_before ⊑ select_constants_and_icmp_ne0_after

theorem absdiff2_proof : absdiff2_before ⊑ absdiff2_after

theorem t6_no_extrause_proof : t6_no_extrause_before ⊑ t6_no_extrause_after

theorem and_zext_zext_thm (e : IntW 4) (e_1 : IntW 8) :
  LLVM.and (zext 16 e_1) (zext 16 e) ⊑ zext 16 (LLVM.and e_1 (zext 8 e)) { «nneg» := true }

theorem add_eq_xor_add_mul_and' (x y : BitVec w) :
    x + y = (x ^^^ y) + (x &&& y) + (x &&& y)

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

theorem bitwise_and_logical_and_masked_icmp_allones_poison2_proof : bitwise_and_logical_and_masked_icmp_allones_poison2_before ⊑ bitwise_and_logical_and_masked_icmp_allones_poison2_after

theorem substitute_constant_or_ne_swap_sle_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != 42#8) ||

theorem icmp_shl_nsw_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (x <<< 5#32).sshiftRight' 5#32 ≠ x ∨ 5#32 ≥ ↑32) → ofBool (x <<< 5#32 == 0#32) = ofBool (x == 0#32)

theorem shift_xor_multiuse_cmp_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 ashr_pow2_ult_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → True ∧ BitVec.ofInt 8 (-128) >>> x <<< x ≠ BitVec.ofInt 8 (-128) ∨ x ≥ ↑8 → False

@[simp]
lemma inter_accepts (M N : NFA' n) :
    (M.inter N).accepts = M.accepts ∩ N.accepts

@[simp] theorem dropUntil_castCtxt {h : Γ = Γ'} :
    Γ'.dropUntil (v.castCtxt h) = Γ.dropUntil v

theorem foo_thm (e : IntW 32) :
  LLVM.and (sub (const? 32 5) e) (const? 32 2) ⊑ LLVM.and (sub (const? 32 1) e) (const? 32 2)

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

theorem main7c_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 == x_1 &&& x) = 1#1 → ofBool (x_1 != x_1 &&& x) = 1#1 → ¬0#1 = 1#1 → 1#32 = zeroExtend 32 1#1

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

theorem e_1952 :
     - 11 * (c ^^^ (a ||| (b ||| c))) - 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 2 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 1 * c - 2 * (c ^^^  ~~~(a ||| b)) + 3 * (a ^^^ c) - 2 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * (c ^^^ (a &&&  ~~~b)) + 7 * ( ~~~a ||| ( ~~~b &&& c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 7 * (a &&& c) + 1 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 2 * (b ^^^ (a &&&  ~~~c)) - 3 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 7 * (b ^^^ ( ~~~a &&& (b ||| c))) - 1 * (c ||| (a &&&  ~~~b)) + 11 *  ~~~(a ^^^ b) - 1 * (b &&& (a ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 5 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 4 * (a |||  ~~~c) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 2 * (c ^^^ ( ~~~a &&& (b ||| c))) + 2 * (a ||| c) - 1 * (c |||  ~~~(a |||  ~~~b)) - 7 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 4 * (b &&&  ~~~(a ^^^ c)) + 1 * (b ^^^ (a ||| (b ||| c))) - 5 * (a ^^^ (b ||| c)) + 5 * ((a ^^^ b) &&& (a ^^^ c)) - 6 * (b &&&  ~~~(a &&&  ~~~c)) + 11 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 * (c ^^^ (a ||| (b &&& c))) - 2 * (a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a &&& b)) - 1 * (b |||  ~~~c) + 3 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 4 * (c ^^^ (a ||| b)) - 2 * (b ^^^  ~~~(a |||  ~~~c)) - 28 *  ~~~(a ||| (b ||| c)) + 12 *  ~~~(a ||| ( ~~~b ||| c)) - 8 *  ~~~( ~~~a ||| (b ||| c)) - 24 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 13 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) - 6 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) = 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 5 * (a ||| b)

theorem sgt_mulzero_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 0#8 = true) → ofBool (21#8 <ₛ x * 0#8) = 0#1

theorem lt_unsigned_to_small_unsigned_thm (e : IntW 8) :
  icmp IntPred.ult (zext 32 e) (const? 32 17) ⊑ icmp IntPred.ult e (const? 8 17)

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 shl_nsw_nuw_ult_Csle0_proof : shl_nsw_nuw_ult_Csle0_before ⊑ shl_nsw_nuw_ult_Csle0_after

theorem testtrunclowhigh_thm.extracted_1._4 : ∀ (x x_1 : BitVec 16) (x_2 : BitVec 32),
  ¬ofBool (x_2 + 128#32 <ᵤ 256#32) = 1#1 → ¬ofBool (-1#32 <ₛ x_2) = 1#1 → ¬ofBool (x_2 <ₛ 0#32) = 1#1 → x = x_1

theorem ashrslt_01_08_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 1)) (const? 4 (-8)) ⊑ const? 1 0

theorem e_1921 :
     - 2 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 5 *  ~~~(b &&&  ~~~c) - 1 * ( ~~~b &&& (a ^^^ c)) + 11 * (b &&&  ~~~c) - 6 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) - 6 * (c ||| (a &&& b)) + 4 * (a ||| (b ||| c)) + 11 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 * (c &&& (a |||  ~~~b)) + 2 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 1 * (b ||| c) + 2 * (a ^^^ (b ^^^ c)) + 1 *  ~~~(a ||| c) - 2 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 7 *  ~~~(a &&& ( ~~~b ||| c)) + 11 * ( ~~~b &&&  ~~~(a ^^^ c)) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 2 * (a &&& ( ~~~b ||| c)) + 3 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 4 * ( ~~~a &&& (b ^^^ c)) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 3 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 7 * (c &&& (a ^^^ b)) - 7 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 5 * (b &&&  ~~~(a ^^^ c)) - 6 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 * ((a &&& b) ^^^ (b |||  ~~~c)) + 11 * (c |||  ~~~(a ^^^ b)) - 11 *  ~~~(a ^^^ (b &&& c)) + 3 * (c ^^^ (a ||| ( ~~~b ||| c))) + 7 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 *  ~~~(a ^^^ ( ~~~b ||| c)) - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 1 * (a &&&  ~~~c) + 1 * (a ^^^ b) + 1 * ((a &&& c) |||  ~~~(b ||| c)) + 2 * (c ^^^  ~~~(a ||| b)) - 2 * (b |||  ~~~(a ||| c)) - 2 *  ~~~(a &&&  ~~~c) - 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 20 *  ~~~(a ||| (b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) - 34 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 11 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) + 2 * (a &&& ( ~~~b &&& c)) + 20 * (a &&& (b &&& c)) =  - 3 * (b ^^^ ( ~~~a ||| (b &&& c)))

theorem test_sub__nsw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.or e (const? 32 (-2147483648))) (const? 32 (-2147483647))) (const? 32 (-1))
      (sub (const? 32 (-2147483648)) (LLVM.or e (const? 32 (-2147483648)))) ⊑
    sub (const? 32 (-2147483648)) (LLVM.or e (const? 32 (-2147483648))) { «nsw» := true, «nuw» := false }

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

theorem udiv400_proof : udiv400_before ⊑ udiv400_after

@[grind =, simp]
lemma createSink_trans [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) :
    s₂ ∈ m.createSink.2.tr s₁ a ↔
      (s₁ = m.stateMax ∧ s₂ = m.stateMax) ∨
      (s₁ ∈ m.states ∧ s₂ ∈ m.states ∧ s₂ ∈ m.tr s₁ a)

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

theorem p0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 → ofBool ((-1#8) >>> x_1 &&& x == x) = ofBool (x ≤ᵤ (-1#8) >>> x_1)

theorem negation_of_increment_via_or_disjoint_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x &&& 1#8 != 0) = true) → x_1 - (x ||| 1#8) = x_1 + (x ^^^ -1#8)

theorem test83_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 16),
  ¬(True ∧ x.saddOverflow (-1#64) = true ∨ truncate 32 (x + -1#64) ≥ ↑32) → truncate 32 x + -1#32 ≥ ↑32 → False

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

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x <ₛ x) = 0#1

theorem shl_mask_proof : shl_mask_before ⊑ shl_mask_after

theorem t_2_63_or_thm (e : IntW 8) :
  LLVM.or (select (icmp IntPred.ugt e (const? 8 2)) e (const? 8 2)) (const? 8 63) ⊑
    LLVM.or e (const? 8 63)

theorem udiv_shl_pair1_thm.extracted_1._2 : ∀ (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) → x_2 <<< x_1 / x_2 <<< x = 1#32 <<< x_1 >>> x

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem icmp_eq_sext_ne_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x != 0#32)) == x) = ofBool (x + 1#32 <ᵤ 2#32)

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

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

theorem test3_proof : test3_before ⊑ test3_after

theorem const_sub_add_const_proof : const_sub_add_const_before ⊑ const_sub_add_const_after

theorem sextinreg2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(24#32 ≥ ↑32 ∨ True ∧ x <<< 24#32 >>> 24#32 <<< 24#32 ≠ x <<< 24#32 ∨ 24#32 ≥ ↑32) →
    (x &&& 255#32 ^^^ 128#32) + BitVec.ofInt 32 (-128) = (x <<< 24#32).sshiftRight' 24#32

theorem e_304 :
    2 *  ~~~x + 2 * x - 2 *  ~~~(x ^^^ y) + 2 * (x ^^^ y) - 15 *  ~~~(x |||  ~~~y) - 15 * (x &&&  ~~~y) - 11 * (x &&& y) =  - 11 * (x ||| y)

theorem e_1080 :
     - 6 * (z |||  ~~~t) - 6 *  ~~~t - 6 * t - 1 *  ~~~(z &&&  ~~~z) - 11 * (z ^^^ t) + 18 *  ~~~(z |||  ~~~t) + 24 * (z &&&  ~~~t) + 13 * (z &&& t) =  - 13 *  ~~~(z ||| t)

theorem logic_and_logic_or_7_proof : logic_and_logic_or_7_before ⊑ logic_and_logic_or_7_after

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

@[simp]
theorem denote_splitProgramAt [LawfulMonad d.m] {pos : ℕ} {prog : Com d Γ eff t}
    {res : _} (hres : res ∈ splitProgramAt pos prog) :
    res.denote = prog.denote

theorem or_nosignbit_lshr_proof : or_nosignbit_lshr_before ⊑ or_nosignbit_lshr_after

@[simp]
theorem bind_if_then_none_eq_if_bind (h : Prop) [Decidable h] (x : Option α) :
    (if h then none else x) >>= f = if h then none else x >>= f

theorem trunc_shl_lshr_var_thm (e e_1 : IntW 64) :
  trunc 32 (shl (lshr e_1 e) (const? 64 2)) ⊑ shl (trunc 32 (lshr e_1 e)) (const? 32 2)

theorem e_758 :
    5 *  ~~~(z ^^^ t) - 2 *  ~~~(z &&& t) + 5 *  ~~~(z |||  ~~~t) - 2 * (z &&& t) =  - 5 * (z &&&  ~~~t) + 3 *  ~~~(z &&&  ~~~z)

theorem do_not_add_annotation_to_existing_instr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  0#32 + (x_1 + x) = x_1 + x

theorem neg_nsw_slt_n1_proof : neg_nsw_slt_n1_before ⊑ neg_nsw_slt_n1_after

theorem test34_proof : test34_before ⊑ test34_after

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

theorem test11_proof : test11_before ⊑ test11_after

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

theorem com_Γ : com.1 = (Γn 1)

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

theorem select_add_proof : select_add_before ⊑ select_add_after

theorem select_xor_icmp_meta_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.eq e_2 (const? 32 0)) (LLVM.xor e_2 e_1) e ⊑
    select (icmp IntPred.eq e_2 (const? 32 0)) e_1 e

theorem carry_add_succ (x : Bool → BitStream) (n : ℕ) :
    add.carry x (n+1) =
      fun _ => (BitStream.addAux (x true) (x false) n).2

theorem a_false_implies_b_true2_proof : a_false_implies_b_true2_before ⊑ a_false_implies_b_true2_after

theorem shl_lshr_demand1_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ 3#8 ≥ ↑8) → x ≥ ↑8 → False

theorem is_ascii_alphabetic_inverted_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow (BitVec.ofInt 32 (-91)) = true) →
    ¬ofBool (x + BitVec.ofInt 32 (-91) <ᵤ BitVec.ofInt 32 (-26)) = 1#1 →
      0#1 = ofBool ((x &&& BitVec.ofInt 32 (-33)) + BitVec.ofInt 32 (-91) <ᵤ BitVec.ofInt 32 (-26))

theorem urem_i8_thm (e e_1 : IntW 8) : trunc 8 (urem (zext 32 e_1) (zext 32 e)) ⊑ urem e_1 e

theorem eq_nsw_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 5#8 = true) → ofBool (x * 5#8 == BitVec.ofInt 8 (-11)) = 0#1

theorem or_eq_and_not_add :
    x ||

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

@[simp, simp_denote, simp_sllvm]
lemma run_ub : StateT.run (throwUB : EffectM α) s = .poison

@[simp]
theorem EnvFin.apply_getLsb_eq (env : EnvFin (w + 1) n) (i : Fin n) : env.getLsb i =
  BitVec.ofBool (env i)[0]

theorem e_314 :
     - 7 * (x ^^^ y) - 1 *  ~~~y - 1 *  ~~~(x &&&  ~~~y) - 1 * (x ||| y) + 2 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) - 1 * (x &&& y) =  - 9 * (x &&&  ~~~y) - 3 * y

theorem udiv_illegal_type_c_proof : udiv_illegal_type_c_before ⊑ udiv_illegal_type_c_after

theorem bv_AddSub_1156 :
    ∀ (e : LLVM.IntW w), LLVM.add e e ⊑ LLVM.shl e (LLVM.const? w 1)

theorem xor_notand_to_or_not4_proof : xor_notand_to_or_not4_before ⊑ xor_notand_to_or_not4_after

theorem test7_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (20000#32).ssubOverflow (x &&& 511#32) = true ∨
        True ∧ (20000#32).usubOverflow (x &&& 511#32) = true ∨ True ∧ (20000#32 - (x &&& 511#32)).msb = true) →
    signExtend 64 (20000#32 - (x &&& 511#32)) = zeroExtend 64 (20000#32 - (x &&& 511#32))

theorem shl_xor_xor_bad_mask_distribute_thm (e e_1 : IntW 8) :
  LLVM.xor (shl e_1 (const? 8 1)) (LLVM.xor (shl e (const? 8 1)) (const? 8 (-68))) ⊑
    LLVM.xor (shl (LLVM.xor e e_1) (const? 8 1)) (const? 8 (-68))

theorem e_245 :
     - 1 * (x ^^^ y) - 6 *  ~~~(x &&& y) + 1 * y - 1 *  ~~~(x &&&  ~~~y) + 6 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 6 * (x &&&  ~~~y) =  - 1 *  ~~~y

theorem sub_to_xor_or_commuted_proof : sub_to_xor_or_commuted_before ⊑ sub_to_xor_or_commuted_after

theorem test13_thm (e : IntW 1024) :
  LLVM.and (ashr e (const? 1024 1016)) (const? 1024 255) ⊑ lshr e (const? 1024 1016)

theorem and_orn_cmp_1_proof : and_orn_cmp_1_before ⊑ and_orn_cmp_1_after

@[aesop 50% unsafe]
theorem Std.HashMap.mem_of_getElem? [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} :
    m[k]? = some v → k ∈ m

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

theorem p_constmask2_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 61440)) (LLVM.and e (const? 32 (-65281))) { «disjoint» := true }

theorem fold_sext_to_and_wrong8_proof : fold_sext_to_and_wrong8_before ⊑ fold_sext_to_and_wrong8_after

theorem ashrsgt_02_06_exact_thm (e : IntW 4) :
  icmp IntPred.sgt (ashr e (const? 4 2) { «exact» := true }) (const? 4 6) ⊑ const? 1 0

theorem e_26 :
     - 2 * (x ^^^ y) + 3 * y - 12 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) - 14 * (x &&& y) =  - 11 * (x ||| y)

theorem and_orn_cmp_1_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (icmp IntPred.sgt e_2 e_1)
      (LLVM.or (icmp IntPred.ugt e (const? 32 42)) (icmp IntPred.sle e_2 e_1)) ⊑
    LLVM.and (icmp IntPred.sgt e_2 e_1) (icmp IntPred.ugt e (const? 32 42))

theorem or_consts_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (4#32 &&& x != 0#32) = 1#1 → ofBool (8#32 &&& x != 0#32) = ofBool (x &&& 12#32 == 12#32)

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

theorem zext_sext_add_icmp_slt_minus1_proof : zext_sext_add_icmp_slt_minus1_before ⊑ zext_sext_add_icmp_slt_minus1_after

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

theorem fold_sext_to_and1_proof : fold_sext_to_and1_before ⊑ fold_sext_to_and1_after

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

theorem positive_biggershl_shlnsw_lshrexact_thm (e : IntW 8) :
  shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 6) { «nsw» := true, «nuw» := false } ⊑
    shl e (const? 8 3) { «nsw» := true, «nuw» := true }

theorem sle_or_not_min_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sle e_1 e) (const? 1 1) (icmp IntPred.ne e_1 (const? 8 (-128))) ⊑ const? 1 1

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

theorem trunc_sel_equal_sext_proof : trunc_sel_equal_sext_before ⊑ trunc_sel_equal_sext_after

theorem eq_umin4_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (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.ule (add e_1 (const? 32 3)) e

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

theorem bor_lor_left1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 ||

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 12#32 == 0#32) ||

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

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

@[simp]
theorem eval_mkMaskZeroFsm_eq_decide (env : α → BitStream):
  mkMaskZeroFSM.eval env i =
    decide (0 < i)

theorem andn_or_cmp_4_proof : andn_or_cmp_4_before ⊑ andn_or_cmp_4_after

theorem t0_proof : t0_before ⊑ t0_after

theorem or_eq_with_one_bit_diff_constants3_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == BitVec.ofInt 8 (-2)) = 1#1 → 1#1 = ofBool (x &&& 127#8 == 126#8)

theorem test68_proof : test68_before ⊑ test68_after

theorem test_eq_0_and_15_add_3_proof : test_eq_0_and_15_add_3_before ⊑ test_eq_0_and_15_add_3_after

theorem e_1810 :
     - 1 * (c ^^^  ~~~(a &&&  ~~~b)) + 4 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 11 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 7 * (c ^^^  ~~~(a &&& (b &&& c))) + 2 * (a ||| ( ~~~b &&& c)) - 2 * (b |||  ~~~(a ^^^ c)) + 4 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 2 * (a &&& c) + 2 *  ~~~(a ^^^ (b ||| c)) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 3 * (b &&& (a ||| c)) + 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 11 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 5 *  ~~~(a &&&  ~~~b) - 6 * (a ||| (b &&& c)) + 4 * (c |||  ~~~(a ||| b)) + 3 *  ~~~(a ||| ( ~~~b &&& c)) - 11 *  ~~~(a &&&  ~~~c) - 3 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 1 * ((a &&& c) |||  ~~~(b ||| c)) + 2 * (c ^^^ (a ||| (b &&& c))) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 11 * (a ||| (b ||| c)) + 11 * (b |||  ~~~(a |||  ~~~c)) + 1 * (b ^^^ (a &&&  ~~~c)) + 7 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 7 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 * (c ^^^ (a &&& (b ||| c))) - 18 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) - 9 *  ~~~( ~~~a ||| (b ||| c)) - 22 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 28 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * ( ~~~a &&& (b &&& c)) + 25 * (a &&& ( ~~~b &&& c)) - 22 * (a &&& (b &&& c)) =  - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 *  ~~~(a ||| (b &&& c))

theorem positive_sameconst_ashrexact_proof : positive_sameconst_ashrexact_before ⊑ positive_sameconst_ashrexact_after

theorem PR42691_4_proof : PR42691_4_before ⊑ PR42691_4_after

theorem trunc_unsigned_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 x_1) ≠ x_1 ∨ True ∧ signExtend 16 (truncate 8 x) ≠ x) →
    ofBool (truncate 8 x_1 <ᵤ truncate 8 x) = ofBool (x_1 <ᵤ x)

theorem test7_proof : test7_before ⊑ test7_after

theorem lshr_ne_msb_low_last_zero_proof : lshr_ne_msb_low_last_zero_before ⊑ lshr_ne_msb_low_last_zero_after

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

theorem no_reassoc_add_nuw_none_proof : no_reassoc_add_nuw_none_before ⊑ no_reassoc_add_nuw_none_after

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1b_logical_after

theorem must_drop_poison_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ ((x_1 &&& 255#32) <<< x).sshiftRight' x ≠ x_1 &&& 255#32 ∨
        True ∧ (x_1 &&& 255#32) <<< x >>> x ≠ x_1 &&& 255#32 ∨ x ≥ ↑32) →
    ¬x ≥ ↑32 → truncate 8 ((x_1 &&& 255#32) <<< x) = truncate 8 (x_1 <<< x)

theorem test_xor_eq_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 ^^^ -1#8 == x_1 ^^^ -1#8 ^^^ x) = ofBool (x_2 == x_1 ^^^ x)

theorem foo1_and_signbit_lshr_without_shifting_signbit_both_sides_proof : foo1_and_signbit_lshr_without_shifting_signbit_both_sides_before ⊑ foo1_and_signbit_lshr_without_shifting_signbit_both_sides_after

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

theorem sdiv_ult_smin_proof : sdiv_ult_smin_before ⊑ sdiv_ult_smin_after

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

theorem alive_AndOrXor_2123___A__B__A__B___A__B : alive_AndOrXor_2123___A__B__A__B___A__B_src ⊑ alive_AndOrXor_2123___A__B__A__B___A__B_tgt

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 test_nuw_nsw_and_signed_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).ssubOverflow x = true ∨ True ∧ (10#64).usubOverflow x = true) →
    ofBool (10#64 - x <ₛ 3#64) = ofBool (7#64 <ᵤ x)

theorem p_constmask_proof : p_constmask_before ⊑ p_constmask_after

theorem ashr_can_be_lshr_2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(34#64 ≥ ↑64 ∨
        True ∧
            (zeroExtend 64 x ||| 4278190080#64) <<< 34#64 >>> 32#64 <<< 32#64 ≠
              (zeroExtend 64 x ||| 4278190080#64) <<< 34#64 ∨
          32#64 ≥ ↑64 ∨
            True ∧
              signExtend 64 (truncate 32 (((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64)) ≠
                ((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64) →
    2#32 ≥ ↑32 → False

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

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

theorem trunc_sel_larger_zext_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬(True ∧ (x &&& 65535#32).msb = true) → zeroExtend 64 (truncate 16 x) = zeroExtend 64 (x &&& 65535#32)

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

theorem test6_proof : test6_before ⊑ test6_after

theorem shift_no_xor_multiuse_xor_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1#32 == 0#32) = 1#1 →
    ¬1#32 ≥ ↑32 → (x ^^^ 2#32) * (x ^^^ 2#32) = (x ^^^ x_1 <<< 1#32 &&& 2#32) * (x ^^^ 2#32)

@[simp] theorem denote_mk {lets : Lets d Γ_in eff Γ_out} {com : Com d Γ_out eff ty} :
    denote ⟨lets, com⟩ = fun V => (lets.denote V) >>= com.denote

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

theorem test_and_ne_a_b_commuted_proof : test_and_ne_a_b_commuted_before ⊑ test_and_ne_a_b_commuted_after

theorem ult_192_proof : ult_192_before ⊑ ult_192_after

theorem ashrslt_03_06_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (x.sshiftRight' 3#4 <ₛ 6#4) = 1#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 sgt_3_impliesT_sgt_2_thm.extracted_1._5 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (3#8 <ₛ x_1) = 1#1 → ¬ofBool (x_1 <ₛ 4#8) = 1#1 → ofBool (x_1 <ₛ x) = 0#1

@[simp] theorem eval_falseAfterIncluding (n : Nat) (i : Nat) {env : Fin 0 → BitStream} :
    (falseAfterIncluding n).eval env i = decide (i < n)

theorem positive_with_mask_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 1107296256)) (const? 32 0))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem test_shl_nuw__nuw_is_safe_proof : test_shl_nuw__nuw_is_safe_before ⊑ test_shl_nuw__nuw_is_safe_after

theorem icmp_eq_and_pow2_shl1_proof : icmp_eq_and_pow2_shl1_before ⊑ icmp_eq_and_pow2_shl1_after

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

theorem test5_thm (e : IntW 32) :
  sext 64 (urem e (const? 32 30000)) ⊑ zext 64 (urem e (const? 32 30000)) { «nneg» := true }

theorem demo4 (x y : BitVec 32) : (x ^^^ y) &&& 1#32 ||

theorem t2_commutative_proof : t2_commutative_before ⊑ t2_commutative_after

theorem mul_sel_op0_proof : mul_sel_op0_before ⊑ mul_sel_op0_after

theorem shl_and_and_fail_proof : shl_and_and_fail_before ⊑ shl_and_and_fail_after

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

theorem test_add_nuw_nsw__nuw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 2147483647#32 == 2147483647#32) = 1#1 →
    ¬(True ∧ (x &&& 2147483647#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true) →
      True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true → False

theorem test2_proof : test2_before ⊑ test2_after

theorem test12_proof : test12_before ⊑ test12_after

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

theorem shl_nuw_add_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 1#32 = true ∨ True ∧ 1#32 <<< (x + 1#32) >>> (x + 1#32) ≠ 1#32 ∨ x + 1#32 ≥ ↑32) →
    ¬(True ∧ 2#32 <<< x >>> x ≠ 2#32 ∨ x ≥ ↑32) → 1#32 <<< (x + 1#32) = 2#32 <<< x

theorem select_1_proof : select_1_before ⊑ select_1_after

theorem ashr_and_proof : ashr_and_before ⊑ ashr_and_after

theorem or_signbit_select_ashr_proof : or_signbit_select_ashr_before ⊑ or_signbit_select_ashr_after

lemma TermUnop.alt_lang {t : Term} (op : TermUnop) :
  (op.subst_arity' ▸ (op.subst t).language) =
    let lop : Set (BitVecs 2) := op.openTerm_arity' ▸ op.openTerm.language
    let lop' : Set (BitVecs (t.arity + 2)) := lop.lift (λ i ↦ i.natAdd t.arity)
    let lt : Set (BitVecs (t.arity + 2)) := t.language.lift (λ i ↦ i.castLE (by omega))
    let l := lt ∩ lop'
    l.proj (liftUnop t.arity)

theorem or_or_and_pat5_proof : or_or_and_pat5_before ⊑ or_or_and_pat5_after

theorem test6_thm (e : IntW 64) :
  trunc 32 (lshr (zext 128 e) (const? 128 32)) ⊑
    trunc 32 (lshr e (const? 64 32)) { «nsw» := false, «nuw» := true }

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 e_816 :
     - 2 * (z ^^^ t) + 7 *  ~~~t - 7 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) + 5 * (z &&& t) = 5 * z

theorem select_icmp_ne_0_and_4096_xor_4096_proof : select_icmp_ne_0_and_4096_xor_4096_before ⊑ select_icmp_ne_0_and_4096_xor_4096_after

theorem band_lor_left2_proof : band_lor_left2_before ⊑ band_lor_left2_after

@[simp] theorem Hom.consMap_toCons {Γ Γ' : Ctxt Ty} (f : Hom Γ Γ') {t t' : Ty} (v : Γ.Var t') :
    (f.consMap v.toCons (t := t)) = (f v).toCons

@[simp, defeq]
theorem entries_symm_eqvVar (varMap : MatchVarResult lets v matchLets w ma) :
  (eqvVarLeft (matchExpr:=matchExpr) |>.symm  varMap).val.entries = varMap.val.entries

@[simp, simp_denote]
theorem liftEffect_rfl [Pure m] (hle : eff ≤ eff) :
    liftEffect hle (α := α) (m := m) = id

theorem e_514 :
     - 3 * y + 1 *  ~~~y - 1 *  ~~~(x &&&  ~~~x) - 7 *  ~~~(x &&&  ~~~y) - 6 * (x ||| y) + 2 * x + 16 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) + 15 * (x &&& y) =  - 1 *  ~~~(x &&& y) - 6 *  ~~~(x ||| y)

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

theorem e_1441 :
    1 * (z ^^^ t) - 5 *  ~~~(z &&&  ~~~z) - 5 *  ~~~(z &&&  ~~~t) + 4 *  ~~~t - 2 * t - 2 *  ~~~(z ^^^ t) + 8 *  ~~~(z ||| t) + 11 *  ~~~(z |||  ~~~t) + 2 * (z &&&  ~~~t) + 16 * (z &&& t) = 2 * z

theorem test3_proof : test3_before ⊑ test3_after

theorem n4_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬16#32 ≥ ↑32 → True ∧ zeroExtend 32 x <<< 16#32 >>> 16#32 ≠ zeroExtend 32 x ∨ 16#32 ≥ ↑32 → False

theorem test19_proof : test19_before ⊑ test19_after

@[simp, grind=] theorem getElem?_ofList (i : Nat) : (ofList ts)[i]? = ts[i]?

theorem nonexact_ashr_ne_noexactdiv_proof : nonexact_ashr_ne_noexactdiv_before ⊑ nonexact_ashr_ne_noexactdiv_after

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 ||

theorem substitute_constant_and_eq_ugt_swap_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ugt e_1 e) (icmp IntPred.eq e (const? 8 42)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.eq e (const? 8 42)) (icmp IntPred.ugt e_1 (const? 8 42))

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

theorem shl_and_proof : shl_and_before ⊑ shl_and_after

theorem test12_logical_proof : test12_logical_before ⊑ test12_logical_after

theorem self_EqualUpTo_ofBitVecSext_toBitVec (x : BitStream) :
  EqualUpTo w x (BitStream.ofBitVecSext (x.toBitVec w))

theorem eq_umax3_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 n0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& 4#8 <ᵤ x) = ofBool (x &&& BitVec.ofInt 8 (-5) != 0#8)

theorem neg_nsw_sgt_n1_proof : neg_nsw_sgt_n1_before ⊑ neg_nsw_sgt_n1_after

theorem xor_or_xor_common_op_commute5_proof : xor_or_xor_common_op_commute5_before ⊑ xor_or_xor_common_op_commute5_after

theorem ne_umax3_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.ugt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.ult (add e_1 (const? 32 3)) e

theorem shift_xor_multiuse_cmp_with_and_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.and e_2 (const? 32 (-2049))))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) (LLVM.and e_2 (const? 32 (-2049)))
        e_2)
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

theorem test25_thm (e : IntW 32) : icmp IntPred.ugt (LLVM.and e (const? 32 2)) (const? 32 2) ⊑ const? 1 0

theorem ne_21_comm_ne_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) → 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 → False

theorem test19_thm (e : IntW 10) :
  sext 10 (ashr (shl (trunc 3 e) (const? 3 2)) (const? 3 2)) ⊑
    sext 10 (sub (const? 3 0) (LLVM.and (trunc 3 e) (const? 3 1)) { «nsw» := true, «nuw» := false })

theorem t_2_4_thm (e : IntW 8) :
  LLVM.and (select (icmp IntPred.ugt e (const? 8 2)) e (const? 8 2)) (const? 8 4) ⊑
    LLVM.and e (const? 8 4)

theorem test_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 e_256 :
     - 11 * (x |||  ~~~y) - 5 * y + 2 *  ~~~x - 5 * (x ||| y) + 1 * (x ^^^ y) + 7 *  ~~~(x |||  ~~~y) + 15 * (x &&&  ~~~y) =  - 21 * (x &&& y) - 9 *  ~~~(x ||| y)

theorem tryFactorization_add_nuw_mul_nuw_int_max_proof : tryFactorization_add_nuw_mul_nuw_int_max_before ⊑ tryFactorization_add_nuw_mul_nuw_int_max_after

theorem or_and2_commuted_proof : or_and2_commuted_before ⊑ or_and2_commuted_after

theorem slt_or_not_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ne e_1 (const? 8 127)) (const? 1 1) (icmp IntPred.slt e_1 e) ⊑
    icmp IntPred.ne e_1 (const? 8 127)

theorem add_of_selects_thm (e : IntW 32) (e_1 : IntW 1) :
  add (select e_1 (const? 32 0) (const? 32 (-2))) (select e_1 e (const? 32 2)) ⊑ select e_1 e (const? 32 0)

@[simp]
theorem Eqn.reflect_eq_ofInt_denote {w : Nat} (xs : Env w) (e : Eqn) :
    e.reflect xs = BitVec.ofInt w (e.denote xs)

theorem sgt_smax3_proof : sgt_smax3_before ⊑ sgt_smax3_after

theorem e_1428 :
     - 11 *  ~~~z - 11 *  ~~~(z ^^^ t) + 5 *  ~~~(z &&& t) + 4 *  ~~~(z &&&  ~~~t) + 2 * z - 2 * (z ||| t) - 1 * (z |||  ~~~t) + 14 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) = 2 * t - 10 * (z &&& t)

theorem ne_optimized_highbits_cmp_proof : ne_optimized_highbits_cmp_before ⊑ ne_optimized_highbits_cmp_after

@[simp]
theorem union_accepts (M : NFA α σ) (N : NFA α ς) :
    (M.union N).accepts = M.accepts ∪ N.accepts

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

@[simp]
theorem LLVM.lshr?_eq_poison {a b : BitVec w} (hb : b ≥ w) : LLVM.lshr? a b = .poison

theorem mul_splat_fold_too_narrow_proof : mul_splat_fold_too_narrow_before ⊑ mul_splat_fold_too_narrow_after

theorem e_354 :
     - 1 *  ~~~(x &&& y) + 11 * x + 7 * y + 5 *  ~~~x - 1 *  ~~~(x ^^^ y) - 5 *  ~~~(x ||| y) - 13 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) = 19 * (x &&& y) - 2 *  ~~~(x &&&  ~~~y)

theorem ashrslt_02_15_exact_proof : ashrslt_02_15_exact_before ⊑ ashrslt_02_15_exact_after

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

theorem test_srem_canonicalize_op0_proof : test_srem_canonicalize_op0_before ⊑ test_srem_canonicalize_op0_after

theorem addhshlhsdivhscalar1_proof : addhshlhsdivhscalar1_before ⊑ addhshlhsdivhscalar1_after

theorem sgt_and_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == BitVec.ofInt 8 (-128)) &&& ofBool (x <ₛ x_1) = 0#1

theorem or_test1_proof : or_test1_before ⊑ or_test1_after

theorem mul_of_udiv_fail_bad_remainder_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umod 11#8 ≠ 0 ∨ 11#8 = 0) →
    True ∧ x.umod 11#8 ≠ 0 ∨ 11#8 = 0 ∨ True ∧ (x / 11#8).umulOverflow 6#8 = true → False

theorem test9_thm (e : IntW 42) : sub e (mul (const? 42 3) e) ⊑ mul e (const? 42 (-2))

theorem factorize5_proof : factorize5_before ⊑ factorize5_after

theorem test_ashr_exact__exact_is_unsafe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2147483585))) (const? 32 0)) e
      (ashr e (zext 64 (ashr (LLVM.and e_1 (const? 32 (-2147483585))) (const? 32 2) { «exact» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (ashr e_1 (const? 32 2)) (const? 32 (-536870897))) { «nneg» := true })

theorem udiv_i32_c_thm (e : IntW 8) :
  LLVM.udiv (zext 32 e) (const? 32 10) ⊑ zext 32 (LLVM.udiv e (const? 8 10)) { «nneg» := true }

theorem or_not_xor_common_op_commute3_proof : or_not_xor_common_op_commute3_before ⊑ or_not_xor_common_op_commute3_after

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

theorem test1_logical_proof : test1_logical_before ⊑ test1_logical_after

@[bv_automata_nnf↓] theorem not_ite {_ : Decidable p} (q r : Prop) : (¬ite p q r) = ite p (¬q) (¬r)

theorem icmp_ne_sext_eq_allones_proof : icmp_ne_sext_eq_allones_before ⊑ icmp_ne_sext_eq_allones_after

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

theorem udiv2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x ≥ ↑32 ∨ True ∧ x_1.umod (1#32 <<< x) ≠ 0 ∨ 1#32 <<< x = 0) →
    ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → x_1 / 1#32 <<< x = x_1 >>> x

theorem fold_add_udiv_urem_to_mul_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(7#32 = 0 ∨ 7#32 = 0) → x / 7#32 * 21#32 + x % 7#32 * 3#32 = x * 3#32

theorem t0_commutative_thm (e e_1 : IntW 8) (e_2 : IntW 1) (e_3 e_4 : IntW 8) :
  select (select (icmp IntPred.eq e_4 e_3) (const? 1 1) (LLVM.xor e_2 (const? 1 1))) e_1 e ⊑
    select (select (icmp IntPred.ne e_4 e_3) e_2 (const? 1 0)) e e_1

theorem test2_thm.extracted_1._2 : ∀ (x : BitVec 49),
  ¬(17#49 ≥ ↑49 ∨ 4096#49 <<< 17#49 = 0) → ¬29#49 ≥ ↑49 → x / 4096#49 <<< 17#49 = x >>> 29#49

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 + 1#32 + ((x ||| BitVec.ofInt 32 (-1431655767)) ^^^ 1431655766#32) = x_1 - (x &&& 1431655766#32)

theorem select_icmp_ne_0_and_4096_or_32_proof : select_icmp_ne_0_and_4096_or_32_before ⊑ select_icmp_ne_0_and_4096_or_32_after

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

theorem differentconsts_proof : differentconsts_before ⊑ differentconsts_after

theorem t3_thm (e : IntW 8) :
  icmp IntPred.sle (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.sgt e (const? 8 (-1))

theorem PR38781_thm (e e_1 : IntW 32) :
  LLVM.and (LLVM.xor (lshr e_1 (const? 32 31)) (const? 32 1)) (LLVM.xor (lshr e (const? 32 31)) (const? 32 1)) ⊑
    zext 32 (icmp IntPred.sgt (LLVM.or e_1 e) (const? 32 (-1)))

theorem and_signbit_lshr_thm (e : IntW 32) :
  lshr (LLVM.and e (const? 32 (-65536))) (const? 32 8) ⊑ LLVM.and (lshr e (const? 32 8)) (const? 32 16776960)

theorem e_1691 :
     - 2 * (a ||| (b ^^^ c)) + 2 * (a ^^^ b) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 2 * (b ^^^ (a |||  ~~~c)) - 11 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * (b ||| (a &&& c)) - 6 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 4 * (b &&& (a |||  ~~~c)) - 2 *  ~~~(a &&& b) - 1 * (a &&& (b ||| c)) + 4 * (c &&& (a ^^^ b)) + 1 *  ~~~(a ||| b) - 5 * (b ^^^ (a &&& (b ^^^ c))) - 6 * (a ||| (b &&& c)) - 1 * c + 2 *  ~~~(a |||  ~~~b) - 2 *  ~~~(a ^^^ b) - 7 * (c ^^^  ~~~(a &&& (b ||| c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 1 * (b &&&  ~~~c) - 6 * (c ^^^ (a ||| ( ~~~b ||| c))) + 1 * ( ~~~a ||| (b ^^^ c)) + 28 *  ~~~(a ||| (b ||| c)) + 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 10 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 33 * (a &&& ( ~~~b &&& c)) + 27 * (a &&& (b &&& c)) =  - 11 *  ~~~(a ||| ( ~~~b ||| c)) - 39 *  ~~~( ~~~a ||| (b ||| c))

theorem sgt_and_min_logical_proof : sgt_and_min_logical_before ⊑ sgt_and_min_logical_after

theorem test4_thm (e : IntW 32) :
  LLVM.xor (LLVM.and (LLVM.xor e (const? 32 (-1))) (const? 32 5)) (const? 32 (-1)) ⊑ LLVM.or e (const? 32 (-6))

theorem mul_may_overflow_thm (e e_1 : IntW 32) :
  zext 32 (icmp IntPred.ule (mul (zext 34 e_1) (zext 34 e)) (const? 34 4294967295)) ⊑
    zext 32 (icmp IntPred.ult (mul (zext 34 e_1) (zext 34 e)) (const? 34 4294967296))

theorem select_icmp_ne_0_and_8_or_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 ||

theorem e_410 :
    4 * (x |||  ~~~y) - 5 *  ~~~x + 7 *  ~~~(x &&&  ~~~x) - 6 *  ~~~y - 2 *  ~~~(x ^^^ y) - 2 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) - 9 * (x &&& y) =  - 2 *  ~~~(x ||| y)

theorem and_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a &&& c) ≈ʷ (b &&& d)

theorem e_1325 :
    11 *  ~~~z + 1 * (z |||  ~~~t) + 2 * (z ^^^ t) - 11 *  ~~~t + 1 *  ~~~(z ^^^ t) + 2 * (z ||| t) - 4 *  ~~~(z ||| t) - 17 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) =  - 2 *  ~~~(z &&&  ~~~t) + 6 * (z &&& t)

theorem not_lshr_bitwidth_mask_proof : not_lshr_bitwidth_mask_before ⊑ not_lshr_bitwidth_mask_after

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

theorem ule_umax1_proof : ule_umax1_before ⊑ ule_umax1_after

theorem test_sub_nuw_nsw__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true) →
      1073741824#32 = BitVec.ofInt 32 (-2147483648) - (x &&& 2147483647#32)

theorem ashr_ugt_5_proof : ashr_ugt_5_before ⊑ ashr_ugt_5_after

theorem and_sel_op0_thm (e : IntW 1) : LLVM.and (select e (const? 32 25) (const? 32 0)) (const? 32 1) ⊑ zext 32 e

theorem ashrsgt_01_10_proof : ashrsgt_01_10_before ⊑ ashrsgt_01_10_after

theorem e_925 :
     - 2 *  ~~~(z &&&  ~~~t) + 3 *  ~~~z + 5 *  ~~~(z ||| t) + 5 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) + 8 * (z &&& t) = 6 *  ~~~(z &&&  ~~~z)

theorem src_is_mask_p2_m1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (2#8 <<< x_1 + -1#8 &&& (x ^^^ 123#8) <ᵤ x ^^^ 123#8) = ofBool (2#8 <<< x_1 + -1#8 <ᵤ x ^^^ 123#8)

theorem PR24873_proof : PR24873_before ⊑ PR24873_after

theorem PR1817_2_proof : PR1817_2_before ⊑ PR1817_2_after

theorem select_icmp_ne_0_and_1073741824_or_8_thm (e : IntW 8) (e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 1073741824))) e (LLVM.or e (const? 8 8)) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 1073741824)) (const? 32 0)) (LLVM.or e (const? 8 8))
      e

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

theorem trunc_shl_33_i32_i64_proof : trunc_shl_33_i32_i64_before ⊑ trunc_shl_33_i32_i64_after

theorem e_312 :
     - 1 * (x |||  ~~~y) - 11 * (x ||| y) + 11 *  ~~~(x &&& y) - 6 * y + 1 * x - 12 *  ~~~(x ||| y) + 15 * (x &&& y) =  - 4 *  ~~~(x |||  ~~~y) - 2 *  ~~~(x &&&  ~~~y)

theorem e_559 :
    11 * (x |||  ~~~y) + 7 * (x ^^^ y) - 7 *  ~~~y + 2 *  ~~~(x ^^^ y) - 2 * x + 3 * y - 7 *  ~~~(x ||| y) - 9 * (x &&&  ~~~y) - 15 * (x &&& y) = 11 *  ~~~(x |||  ~~~y) - 1 *  ~~~(x &&&  ~~~y)

theorem mul_splat_fold_no_nuw_proof : mul_splat_fold_no_nuw_before ⊑ mul_splat_fold_no_nuw_after

theorem select_exact_lshr_icmp_const_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (31#32 <ᵤ x) = 1#1 → 5#32 ≥ ↑32 → False

theorem ashr_ult_4_proof : ashr_ult_4_before ⊑ ashr_ult_4_after

theorem bools_logical_commute0_and2_proof : bools_logical_commute0_and2_before ⊑ bools_logical_commute0_and2_after

theorem getPureExpr_eq_some
    (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn) :
    ∃ args, lets.getPureExpr v = some ⟨te, w, ⟨
        matchExpr.op,
        matchExpr.ty_eq,
        matchExpr.eff_le,
        args,
        matchExpr.regArgs
      ⟩⟩

theorem test10_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 2)) (const? 32 0)) (icmp IntPred.ult e (const? 32 4)) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow x = true) → True ∧ x <<< 1#32 >>> 1#32 ≠ x ∨ 1#32 ≥ ↑32 → False

theorem e_741 :
     - 3 *  ~~~(x &&& y) + 1 *  ~~~(x &&&  ~~~x) + 1 * x + 4 * (x ^^^ y) - 1 * y + 4 *  ~~~y + 5 * (x ||| y) + 7 *  ~~~(x ^^^ y) - 9 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) = 13 * (x &&& y)

theorem sge_or_not_max_commute_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 127#8) = 1#1 → ofBool (x ≤ₛ x_1) = 1#1

theorem and_ranges_signed_pred_thm (e : IntW 64) :
  LLVM.and (icmp IntPred.slt (add e (const? 64 127)) (const? 64 1024))
      (icmp IntPred.slt (add e (const? 64 128)) (const? 64 256)) ⊑
    icmp IntPred.ult (add e (const? 64 (-9223372036854775681))) (const? 64 (-9223372036854775553))

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

@[simp] theorem carry'_succ (initCarry : Bool) (x y : BitStream) :
    (carry' initCarry x y (i + 1)) =
    let out := carry' initCarry x y i
  let a := x i
  let b := y i
  Bool.atLeastTwo a b out

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

theorem e_1345 :
     - 1 * z - 5 * (z ^^^ t) + 11 *  ~~~(z ^^^ t) + 1 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~t) - 6 *  ~~~z - 11 *  ~~~(z ||| t) + 3 *  ~~~(z |||  ~~~t) + 7 * (z &&&  ~~~t) - 15 * (z &&& t) = 2 * (z |||  ~~~t)

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

theorem add_shl_same_amount_partial_nuw1_proof : add_shl_same_amount_partial_nuw1_before ⊑ add_shl_same_amount_partial_nuw1_after

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 t0_proof : t0_before ⊑ t0_after

theorem alive_Select_746 : forall (w : Nat) (A : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp slt  w %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v1 %v7;
  %v9 := op:select w %v8;
  %v10 := op:const (0) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  w %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub w %v14;
  %v16 := triple:%v12 %v9 %v15;
  %v17 := op:select w %v16
  dsl_ret %v17
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (0) %v0;
  %v2 := op:const (A) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:sub 1 %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v2 %v5;
  %v7 := op:icmp sgt  1 %v6;
  %v8 := op:const (0) %v0;
  %v9 := pair:%v2 %v8;
  %v10 := op:icmp slt  1 %v9;
  %v11 := triple:%v10 %v2 %v4;
  %v12 := op:select 1 %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v12 %v13;
  %v15 := op:icmp sgt  1 %v14;
  %v16 := op:const (0) %v0;
  %v17 := pair:%v16 %v12;
  %v18 := op:sub 1 %v17;
  %v19 := triple:%v7 %v2 %v4;
  %v20 := op:select 1 %v19
  dsl_ret %v20
  ]

theorem sub_ashr_and_i32_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 31#32 ≥ ↑32) →
    ¬ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 31#32 &&& x = 0#32

theorem ashrslt_03_09_exact_proof : ashrslt_03_09_exact_before ⊑ ashrslt_03_09_exact_after

theorem zext_ashr_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬2#16 ≥ ↑16 → 2#8 ≥ ↑8 ∨ True ∧ (x >>> 2#8 &&& x).msb = true → False

@[simp] theorem Valuation.nil_append {V : Γ.Valuation} :
    HAppend.hAppend (α := Valuation no_index _) (γ := Valuation no_index _)
      (nil (Ty:=Ty)) V -- nil ++ V
    = V

theorem positive_samevar_shlnuwnsw_lshrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨
        x ≥ ↑8 ∨
          True ∧ (x_1 >>> x <<< x).sshiftRight' x ≠ x_1 >>> x ∨ True ∧ x_1 >>> x <<< x >>> x ≠ x_1 >>> x ∨ x ≥ ↑8) →
    x_1 >>> x <<< x = x_1

theorem mul_selectp2_x_propegate_nuw_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(True ∧ (2#8).smulOverflow x = true ∨ True ∧ (2#8).umulOverflow x = true) →
      ¬(True ∧ x <<< 1#8 >>> 1#8 ≠ x ∨ 1#8 ≥ ↑8) → 2#8 * x = x <<< 1#8

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

theorem add_mask_sign_commute_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(31#32 ≥ ↑32 ∨ 31#32 ≥ ↑32) →
    ofBool (x <ₛ 0#32) = 1#1 → x.sshiftRight' 31#32 + (x.sshiftRight' 31#32 &&& 8#32) = 7#32

theorem lshr_lshr_pow2_const_negative_overflow_proof : lshr_lshr_pow2_const_negative_overflow_before ⊑ lshr_lshr_pow2_const_negative_overflow_after

theorem uge_swap_or_max_logical_proof : uge_swap_or_max_logical_before ⊑ uge_swap_or_max_logical_after

theorem lor_bor_left2_thm (e e_1 : IntW 1) : LLVM.or (select e_1 (const? 1 1) e) e ⊑ select e_1 (const? 1 1) e

theorem PR39793_bswap_u64_as_u16_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(8#64 ≥ ↑64 ∨ 8#64 ≥ ↑64) → 8#64 ≥ ↑64 → False

theorem BitVec.eq_iff_sub_zero (x y : BitVec w) : x = y ↔ x - y = 0

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 and_not_or_commute8_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
          (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
            (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    (x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true →
      False

@[simp]
lemma lift_accepts (M : NFA' n) (f : Fin n → Fin m) :
    (M.lift f).accepts = BitVecs.transport f ⁻¹' M.accepts

theorem negate_sdiv_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true →
    ¬(BitVec.ofInt 8 (-42) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-42) == -1) = true →
      x_1 - x.sdiv 42#8 = x.sdiv (BitVec.ofInt 8 (-42)) + x_1

theorem or_to_nxor1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  x_1 &&& x ||

theorem shl_nuw_add_nuw_proof : shl_nuw_add_nuw_before ⊑ shl_nuw_add_nuw_after

theorem shl_add_nuw_and_nsw_thm (e e_1 : IntW 8) :
  shl (LLVM.and e_1 (const? 8 31)) (LLVM.and e (const? 8 2)) ⊑
    shl (LLVM.and e_1 (const? 8 31)) (LLVM.and e (const? 8 2)) { «nsw» := true, «nuw» := true }

theorem e_2307 :
    1 * (e &&&  ~~~f) - 2 *  ~~~(d &&&  ~~~e) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^ (d &&&  ~~~f)) + 2 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 5 * (f ^^^ (d &&& (e ||| f))) + 3 * (d ||| (e &&& f)) + 7 *  ~~~(d &&&  ~~~f) + 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (d |||  ~~~f) - 1 *  ~~~(e ^^^ f) - 2 *  ~~~(d ^^^ (e ^^^ f)) + 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * (f &&& (d |||  ~~~e)) - 6 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (d ^^^ f) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 4 *  ~~~(d &&& (e &&& f)) + 11 *  ~~~e + 1 * (f ||| (d &&&  ~~~e)) - 11 * ( ~~~e &&& (d ^^^ f)) - 11 *  ~~~(d |||  ~~~f) - 6 *  ~~~(d &&& (e ^^^ f)) - 3 *  ~~~(d &&&  ~~~d) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 2 *  ~~~(e ||| f) - 6 * (d &&&  ~~~f) - 1 * (f &&& (d ^^^ e)) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) + 11 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 *  ~~~(d &&& (e ||| f)) + 2 * (f ^^^ (d &&& e)) + 5 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 11 * (f &&& (d ||| e)) - 1 *  ~~~(d ^^^ f) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 3 * (e ^^^ (d ||| f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 4 *  ~~~d + 3 * (f ^^^  ~~~(d |||  ~~~e)) - 5 * ( ~~~d ||| ( ~~~e ||| f)) + 4 *  ~~~(d ||| f) + 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~(d &&& e)) + 1 * ( ~~~e ||| (d ^^^ f)) - 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 5 * (f ^^^ (d &&&  ~~~e)) + 4 * (d ^^^ e) - 12 *  ~~~(d ||| (e ||| f)) + 12 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) - 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 17 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) - 24 * (d &&& ( ~~~e &&& f)) - 26 * (d &&& (e &&& f)) = 7 * (d &&& ( ~~~e ||| f))

theorem trunc_shl_1_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬1#64 ≥ ↑64 → ¬1#32 ≥ ↑32 → truncate 32 (x <<< 1#64) = truncate 32 x <<< 1#32

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

theorem and_ranges_overlap_proof : and_ranges_overlap_before ⊑ and_ranges_overlap_after

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 ashr_lshr_exact_lshr_only_proof : ashr_lshr_exact_lshr_only_before ⊑ ashr_lshr_exact_lshr_only_after

theorem commutativity_constant_varx_6_invmask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 4),
  (x_1 ^^^ -1#4) &&& (x ^^^ 6#4) ^^^ 6#4 = (x ^^^ 6#4) &&& x_1 ^^^ x

lemma CNFA.neg_bv_language {m : CNFA n} :
    m.bv_recognizes L → (m.neg.bv_recognizes Lᶜ)

theorem test_add_nuw_nsw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true →
      False

theorem test_add_nuw__all_are_safe_proof : test_add_nuw__all_are_safe_before ⊑ test_add_nuw__all_are_safe_after

theorem lshr_lshr_pow2_const_thm (e : IntW 16) :
  LLVM.and (lshr (lshr (const? 16 2048) e) (const? 16 6)) (const? 16 4) ⊑
    select (icmp IntPred.eq e (const? 16 3)) (const? 16 4) (const? 16 0)

theorem e_680 :
     - 11 *  ~~~(x &&& y) - 6 * (x |||  ~~~y) - 5 * (x ||| y) - 7 *  ~~~(x ^^^ y) - 2 * (x ^^^ y) + 1 *  ~~~(x &&&  ~~~y) + 34 *  ~~~(x ||| y) + 31 *  ~~~(x |||  ~~~y) + 24 * (x &&&  ~~~y) + 20 * (x &&& y) = 11 *  ~~~x + 3 * y

theorem badimm4_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬ofBool (127#16 <ₛ x) = 1#1 → ofBool (x <ₛ BitVec.ofInt 16 (-128)) = 1#1 → truncate 8 x = BitVec.ofInt 8 (-127)

theorem bv_AddSub_1152 :
    ∀ (e e_1 : LLVM.IntW 1), LLVM.add e_1 e ⊑ LLVM.xor e_1 e

theorem alive_Select_858 : forall (w : Nat) (a b : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (a) %v0;
  %v2 := op:const (-1) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:xor w %v3;
  %v5 := op:const (b) %v0;
  %v6 := triple:%v1 %v4 %v5;
  %v7 := op:select w %v6
  dsl_ret %v7
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (a) %v0;
  %v2 := op:const (-1) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:xor 1 %v3;
  %v5 := op:const (b) %v0;
  %v6 := pair:%v4 %v5;
  %v7 := op:and 1 %v6
  dsl_ret %v7
  ]

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_logical_after

theorem sgt_swap_and_not_min_proof : sgt_swap_and_not_min_before ⊑ sgt_swap_and_not_min_after

theorem land_lor_left1_thm (e e_1 : IntW 1) : select (select e_1 e (const? 1 0)) (const? 1 1) e_1 ⊑ e_1

theorem test1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 47),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 47 (-70368744177664) &&& (x &&& 70368744177661#47) != 0) = true) →
    x_1 &&& BitVec.ofInt 47 (-70368744177664) ^^^ x &&& 70368744177661#47 =
      x_1 &&& BitVec.ofInt 47 (-70368744177664) ||

theorem n1_proof : n1_before ⊑ n1_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → x >>> 63#64 ||

theorem ult_to_slt_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor e_1 (const? 8 (-128))) (LLVM.xor e (const? 8 (-128))) ⊑
    icmp IntPred.slt e_1 e

theorem lshr_pow2_ugt_proof : lshr_pow2_ugt_before ⊑ lshr_pow2_ugt_after

theorem exact_ashr_ne_both_equal_proof : exact_ashr_ne_both_equal_before ⊑ exact_ashr_ne_both_equal_after

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

theorem e_503 :
    2 *  ~~~(x &&& y) - 5 * x + 4 * (x ^^^ y) + 11 *  ~~~x + 5 *  ~~~(x &&&  ~~~x) - 5 * y - 23 *  ~~~(x ||| y) - 11 * (x &&&  ~~~y) + 5 * (x &&& y) =  - 5 *  ~~~y + 17 *  ~~~(x |||  ~~~y)

theorem test18_proof : test18_before ⊑ test18_after

theorem ashr_lshr_inv2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ₛ 7#32) = 1#1 → ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → x ≥ ↑32 → False

theorem mul_of_bool_thm (e : IntW 8) (e_1 : IntW 32) :
  icmp IntPred.ugt (mul (LLVM.and e_1 (const? 32 1)) (zext 32 e)) (const? 32 255) ⊑ const? 1 0

theorem neg_slt_0_proof : neg_slt_0_before ⊑ neg_slt_0_after

theorem ne_smax4_proof : ne_smax4_before ⊑ ne_smax4_after

theorem narrow_zext_add_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (zeroExtend 32 x_1 + x) = x_1 + truncate 16 x

theorem bools2_logical_commute1_thm.extracted_1._18 : ∀ (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 → 1#1 = x_2

theorem add_and_or_commutative_proof : add_and_or_commutative_before ⊑ add_and_or_commutative_after

@[simp] theorem map'_cons : map' f g (cons x xs) = cons (g _ x) (map' f g xs)

theorem and_not_or_commute5_thm (e e_1 e_2 : IntW 32) :
  LLVM.and
      (LLVM.or (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor (LLVM.and (LLVM.sdiv (const? 32 42) e_1) e) (const? 32 (-1))))
      (LLVM.or (LLVM.xor (LLVM.and (LLVM.sdiv (const? 32 42) e_1) (LLVM.sdiv (const? 32 42) e_2)) (const? 32 (-1))) e) ⊑
    LLVM.xor (LLVM.and (LLVM.xor e (LLVM.sdiv (const? 32 42) e_2)) (LLVM.sdiv (const? 32 42) e_1))
      (const? 32 (-1))

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

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 shl_add_add_fail_thm (e e_1 : IntW 8) :
  add (lshr e_1 (const? 8 2)) (add (lshr e (const? 8 2)) (const? 8 48)) ⊑
    add (lshr e_1 (const? 8 2)) (add (lshr e (const? 8 2)) (const? 8 48) { «nsw» := true, «nuw» := true })
      { «nsw» := false, «nuw» := true }

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

theorem width_specific_1 (x : BitVec w) : w = 1 →  x + x = x ^^^ x

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

@[bv_multi_width_normalize] theorem BitVec.one_mul (x : BitVec w) : 1#w * x = x

@[simp]
theorem Term.toBV_zext {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) :
  Term.toBV benv nenv ienv penv tenv (.zext a v) = (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)

theorem ult_1_impliesF_eq_1_thm.extracted_1._5 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 <ᵤ 1#8) = 1#1 → ofBool (x_1 != 0#8) = 1#1 → ofBool (x_1 == x) = ofBool (x == x_1)

theorem alive_1030 : alive_1030_src ⊑ alive_1030_tgt

theorem shift_xor_multiuse_cmp_with_xor_proof : shift_xor_multiuse_cmp_with_xor_before ⊑ shift_xor_multiuse_cmp_with_xor_after

theorem test3_apint_proof : test3_apint_before ⊑ test3_apint_after

theorem t3_const_after_fold_lshr_shl_ne_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ x_1 + -1#32 ≥ ↑32) →
    ¬31#32 ≥ ↑32 →
      ofBool (x_2 >>> (32#32 - x_1) &&& x <<< (x_1 + -1#32) != 0#32) = ofBool (x_2 >>> 31#32 &&& x != 0#32)

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

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

lemma reduce_stepSet' {M : NFA α σ} (q : M.Reachable) (S1 : Set M.Reachable) (S2 : Set σ) :
    (∀ q, (∃ hq, S1 ⟨q, hq⟩) ↔ S2 q) →
    (q ∈ M.reduce.stepSet S1 a → q.val ∈ M.stepSet S2 a)

theorem test9a_proof : test9a_before ⊑ test9a_after

theorem e_1076 :
     - 6 * t + 2 * (z ||| t) - 6 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z ||| t) + 10 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) + 3 * (z &&& t) =  - 7 * (z |||  ~~~t)

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

theorem nonexact_lshr_ne_proof : nonexact_lshr_ne_before ⊑ nonexact_lshr_ne_after

theorem add_nuw_const_const_sub_nuw_proof : add_nuw_const_const_sub_nuw_before ⊑ add_nuw_const_const_sub_nuw_after

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

theorem both_sides_fold_eq_thm (e : IntW 32) (e_1 : IntW 1) :
  icmp IntPred.eq (select e_1 (const? 32 9) e) (select e_1 (const? 32 1) e) ⊑ LLVM.xor e_1 (const? 1 1)

theorem n2_badmask_proof : n2_badmask_before ⊑ n2_badmask_after

theorem test19_proof : test19_before ⊑ test19_after

theorem xor_icmp_invalid_range_proof : xor_icmp_invalid_range_before ⊑ xor_icmp_invalid_range_after

theorem alive_276_2 : alive_276_2_src ⊑ alive_276_2_tgt

@[simp] theorem size_var : (var e body : Com d Γ eff t).size = body.size + 1

theorem and_logic_and_logic_or_5_proof : and_logic_and_logic_or_5_before ⊑ and_logic_and_logic_or_5_after

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

theorem shl_or_with_or_disjoint_instead_of_add_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ True ∧ (x &&& 1#8 != 0) = true ∨ x ||| 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 → 16#8 <<< x ||

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

theorem e_1270 :
     - 7 * (z ||| t) + 2 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z &&& t) + 1 *  ~~~t + 11 *  ~~~z - 5 *  ~~~(z &&&  ~~~t) - 4 *  ~~~(z |||  ~~~t) - 4 * (z &&&  ~~~t) + 5 * (z &&& t) = 17 *  ~~~(z ||| t) - 5 * (z |||  ~~~t)

theorem pr40493_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (mul e (const? 32 12)) (const? 32 4)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 1)) (const? 32 0)

theorem main7f_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 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 not_match_inconsistent_signs_thm (e : IntW 64) :
  add (urem e (const? 64 299)) (mul (urem (LLVM.sdiv e (const? 64 299)) (const? 64 64)) (const? 64 299)) ⊑
    add (urem e (const? 64 299))
      (mul (LLVM.and (LLVM.sdiv e (const? 64 299)) (const? 64 63)) (const? 64 299) { «nsw» := true, «nuw» := true })
      { «nsw» := true, «nuw» := true }

theorem tryFactorization_xor_lshr_lshr_proof : tryFactorization_xor_lshr_lshr_before ⊑ tryFactorization_xor_lshr_lshr_after

theorem AvoidCollision_getLsbD_signExtend (x  : BitVec w) {v i : Nat} :
    (x.signExtend v).getLsbD i = (decide (i < v) && if i < w then x.getLsbD i else x.msb)

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

theorem lshr_not_nneg2_proof : lshr_not_nneg2_before ⊑ lshr_not_nneg2_after

theorem lshr_32_add_known_32_leading_zeroes_proof : lshr_32_add_known_32_leading_zeroes_before ⊑ lshr_32_add_known_32_leading_zeroes_after

theorem smear_set_bit_different_dest_type_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬7#8 ≥ ↑8 →
    ¬(24#32 ≥ ↑32 ∨
          31#32 ≥ ↑32 ∨
            True ∧ signExtend 32 (truncate 16 ((x <<< 24#32).sshiftRight' 31#32)) ≠ (x <<< 24#32).sshiftRight' 31#32) →
      signExtend 16 ((truncate 8 x).sshiftRight' 7#8) = truncate 16 ((x <<< 24#32).sshiftRight' 31#32)

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

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

theorem shl_trunc_bigger_lshr_thm (e : IntW 32) :
  shl (trunc 8 (lshr e (const? 32 5))) (const? 8 3) ⊑ LLVM.and (trunc 8 (lshr e (const? 32 2))) (const? 8 (-8))

theorem goo_proof : goo_before ⊑ goo_after

theorem sext_xor_sub_3_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 64 x_1 - (signExtend 64 x_1 ^^^ x) = x

theorem test9_proof : test9_before ⊑ test9_after

theorem or_eq_with_diff_one_thm (e : IntW 8) :
  LLVM.or (icmp IntPred.eq e (const? 8 13)) (icmp IntPred.eq e (const? 8 14)) ⊑
    icmp IntPred.ult (add e (const? 8 (-13))) (const? 8 2)

theorem not_cond_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1), ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → False

theorem one_side_fold_sgt_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → False

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

theorem and_or2_wrong_operand_proof : and_or2_wrong_operand_before ⊑ and_or2_wrong_operand_after

theorem and_xor_or2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x = 0 ∨ x_2 = 0) → x = 0 ∨ x_2 = 0 → False

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

theorem ashrslt_03_01_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 3)) (const? 4 1) ⊑ const? 1 1

theorem sle_smax3_proof : sle_smax3_before ⊑ sle_smax3_after

theorem e_1992 :
    4 * (c ||| (a &&&  ~~~b)) - 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 2 * (b ^^^ (a ||| (b ||| c))) + 1 * (b ||| (a &&& c)) - 7 * (b ^^^ (a &&& c)) + 1 * (b ||| (a &&&  ~~~c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) - 2 * (c ^^^  ~~~(a &&& b)) - 2 *  ~~~(a &&& (b ||| c)) + 2 * (b ^^^ c) - 2 *  ~~~(a ||| c) + 4 * (b ^^^ ( ~~~a &&& (b ||| c))) - 1 * ( ~~~a ||| (b ||| c)) - 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 5 * ( ~~~b ||| (a ^^^ c)) + 1 *  ~~~a - 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * (b ^^^  ~~~(a &&& (b &&& c))) - 3 * ( ~~~a &&& ( ~~~b ||| c)) - 7 * (b ||| (a ^^^ c)) + 1 * ( ~~~a &&& (b ^^^ c)) - 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 4 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 1 *  ~~~(a ^^^ (b ||| c)) + 7 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 11 * ((a &&& b) ^^^ (b ||| c)) + 1 * c + 2 *  ~~~(a &&& b) + 2 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 *  ~~~(a |||  ~~~b) + 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (a ^^^ c) - 11 * (a ||| ( ~~~b ||| c)) + 11 * (c &&&  ~~~(a &&&  ~~~b)) - 3 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 11 * ((a ||| b) &&& (b ^^^ c)) - 2 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 7 *  ~~~(a ^^^ (b &&& c)) - 1 * ( ~~~c ||| (a ^^^ b)) - 5 * (c &&&  ~~~(a &&& b)) - 1 *  ~~~(a &&&  ~~~c) - 11 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 * (a &&&  ~~~b) - 5 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 16 *  ~~~(a ||| (b ||| c)) + 57 *  ~~~(a ||| ( ~~~b ||| c)) + 29 *  ~~~( ~~~a ||| (b ||| c)) + 55 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 11 * ( ~~~a &&& ( ~~~b &&& c)) + 25 * ( ~~~a &&& (b &&& c)) + 58 * (a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) =  - 3 * (c ^^^ ( ~~~a &&& (b ||| c))) + 6 * ((a ^^^ b) ||| (a ^^^ c))

theorem test44_thm (e : IntW 8) :
  zext 64 (LLVM.or (zext 16 e) (const? 16 1234)) ⊑
    zext 64 (LLVM.or (zext 16 e) (const? 16 1234)) { «nneg» := true }

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

theorem lshrult_02_13_exact_proof : lshrult_02_13_exact_before ⊑ lshrult_02_13_exact_after

theorem select_or_icmp_bad_proof : select_or_icmp_bad_before ⊑ select_or_icmp_bad_after

@[simp]
lemma dec_spec' (bvs' : BitVecs' n) (k : Fin n) (i : Fin bvs'.length) :
    ((dec bvs').bvs.get k).getLsbD i = bvs'[i].getLsbD k

theorem src_is_mask_p2_m1_proof : src_is_mask_p2_m1_before ⊑ src_is_mask_p2_m1_after

theorem test17_thm (e : IntW 1) : sub (const? 32 0) (sext 32 e) ⊑ zext 32 e

theorem test6_thm (e : IntW 7) : LLVM.xor (LLVM.xor e (const? 7 23)) (const? 7 23) ⊑ e

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

theorem select_icmp_ne_not_pow2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x &&& 5#8 != 0#8) = 1#1 → ofBool (x &&& 5#8 == 0#8) = 1#1 → x ^^^ 5#8 = x

theorem select_add_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1), ¬x_1 = 1#1 → x = x + 0#64

theorem p0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 → ofBool (x ≤ᵤ (-1#8) <<< x_1 ^^^ -1#8) = ofBool (x >>> x_1 == 0#8)

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

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

theorem t10_shl_nuw_flag_preservation_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 <<< (32#32 - x) >>> (32#32 - x) ≠ x_1 ∨
        32#32 - x ≥ ↑32 ∨
          True ∧
              (x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2))).sshiftRight' (x + BitVec.ofInt 32 (-2)) ≠
                x_1 <<< (32#32 - x) ∨
            True ∧
                x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2)) >>> (x + BitVec.ofInt 32 (-2)) ≠
                  x_1 <<< (32#32 - x) ∨
              x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    ¬(True ∧ x_1 <<< 30#32 >>> 30#32 ≠ x_1 ∨ 30#32 ≥ ↑32) →
      x_1 <<< (32#32 - x) <<< (x + BitVec.ofInt 32 (-2)) = x_1 <<< 30#32

theorem e_2477 :
     - 6 * (e &&& f) + 3 *  ~~~(d ^^^ ( ~~~e &&& f)) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 *  ~~~(d &&&  ~~~f) - 7 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (f ^^^ (d ||| (e &&& f))) + 11 * (e |||  ~~~f) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 4 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * (f ^^^  ~~~(d &&& e)) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 6 * ( ~~~d &&& (e ||| f)) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 11 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (e &&& (d |||  ~~~f)) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 3 * (d ^^^ (e &&& f)) + 7 * (f &&& (d ||| e)) + 4 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 6 * (d ^^^ ( ~~~e ||| f)) + 4 * (e &&& (d ^^^ f)) - 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * ( ~~~e |||  ~~~(d ^^^ f)) - 11 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * (f ^^^ (d ||| (e ||| f))) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 11 * ( ~~~d ||| ( ~~~e &&& f)) - 7 * (f &&&  ~~~(d &&&  ~~~e)) + 5 * (d ||| (e &&& f)) + 2 * e - 1 *  ~~~(e |||  ~~~f) + 1 *  ~~~(e ||| f) + 5 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * ((d &&& e) ^^^ (e ||| f)) - 11 *  ~~~(e ^^^ f) - 1 * (d ||| e) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 3 * (d &&& (e ^^^ f)) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * (f ^^^ (d &&&  ~~~e)) - 6 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 *  ~~~f - 2 * (f |||  ~~~(d ^^^ e)) - 11 * ((d &&& e) |||  ~~~(e ^^^ f)) + 4 * ( ~~~e &&& (d ^^^ f)) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 4 * (f ^^^ (d ||| ( ~~~e ||| f))) + 11 *  ~~~(d ^^^ (e ^^^ f)) - 2 *  ~~~(d &&&  ~~~e) - 3 * (e ^^^ ( ~~~d ||| (e ||| f))) + 11 * (e ^^^ (d &&&  ~~~f)) + 1 * (e ^^^ (d &&& f)) - 3 * (e |||  ~~~(d ^^^ f)) + 3 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (e ^^^ (d |||  ~~~f)) - 7 *  ~~~(d ^^^ e) + 7 * (d ||| ( ~~~e ||| f)) - 1 * ((d ^^^ e) ||| (d ^^^ f)) - 7 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * (d ||| (e ||| f)) + 1 * (d ||| f) + 1 *  ~~~(e &&&  ~~~f) - 2 *  ~~~(d ||| (e ||| f)) - 29 *  ~~~(d ||| ( ~~~e ||| f)) - 63 *  ~~~( ~~~d ||| (e ||| f)) - 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 22 * ( ~~~d &&& ( ~~~e &&& f)) - 12 * ( ~~~d &&& (e &&& f)) - 42 * (d &&& ( ~~~e &&& f)) =  - 1 *  ~~~(d ^^^ (e ||| f)) - 4 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f)))

theorem and_logic_and_logic_or_8_thm (e e_1 e_2 : IntW 1) :
  select (select e_2 e_1 (const? 1 0)) (const? 1 1) (LLVM.and e e_1) ⊑ LLVM.and e_1 (select e_2 (const? 1 1) e)

theorem sub_ashr_and_i32_commute_proof : sub_ashr_and_i32_commute_before ⊑ sub_ashr_and_i32_commute_after

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

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

theorem and_or_not_not_commute5_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 &&& x_1 ^^^ -1#32) &&& (x_1 &&& x ^^^ -1#32 ||| x_2) = (x ||| x_2) &&& x_1 ^^^ -1#32

theorem not_or_or_and_no_and_commute2_or_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 e e_2) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.and e_1 (LLVM.xor e (const? 32 (-1)))) (LLVM.xor e_2 (const? 32 (-1)))

theorem or_xor_commute3_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.or (LLVM.udiv (const? 32 42) e_1) (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 eq_21_comm_and_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.eq (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8))))
      (icmp IntPred.eq (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16)))) ⊑
    icmp IntPred.eq (trunc 16 (lshr e_1 (const? 32 8))) (trunc 16 (lshr e (const? 32 8)))

theorem ugt_rem_zero_thm (e : IntW 8) :
  icmp IntPred.ugt (mul e (const? 8 7) { «nsw» := false, «nuw» := true }) (const? 8 21) ⊑
    icmp IntPred.ugt e (const? 8 3)

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

theorem trunc_shl_7_i8_i64_proof : trunc_shl_7_i8_i64_before ⊑ trunc_shl_7_i8_i64_after

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

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

theorem bools2_logical_commute1_thm.extracted_1._15 : ∀ (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 → 1#1 = x_2

@[simp]
theorem R.fromPoly_representative [Fact (q > 1)]:
    forall a : R q n, (R.fromPoly (n:=n) (R.representative q n a)) = a

theorem or_simplify_ule_fail_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (LLVM.or (LLVM.or e_1 (const? 8 64)) (LLVM.and e (const? 8 127))) (LLVM.and e (const? 8 127)) ⊑
    icmp IntPred.ule (LLVM.or (LLVM.or e_1 (LLVM.and e (const? 8 127))) (const? 8 64))
      (LLVM.and e (const? 8 127))

theorem lshrult_01_12_proof : lshrult_01_12_before ⊑ lshrult_01_12_after

theorem and_zext_demanded_thm (e : IntW 16) (e_1 : IntW 32) :
  LLVM.and (LLVM.or e_1 (const? 32 255)) (zext 32 (lshr e (const? 16 8))) ⊑
    zext 32 (lshr e (const? 16 8)) { «nneg» := true }

theorem demorgan_nor_use2a_proof : demorgan_nor_use2a_before ⊑ demorgan_nor_use2a_after

theorem lor_lor_left1_proof : lor_lor_left1_before ⊑ lor_lor_left1_after

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

theorem t10_constants_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 14#64 ≥ ↑64) → 26#32 ≥ ↑32 → False

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

theorem add_const_const_sub_nuw_thm (e : IntW 8) :
  sub (const? 8 (-127)) (add e (const? 8 1)) { «nsw» := false, «nuw» := true } ⊑ sub (const? 8 (-128)) e

theorem logic_and_logic_or_8_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1), ¬x_1 = 1#1 → 0#1 = 1#1 → False

theorem e_65 :
     - 11 * (x ^^^ y) + 5 * x + 4 *  ~~~(x &&& y) + 7 *  ~~~(x |||  ~~~y) - 5 * (x &&& y) = 4 *  ~~~(x ||| y) - 2 * (x &&&  ~~~y)

theorem udiv_eq_big_proof : udiv_eq_big_before ⊑ udiv_eq_big_after

theorem not_or_or_and_not_and_and_commute3_thm (e e_1 e_2 : IntW 32) :
  LLVM.and (LLVM.or (LLVM.or (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor e_1 (const? 32 (-1)))) e)
      (LLVM.xor (LLVM.and (LLVM.and (LLVM.sdiv (const? 32 42) e_2) e_1) e) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.xor e (LLVM.sdiv (const? 32 42) e_2)) (LLVM.xor e_1 (const? 32 (-1)))

theorem t1_flags_nuw_first_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ x_2.usubOverflow x_1 = true) → x_2 - x_1 - x = x_2 - (x_1 + x)

theorem udiv_common_dividend_defined_cond_proof : udiv_common_dividend_defined_cond_before ⊑ udiv_common_dividend_defined_cond_after

theorem test1_thm (e : IntW 32) : LLVM.xor (LLVM.xor e (const? 32 (-1))) (const? 32 (-1)) ⊑ e

theorem substitute_constant_and_eq_ugt_swap_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) = 1#1 → ofBool (x == 42#8) = ofBool (x == 42#8) &&& ofBool (42#8 <ᵤ x_1)

theorem zext_add_proof : zext_add_before ⊑ zext_add_after

theorem sge_or_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x ≤ₛ x_1) ||

theorem n12_proof : n12_before ⊑ n12_after

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 test_proof : test_before ⊑ test_after

theorem positive_samevar_shlnuw_thm (e e_1 : IntW 32) : lshr (shl e_1 e { «nsw» := false, «nuw» := true }) e ⊑ e_1

theorem mul_of_sdiv_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smod 12#8 ≠ 0 ∨ (12#8 == 0 || 8 != 1 && x == intMin 8 && 12#8 == -1) = true) →
    ¬(True ∧ x >>> 1#8 <<< 1#8 ≠ x ∨ 1#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 1#8) = true) →
      x.sdiv 12#8 * BitVec.ofInt 8 (-6) = 0#8 - x.sshiftRight' 1#8

theorem ashrsgt_02_13_exact_proof : ashrsgt_02_13_exact_before ⊑ ashrsgt_02_13_exact_after

theorem icmp_mul_nsw_sgt_proof : icmp_mul_nsw_sgt_before ⊑ icmp_mul_nsw_sgt_after

theorem or_signbit_shl_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ||| BitVec.ofInt 32 (-65536)) <<< 8#32 = x <<< 8#32 ||

theorem f_var0_thm (e e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 e) (const? 32 0)) (LLVM.and (lshr e_1 (const? 32 1)) (const? 32 1))
      (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e_1 (LLVM.or e (const? 32 2))) (const? 32 0))

theorem test_nuw_nsw_and_unsigned_pred_proof : test_nuw_nsw_and_unsigned_pred_before ⊑ test_nuw_nsw_and_unsigned_pred_after

theorem bitwise_or_logical_or_icmps_comm3_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ofBool (x_2 &&& 1#8 == 0#8) = 1#1 →
      True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 ∨ True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 → False

theorem sub_sel_op1_thm (e : IntW 1) :
  sub (const? 32 42) (select e (const? 32 42) (const? 32 41)) { «nsw» := true, «nuw» := false } ⊑
    zext 32 (LLVM.xor e (const? 1 1))

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

theorem zext_masked_bit_zero_to_larger_bitwidth_proof : zext_masked_bit_zero_to_larger_bitwidth_before ⊑ zext_masked_bit_zero_to_larger_bitwidth_after

theorem not_xor_to_or_not1_thm (e e_1 e_2 : IntW 3) :
  LLVM.xor (LLVM.xor (LLVM.and e_2 e_1) (LLVM.or e e_1)) (const? 3 (-1)) ⊑
    LLVM.or (LLVM.and e_2 e_1) (LLVM.xor (LLVM.or e e_1) (const? 3 (-1)))

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 sub_not_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 - x ^^^ -1#8 = x + (x_1 ^^^ -1#8)

theorem t0_thm (e : IntW 64) : sub (const? 64 0) (lshr e (const? 64 63)) ⊑ ashr e (const? 64 63)

theorem sge_swap_and_max_commute_logical_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x == 127#8) = 1#1 → 0#1 = ofBool (x == 127#8)

theorem test10_proof : test10_before ⊑ test10_after

theorem test2_thm (e : IntW 32) :
  icmp IntPred.ugt e (const? 32 0) ⊑ icmp IntPred.ne e (const? 32 0)

theorem ashr_uge_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 (72#8 <ᵤ x)

theorem masked_and_notA_proof : masked_and_notA_before ⊑ masked_and_notA_after

theorem lshr_mul_negative_nsw_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x.smulOverflow 52#64 = true ∨ 2#64 ≥ ↑64) →
    True ∧ x.smulOverflow 52#64 = true ∨ True ∧ (x * 52#64) >>> 2#64 <<< 2#64 ≠ x * 52#64 ∨ 2#64 ≥ ↑64 → False

@[simp] theorem Valuation.comap_id {Γ : Ctxt Ty} (V : Valuation Γ) : comap V Hom.id = V

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

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

theorem lshr_mul_times_5_div_4_proof : lshr_mul_times_5_div_4_before ⊑ lshr_mul_times_5_div_4_after

theorem ashrslt_03_00_proof : ashrslt_03_00_before ⊑ ashrslt_03_00_after

theorem fold_sext_to_and_wrong3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 128#32 == BitVec.ofInt 32 (-2147483648)) = 0#1

theorem p0_proof : p0_before ⊑ p0_after

theorem e_1703 :
    5 * (b ^^^  ~~~(a &&& (b &&& c))) - 1 * (c ||| (a ^^^ b)) + 2 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 6 * (c ^^^ (a ||| ( ~~~b ||| c))) + 2 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 2 * (a &&& ( ~~~b ||| c)) + 3 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 7 * ( ~~~b &&&  ~~~(a ^^^ c)) + 4 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 7 * (c ^^^ (a &&& b)) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 5 * (b ^^^ ( ~~~a ||| (b ||| c))) + 1 * (b &&&  ~~~c) + 2 * (c ^^^  ~~~(a ||| b)) - 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 5 * ( ~~~a ||| (b ^^^ c)) - 6 *  ~~~( ~~~a &&& (b ^^^ c)) - 5 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 1 * ( ~~~c ||| (a ^^^ b)) + 1 *  ~~~(a ||| (b ||| c)) - 10 *  ~~~(a ||| ( ~~~b ||| c)) + 6 *  ~~~( ~~~a ||| (b ||| c)) - 2 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 22 * ( ~~~a &&& ( ~~~b &&& c)) - 11 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 9 * (a &&& (b &&& c)) =  - 11 *  ~~~(a ||| (b ^^^ c)) + 5 * (c ^^^  ~~~( ~~~a &&& (b &&& c)))

theorem ashr_or_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x ||

theorem test7_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬1#32 ≥ ↑32 →
    ¬(1#32 ≥ ↑32 ∨ True ∧ (x >>> 1#32).uaddOverflow 2147483647#32 = true) →
      zeroExtend 64 (x >>> 1#32) + 2147483647#64 = zeroExtend 64 (x >>> 1#32 + 2147483647#32)

theorem ashrslt_02_05_exact_proof : ashrslt_02_05_exact_before ⊑ ashrslt_02_05_exact_after

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

theorem sdiv_shl_shl_nsw2_nuw_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        x_1 ≥ ↑8 ∨
          True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨
            True ∧ x <<< x_1 >>> x_1 ≠ x ∨
              x_1 ≥ ↑8 ∨ (x <<< x_1 == 0 || 8 != 1 && x_2 <<< x_1 == intMin 8 && x <<< x_1 == -1) = true) →
    (x == 0 || 8 != 1 && x_2 == intMin 8 && x == -1) = true → False

theorem test1_thm (e : IntW 32) :
  icmp IntPred.slt (LLVM.xor e (const? 32 12345)) (const? 32 0) ⊑ icmp IntPred.slt e (const? 32 0)

theorem and_ranges_overlap_proof : and_ranges_overlap_before ⊑ and_ranges_overlap_after

theorem prove_exact_with_high_mask_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-4) == 0 || 8 != 1 && x &&& BitVec.ofInt 8 (-32) == intMin 8 && BitVec.ofInt 8 (-4) == -1) = true →
    ¬(2#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 2#8 &&& BitVec.ofInt 8 (-8)) = true) →
      (x &&& BitVec.ofInt 8 (-32)).sdiv (BitVec.ofInt 8 (-4)) = 0#8 - (x.sshiftRight' 2#8 &&& BitVec.ofInt 8 (-8))

theorem ashrsgt_01_10_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 1)) (const? 4 (-6)) ⊑ const? 1 1

theorem lshrugt_03_08_exact_proof : lshrugt_03_08_exact_before ⊑ lshrugt_03_08_exact_after

theorem e_850 :
    5 *  ~~~(z &&& t) + 2 *  ~~~(z &&&  ~~~t) - 6 *  ~~~t - 1 *  ~~~(z ||| t) - 7 *  ~~~(z |||  ~~~t) - 2 * (z &&& t) =  - 1 * (z &&&  ~~~t)

theorem e_395 :
    2 * (x ||| y) + 3 * (x ^^^ y) - 1 *  ~~~(x &&&  ~~~x) - 3 *  ~~~(x &&& y) - 1 *  ~~~x + 7 *  ~~~(x ||| y) + 1 * (x &&&  ~~~y) - 1 * (x &&& y) = 2 *  ~~~y

theorem t9_ashr_exact_flag_preservation_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 >>> (32#32 - x) <<< (32#32 - x) ≠ x_1 ∨
        32#32 - x ≥ ↑32 ∨
          True ∧
              x_1.sshiftRight' (32#32 - x) >>> (x + BitVec.ofInt 32 (-2)) <<< (x + BitVec.ofInt 32 (-2)) ≠
                x_1.sshiftRight' (32#32 - x) ∨
            x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    True ∧ x_1 >>> 30#32 <<< 30#32 ≠ x_1 ∨ 30#32 ≥ ↑32 → False

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

theorem main4b_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 == 7#32) = 1#1 →
    ¬ofBool (x &&& 16#32 != 0#32) = 1#1 → 1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

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

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

theorem add_smax_simplify2_proof : add_smax_simplify2_before ⊑ add_smax_simplify2_after

theorem or_xor_tree_1011_proof : or_xor_tree_1011_before ⊑ or_xor_tree_1011_after

theorem max_sub_ult_c12_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 1#32) = 1#1 → ¬ofBool (x == 0#32) = 1#1 → x + BitVec.ofInt 32 (-2) = 0#32

theorem e_169 :
     - 3 *  ~~~x - 1 * (x |||  ~~~y) + 3 *  ~~~y + 3 *  ~~~(x |||  ~~~y) - 2 * (x &&&  ~~~y) + 1 * (x &&& y) =  - 1 *  ~~~(x ||| y)

theorem select_zext_different_condition_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 →
    True ∧ (64#64).saddOverflow (zeroExtend 64 x) = true ∨ True ∧ (64#64).uaddOverflow (zeroExtend 64 x) = true →
      False

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

theorem e_439 :
     - 11 * y + 11 * (x |||  ~~~y) - 7 *  ~~~y + 3 *  ~~~(x &&&  ~~~y) - 17 *  ~~~(x ||| y) - 2 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) - 2 * (x &&& y) =  - 11 *  ~~~x + 1 *  ~~~(x &&&  ~~~x)

theorem shift_xor_multiuse_cmp_with_and_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (0#32 != x_2 &&& 4096#32) = 1#1 → ¬ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → False

theorem e_482 :
    4 * (x |||  ~~~y) + 2 *  ~~~(x ^^^ y) + 11 *  ~~~y - 11 * x - 1 *  ~~~x - 15 *  ~~~(x ||| y) + 2 *  ~~~(x |||  ~~~y) - 3 * (x &&&  ~~~y) + 5 * (x &&& y) = 1 *  ~~~(x &&& y)

theorem t9_ashr_proof : t9_ashr_before ⊑ t9_ashr_after

theorem test15f_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 128#32 != 0#32) = 1#1 → ¬1#32 ≥ ↑32 → 256#32 = x <<< 1#32 &&& 256#32 ^^^ 256#32

theorem e_687 :
    2 * (x ^^^ y) - 2 *  ~~~(x ^^^ y) + 5 *  ~~~y - 6 *  ~~~(x &&&  ~~~y) - 7 *  ~~~(x &&&  ~~~x) - 1 * (x |||  ~~~y) - 2 *  ~~~(x &&& y) + 13 *  ~~~(x ||| y) + 15 *  ~~~(x |||  ~~~y) + 3 * (x &&&  ~~~y) =  - 18 * (x &&& y) + 2 * y

theorem t5_ugt_slt_0_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ugt (add e_2 (const? 32 16)) (const? 32 143))
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e_1 e) e_2 ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e_1 e_2)

theorem ashrsgt_02_06_exact_proof : ashrsgt_02_06_exact_before ⊑ ashrsgt_02_06_exact_after

theorem sdiv_shl_pair2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        True ∧ x_2 <<< x_1 >>> 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).sshiftRight' x_1 ≠ 1#32 ∨ 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 test_nuw_dropped_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 0#32) = 1#1 → 2#32 ≥ ↑32 → False

theorem test5_proof : test5_before ⊑ test5_after

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

theorem udiv_c_i32_thm (e : IntW 8) :
  LLVM.udiv (const? 32 10) (zext 32 e) ⊑ zext 32 (LLVM.udiv (const? 8 10) e) { «nneg» := true }

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

theorem a_or_b_proof : a_or_b_before ⊑ a_or_b_after

theorem narrow_zext_ashr_keep_trunc2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 9),
  ¬(True ∧ (signExtend 64 x_1).saddOverflow (signExtend 64 x) = true ∨ 1#64 ≥ ↑64) →
    True ∧ (zeroExtend 16 x_1).saddOverflow (zeroExtend 16 x) = true ∨
        True ∧ (zeroExtend 16 x_1).uaddOverflow (zeroExtend 16 x) = true ∨ 1#16 ≥ ↑16 →
      False

theorem e_2086 :
    2 * (f &&& (d ^^^ e)) - 1 * (d &&& (e ^^^ f)) - 1 * (d |||  ~~~f) + 1 * (e ||| f) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 11 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * ( ~~~f |||  ~~~(d ^^^ e)) + 11 * (e ^^^  ~~~(d &&& f)) + 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 * (e ||| (d &&& f)) - 1 *  ~~~(e ^^^ f) + 3 *  ~~~(d ||| e) - 2 *  ~~~( ~~~d ||| (e ^^^ f)) + 4 * (d &&& ( ~~~e ||| f)) + 5 * (d ||| e) + 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 5 * (e &&& f) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 5 * (f ^^^ (d ||| (e ||| f))) + 2 * (d ||| ( ~~~e &&& f)) + 2 * (d ^^^ ( ~~~e &&& f)) + 1 *  ~~~e - 6 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 7 *  ~~~(d ||| (e ^^^ f)) - 6 * (d ^^^ e) - 1 * (d ^^^ f) + 4 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 8 *  ~~~(d ||| (e ||| f)) + 29 *  ~~~(d ||| ( ~~~e ||| f)) - 8 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 15 * ( ~~~d &&& ( ~~~e &&& f)) + 7 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) - 9 * (d &&& (e &&& f)) = 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f)))

theorem main5e_like_logical_proof : main5e_like_logical_before ⊑ main5e_like_logical_after

theorem and_umin_thm (e : IntW 32) :
  LLVM.and (select (icmp IntPred.ult (const? 32 15) e) (const? 32 15) e) (const? 32 (-32)) ⊑ const? 32 0

theorem and_zext_demanded_proof : and_zext_demanded_before ⊑ and_zext_demanded_after

theorem add_or_sub_comb_i8_negative_xor_instead_or_thm (e : IntW 8) :
  add (LLVM.xor (sub (const? 8 0) e) e) e ⊑ add (LLVM.xor e (sub (const? 8 0) e)) e

theorem urem_common_divisor_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (urem e_2 e_1) (urem e e_1) ⊑ urem (select e_3 e_2 e) e_1

theorem low_bitmask_ult_thm (e : IntW 8) :
  icmp IntPred.ult (LLVM.and (add e (const? 8 31)) (const? 8 31)) e ⊑ icmp IntPred.ne e (const? 8 0)

theorem eq_irregular_bit_widths_thm.extracted_1._1 : ∀ (x x_1 : BitVec 31),
  ¬(13#31 ≥ ↑31 ∨ 13#31 ≥ ↑31 ∨ 7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31) → 7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31 → False

@[simp] theorem getValue_poison [Inhabited α] : (@poison α).getValue = default

theorem t0_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  x_3 ^^^ 1#1 = 1#1 → x_3 = 1#1 → ofBool (x_2 == x_1) = 1#1 → False

theorem test14a_proof : test14a_before ⊑ test14a_after

theorem src_is_mask_lshr_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 : BitVec 8),
  ¬x_2 = 1#1 →
    ¬x ≥ ↑8 → ofBool (x_3 ^^^ 123#8 != 15#8 >>> x &&& (x_3 ^^^ 123#8)) = ofBool (15#8 >>> x <ᵤ x_3 ^^^ 123#8)

theorem udiv_shl_pair_const_thm (e : IntW 32) :
  LLVM.udiv (shl e (const? 32 2) { «nsw» := false, «nuw» := true })
      (shl e (const? 32 1) { «nsw» := false, «nuw» := true }) ⊑
    const? 32 2

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

theorem ule_swap_or_not_min_logical_proof : ule_swap_or_not_min_logical_before ⊑ ule_swap_or_not_min_logical_after

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

theorem icmp_ne_sext_eq_otherwise_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == 2#32)) != x) = ofBool (x != 0#32)

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 syncMap2_flip {f : α → β → γ} :
  syncMap₂ f xs ys = syncMap₂ (fun y x => f x y) ys xs

theorem positive_biggerLshr_proof : positive_biggerLshr_before ⊑ positive_biggerLshr_after

theorem shl_nsw_add_nsw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (1#32 <<< x).sshiftRight' x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ (1#32 <<< x).saddOverflow (-1#32) = true) →
    ¬(True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32) → 1#32 <<< x + -1#32 = (-1#32) <<< x ^^^ -1#32

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

theorem different_size_zext_zext_ugt_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (zeroExtend 25 x <ᵤ zeroExtend 25 x_1) = ofBool (zeroExtend 7 x <ᵤ x_1)

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_2_logical_after

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

theorem lshrult_02_14_proof : lshrult_02_14_before ⊑ lshrult_02_14_after

lemma dec_enc_w (bvs : BitVecs n) : (dec (enc bvs)).w = bvs.w

theorem lt_signed_to_large_signed_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (signExtend 32 x <ₛ 1024#32) = 1#1

theorem sub_ult_zext_thm (e : IntW 1) (e_1 e_2 : IntW 8) :
  icmp IntPred.ult (sub e_2 e_1) (zext 8 e) ⊑ LLVM.and (icmp IntPred.eq e_2 e_1) e

theorem sge_swap_or_max_logical_proof : sge_swap_or_max_logical_before ⊑ sge_swap_or_max_logical_after

theorem test35_with_trunc_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬ofBool (0#32 ≤ₛ truncate 32 x) = 1#1 → ofBool (x &&& 2147483648#64 == 0#64) = 1#1 → 100#32 = 60#32

theorem lshrult_01_05_proof : lshrult_01_05_before ⊑ lshrult_01_05_after

theorem masked_or_allzeroes_notoptimised_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 15#32 == 0#32) = 1#1 →
    ofBool (x &&& 39#32 == 0#32) = ofBool (x &&& 15#32 == 0#32) ||

theorem dont_narrow_zext_ashr_keep_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 16 x_1).saddOverflow (signExtend 16 x) = true ∨ 1#16 ≥ ↑16) →
    truncate 8 ((signExtend 16 x_1 + signExtend 16 x).sshiftRight' 1#16) =
      truncate 8 ((signExtend 16 x_1 + signExtend 16 x) >>> 1#16)

theorem lshrugt_01_02_proof : lshrugt_01_02_before ⊑ lshrugt_01_02_after

theorem ripple_nsw5_proof : ripple_nsw5_before ⊑ ripple_nsw5_after

theorem lshr_add_or_fail_proof : lshr_add_or_fail_before ⊑ lshr_add_or_fail_after

theorem main7f_logical_proof : main7f_logical_before ⊑ main7f_logical_after

theorem t0_proof : t0_before ⊑ t0_after

theorem uge_and_max_proof : uge_and_max_before ⊑ uge_and_max_after

theorem p0_thm (e e_1 e_2 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 1)) e_1 e ⊑
    select (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 0)) e e_1

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

theorem PR96857_xor_without_noundef_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  x_2 &&& x_1 ^^^ (x_2 ^^^ -1#4) &&& x = x_2 &&& x_1 ||

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

theorem ashr_lshr_exact_lshr_only_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) = 1#1 → ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → ¬x ≥ ↑32 → x_1 >>> x = x_1.sshiftRight' x

theorem e_1562 :
     - 1 * (b ||| (a ^^^ c)) + 4 *  ~~~( ~~~a ||| (b &&& c)) - 2 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 * (b ^^^ ( ~~~a ||| (b ||| c))) - 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 6 * ( ~~~b ||| (a ^^^ c)) - 7 * ((a &&& b) ^^^ (b |||  ~~~c)) + 7 *  ~~~(b ^^^ c) + 22 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 13 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 21 * ( ~~~a &&& ( ~~~b &&& c)) + 10 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) = 3 * ( ~~~a ||| (b ||| c)) - 11 *  ~~~(a ||| ( ~~~b ||| c))

theorem test2_thm.extracted_1._2 : ∀ (x : BitVec 167),
  ¬(9#577 ≥ ↑577 ∨ 8#577 ≥ ↑577) →
    ¬(9#167 ≥ ↑167 ∨ 8#167 ≥ ↑167) →
      truncate 167 (zeroExtend 577 x >>> 9#577 ||| zeroExtend 577 x <<< 8#577) = x >>> 9#167 ||

theorem main6_logical_proof : main6_logical_before ⊑ main6_logical_after

theorem ashrslt_02_00_proof : ashrslt_02_00_before ⊑ ashrslt_02_00_after
</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

def List.Vector.transport (v : Vector α m) (f : Fin n → Fin m) : Vector α n :=
  Vector.ofFn fun i => v.get (f i)

def BitVec.transport (f : Fin n2 → Fin n1) (bv : BitVec n1) : BitVec n2 :=
  BitVec.ofFn fun i => bv.getLsbD (f i)

structure BitVecs (n : Nat) where
  w : Nat
  bvs : List.Vector (BitVec w) n

abbrev BitVecs' (n : Nat) := List (BitVec n)

def BitVecs.transport (f : Fin n → Fin m) (bvs : BitVecs m) : BitVecs n :=
  { w := bvs.w, bvs := bvs.bvs.transport f }

def BitVecs'.transport (f : Fin n → Fin m) (bvs' : BitVecs' m): BitVecs' n :=
  bvs'.map fun bv => bv.transport f

namespace NFA

structure Deterministic (M : NFA α σ) : Prop where
  start : M.start.Subsingleton
  step : ∀ q a, M.step q a |>.Subsingleton

@[simps]
def proj (M: NFA (BitVec n1) σ) (f : Fin n2 → Fin n1) : NFA (BitVec n2) σ where
  start := M.start
  accept := M.accept
  step q a := { q' | ∃ a', a'.transport f = a ∧ q' ∈ M.step q a' }
</local_ctx>

<target_theorem>
@[simp]
lemma proj_eval (M : NFA (BitVec m) σ) (f : Fin n → Fin m) :
    (M.proj f).eval w =
      ⋃ w' ∈ BitVecs'.transport f ⁻¹' {w}, M.eval w' :=
</target_theorem>

