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>
Inhabited in Init.Prelude
Nat in Init.Prelude

syntax "neg" : MLIR.Pretty.uniform_op

macro_rules
  | `(mlir_op| $res:mlir_op_operand = const ($x)
      $[: $outer_type]? ) => do
      let outer_type ← outer_type.getDM `(mlir_type| _)
      `(mlir_op| $res:mlir_op_operand = "const"()
          {val = $x:num : $outer_type} : ($outer_type) -> ($outer_type) )

macro_rules
  | `(mlir_op| $res:mlir_op_operand = li ($x)
     $[: $outer_type]?  ) => do
      let outer_type ← outer_type.getDM `(mlir_type| _ )
      `(mlir_op| $res:mlir_op_operand = "li"()
          {imm = $x:num : $outer_type } : ($outer_type) -> ($outer_type))

macro_rules
| `(mlir_op| $res:mlir_op_operand = $op1:MLIR.Pretty.RV.opWithImmediate $reg1 , $x : $t)  => do
    let some opName := MLIR.EDSL.Pretty.extractOpName op1.raw
      | Macro.throwUnsupported
    `(mlir_op| $res:mlir_op_operand = $opName ($reg1) {imm = $x:num : $t} : ($t) -> ($t) )

macro_rules
| `(mlir_op| $res:mlir_op_operand = $op1:MLIR.Pretty.RV.opWithShamt $reg1 , $x  : $t )  => do
    let some opName := MLIR.EDSL.Pretty.extractOpName op1.raw
      | Macro.throwUnsupported
    `(mlir_op| $res:mlir_op_operand = $opName ($reg1) {shamt = $x:num : $t}  : ($t) -> ($t) )

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

Id in Init.Control.Id

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

def p0_scalar_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg14, %0 : i32
  %2 = llvm.sub %arg15, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def mul9_low_after := [llvm|
{
^0(%arg8 : i9, %arg9 : i9):
  %0 = llvm.mlir.constant(15 : i9) : i9
  %1 = llvm.mlir.constant(4 : i9) : i9
  %2 = llvm.and %arg8, %0 : i9
  %3 = llvm.lshr %arg8, %1 : i9
  %4 = llvm.and %arg9, %0 : i9
  %5 = llvm.lshr %arg9, %1 : i9
  %6 = llvm.mul %5, %2 overflow<nuw> : i9
  %7 = llvm.mul %4, %3 overflow<nuw> : i9
  %8 = llvm.mul %4, %2 overflow<nsw,nuw> : i9
  %9 = llvm.add %6, %7 : i9
  %10 = llvm.shl %9, %1 : i9
  %11 = llvm.add %10, %8 : i9
  "llvm.return"(%11) : (i9) -> ()
}
]

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_of_selects_after := [llvm|
{
^0(%arg2 : i1, %arg3 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = "llvm.select"(%arg2, %arg3, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

IO.FS.Handle in Init.System.IO

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

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 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_sle9_before := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-128 : i8) : i8
  %2 = llvm.shl %arg4, %0 overflow<nsw> : i8
  %3 = llvm.icmp "sle" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

Int.le in Init.Data.Int.Basic

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

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

@[simp_denote]
def icmp_ne_riscv_32_pseudo := [LV| {
  ^entry (%lhs: i32, %rhs: i32):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i32) -> (!riscv.reg)
    %rhsr = "builtin.unrealized_conversion_cast"(%rhs) : (i32) -> (!riscv.reg)
    %0 = xor    %lhsr, %rhsr : !riscv.reg
    %1 = snez    %0 : !riscv.reg
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!riscv.reg) -> (i1)
    llvm.return %2 : i1
  }]

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_sameconst_shlnuwnsw_ashrexact_after := [llvm|
{
^0(%arg26 : i8):
  "llvm.return"(%arg26) : (i8) -> ()
}
]

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

def or_ugt_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.or %arg58, %arg59 : i8
  %1 = llvm.icmp "ne" %0, %arg58 : i8
  "llvm.return"(%1) : (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) -> ()
}
]

@[simp_denote]
def add_hi_and_lo_negone_llvm_i64 := [LV| {
    ^entry (%arg: i64):
    %1 = llvm.mlir.constant (-1) : i64
    %0 = llvm.add %arg, %1 overflow<nsw> : i64
    llvm.return %0 : 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 andn_or_cmp_2_partial_logical_after := [llvm|
{
^0(%arg117 : i16, %arg118 : i16, %arg119 : i1):
  %0 = llvm.icmp "slt" %arg117, %arg118 : i16
  %1 = llvm.and %arg119, %0 : i1
  "llvm.return"(%1) : (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_nsw__none_are_safe_before := [llvm|
{
^0(%arg66 : i32, %arg67 : 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 %arg66, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw> : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.icmp "eq" %3, %2 : i32
  %7 = llvm.ashr %arg67, %5 : i64
  %8 = "llvm.select"(%6, %arg67, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%8) : (i64) -> ()
}
]

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

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_llvm_16_to_32 := [LV| {
  ^entry (%arg: i16):
    %0 = llvm.zext %arg: i16 to i32
    llvm.return %0: i32
  }]

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

class DecidableNFA [Fintype σ] [Fintype α] [DecidableEq σ] [DecidableEq α] (m : NFA α σ) where
  decidable_start : Decidable (q ∈ m.start)
  decidable_accept : Decidable (q ∈ m.accept)
  decidable_step : Decidable (s' ∈ m.step s a)

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

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

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

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

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

def is_ascii_alphabetic_inverted_before := [llvm|
{
^0(%arg247 : i32):
  %0 = llvm.mlir.constant(-91 : i32) : i32
  %1 = llvm.mlir.constant(-26 : i32) : i32
  %2 = llvm.mlir.constant(-123 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.add %arg247, %0 overflow<nsw> : i32
  %5 = llvm.icmp "ult" %4, %1 : i32
  %6 = llvm.add %arg247, %2 overflow<nsw> : i32
  %7 = llvm.icmp "ult" %6, %1 : i32
  %8 = "llvm.select"(%5, %7, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (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 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_before := [llvm|
{
^0(%arg71 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-2 : i4) : i4
  %2 = llvm.ashr exact %arg71, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def irc_constants_APlusC1MinusC2_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.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 (0) : i64
      %0 = llvm.sub %c1, %c2 : i64
      %1 = llvm.add %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_smaller_sext_after := [llvm|
{
^0(%arg81 : i64, %arg82 : i1):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.trunc %arg81 : i64 to i16
  %2 = llvm.sext %1 : i16 to i32
  %3 = "llvm.select"(%arg82, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

Std.HashSet.ofList in Std.Data.HashSet.Basic

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_lshr_var_before := [llvm|
{
^0(%arg33 : i64, %arg34 : i64):
  %0 = llvm.mlir.constant(2) : i64
  %1 = llvm.lshr %arg33, %arg34 : 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_sge_after := [llvm|
{
^0(%arg16 : i8, %arg17 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mul %arg16, %arg16 : i8
  %2 = llvm.or %arg17, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "slt" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def select_icmp_ne_0_and_8_or_1073741824_before := [llvm|
{
^0(%arg189 : i8, %arg190 : i32):
  %0 = llvm.mlir.constant(8 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(1073741824 : i32) : i32
  %3 = llvm.and %arg189, %0 : i8
  %4 = llvm.icmp "ne" %1, %3 : i8
  %5 = llvm.or %arg190, %2 : i32
  %6 = "llvm.select"(%4, %arg190, %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_not_const_case2_after := [llvm|
{
^0(%arg71 : i16):
  %0 = llvm.mlir.constant(2 : i16) : i16
  %1 = llvm.mlir.constant(0 : i16) : i16
  %2 = llvm.mlir.constant(8 : i16) : i16
  %3 = llvm.icmp "eq" %arg71, %0 : i16
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i16, i16) -> i16
  "llvm.return"(%4) : (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 in_constant_14_vary_after := [llvm|
{
^0(%arg22 : i4, %arg23 : i4):
  %0 = llvm.mlir.constant(-2 : i4) : i4
  %1 = llvm.and %arg22, %0 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

def neg (M : NFA α σ) := M.toDFA.toNFA.flipAccept

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

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

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

List.foldr in Init.Data.List.Basic

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

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

def subMax (a : BitVec v) (b : BitVec w) : BitVec (max v w + 1) :=
   a.signExtend _ - b.signExtend _

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

Ideal.Quotient.mk in Mathlib.RingTheory.Ideal.Quotient.Defs

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

def 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_nsw1_before := [llvm|
{
^0(%arg23 : i16, %arg24 : i16):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.mlir.constant(-16385 : i16) : i16
  %2 = llvm.and %arg24, %0 : i16
  %3 = llvm.and %arg23, %1 : i16
  %4 = llvm.add %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

def and_or_not_not_commute5_after := [llvm|
{
^0(%arg360 : i32, %arg361 : i32, %arg362 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg362, %arg361 : i32
  %2 = llvm.and %1, %arg360 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def oppositesign_after := [llvm|
{
^0(%arg32 : i16, %arg33 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(32767 : i16) : i16
  %2 = llvm.or %arg32, %0 : i16
  %3 = llvm.and %arg33, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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

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

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

def add {Γ : Ctxt _} (e₁ e₂ : Var Γ .nat) : Expr Γ .nat :=
  Expr.mk
    (op := .add)
    (ty_eq := rfl)
    (eff_le := EffectKind.pure_le _)
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := .nil)

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

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

def 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 }

    |

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

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 generatePreconditions (bvLogicalExpr: BoolExpr GenBVPred) (positiveExamples negativeExamples: List (Std.HashMap Nat BVExpr.PackedBitVec))
              (_numConjunctions: Nat) : GeneralizerStateM ParsedBVExpr GenBVPred (Option (BoolExpr GenBVPred)) := do

    let state ← get
    let widthId := state.widthId

    let validCandidates ← withTraceNode `Generalize (fun _ => return "Attempted to generate valid preconditions") do
      let mut preconditionCandidates : Std.HashSet (BoolExpr GenBVPred) := Std.HashSet.emptyWithCapacity

      
      for (const, val) in positiveExamples[0]!.toArray do
        let bvExprVar := GenBVExpr.var const
        let powerOf2Expr :=  GenBVExpr.bin bvExprVar BVBinOp.and (GenBVExpr.bin bvExprVar BVBinOp.add (minusOne val.w))
        let powerOfTwoResults := positiveExamples.map (λ pos => evalBVExpr pos powerOf2Expr)

        if powerOfTwoResults.any (λ val => val == 0) then
          let powerOf2 := BoolExpr.literal (GenBVPred.bin powerOf2Expr BVBinPred.eq (zero val.w))
          preconditionCandidates := preconditionCandidates.insert powerOf2

      let mut bitwidth := negativeExamples[0]!.values[0]!.w 

      let specialConstants : Std.HashMap (GenBVExpr bitwidth) BVExpr.PackedBitVec := Std.HashMap.ofList [
      ((one bitwidth), {bv := BitVec.ofNat bitwidth 1}),
      ((minusOne bitwidth), {bv := BitVec.ofInt bitwidth (-1)}),
      (GenBVExpr.var widthId, {bv := BitVec.ofNat bitwidth bitwidth})]

      let synthesisComponents : Std.HashMap (GenBVExpr bitwidth)  PreconditionSynthesisCacheValue := getPreconditionSynthesisComponents positiveExamples negativeExamples specialConstants
      let mut previousLevelCache : Std.HashMap (GenBVExpr bitwidth) PreconditionSynthesisCacheValue := synthesisComponents

      let numVariables := positiveExamples[0]!.keys.length + 1 
      let ops : List (GenBVExpr bitwidth -> GenBVExpr bitwidth -> GenBVExpr bitwidth):= [add, subtract, multiply, and, or, xor, shiftLeft, shiftRight, arithShiftRight]

      let mut currentLevel := 0
      let mut validCandidates : List (BoolExpr GenBVPred) := []
      let mut visited : Std.HashSet (BoolExpr GenBVPred) := Std.HashSet.emptyWithCapacity

      while currentLevel < numVariables do
          logInfo m! "Precondition Synthesis: Processing level {currentLevel}"

          let origCandidatesSize := preconditionCandidates.size
          for (bvExpr, intermediateRes) in previousLevelCache.toArray do
            let evaluatedNegativeExs := intermediateRes.negativeExampleValues.map (λ ex => ex.bv.toInt)
            let evaluatedPositiveExs := intermediateRes.positiveExampleValues.map (λ ex => ex.bv.toInt)

            if (evaluatedPositiveExs.all ( λ val => val == 0)) && evaluatedNegativeExs.all (λ val => val != 0) then
              preconditionCandidates := preconditionCandidates.insert (eqToZero bvExpr)
              continue

            if (evaluatedPositiveExs.any ( λ val => val < 0 || val == 0)) && evaluatedNegativeExs.all (λ val => val > 0) then
              let mut cand := lteZero bvExpr widthId
              if (evaluatedPositiveExs.all ( λ val => val < 0)) then
                cand := strictlyLTZero bvExpr widthId

              preconditionCandidates := preconditionCandidates.insert cand

            if (evaluatedPositiveExs.any ( λ val => val > 0 || val == 0)) && evaluatedNegativeExs.all (λ val => val < 0) then
              let mut cand := gteZero bvExpr widthId
              if (evaluatedPositiveExs.all ( λ val => val > 0)) then
                  cand := strictlyGTZero bvExpr widthId

              preconditionCandidates := preconditionCandidates.insert cand

          
          if preconditionCandidates.size > origCandidatesSize then
            validCandidates ← filterCandidatePredicates bvLogicalExpr preconditionCandidates visited
            match validCandidates with
            | [] => visited := preconditionCandidates
            | _ => return validCandidates

          checkTimeout

          previousLevelCache ← precondSynthesisUpdateCache previousLevelCache synthesisComponents positiveExamples negativeExamples specialConstants ops
          currentLevel := currentLevel + 1

      pure validCandidates

    if validCandidates.isEmpty then
      return none

    if validCandidates.length == 1 then
      return validCandidates[0]?

    
    let prunedResults ← pruneEquivalentBVLogicalExprs validCandidates
    match prunedResults with
    | [] => return none
    | _ =>  return some (bigOr prunedResults)

def src_srem_shl_demand_min_signbit_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(1073741823 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(-2147483648 : i32) : i32
  %3 = llvm.srem %arg23, %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_logical_before := [llvm|
{
^0(%arg262 : i8, %arg263 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "uge" %arg263, %arg262 : i8
  %3 = llvm.icmp "ne" %arg262, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def or_and_shifts1_after := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.mlir.constant(5 : i32) : i32
  %3 = llvm.mlir.constant(32 : i32) : i32
  %4 = llvm.shl %arg14, %0 : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.shl %arg14, %2 : i32
  %7 = llvm.and %6, %3 : i32
  %8 = llvm.or disjoint %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) -> ()
}
]

Lean.mkAppN in Lean.Expr

def src4_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg6, %arg7 : i32
  %2 = llvm.or %arg7, %arg6 : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.add %1, %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) -> ()
}
]

List.Vector.ofFn in Mathlib.Data.Vector.Defs

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

def test6a_after := [llvm|
{
^0(%arg1 : i1):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 t6_after := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "slt" %arg7, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

@[simp_denote]
def riscvArgsFromHybrid : {tys : List RISCV64.RV64.Ty} →
  HVector TyDenote.toType (tys.map LLVMRiscV.Ty.riscv) → HVector TyDenote.toType tys
  | [], .nil => .nil
  | _ :: _, .cons x xs => .cons x (riscvArgsFromHybrid xs)

def test29_before := [llvm|
{
^0(%arg173 : i1):
  %0 = llvm.mlir.constant(1000 : i32) : i32
  %1 = llvm.mlir.constant(10 : i32) : i32
  %2 = llvm.mlir.constant(123 : i32) : i32
  %3 = "llvm.select"(%arg173, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.xor %3, %2 : 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 HVector.toVarSet : {l : List d.Ty} → (T : HVector (Var Γ) l) → VarSet Γ
  | [], .nil => ∅
  | _::_, .cons v vs => insert ⟨_, v⟩ vs.toVarSet

def udiv_exact_ne_30_no_of_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(30 : i8) : i8
  %2 = llvm.and %arg1, %0 : i8
  %3 = llvm.mul %2, %1 overflow<nuw> : i8
  %4 = llvm.icmp "ne" %3, %arg0 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

def src2_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg11, %arg10 : 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_1_before := [llvm|
{
^0(%arg317 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg317 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test_imply_not2_before := [llvm|
{
^0(%arg3 : i32, %arg4 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "eq" %arg3, %0 : i32
  %4 = "llvm.select"(%3, %arg4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = llvm.xor %3, %2 : i1
  %6 = llvm.or %4, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

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

instance : DialectPrint Handshake where
  printOpName := reprStr
  printTy := reprStr
  printAttributes _ := ""
  dialectName := "handshake"
  printReturn _ := "return"

def constLLVM13 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (13) : 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_00_exact_after := [llvm|
{
^0(%arg53 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  %1 = llvm.icmp "slt" %arg53, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def different_size_zext_zext_eq_before := [llvm|
{
^0(%arg22 : i4, %arg23 : i7):
  %0 = llvm.zext %arg22 : i4 to i25
  %1 = llvm.zext %arg23 : i7 to i25
  %2 = llvm.icmp "eq" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

def ashr_ugt_2_after := [llvm|
{
^0(%arg112 : i4):
  %0 = llvm.mlir.constant(5 : i4) : i4
  %1 = llvm.icmp "ugt" %arg112, %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_before := [llvm|
{
^0(%arg41 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.lshr %0, %arg41 : 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) -> ()
}
]

structure Inputs (ι : Type) (n : Nat) : Type  where
  ix : Fin n
  input : ι
deriving DecidableEq, Hashable

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

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

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

def t2_before := [llvm|
{
^0(%arg220 : i8, %arg221 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.shl %0, %arg221 : i8
  %2 = llvm.sub %arg220, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

def List.Vector.transport (v : Vector α m) (f : Fin n → Fin m) : Vector α n :=
  Vector.ofFn fun i => v.get (f i)

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 test18_after := [llvm|
{
^0(%arg34 : i32, %arg35 : i32):
  %0 = llvm.mlir.constant(1431655765 : i32) : i32
  %1 = llvm.or %arg34, %0 : i32
  %2 = llvm.sub %arg35, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def main4e_like_after := [llvm|
{
^0(%arg128 : i32, %arg129 : i32, %arg130 : i32):
  %0 = llvm.or %arg129, %arg130 : i32
  %1 = llvm.and %arg128, %0 : i32
  %2 = llvm.icmp "ne" %1, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

inductive Signedness where
  | Signless 
  | Unsigned 
  | Signed   
deriving DecidableEq, Repr

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

def positive_biggershl_ashrexact_after := [llvm|
{
^0(%arg39 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.shl %arg39, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def sge_swap_or_max_before := [llvm|
{
^0(%arg182 : i8, %arg183 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "sle" %arg183, %arg182 : i8
  %2 = llvm.icmp "eq" %arg182, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

@[simp_denote]
def llvm_shl_lower_riscv_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := shl_llvm_32
  rhs := shl_riscv_32

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

def masked_or_allzeroes_notoptimised_logical_before := [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.mlir.constant(true) : i1
  %4 = llvm.and %arg116, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.and %arg116, %2 : i32
  %7 = llvm.icmp "eq" %6, %1 : i32
  %8 = "llvm.select"(%5, %3, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (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_before := [llvm|
{
^0(%arg22 : i64, %arg23 : i1):
  %0 = llvm.sext %arg23 : i1 to i64
  %1 = llvm.xor %0, %arg22 : i64
  %2 = llvm.sub %0, %1 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

def select_or_disjoint_or_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = "llvm.select"(%arg15, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.shl %arg14, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  %5 = llvm.add %4, %1 overflow<nsw,nuw> : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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_sameconst_lshrexact_before := [llvm|
{
^0(%arg41 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.lshr exact %arg41, %0 : i8
  %2 = llvm.shl %1, %0 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

@[simp_llvm]
def not? {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 mul8_low_after := [llvm|
{
^0(%arg26 : i8, %arg27 : i8):
  %0 = llvm.mul %arg26, %arg27 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

def positive_biggershl_shlnsw_after := [llvm|
{
^0(%arg49 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg49, %0 overflow<nsw,nuw> : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (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 and_zext_demanded_after := [llvm|
{
^0(%arg255 : i16, %arg256 : i32):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.lshr %arg255, %0 : i16
  %2 = llvm.zext nneg %1 : i16 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test6_after := [llvm|
{
^0(%arg88 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.lshr %arg88, %0 : i64
  %2 = llvm.trunc %1 overflow<nuw> : i64 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

Fin.elim0 in Init.Data.Fin.Basic

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_after := [llvm|
{
^0(%arg122 : i8, %arg123 : i8, %arg124 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(123 : i8) : i8
  %3 = llvm.lshr %0, %arg123 : i8
  %4 = llvm.lshr %1, %arg124 : i8
  %5 = llvm.and %3, %4 : i8
  %6 = llvm.xor %arg122, %2 : i8
  %7 = llvm.icmp "ule" %6, %5 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

def urem_illegal_type_c_after := [llvm|
{
^0(%arg7 : i9):
  %0 = llvm.mlir.constant(10 : i9) : i9
  %1 = llvm.urem %arg7, %0 : i9
  %2 = llvm.zext nneg %1 : i9 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def Env.ofEnvFin (envFin : EnvFin w n) : Env w := (List.finRange n).map envFin

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

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

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

def and_or2_wrong_operand_after := [llvm|
{
^0(%arg172 : i1, %arg173 : i1, %arg174 : i1, %arg175 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg174, %0 : i1
  %2 = llvm.and %arg173, %1 : i1
  %3 = "llvm.select"(%2, %arg172, %arg175) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

structure Item where
 name : String
 tac : Syntax

def icmp_eq_x_invertable_y2_todo_after := [llvm|
{
^0(%arg4 : i8, %arg5 : i1):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.mlir.constant(-25 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i8) : i8
  %3 = "llvm.select"(%arg5, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.or %arg4, %3 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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_before := [llvm|
{
^0(%arg2 : i7):
  %0 = llvm.mlir.constant(23 : i7) : i7
  %1 = llvm.or %arg2, %0 : i7
  %2 = llvm.xor %1, %0 : i7
  "llvm.return"(%2) : (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_before := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.shl %arg154, %arg155 overflow<nuw> : i32
  %1 = llvm.add %0, %arg156 overflow<nuw> : i32
  %2 = llvm.lshr %1, %arg155 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

@[simp_llvm_option]
def udiv {w : Nat} (x y : IntW w) (flag : ExactFlag := {exact := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.exact ∧ x'.umod y' ≠ 0 then
    .poison
  else
    udiv? 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) -> ()
}
]

Lean.Meta.mkFreshExprMVar in Lean.Meta.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 constLLVM_23 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (-23) : i64
    llvm.return %1 : i64
  }]

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

def ne_10_after := [llvm|
{
^0(%arg78 : i32, %arg79 : i32):
  %0 = llvm.trunc %arg78 : i32 to i16
  %1 = llvm.trunc %arg79 : i32 to i16
  %2 = llvm.icmp "ne" %0, %1 : i16
  "llvm.return"(%2) : (i1) -> ()
}
]

@[grind=]
def length (Γ : Ctxt Ty) : Nat := Γ.toList.length

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_equality_both_before := [llvm|
{
^0(%arg40 : i16, %arg41 : i16):
  %0 = llvm.trunc %arg40 overflow<nsw,nuw> : i16 to i8
  %1 = llvm.trunc %arg41 overflow<nsw,nuw> : i16 to i8
  %2 = llvm.icmp "eq" %0, %1 : i8
  "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) -> ()
}
]

def Eqn.denote {w : Nat} (e : Eqn) (env : Env w) : Int :=
  match e with
  | [] => 0
  | t :: ts => t.denote env + Eqn.denote ts env

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

@[simp_denote]
def add32_accept_riscv := [LV| {
  ^entry (%arg: i32):
  %0 = "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
  %1 = "addi" (%0) {imm = 2047 : !i64} : (!i64) -> (!i64)
  %2 = addiw %1, 952 : !i64
  %3 =  "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i32)
  llvm.return %3 : 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_after := [llvm|
{
^0(%arg37 : 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.and %arg37, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.trunc %arg37 : i32 to i16
  %7 = llvm.add %6, %2 : i16
  %8 = llvm.icmp "ult" %7, %3 : i16
  %9 = llvm.and %5, %8 : i1
  "llvm.return"(%9) : (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.ctz in RISCV.Instructions

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

def handshakeAdd := [HSxComb_com| {
  ^entry(%a: !Stream_BitVec_32, %b: !Stream_BitVec_32):
    %add1 = "HSxComb.add" (%a, %a) : (!Stream_BitVec_32, !Stream_BitVec_32) -> (!Stream_BitVec_32)
    %syncAdd = "HSxComb.sync" (%add1, %b) : (!Stream_BitVec_32, !Stream_BitVec_32) -> (!Stream2_BitVec_32)
    %syncAdd1 = "HSxComb.snd" (%syncAdd) : (!Stream2_BitVec_32) -> !Stream_BitVec_32
    %add2 = "HSxComb.add" (%syncAdd1, %a) : (!Stream_BitVec_32, !Stream_BitVec_32) -> (!Stream_BitVec_32)
    "return" (%add2) : (!Stream_BitVec_32) -> ()
  }]

def udiv_shl_pair3_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg25 overflow<nuw> : i32
  %2 = llvm.lshr %1, %arg26 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def 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_before := [llvm|
{
^0(%arg95 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.ashr exact %arg95, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (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.Meta.Context in Lean.Meta.Basic

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

def canonicalize_logic_first_or0_nswnuw_before := [llvm|
{
^0(%arg38 : i32):
  %0 = llvm.mlir.constant(112 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.add %arg38, %0 overflow<nsw,nuw> : i32
  %3 = llvm.or %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

partial def Com.printModule (com : Com d Γ eff ts) : Format :=
  f!"builtin.module {com.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_0_after := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "sgt" %arg20, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def slt_zero_eq_ne_0_fail2_before := [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" %3, %4 : 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 main7c_logical_before := [llvm|
{
^0(%arg69 : i32, %arg70 : i32, %arg71 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.and %arg70, %arg69 : i32
  %4 = llvm.icmp "eq" %arg70, %3 : i32
  %5 = llvm.and %arg71, %arg69 : i32
  %6 = llvm.icmp "eq" %arg71, %5 : i32
  %7 = "llvm.select"(%4, %6, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %8 = "llvm.select"(%7, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

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

Qq.synthInstanceQ in Qq.MetaM

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 match_signed_after := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(172224) : i64
  %1 = llvm.srem %arg15, %0 : i64
  "llvm.return"(%1) : (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_11_exact_after := [llvm|
{
^0(%arg210 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def positive_samevar_shlnsw_ashrexact_before := [llvm|
{
^0(%arg37 : i8, %arg38 : i8):
  %0 = llvm.ashr exact %arg37, %arg38 : i8
  %1 = llvm.shl %0, %arg38 overflow<nsw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

@[simp_llvm_option]
def neg {w : Nat} (x : IntW w) : IntW w := do
  let x' ← x
  neg? x'

BitVec.cast in Init.Data.BitVec.Basic

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

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

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

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

def scalar_i32_udiv_and_negC_eq_X_is_constant3_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(12345 : i32) : i32
  %1 = llvm.mlir.constant(16376 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.udiv %0, %arg7 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

instance : MonadLiftT (pure.toMonad m) (eff.toMonad m)   := instMonadLiftOfLe (pure_le eff)

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

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

def neg_after := [llvm|
{
^0(%arg10 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.udiv %arg10, %0 : i8
  %3 = llvm.sub %1, %arg10 : i8
  %4 = llvm.xor %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_ashr_ne_both_equal_after := [llvm|
{
^0(%arg167 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg167, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

instance : Lean.ToExpr RegIndex := inherit

def test_and2_after := [llvm|
{
^0(%arg48 : i32, %arg49 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg49, %0 : i32
  %2 = llvm.icmp "ule" %arg48, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def udiv_shl_mul_nuw_swap_after := [llvm|
{
^0(%arg145 : i5, %arg146 : i5, %arg147 : i5):
  %0 = llvm.mlir.constant(1 : i5) : i5
  %1 = llvm.shl %0, %arg147 overflow<nuw> : i5
  %2 = llvm.udiv %1, %arg146 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

def irc_constants_C1Minus2MinusC2_neg1_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 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_02_after := [llvm|
{
^0(%arg397 : i4):
  %0 = llvm.mlir.constant(-5 : i4) : i4
  %1 = llvm.icmp "ugt" %arg397, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def lshrult_01_07_before := [llvm|
{
^0(%arg360 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(7 : i4) : i4
  %2 = llvm.lshr %arg360, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (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 test5_after := [llvm|
{
^0(%arg45 : i32, %arg46 : i32):
  %0 = llvm.and %arg45, %arg46 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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_neg_i32_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sub %0, %arg7 : i32
  %3 = llvm.and %2, %arg7 : i32
  %4 = llvm.add %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def lshrugt_02_10_exact_before := [llvm|
{
^0(%arg195 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-6 : i4) : i4
  %2 = llvm.lshr exact %arg195, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (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_eq_after := [llvm|
{
^0(%arg158 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.icmp "eq" %arg158, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def const (a : α) (_b : β) : α := a

def constLLVM_33 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (-33) : 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_07_after := [llvm|
{
^0(%arg392 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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_10_after := [llvm|
{
^0(%arg104 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  %1 = llvm.icmp "slt" %arg104, %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_zext_zext_sgt_after := [llvm|
{
^0(%arg16 : i7, %arg17 : i4):
  %0 = llvm.zext %arg17 : i4 to i7
  %1 = llvm.icmp "ugt" %arg16, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def 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_ugt_15_after := [llvm|
{
^0(%arg99 : 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_and3_after := [llvm|
{
^0(%arg14 : i8):
  %0 = llvm.mlir.constant(-126 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.and %arg14, %0 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (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_3b_logical_before := [llvm|
{
^0(%arg85 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(3 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.and %arg85, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg85, %2 : i32
  %7 = llvm.icmp "eq" %6, %1 : i32
  %8 = "llvm.select"(%5, %7, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> 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 n10_wrong_pred2_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg10, %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_xor_after := [llvm|
{
^0(%arg65 : i8, %arg66 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.mlir.constant(-8 : i8) : i8
  %3 = llvm.srem %arg65, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg66, %2 : i8
  %6 = llvm.xor %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

HAdd.hAdd in Init.Prelude

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

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

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

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

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

@[simp_denote]
def add_positive_low_bound_reject_riscv :=
  [LV| {
    ^entry (%arg: i32):
    %a =  "builtin.unrealized_conversion_cast" (%arg) : (i32) -> (!i64)
    %0 = addiw %a, 2047 : !i64
    %1 =  "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i32)
    llvm.return %1 :i32
  }]

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

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

def ult_to_slt_before := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.xor %arg32, %0 : i8
  %2 = llvm.xor %arg33, %0 : i8
  %3 = llvm.icmp "ult" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

@[simp_denote]
def zext_llvm_1_to_8 := [LV| {
  ^entry (%arg: i1):
    %0 = llvm.zext %arg: i1 to i8
    llvm.return %0: i8
  }]

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

def trunc_ashr_after := [llvm|
{
^0(%arg83 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-8388608 : i32) : i32
  %2 = llvm.lshr %arg83, %0 : i32
  %3 = llvm.or %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def sext_zext_nneg_uge_op0_wide_after := [llvm|
{
^0(%arg26 : i16, %arg27 : i8):
  %0 = llvm.sext %arg27 : i8 to i16
  %1 = llvm.icmp "uge" %arg26, %0 : i16
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def elabIntoCom' (region : TSyntax `mlir_region) (d : Dialect) {φ : Nat}
    [ToExpr d.Op] [ToExpr d.Ty] [DialectToExpr d]
    [DialectSignature d] [Repr d.Ty]
    [TransformTy d φ] [TransformExpr d φ] [TransformReturn d φ] :
    TermElabM Expr := withRef region <| do
  let ⟨_Γ, _eff, _ty, com⟩ ← elabIntoComObj region d
  com.toExprM

def xor_common_op_commute0_before := [llvm|
{
^0(%arg208 : i8, %arg209 : i8):
  %0 = llvm.xor %arg208, %arg209 : i8
  %1 = llvm.or %0, %arg208 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def ashrsgt_03_06_before := [llvm|
{
^0(%arg279 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.ashr %arg279, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (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_7_after := [llvm|
{
^0(%arg89 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.icmp "sgt" %arg89, %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 sdiv {Γ : 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.sdiv 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_ne_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ne" %arg58, %0 : i8
  %3 = llvm.icmp "ne" %arg59, %arg58 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def lshr_2_add_zext_basic_before := [llvm|
{
^0(%arg37 : i1, %arg38 : i1):
  %0 = llvm.mlir.constant(1 : i2) : i2
  %1 = llvm.zext %arg37 : i1 to i2
  %2 = llvm.zext %arg38 : i1 to i2
  %3 = llvm.add %1, %2 : i2
  %4 = llvm.lshr %3, %0 : i2
  "llvm.return"(%4) : (i2) -> ()
}
]

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

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

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

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

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

def isCloseBracket(c: Char):Option Bracket :=
match c with
| ')' => some .Round
| ']' => some .Square
| '{' => some .Curly
| '<' => some .Angle
| _ => none

def llvm_const_lower_riscv_li_7 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_7, rhs:= liRiscv_7,
   correct := by admit /- proof elided -/

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

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

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

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

def uadd_sat_flipped_wrong_bounds_before := [llvm|
{
^0(%arg96 : i32):
  %0 = llvm.mlir.constant(-12 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.icmp "uge" %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 par_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32, %arg83 : i32, %arg84 : i32):
  %0 = llvm.icmp "slt" %arg81, %arg82 : i32
  %1 = "llvm.select"(%0, %arg83, %arg84) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def lshrult_02_02_before := [llvm|
{
^0(%arg349 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.lshr %arg349, %0 : i4
  %2 = llvm.icmp "ult" %1, %0 : i4
  "llvm.return"(%2) : (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_odd_commuted_before := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.icmp "eq" %arg30, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  %3 = llvm.and %2, %arg30 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test19_before := [llvm|
{
^0(%arg192 : i32, %arg193 : i32):
  %0 = llvm.xor %arg192, %arg193 : i32
  %1 = llvm.xor %0, %arg192 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

@[simp_denote]
def xor_llvm_i32 := [LV| {
    ^entry (%a: i32, %b: i32):
    %0 = llvm.xor %a, %b : i32
    llvm.return %0 : 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_or2_after := [llvm|
{
^0(%arg15 : i64, %arg16 : i64, %arg17 : i64):
  %0 = llvm.mlir.constant(24) : i64
  %1 = llvm.mlir.constant(60) : i64
  %2 = llvm.icmp "ult" %arg15, %0 : i64
  %3 = llvm.icmp "ult" %arg16, %1 : i64
  %4 = llvm.and %2, %3 : i1
  %5 = llvm.icmp "ult" %arg17, %1 : i64
  %6 = llvm.and %4, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

def 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 test12_logical_after := [llvm|
{
^0(%arg290 : i32, %arg291 : i32):
  %0 = llvm.icmp "ult" %arg290, %arg291 : i32
  "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) -> ()
}
]

DecidableRel in Init.Prelude

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 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_05_exact_after := [llvm|
{
^0(%arg112 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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_before := [llvm|
{
^0(%arg3 : i8):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.sext %arg3 : i8 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def shl_bad_sub2_i32_after := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(-31 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.add %arg10, %0 : i32
  %3 = llvm.shl %1, %2 overflow<nuw> : 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_signbit_lshr_before := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.or %arg13, %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 uge_sext_before := [llvm|
{
^0(%arg134 : i1, %arg135 : i8):
  %0 = llvm.sext %arg134 : i1 to i8
  %1 = llvm.icmp "uge" %0, %arg135 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def select_constants_and_icmp_eq0_before := [llvm|
{
^0(%arg46 : i1, %arg47 : 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"(%arg46, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = "llvm.select"(%arg47, %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_logical_before := [llvm|
{
^0(%arg12 : i8, %arg13 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg12, %arg13 : i8
  %3 = llvm.icmp "ne" %arg12, %0 : i8
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def sgt_positive_multip_rem_nz_after := [llvm|
{
^0(%arg168 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.icmp "sgt" %arg168, %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 mul (w : Width φ)
  (NoWrapFlags: NoWrapFlags := {nsw := false , nuw := false}) : MOp φ
    := .binary w (.mul NoWrapFlags )

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

def scalar_i32_lshr_and_negC_ne_after := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(262143 : i32) : i32
  %1 = llvm.lshr %arg31, %arg32 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (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_pass_after := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.and %arg9, %0 : i32
  %3 = llvm.xor %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def ashrslt_02_10_before := [llvm|
{
^0(%arg243 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-6 : i4) : i4
  %2 = llvm.ashr %arg243, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (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 pr4917_3_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(4294967295) : i64
  %1 = llvm.mlir.constant(111) : i64
  %2 = llvm.zext %arg25 : i32 to i64
  %3 = llvm.zext %arg26 : i32 to i64
  %4 = llvm.mul %2, %3 : i64
  %5 = llvm.icmp "ugt" %4, %0 : i64
  %6 = "llvm.select"(%5, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%6) : (i64) -> ()
}
]

inductive AttrDefn where
  | mk: (name: String) -> (val: AttrValue φ) -> AttrDefn

def cast (h_eq : ty₁ = ty₂) : Γ.Var ty₁ → Γ.Var ty₂
  | ⟨i, h⟩ => ⟨i, h_eq ▸ h⟩

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_logical_before := [llvm|
{
^0(%arg33 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(8 : i32) : i32
  %4 = llvm.mlir.constant(false) : i1
  %5 = llvm.and %arg33, %0 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %arg33, %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 scalar_i8_shl_and_negC_eq_after := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.shl %arg35, %arg36 : i8
  %2 = llvm.icmp "ult" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

def ashrsgt_02_01_exact_after := [llvm|
{
^0(%arg84 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 bools_logical_commute0_and1_after := [llvm|
{
^0(%arg105 : i1, %arg106 : i1, %arg107 : i1):
  %0 = "llvm.select"(%arg107, %arg106, %arg105) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def test11_after := [llvm|
{
^0(%arg43 : 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_before := [llvm|
{
^0(%arg48 : i1, %arg49 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.zext %arg48 : i1 to i32
  %3 = llvm.zext %arg49 : i1 to i32
  %4 = llvm.sub %0, %3 : i32
  %5 = llvm.add %2, %1 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def select_constants_and_icmp_ne0_common_bit_before := [llvm|
{
^0(%arg18 : i1, %arg19 : 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"(%arg18, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = "llvm.select"(%arg19, %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 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_3_after := [llvm|
{
^0(%arg132 : i1, %arg133 : i1, %arg134 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg133, %0, %arg134) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg132, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

@[irreducible]
def irreduciblePow (q n : Nat) : Nat := q^n

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

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

def udiv_exact_eq_1_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.icmp "ne" %arg10, %arg11 : i8
  "llvm.return"(%0) : (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 n5_before := [llvm|
{
^0(%arg9 : i8, %arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.and %arg9, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  %4 = "llvm.select"(%3, %arg10, %arg11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

def CollectState.pcard (state : CollectState) : Nat :=
  state.pToIx.size

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

def sel_false_val_is_a_masked_shl_of_true_val1_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(60 : i32) : i32
  %2 = llvm.shl %arg10, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg11, %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) -> ()
}
]

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

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

abbrev EnumerativeSearchCache :=  Std.HashMap BVExprWrapper BVExpr.PackedBitVec

def test_mul_nuw_nsw__nsw_is_safe_before := [llvm|
{
^0(%arg7 : 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 %arg7, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.mul %4, %2 overflow<nsw,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 sle_smin4_before := [llvm|
{
^0(%arg49 : i32, %arg50 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg49, %0 : i32
  %2 = llvm.icmp "slt" %arg50, %1 : i32
  %3 = "llvm.select"(%2, %arg50, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "sge" %1, %3 : i32
  "llvm.return"(%4) : (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_rem2_neg_i8_before := [llvm|
{
^0(%arg57 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.srem %arg57, %0 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def or_not_and_after := [llvm|
{
^0(%arg537 : i32, %arg538 : i32, %arg539 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg538, %arg539 : i32
  %2 = llvm.xor %arg537, %0 : i32
  %3 = llvm.and %1, %2 : i32
  "llvm.return"(%3) : (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_samevar_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.lshr %0, %arg37 : i32
  %2 = llvm.and %1, %arg36 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def lshr_32_add_not_known_32_leading_zeroes_after := [llvm|
{
^0(%arg13 : i64, %arg14 : i64):
  %0 = llvm.mlir.constant(8589934591) : i64
  %1 = llvm.mlir.constant(4294967295) : i64
  %2 = llvm.mlir.constant(32) : i64
  %3 = llvm.and %arg13, %0 : i64
  %4 = llvm.and %arg14, %1 : i64
  %5 = llvm.add %3, %4 overflow<nsw,nuw> : i64
  %6 = llvm.lshr %5, %2 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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 and_zext_zext_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i4):
  %0 = llvm.zext %arg59 : i4 to i8
  %1 = llvm.and %arg58, %0 : i8
  %2 = llvm.zext nneg %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_i32_multiuse_before := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.zext %arg25 : i8 to i32
  %1 = llvm.zext %arg26 : i8 to i32
  %2 = llvm.udiv %0, %1 : i32
  %3 = llvm.add %0, %1 : i32
  %4 = llvm.mul %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def testi64i32_ne_before := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.lshr %arg7, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.trunc %arg7 : i64 to i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.icmp "ne" %5, %3 : i32
  "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.Declaration.defnDecl in Lean.Declaration

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

def constLLVM17 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (17) : 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 test4b_after := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(1) : i64
  %1 = llvm.icmp "slt" %arg8, %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_simplify_before := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(-3 : i32) : i32
  %1 = llvm.mlir.constant(2147483644 : i32) : i32
  %2 = llvm.add %arg34, %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 sub_to_add_5 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant 5 : i64
      %1 = llvm.sub %x, %c : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant -5 : i64
      %1 = llvm.add %x, %c : i64
      llvm.return %1 : 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 test_invalid_simplify_other_after := [llvm|
{
^0(%arg204 : i8, %arg205 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.icmp "eq" %arg204, %0 : i8
  %3 = llvm.add %arg205, %1 : i8
  %4 = "llvm.select"(%2, %0, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

inductive AttrEntry where
  | mk: (key: String)
      -> (value: AttrValue)
      -> AttrEntry

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

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

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

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

def or_logic_or_logic_and_1_before := [llvm|
{
^0(%arg48 : i1, %arg49 : i1, %arg50 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.or %arg48, %arg49 : i1
  %3 = "llvm.select"(%arg48, %0, %arg50) <{"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 t8_lshr_exact_flag_preservation_after := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.lshr exact %arg27, %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_10_exact_after := [llvm|
{
^0(%arg11 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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_logical_before := [llvm|
{
^0(%arg68 : i8, %arg69 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ult" %arg69, %arg68 : i8
  %3 = llvm.icmp "ne" %arg68, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def test4_after := [llvm|
{
^0(%arg57 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %arg57, %0 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def testi16i8_after := [llvm|
{
^0(%arg9 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(27 : i8) : i8
  %2 = llvm.mlir.constant(-28 : i8) : i8
  %3 = llvm.icmp "sgt" %arg9, %0 : i16
  %4 = "llvm.select"(%3, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

LawfulMonad in Init.Control.Lawful.Basic

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

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

Lean.mkApp2 in Lean.Expr

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_fail1_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i1):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.zext %arg9 : i1 to i32
  %2 = llvm.lshr %arg8, %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 urem_c_i32_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.zext %arg5 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  "llvm.return"(%2) : (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_0_Y_ne_0_after := [llvm|
{
^0(%arg48 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg48, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def a_false_implies_b_true2_after := [llvm|
{
^0(%arg12 : i8, %arg13 : i1, %arg14 : i1):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ugt" %arg12, %0 : i8
  %3 = "llvm.select"(%2, %1, %arg13) <{"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_C2MinusAPlusC1_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.add %a, %c1 : i64
      %1 = llvm.sub %c2, %0 : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (1) : i64
      %c2 = llvm.mlir.constant (-2) : i64
      %0 = llvm.sub %c2, %c1 : 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_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 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 llvm_const_lower_riscv_li39 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM39, rhs:= liRiscv39,
   correct := by admit /- proof elided -/

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

def Stream (β : Type) := Stream' (Option β)

@[simp]
def Op.denote (o : LLVM.Op) (op : HVector TyDenote.toType (DialectSignature.sig o)) :
    (TyDenote.toType (β := LLVM.Ty) o.outTy) :=
  match o with
  | LLVM.Op.const _ val    => const? _ val
  | LLVM.Op.copy _         =>               (op.getN 0 (by admit /- proof elided -/
  ))
  | LLVM.Op.freeze _       => LLVM.freeze   (op.getN 0 (by admit /- proof elided -/
  ))
  | LLVM.Op.not _          => LLVM.not      (op.getN 0 (by admit /- proof elided -/
  ))
  | LLVM.Op.neg _          => LLVM.neg      (op.getN 0 (by admit /- proof elided -/
  ))
  | LLVM.Op.trunc w w'    flags => LLVM.trunc w' (op.getN 0 (by admit /- proof elided -/
  )) flags
  | LLVM.Op.zext w w' flag => LLVM.zext  w' (op.getN 0 (by admit /- proof elided -/
  )) flag
  | LLVM.Op.sext w w'      => LLVM.sext  w' (op.getN 0 (by admit /- proof elided -/
  ))
  | LLVM.Op.and _          => LLVM.and      (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  ))
  | LLVM.Op.or _ flag      => LLVM.or       (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flag
  | LLVM.Op.xor _          => LLVM.xor      (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  ))
  | LLVM.Op.shl _ flags    => LLVM.shl      (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flags
  | LLVM.Op.lshr _ flag    => LLVM.lshr     (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flag
  | LLVM.Op.ashr _ flag    => LLVM.ashr     (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flag
  | LLVM.Op.sub _ flags    => LLVM.sub      (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flags
  | LLVM.Op.add _ flags    => LLVM.add      (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flags
  | LLVM.Op.mul _ flags    => LLVM.mul      (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flags
  | LLVM.Op.sdiv _ flag    => LLVM.sdiv     (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flag
  | LLVM.Op.udiv _ flag    => LLVM.udiv     (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) flag
  | LLVM.Op.urem _         => LLVM.urem     (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  ))
  | LLVM.Op.srem _         => LLVM.srem     (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  ))
  | LLVM.Op.icmp c _       => LLVM.icmp  c  (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  ))
  | LLVM.Op.select _       => LLVM.select   (op.getN 0 (by admit /- proof elided -/
  )) (op.getN 1 (by admit /- proof elided -/
  )) (op.getN 2 (by admit /- proof elided -/
  ))

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_12_after := [llvm|
{
^0(%arg355 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 cMerge (x y : TokenStream) : ValueStream (BitVec 1) × TokenStream :=
  Stream.corec₂ (β := TokenStream × TokenStream) (x, y) fun ⟨x, y⟩ =>
    match x 0, y 0 with
    | some x', some _ => (some 1, some x', (x.tail, y))
    | some x', none => (some 1, some x', (x.tail, y.tail))
    | none, some y' => (some 0, some y', (x.tail, y.tail))
    | none, none => (none, none, (x.tail, y.tail))

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_wrong8_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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_or_min_commute_after := [llvm|
{
^0(%arg154 : i8, %arg155 : i8):
  %0 = llvm.icmp "sle" %arg154, %arg155 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

def or_not_and_wrong_b_before := [llvm|
{
^0(%arg484 : i32, %arg485 : i32, %arg486 : i32, %arg487 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg484, %arg485 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.and %2, %arg486 : i32
  %4 = llvm.or %arg484, %arg486 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %5, %arg487 : i32
  %7 = llvm.or %3, %6 : i32
  "llvm.return"(%7) : (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 State.cseCom {α}
  {lets : Lets d Γstart .pure Γ}
  (s : State d lets)
  (com: Com d Γ .pure α) :
  { com' : Com d Γ .pure α
    // ∀ (V : Ctxt.Valuation Γstart), com.denote (lets.denote V) = com'.denote (lets.denote V) } :=
  match com with
  | .rets vs =>
      let ⟨vs', hvs'⟩ := s.vars2vars vs
      ⟨.rets vs', by admit /- proof elided -/
        ⟩
  | .var e body =>
      let ⟨⟨e', he'⟩, v'?⟩ := s.cseExpr e
      match v'? with
      | .none =>  
        let s' := s.consNewExpr2Cache (e := e')
         
        let ⟨body', hbody'⟩ := s'.cseCom body
        ⟨.var e' body',  by admit /- proof elided -/
            ⟩
      | .some ⟨v', hv'⟩ =>
        let s' := s.consOldExpr2Cache (enew := e') (eold := e) (henew := by admit /- proof elided -/
        )
          (vold := v') (hv := by admit /- proof elided -/
          )
          
        let ⟨body', hbody'⟩ := s'.cseCom body
        
        ⟨.var e body' 
        , by admit /- proof elided -/
        ⟩

noncomputable def R.monomial {q n : Nat} (c : ZMod q) (i : Nat): R q n :=
  R.fromPoly (Polynomial.monomial i c)

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 test11_after := [llvm|
{
^0(%arg3 : i737):
  %0 = llvm.mlir.constant(2147483647 : i737) : i737
  %1 = llvm.icmp "ugt" %arg3, %0 : i737
  "llvm.return"(%1) : (i1) -> ()
}
]

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 closed_set (M : NFA α σ) (S : Set σ) := M.start ⊆ S ∧ ∀ a, M.stepSet S a ⊆ S

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

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

def test_invert_demorgan_or2_before := [llvm|
{
^0(%arg15 : i64, %arg16 : i64, %arg17 : i64):
  %0 = llvm.mlir.constant(23) : i64
  %1 = llvm.mlir.constant(59) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ugt" %arg15, %0 : i64
  %4 = llvm.icmp "ugt" %arg16, %1 : i64
  %5 = llvm.or %3, %4 : i1
  %6 = llvm.icmp "ugt" %arg17, %1 : i64
  %7 = llvm.or %5, %6 : i1
  %8 = llvm.xor %7, %2 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

def 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_slt_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.lshr %arg2, %arg3 : i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

RV64.srliw in RISCV.Instructions

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

abbrev instHadd : HAdd ⟦ScfFunctor.Arith.Ty.int⟧ ⟦ScfFunctor.Arith.Ty.int⟧
  ⟦ScfFunctor.Arith.Ty.int⟧ := @instHAdd ℤ Int.instAdd

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_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(-8 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.lshr %arg2, %arg3 : i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (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 xor_logic_and_logic_or1_before := [llvm|
{
^0(%arg54 : i1, %arg55 : i1, %arg56 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg54, %0, %arg56) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg54, %arg55, %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 liRiscv_2 := [LV| {
  ^entry ():
    %0 = "li"() {imm = -2 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

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 forkVal (x : ValueStream (BitVec 1)) : ValueStream (BitVec 1) × ValueStream (BitVec 1)  :=
  Stream.corec₂ (β := ValueStream (BitVec 1)) x
    fun x => Id.run <| do
      (x 0, x 0, x.tail)

def c0_before := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.and %arg7, %0 : i8
  %2 = llvm.icmp "sgt" %1, %arg7 : i8
  "llvm.return"(%2) : (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) -> ()
}
]

structure ExactFlag where
  exact : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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_128 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (128) : i64
      %0 = llvm.udiv %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (7) : i64
      %0 = llvm.lshr %x, %c : i64
      llvm.return %0 : i64
  }]

def llvm_shl_lower_riscv_nsw_nuw_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := shl_llvm_nsw_nuw_32
  rhs := shl_riscv_32

def ExtEq (Γ Δ : Context Ty) : Prop :=
  ∀ v, Γ.lookup v = Δ.lookup v

def a_false_implies_b_false2_comm_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i1, %arg2 : i1):
  %0 = llvm.mlir.constant(10 : i8) : i8
  %1 = llvm.mlir.constant(20 : i8) : i8
  %2 = llvm.icmp "ugt" %arg0, %0 : i8
  %3 = llvm.icmp "ugt" %arg0, %1 : i8
  %4 = "llvm.select"(%3, %arg1, %arg2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = llvm.or %4, %2 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def const_sub_sub_const_after := [llvm|
{
^0(%arg25 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.sub %0, %arg25 : 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_eq_zero_after := [llvm|
{
^0(%arg25 : i32):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def select_icmp_eq_pow2_before := [llvm|
{
^0(%arg13 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.and %arg13, %0 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  %4 = llvm.xor %arg13, %0 : i8
  %5 = "llvm.select"(%3, %arg13, %4) <{"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 sll  {Γ : Ctxt _} (e₁ e₂: Ctxt.Var Γ .bv) : Expr RV64 Γ .pure [.bv]  :=
  Expr.mk
    (op := Op.sll)
    (eff_le := by admit /- proof elided -/
    )
    (ty_eq := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := HVector.nil)

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

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

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

macro "[mlir_attr_entry|" entry:mlir_attr_entry "]" : term => do
  let `(mlir_attr_entry| $key $[= $val]?) := entry | Macro.throwUnsupported
  let key ← match key.raw[0] with
    | .ident _ key _ _ => pure key.toString
    
    
    
    | .node _ `str ⟨(.atom _ val)::[]⟩ => pure val
    
    | _ => Macro.throwUnsupported
  let value ← match val with
    | none      => `(AttrValue.unit)
    | some val  => `([mlir_attr_val| $val])
  `(AttrEntry.mk $(Lean.quote key) $value)

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

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

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

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

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

def or_and3_after := [llvm|
{
^0(%arg104 : i1, %arg105 : i1, %arg106 : i32, %arg107 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ne" %arg106, %arg107 : i32
  %3 = "llvm.select"(%2, %arg105, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg104, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def positive_biggershl_shlnsw_after := [llvm|
{
^0(%arg49 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(-64 : i8) : i8
  %2 = llvm.shl %arg49, %0 overflow<nsw> : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (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.fromTensorFinsupp (q : Nat) (coeffs : List Int) : (ZMod q)[X] :=
  Polynomial.ofFinsupp (List.toFinsupp (coeffs.map Int.cast))

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

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

@[instance] def instReprTy := instPrint.instReprTy

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

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

def multiuse1_after := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mlir.constant(6 : i32) : i32
  %3 = llvm.mlir.constant(384 : i32) : i32
  %4 = llvm.lshr %arg11, %0 : i32
  %5 = llvm.and %4, %0 : i32
  %6 = llvm.lshr %arg11, %0 : i32
  %7 = llvm.and %6, %1 : i32
  %8 = llvm.shl %arg11, %2 : i32
  %9 = llvm.and %8, %3 : i32
  %10 = llvm.or disjoint %5, %7 : i32
  %11 = llvm.or disjoint %10, %9 : i32
  "llvm.return"(%11) : (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_or_disjoint_after := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.udiv %arg5, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  %4 = llvm.add %3, %arg5 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def urem_i8_before := [llvm|
{
^0(%arg33 : i8, %arg34 : i8):
  %0 = llvm.zext %arg33 : i8 to i32
  %1 = llvm.zext %arg34 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  %3 = llvm.trunc %2 : i32 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

modify in Init.Prelude
</all_available_defs>

<all_available_lemmas>
...

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_01_14_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 1) { «exact» := true }) (const? 4 (-2)) ⊑
    icmp IntPred.slt e (const? 4 (-4))

theorem mul_of_bool_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ofBool (255#32 <ᵤ (x_1 &&& 1#32) * zeroExtend 32 x) = 0#1

theorem ashrslt_01_05_proof : ashrslt_01_05_before ⊑ ashrslt_01_05_after

theorem shl_nsw_nuw_add_nsw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ (1#32 <<< x).sshiftRight' x ≠ 1#32 ∨
        True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ (1#32 <<< x).saddOverflow (-1#32) = true) →
    True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32 → False

theorem sgt_smax4_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (add e_1 (const? 32 3))
      (select (icmp IntPred.sgt e (add e_1 (const? 32 3))) e (add e_1 (const? 32 3))) ⊑
    icmp IntPred.sgt e (add e_1 (const? 32 3))

theorem lshr_32_add_zext_trunc_proof : lshr_32_add_zext_trunc_before ⊑ lshr_32_add_zext_trunc_after

theorem trunc_unsigned_nuw_zext_proof : trunc_unsigned_nuw_zext_before ⊑ trunc_unsigned_nuw_zext_after

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

theorem test_proof : test_before ⊑ test_after

theorem and_comm (x y : BitStream) : x &&& y = y &&& x

theorem or_or_logic_and_1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 ||

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_444 :
    1 *  ~~~(x &&&  ~~~x) - 5 *  ~~~y - 5 * (x ^^^ y) + 3 *  ~~~(x &&& y) + 1 *  ~~~(x ||| y) - 3 *  ~~~(x |||  ~~~y) + 5 * (x &&&  ~~~y) - 6 * (x &&& y) =  - 4 * y - 1 * x

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

lemma simulFun_sim_raw [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) f :
    m.SimulFun M f → m.Sim M

theorem zext_or_eq_ult_add_thm (e : IntW 32) :
  zext 32
      (LLVM.or (icmp IntPred.ult (add e (const? 32 (-3))) (const? 32 3)) (icmp IntPred.eq e (const? 32 5))) ⊑
    zext 32 (icmp IntPred.ult (add e (const? 32 (-3))) (const? 32 3))

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

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

theorem mul8_low_A0_B0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(4#8 ≥ ↑8 ∨ 4#8 ≥ ↑8 ∨ 4#8 ≥ ↑8) →
    (x_1 >>> 4#8 * x + x >>> 4#8 * x_1) <<< 4#8 + (x_1 &&& 15#8) * (x &&& 15#8) = x * x_1

theorem reassoc_mul_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 4#32 = true ∨ True ∧ (x * 4#32).umulOverflow 65#32 = true) →
    ¬(True ∧ x.umulOverflow 260#32 = true) → x * 4#32 * 65#32 = x * 260#32

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

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

theorem t2_proof : t2_before ⊑ t2_after

theorem zext_nneg_proof : zext_nneg_before ⊑ zext_nneg_after

theorem or_xor_tree_1001_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_2 (const? 32 42)) (mul e (const? 32 42))) ⊑
    LLVM.or (LLVM.xor (mul e_2 (const? 32 42)) (mul e (const? 32 42))) (mul e_1 (const? 32 42))

theorem bv_InstCombineShift__440 :
    ∀ (e e_1 e_2 e_3 : LLVM.IntW w),
      LLVM.shl (LLVM.xor e (LLVM.and (LLVM.lshr e_1 e_2) e_3)) e_2 ⊑
        LLVM.xor (LLVM.and e_1 (LLVM.shl e_3 e_2)) (LLVM.shl e e_2)

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

theorem e_2218 :
    4 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~d &&& (e ^^^ f)) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * (d ||| ( ~~~e ||| f)) + 1 * (d ||| (e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 7 *  ~~~(d &&& ( ~~~e &&& f)) + 5 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 5 * (e ^^^  ~~~(d ||| f)) - 2 * (e |||  ~~~(d ^^^ f)) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 6 * (d &&& (e ^^^ f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * (f ||| (d &&& e)) + 7 *  ~~~(d |||  ~~~f) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (e ^^^ (d |||  ~~~f)) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * ( ~~~d &&& (e ||| f)) + 2 * ( ~~~e &&& (d ^^^ f)) - 7 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 5 *  ~~~(d |||  ~~~e) + 2 * (f ^^^  ~~~(d ||| e)) + 1 * ( ~~~d ||| (e ||| f)) - 6 * (f &&&  ~~~(d &&& e)) + 11 * (f ||| (d &&&  ~~~e)) + 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 3 *  ~~~d - 7 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 7 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 *  ~~~(e ^^^ f) - 1 * (d ^^^ (e ||| f)) + 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 5 * (f |||  ~~~(d ||| e)) - 2 * (f ^^^ (d &&& e)) - 11 * (e &&& f) + 31 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 13 * ( ~~~d &&& ( ~~~e &&& f)) + 18 * ( ~~~d &&& (e &&& f)) + 22 * (d &&& ( ~~~e &&& f)) + 19 * (d &&& (e &&& f)) = 11 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f)))

theorem main6b_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 == 3#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    0#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 19#32))

theorem not_lshr_const_thm (e : IntW 8) : LLVM.xor (lshr (const? 8 42) e) (const? 8 (-1)) ⊑ ashr (const? 8 (-43)) e

theorem factorize4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬1#32 ≥ ↑32 → x_1 <<< 1#32 * x - x * x_1 = x_1 * x

theorem samesign_commute3_proof : samesign_commute3_before ⊑ samesign_commute3_after

theorem main10_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) = 1#1 → ofBool (x &&& 192#32 == 0#32) = 1#1 → ¬0#1 = 1#1 → 1#32 = 2#32

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

theorem nonexact_lshr_eq_noexactlog_proof : nonexact_lshr_eq_noexactlog_before ⊑ nonexact_lshr_eq_noexactlog_after

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

theorem trunc_ashr_trunc_exact_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ truncate 32 x >>> 8#32 <<< 8#32 ≠ truncate 32 x ∨ 8#32 ≥ ↑32) →
    True ∧ x >>> 8#64 <<< 8#64 ≠ x ∨ 8#64 ≥ ↑64 → False

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

@[simp] theorem Expr.comap_denote_contextHom (e : Expr d Γ .pure ty) (V : Γ.Valuation) :
    (Valuation.comap (e.denote V) e.contextHom) = V

theorem e_225 :
     - 3 * (x ||| y) - 1 *  ~~~y + 3 * (x |||  ~~~y) + 5 *  ~~~(x &&&  ~~~y) - 10 *  ~~~(x ||| y) + 3 * (x &&&  ~~~y) - 10 * (x &&& y) =  - 5 *  ~~~(x ^^^ y) + 2 *  ~~~(x &&& y)

theorem test_shift_and_cmp_changed1_thm (e e_1 : IntW 8) :
  icmp IntPred.slt
      (ashr (shl (LLVM.or (LLVM.and e_1 (const? 8 8)) (LLVM.and e (const? 8 6))) (const? 8 5)) (const? 8 5))
      (const? 8 1) ⊑
    icmp IntPred.slt (LLVM.and (shl e (const? 8 5)) (const? 8 (-64))) (const? 8 32)

theorem main4f_like_logical_thm.extracted_1._10 : ∀ (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 → 1#32 = zeroExtend 32 (ofBool (x_2 &&& x == x))

theorem cmpne_xor_cst3_proof : cmpne_xor_cst3_before ⊑ cmpne_xor_cst3_after

theorem icmp_sle2_proof : icmp_sle2_before ⊑ icmp_sle2_after

theorem shl1_trunc_sgt0_thm (e : IntW 9) :
  icmp IntPred.sgt (trunc 6 (shl (const? 9 1) e)) (const? 6 0) ⊑
    icmp IntPred.sgt (trunc 6 (shl (const? 9 1) e { «nsw» := false, «nuw» := true })) (const? 6 0)

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

theorem uge_or_not_max_commute_proof : uge_or_not_max_commute_before ⊑ uge_or_not_max_commute_after

theorem andn_or_cmp_4_logical_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == x_1) = 1#1 → ofBool (x_2 != x_1) = 1#1 → ¬True → ofBool (x_2 != x_1) = ofBool (42#32 <ᵤ x)

@[simp]
theorem toBitVec_neg (a : BitStream) :
    (- a).toBitVec w = - (a.toBitVec w)

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

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

theorem or2_proof : or2_before ⊑ or2_after

theorem mul_splat_fold_no_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 65537#32 = true ∨ 16#32 ≥ ↑32) →
    ¬(16#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x >>> 16#32) = true) → (x * 65537#32) >>> 16#32 = x + x >>> 16#32

theorem and_ne_with_diff_one_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne e (const? 32 40)) (icmp IntPred.ne e (const? 32 39)) ⊑
    icmp IntPred.ult (add e (const? 32 (-41))) (const? 32 (-2))

theorem e_2304 :
     - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * (f ^^^ (d &&& (e ||| f))) + 1 * ((d &&& e) ^^^ (e ||| f)) - 2 * (f &&& (d |||  ~~~e)) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 5 * (d ||| (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 2 * (e ^^^ (d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 11 * (e &&&  ~~~f) + 3 * (e &&&  ~~~(d &&& f)) - 2 * (e ||| (d &&&  ~~~f)) - 1 *  ~~~(d &&&  ~~~f) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~d ||| (e ||| f)) - 11 * (f ^^^ (d &&&  ~~~e)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 *  ~~~(d ||| (e ^^^ f)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 3 * ( ~~~d &&& (e ^^^ f)) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 * (f ^^^ (d ||| (e ||| f))) + 11 *  ~~~(d |||  ~~~e) - 5 * (d &&& e) - 3 *  ~~~(d ||| (e &&& f)) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 7 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * (d ^^^ ( ~~~e ||| f)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 3 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (e ^^^ f) - 1 * (d &&& ( ~~~e ||| f)) - 1 * (e |||  ~~~(d ||| f)) - 6 * (d &&& (e ||| f)) + 2 * (e ||| (d ^^^ f)) + 26 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) + 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) + 41 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) = 2 * (e ^^^  ~~~(d &&& f)) - 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f)))

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

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

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

theorem samesign_inverted_commute3_proof : samesign_inverted_commute3_before ⊑ samesign_inverted_commute3_after

theorem and_zext_eq_odd_commuted_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x == 3#32)) &&& x = zeroExtend 32 (ofBool (x == 3#32))

theorem test6_thm (e : IntW 32) :
  icmp IntPred.ugt (LLVM.udiv (const? 32 5) e) (const? 32 0) ⊑ icmp IntPred.ult e (const? 32 6)

theorem test_proof : test_before ⊑ test_after

theorem or_and_not_not_commute2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ((x_2 ||| x_1) ^^^ -1#32) &&& x ||

theorem sext_zext_slt_known_nonneg_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 <ₛ zeroExtend 32 (x &&& 126#8)) = ofBool (x_1 <ₛ x &&& 126#8)

theorem icmp_power2_and_icmp_shifted_mask_8_6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 8#32) &&& ofBool (x &&& 6#32 != 6#32) = ofBool (x <ᵤ 6#32)

theorem land_lor_left1_proof : land_lor_left1_before ⊑ land_lor_left1_after

theorem cv2_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (LLVM.and (lshr (const? 8 (-1)) e_1) e) e ⊑ const? 1 1

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

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 → (x ^^^ 1234#32) >>> 16#32 + (x ^^^ 1234#32) = x >>> 16#32 + (x ^^^ 1234#32)

theorem differentconsts_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 16)) (const? 32 144)) (trunc 16 e)
      (select (icmp IntPred.slt e (const? 32 128)) (const? 16 256) (const? 16 (-1))) ⊑
    select (icmp IntPred.sgt e (const? 32 127)) (const? 16 (-1))
      (select (icmp IntPred.slt e (const? 32 (-16))) (const? 16 256) (trunc 16 e))

theorem PR42691_2_logical_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 (-2147483648))) (const? 1 1) (icmp IntPred.eq e (const? 32 (-1))) ⊑
    icmp IntPred.sgt e (const? 32 (-2))

theorem urem_illegal_type_proof : urem_illegal_type_before ⊑ urem_illegal_type_after

theorem e_329 :
     - 3 *  ~~~y - 1 *  ~~~x + 5 * (x ||| y) + 5 * y - 11 * (x ^^^ y) - 7 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 19 * (x &&& y) = 2 * x - 11 *  ~~~(x &&&  ~~~x)

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 1), zeroExtend 32 (zeroExtend 8 x) = zeroExtend 32 x

theorem test13_proof : test13_before ⊑ test13_after

theorem icmp_eq_mul_nsw_nonequal_commuted_proof : icmp_eq_mul_nsw_nonequal_commuted_before ⊑ icmp_eq_mul_nsw_nonequal_commuted_after

theorem test_invert_demorgan_logical_and_proof : test_invert_demorgan_logical_and_before ⊑ test_invert_demorgan_logical_and_after

theorem ashrsgt_02_00_exact_proof : ashrsgt_02_00_exact_before ⊑ ashrsgt_02_00_exact_after

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

theorem test1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 57), ¬(x_1 ≥ ↑57 ∨ x_1 ≥ ↑57) → x_1 ≥ ↑57 → False

theorem test5_proof : test5_before ⊑ test5_after

theorem and_ne_with_one_bit_diff_constants1_proof : and_ne_with_one_bit_diff_constants1_before ⊑ and_ne_with_one_bit_diff_constants1_after

theorem main7b_logical_thm.extracted_1._9 : ∀ (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 → 0#1 = 1#1 → 0#32 = zeroExtend 32 1#1

theorem alive_Select_699 : 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 uge  w %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v2;
  %v8 := op:icmp uge  w %v7;
  %v9 := triple:%v8 %v6 %v2;
  %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 uge  1 %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v2;
  %v8 := op:icmp uge  1 %v7;
  %v9 := triple:%v4 %v1 %v2;
  %v10 := op:select 1 %v9
  dsl_ret %v10
  ]

theorem t0_thm.extracted_1._27 : ∀ (x x_1 x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 ^^^ 1#1 = 1#1 → ¬x_4 = 1#1 → True → 0#1 = 1#1 → x_1 = x

theorem mul_select_zext_proof : mul_select_zext_before ⊑ mul_select_zext_after

theorem and_consts_logical_proof : and_consts_logical_before ⊑ and_consts_logical_after

theorem AvoidCollision_setWidth_ofNat_one_eq_ofNat_one_of_lt {v w : Nat} (hv : 0 < v) :
    (BitVec.ofNat v 1).setWidth w = BitVec.ofNat w 1

theorem test0_proof : test0_before ⊑ test0_after

theorem select_icmp_and_2147483648_eq_0_xor_2147483648_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& BitVec.ofInt 32 (-2147483648) == 0#32) = 1#1 →
    x ^^^ BitVec.ofInt 32 (-2147483648) = x ||

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

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

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

theorem unmasked_shlop_insufficient_mask_shift_amount_proof : unmasked_shlop_insufficient_mask_shift_amount_before ⊑ unmasked_shlop_insufficient_mask_shift_amount_after

theorem e_1065 :
    1 *  ~~~(z &&& t) - 7 *  ~~~(z &&&  ~~~t) + 1 * (z |||  ~~~t) - 6 * z + 5 *  ~~~(z ||| t) + 4 * (z &&&  ~~~t) + 12 * (z &&& t) =  - 6 *  ~~~(z |||  ~~~t)

theorem test_nuw_nsw_and_unsigned_pred_proof : test_nuw_nsw_and_unsigned_pred_before ⊑ test_nuw_nsw_and_unsigned_pred_after

theorem test18_thm (e : IntW 11) : icmp IntPred.eq (lshr e (const? 11 10)) (const? 11 123) ⊑ const? 1 0

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

theorem select_replace_one_use_proof : select_replace_one_use_before ⊑ select_replace_one_use_after

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

theorem main4b_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

theorem set_to_set_decomposebittest_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ 0#8) = 1#1 → True ∧ (x &&& BitVec.ofInt 8 (-128) &&& 3#8 != 0) = true → False

theorem test_ne_0_and_15_add_1_proof : test_ne_0_and_15_add_1_before ⊑ test_ne_0_and_15_add_1_after

theorem ne_basic_equal_minus_7_proof : ne_basic_equal_minus_7_before ⊑ ne_basic_equal_minus_7_after

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

theorem test7_thm (e e_1 : IntW 32) :
  LLVM.xor (LLVM.and e_1 (const? 32 7)) (LLVM.and e (const? 32 128)) ⊑
    LLVM.or (LLVM.and e_1 (const? 32 7)) (LLVM.and e (const? 32 128)) { «disjoint» := true }

theorem t0_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smod (BitVec.ofInt 8 (-32)) ≠ 0 ∨
        (BitVec.ofInt 8 (-32) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-32) == -1) = true) →
    ¬(True ∧ x >>> 5#8 <<< 5#8 ≠ x ∨ 5#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 5#8) = true) →
      x.sdiv (BitVec.ofInt 8 (-32)) = 0#8 - x.sshiftRight' 5#8

theorem test_zext4_thm (e e_1 : IntW 1) :
  select e_1 (zext 32 e) (const? 32 1) ⊑ zext 32 (select (LLVM.xor e_1 (const? 1 1)) (const? 1 1) e)

theorem select_constants_and_icmp_eq0_zero_tval_proof : select_constants_and_icmp_eq0_zero_tval_before ⊑ select_constants_and_icmp_eq0_zero_tval_after

theorem e_1443 :
     - 1 * z - 3 *  ~~~(z &&& t) - 7 *  ~~~t + 11 *  ~~~z + 11 *  ~~~(z &&&  ~~~z) - 1 * (z |||  ~~~t) - 10 *  ~~~(z ||| t) - 19 *  ~~~(z |||  ~~~t) + 1 * (z &&&  ~~~t) - 8 * (z &&& t) = 1 *  ~~~(z ^^^ t)

theorem sub_mask1_lshr_thm (e : IntW 8) :
  sub (const? 8 10) (LLVM.and (lshr e (const? 8 1)) (const? 8 1)) ⊑
    add (ashr (shl e (const? 8 6)) (const? 8 7)) (const? 8 10) { «nsw» := true, «nuw» := false }

theorem xor_and_thm.extracted_1._8 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_2 ^^^ 1#1 = 1#1 → 0#1 ^^^ 1#1 = ofBool (x ≤ᵤ x_1)

theorem test_add_nuw__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 or_xor_tree_1010_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  x_2 * 42#32 ^^^ x_1 * 42#32 ^^^ x * 42#32 ||

lemma NFA'.correct2_spec {M : NFA' 2} {ζ : M.sa2} {L : BVRel} :
    M.correct2 ζ L → M.accepts = langRel2 L

theorem differentconsts_thm.extracted_1._5 : ∀ (x : BitVec 32),
  ¬ofBool (x + 16#32 <ᵤ 144#32) = 1#1 →
    ¬ofBool (x <ₛ 128#32) = 1#1 →
      ¬ofBool (127#32 <ₛ x) = 1#1 → ofBool (x <ₛ BitVec.ofInt 32 (-16)) = 1#1 → -1#16 = 256#16

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

theorem test14_proof : test14_before ⊑ test14_after

@[simp] theorem borrow_succ (x y : BitStream) : (x.borrow y (i+1)) =
  let borrow := borrow x y i
  let a := x (i + 1)
  let b := y (i + 1)
  !a && b |

theorem and_or1_wrong_operand_thm (e e_1 e_2 e_3 : IntW 1) :
  select (LLVM.or (LLVM.xor e_3 (const? 1 1)) e_2) e_1 e ⊑
    select (LLVM.or e_2 (LLVM.xor e_3 (const? 1 1))) e_1 e

theorem e_432 :
     - 11 *  ~~~(x &&&  ~~~y) - 1 *  ~~~(x &&& y) + 2 * x - 11 *  ~~~(x &&&  ~~~x) + 2 * y + 23 *  ~~~(x ||| y) + 21 *  ~~~(x |||  ~~~y) + 10 * (x &&&  ~~~y) =  - 18 * (x &&& y)

theorem test_and3_proof : test_and3_before ⊑ test_and3_after

theorem test_and4_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge (LLVM.and e_1 (const? 32 2147483647)) e) (icmp IntPred.sge e (const? 32 0))
      (const? 1 0) ⊑
    icmp IntPred.ule e (LLVM.and e_1 (const? 32 2147483647))

theorem f_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.srem (LLVM.or e (const? 32 1)) (const? 32 1)) (const? 32 0) ⊑ const? 1 0

theorem zext_sext_add_icmp_ugt_1_thm (e e_1 : IntW 1) :
  icmp IntPred.ugt (add (zext 8 e_1) (sext 8 e)) (const? 8 1) ⊑ LLVM.and e (LLVM.xor e_1 (const? 1 1))

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

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

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

theorem shl_add_and_fail_mismatch_shift_proof : shl_add_and_fail_mismatch_shift_before ⊑ shl_add_and_fail_mismatch_shift_after

theorem lshrult_02_13_exact_proof : lshrult_02_13_exact_before ⊑ lshrult_02_13_exact_after

theorem test21_thm (e : IntW 8) : LLVM.and (ashr e (const? 8 7)) (const? 8 1) ⊑ lshr e (const? 8 7)

theorem MatchVar.isMonotone_unifyVars  : IsMonotone (unifyVars w v)

theorem icmp_select_implied_cond_relational_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (select (icmp IntPred.ugt e_1 (const? 8 10)) (const? 8 10) e) e_1 ⊑
    select (icmp IntPred.ugt e_1 (const? 8 10)) (const? 1 1) (icmp IntPred.ult e e_1)

theorem shl_xor_xor_bad_mask_distribute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) → 1#8 ≥ ↑8 → False

theorem test_lshr__exact_is_unsafe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 63)) (const? 32 0)) e
      (ashr e (zext 64 (lshr (LLVM.and e_1 (const? 32 63)) (const? 32 2)))) ⊑
    ashr e (zext 64 (LLVM.and (lshr e_1 (const? 32 2)) (const? 32 15)) { «nneg» := true })

theorem eval_congrEnv {p : FSM arity}
    {x y : arity → BitStream} {n : Nat} (h : ∀ a i, i ≤ n → x a i = y a i) :
    p.eval x n = p.eval y n

theorem e_1066 :
    5 * (z ||| t) + 2 *  ~~~z + 1 *  ~~~(z &&&  ~~~z) + 11 * z - 3 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 17 * (z &&& t) = 18 * (z &&&  ~~~t) - 1 * (z ^^^ t)

theorem positive_trunc_signbit_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (-1#8 <ₛ truncate 8 x) &&& ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x <ᵤ 128#32)

theorem ashr_ult_2_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 2) ⊑ icmp IntPred.ult e (const? 4 4)

theorem udiv_shl_mul_nuw_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 }) ⊑
    LLVM.udiv (shl (const? 5 1) e_1 { «nsw» := false, «nuw» := true }) e

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

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

theorem test_negative_combined_sub_signed_overflow_thm (e : IntW 8) :
  icmp IntPred.slt (sub (const? 8 127) e { «nsw» := true, «nuw» := false }) (const? 8 (-1)) ⊑ const? 1 0

theorem e_1107 :
    11 * (z ^^^ t) + 11 *  ~~~z - 1 * (z |||  ~~~t) - 3 *  ~~~(z ^^^ t) - 12 *  ~~~(z ||| t) - 20 *  ~~~(z |||  ~~~t) - 15 * (z &&&  ~~~t) + 11 * (z &&& t) =  - 5 *  ~~~(z &&& t) + 7 * t

theorem alive_AddSub_1152   : alive_AddSub_1152_src ⊑ alive_AddSub_1152_tgt

theorem t9_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), 0#8 - (x_1 - x) = x - x_1

theorem lshrult_03_09_proof : lshrult_03_09_before ⊑ lshrult_03_09_after

theorem e_1570 :
    1 * (c |||  ~~~(a ^^^ b)) - 7 *  ~~~(a ^^^ ( ~~~b &&& c)) + 2 * (a ^^^ (b &&& c)) - 5 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (a &&& (b ^^^ c)) - 7 * (b &&& c) - 1 * (c ^^^  ~~~(a ||| b)) + 18 *  ~~~(a ||| (b ||| c)) + 6 *  ~~~( ~~~a ||| (b ||| c)) + 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 15 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) = 3 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 10 *  ~~~(a ||| ( ~~~b ||| c))

theorem gt_unsigned_to_large_negative_thm (e : IntW 8) : icmp IntPred.sgt (zext 32 e) (const? 32 (-1024)) ⊑ const? 1 1

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

theorem not_or_or_and_not_and_and_commute1_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 (LLVM.and e e_2) e_1) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.xor e e_1) (LLVM.xor e_2 (const? 32 (-1)))

theorem BitVec.any_iff_exists {bv : BitVec w} :
    bv.any p ↔ ∃ (i : Fin w), p i (bv.getLsbD i)

theorem eq_gen (w : Nat) (a b : BitVec w) : (a &&& b = 0#w) → ((a + b) = (a ||| b))

theorem e_887 :
    5 *  ~~~(z &&& t) + 11 *  ~~~t - 15 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) - 16 * (z &&&  ~~~t) + 1 * (z &&& t) = 1 *  ~~~(z &&&  ~~~t)

theorem max_sub_ult_c0_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 0)) (add e (const? 32 (-1))) (const? 32 0) ⊑ const? 32 0

theorem sle_or_not_min_commute_logical_proof : sle_or_not_min_commute_logical_before ⊑ sle_or_not_min_commute_logical_after

theorem src_is_notmask_ashr_proof : src_is_notmask_ashr_before ⊑ src_is_notmask_ashr_after

theorem positive_sameconst_shlnsw_proof : positive_sameconst_shlnsw_before ⊑ positive_sameconst_shlnsw_after

theorem sub_ashr_or_i32_proof : sub_ashr_or_i32_before ⊑ sub_ashr_or_i32_after

theorem icmp_slt_0_xor_icmp_sgt_neg2_i32_proof : icmp_slt_0_xor_icmp_sgt_neg2_i32_before ⊑ icmp_slt_0_xor_icmp_sgt_neg2_i32_after

theorem sext_sext_slt_thm (e e_1 : IntW 8) :
  icmp IntPred.slt (sext 32 e_1) (sext 32 e) ⊑ icmp IntPred.slt e_1 e

theorem icmp_shl_eq_1_proof : icmp_shl_eq_1_before ⊑ icmp_shl_eq_1_after

theorem t9_nocse_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬(True ∧ 1#8 <<< x >>> x ≠ 1#8 ∨ x ≥ ↑8 ∨ True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8) →
      1#8 <<< x + -1#8 ||

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

theorem test3_logical_proof : test3_logical_before ⊑ test3_logical_after

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

theorem e_2410 :
    7 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 7 * (e ^^^  ~~~(d &&& f)) + 1 * ( ~~~e &&& (d ^^^ f)) - 6 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 1 *  ~~~(e &&&  ~~~f) + 2 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 2 * ((d ^^^ e) &&& (d ^^^ f)) - 5 *  ~~~f - 1 * (e |||  ~~~(d ^^^ f)) - 2 * (f ^^^ (d &&&  ~~~e)) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 3 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 1 *  ~~~(e &&& f) + 5 * ((d ^^^ e) ||| (d ^^^ f)) + 4 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 4 * ((d |||  ~~~e) &&& (e ^^^ f)) - 11 * (e ^^^ (d &&& (e ^^^ f))) + 1 * (e ^^^ (d ||| ( ~~~e ||| f))) + 1 * (e ||| (d &&&  ~~~f)) + 4 * (e &&& (d ||| f)) + 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 2 * (d |||  ~~~e) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 1 * (e ^^^ (d ||| (e &&& f))) + 5 * (f ^^^ (d ||| e)) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 4 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d ^^^ (e ||| f)) - 11 *  ~~~(d |||  ~~~f) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 *  ~~~(d &&& f) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ (e &&& f)) + 3 * ( ~~~f ||| (d ^^^ e)) + 7 * (e ^^^ (d &&& f)) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 3 * (f ^^^  ~~~(d &&&  ~~~e)) + 11 * (e &&& f) + 5 * (d ||| e) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 7 *  ~~~(d ||| e) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 3 * (f ^^^ (d |||  ~~~e)) - 7 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 3 * ( ~~~f &&& (d ^^^ e)) - 6 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 7 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * (f &&& (d |||  ~~~e)) + 11 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 3 * (f |||  ~~~(d |||  ~~~e)) + 1 *  ~~~(d &&& (e &&& f)) - 3 * ((d &&& f) ^^^ (e ||| f)) + 1 *  ~~~(d |||  ~~~e) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * (d ^^^ ( ~~~e &&& f)) - 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 15 *  ~~~(d ||| (e ||| f)) - 30 *  ~~~(d ||| ( ~~~e ||| f)) - 6 *  ~~~( ~~~d ||| (e ||| f)) - 24 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 18 * ( ~~~d &&& ( ~~~e &&& f)) - 6 * ( ~~~d &&& (e &&& f)) - 1 * (d &&& ( ~~~e &&& f)) - 4 * (d &&& (e &&& f)) =  - 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f)))

theorem sub_to_xor_proof : sub_to_xor_before ⊑ sub_to_xor_after

theorem icmp_sle4_proof : icmp_sle4_before ⊑ icmp_sle4_after

theorem sdiv_exact_eq_9_no_of_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.sdiv e_1 (LLVM.and e (const? 8 7)) { «exact» := true }) (const? 8 9) ⊑
    icmp IntPred.eq (mul (LLVM.and e (const? 8 7)) (const? 8 9) { «nsw» := true, «nuw» := true }) e_1

theorem test1_proof : test1_before ⊑ test1_after

theorem eval_fsmTermUle_eq_decide_le {wcard tcard : Nat}
    (tctx : Term.Ctx wcard tcard)
    {wenv : WidthExpr.Env wcard}
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (w : WidthExpr wcard)
    (a : Term bcard ncard icard pcard tctx (.bv w))
    (b : Term bcard ncard icard pcard tctx (.bv w))
    (afsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm a))
    (hafsm : HTermFSMToBitStream afsm)
    (bfsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm b))
    (hbfsm : HTermFSMToBitStream bfsm)
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (henv : HTermEnv fsmEnv tenv benv)
    :
    ((fsmTermUle
      afsm
      bfsm)).eval fsmEnv i =
       decide (((a.toBV benv nenv ienv penv tenv).setWidth i) ≤ ((b.toBV benv nenv ienv penv tenv).setWidth i))

theorem sub_shl_same_amount_partial_nsw1_proof : sub_shl_same_amount_partial_nsw1_before ⊑ sub_shl_same_amount_partial_nsw1_after

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 narrow_sext_and_proof : narrow_sext_and_before ⊑ narrow_sext_and_after

theorem not_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬42#8 = 0 → (-1#8 ^^^ x) * (x / 42#8) = x / 42#8 * (x ^^^ -1#8)

@[simp]
lemma complete_cast {M : NFA α σ} (h : σ = ς) : (h ▸ M).Complete ↔ M.Complete

theorem e_2448 :
     - 2 *  ~~~(d ^^^ e) - 1 * (f ^^^  ~~~(d &&& (e &&& f))) + 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 7 * (d ^^^ f) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~(d ||| ( ~~~e &&& f)) - 11 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * (e &&& (d ^^^ f)) + 5 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 *  ~~~(d &&& (e ||| f)) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * (e &&& f) - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d ^^^ f) - 6 * (f ^^^  ~~~(d ||| e)) - 1 * (d &&&  ~~~e) - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 11 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 11 *  ~~~(d ^^^ (e ^^^ f)) - 6 * ( ~~~f &&& (d ^^^ e)) + 5 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (d ||| ( ~~~e &&& f)) + 7 * (e ^^^ (d ||| ( ~~~e ||| f))) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 6 * ((d ^^^ e) ||| (d ^^^ f)) + 4 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * (e ^^^  ~~~(d ||| f)) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * (f ^^^ (d &&& ( ~~~e ||| f))) + 4 * (d |||  ~~~f) - 3 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 7 * (f &&&  ~~~(d ^^^ e)) - 1 * ((d &&& f) ^^^ (e ||| f)) + 1 * (f ^^^  ~~~(d &&& e)) + 1 * ( ~~~d ||| (e &&& f)) - 2 *  ~~~( ~~~d &&& (e ||| f)) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) + 7 * ( ~~~d &&& (e ||| f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e |||  ~~~(d ^^^ f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 3 *  ~~~(d &&&  ~~~d) - 3 *  ~~~( ~~~d ||| (e &&& f)) - 2 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 3 * (e |||  ~~~(d ||| f)) - 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 2 * (f |||  ~~~(d ^^^ e)) - 3 * (d ||| (e &&& f)) + 11 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 11 * (e ^^^ (d &&& f)) + 4 * (f ^^^  ~~~(d ||| (e &&& f))) + 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 27 *  ~~~(d ||| (e ||| f)) - 68 *  ~~~(d ||| ( ~~~e ||| f)) - 21 *  ~~~( ~~~d ||| (e ||| f)) - 37 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 6 * ( ~~~d &&& ( ~~~e &&& f)) - 33 * ( ~~~d &&& (e &&& f)) - 8 * (d &&& ( ~~~e &&& f)) + 3 * (d &&& (e &&& f)) =  - 1 * (e ^^^ ( ~~~d &&& (e ||| f)))

theorem test10_proof : test10_before ⊑ test10_after

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 16), truncate 16 (signExtend 32 x &&& 15#32) = x &&& 15#16

theorem select_replace_nested_no_simplify_proof : select_replace_nested_no_simplify_before ⊑ select_replace_nested_no_simplify_after

theorem src_x_and_nmask_uge_thm (e : IntW 8) (e_1 : IntW 1) (e_2 : IntW 8) :
  icmp IntPred.uge (LLVM.and e_2 (select e_1 (shl (const? 8 (-1)) e) (const? 8 0)))
      (select e_1 (shl (const? 8 (-1)) e) (const? 8 0)) ⊑
    select (LLVM.xor e_1 (const? 1 1)) (const? 1 1)
      (icmp IntPred.ule (shl (const? 8 (-1)) e { «nsw» := true, «nuw» := false }) e_2)

theorem zext_sext_add_icmp_eq_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (zeroExtend 8 x_1 + signExtend 8 x == 1#8) = x_1 &&& (x ^^^ 1#1)

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

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

@[bv_automata_preprocess] theorem BitVec.two_mul (x : BitVec w) : 2#w * x = x + x

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

theorem positive_biggershl_shlnuwnsw_lshrexact_thm (e : IntW 8) :
  shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 6) { «nsw» := true, «nuw» := true } ⊑
    shl e (const? 8 3) { «nsw» := true, «nuw» := true }

theorem testi64i32_ne_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(31#32 ≥ ↑32 ∨ 32#64 ≥ ↑64) →
    ofBool ((truncate 32 x).sshiftRight' 31#32 != truncate 32 (x >>> 32#64)) =
      ofBool (x + BitVec.ofInt 64 (-2147483648) <ᵤ BitVec.ofInt 64 (-4294967296))

theorem shl_lshr_pow2_const_case2_proof : shl_lshr_pow2_const_case2_before ⊑ shl_lshr_pow2_const_case2_after

theorem add_shl_same_amount_partial_nuw2_thm (e e_1 e_2 : IntW 6) :
  add (shl e_2 e_1 { «nsw» := false, «nuw» := true }) (shl e e_1) { «nsw» := false, «nuw» := true } ⊑
    shl (add e_2 e) e_1

theorem trunc_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬8#36 ≥ ↑36 →
    ¬8#32 ≥ ↑32 →
      truncate 32 ((zeroExtend 36 x ||| BitVec.ofInt 36 (-2147483648)).sshiftRight' 8#36) =
        x >>> 8#32 ||

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

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

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

theorem t8_twoshifts3_proof : t8_twoshifts3_before ⊑ t8_twoshifts3_after

theorem ashrsgt_02_07_exact_proof : ashrsgt_02_07_exact_before ⊑ ashrsgt_02_07_exact_after

theorem ult_and_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ᵤ x) = 1#1 → ofBool (x_1 == -1#8) = 0#1

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

theorem not_and_and_or_not_or_or_commute2_or_proof : not_and_and_or_not_or_or_commute2_or_before ⊑ not_and_and_or_not_or_or_commute2_or_after

theorem select_icmp_eq_and_1_0_lshr_tv_thm.extracted_1._4 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 &&& 1#8 != 0#8) = 1#1 → ¬(1#8 ≥ ↑8 ∨ x_1 <<< 1#8 &&& 2#8 ≥ ↑8) → x = x >>> (x_1 <<< 1#8 &&& 2#8)

theorem bv_276_2 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.udiv e_1 e) (LLVM.sub (LLVM.const? 5 0) e) ⊑ LLVM.sub (LLVM.urem e_1 e) e_1

theorem lsb_mask_sign_sext_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (x + -1#32 &&& (x ^^^ -1#32)).sshiftRight' 31#32 = signExtend 32 (ofBool (x == 0#32))

theorem test2_proof : test2_before ⊑ test2_after

theorem or_signbit_lshr_proof : or_signbit_lshr_before ⊑ or_signbit_lshr_after

theorem or_nosignbit_shl_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ||| 2147418112#32) <<< 8#32 = x <<< 8#32 ||

theorem test_invert_demorgan_or2_thm (e e_1 e_2 : IntW 64) :
  LLVM.xor
      (LLVM.or (LLVM.or (icmp IntPred.ugt e_2 (const? 64 23)) (icmp IntPred.ugt e_1 (const? 64 59)))
        (icmp IntPred.ugt e (const? 64 59)))
      (const? 1 1) ⊑
    LLVM.and (LLVM.and (icmp IntPred.ult e_2 (const? 64 24)) (icmp IntPred.ult e_1 (const? 64 60)))
      (icmp IntPred.ult e (const? 64 60))

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

theorem not_signbit_trunc_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬15#16 ≥ ↑16 → truncate 8 ((x ^^^ -1#16) >>> 15#16) = zeroExtend 8 (ofBool (-1#16 <ₛ x))

theorem uge_umin2_proof : uge_umin2_before ⊑ uge_umin2_after

theorem and_or1_wrong_operand_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 1),
  ¬x_3 ^^^ 1#1 ||

theorem not_not_true_proof : not_not_true_before ⊑ not_not_true_after

theorem ne_irregular_bit_widths_thm (e e_1 : IntW 31) :
  LLVM.or (icmp IntPred.ne (trunc 5 (lshr e_1 (const? 31 13))) (trunc 5 (lshr e (const? 31 13))))
      (icmp IntPred.ne (trunc 6 (lshr e_1 (const? 31 7))) (trunc 6 (lshr e (const? 31 7)))) ⊑
    icmp IntPred.ne (trunc 11 (lshr e_1 (const? 31 7))) (trunc 11 (lshr e (const? 31 7)))

theorem test27_proof : test27_before ⊑ test27_after

theorem main7e_logical_thm.extracted_1._13 : ∀ (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 1#1

theorem ashr_ult_9_proof : ashr_ult_9_before ⊑ ashr_ult_9_after

theorem ashrslt_02_03_proof : ashrslt_02_03_before ⊑ ashrslt_02_03_after

theorem test56_proof : test56_before ⊑ test56_after

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

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

theorem udiv_i1_is_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ¬x = 0 → x_1 / x = x_1

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

theorem scalar_i8_lshr_and_signbit_eq_proof : scalar_i8_lshr_and_signbit_eq_before ⊑ scalar_i8_lshr_and_signbit_eq_after

theorem demorgan_nor_use2c_proof : demorgan_nor_use2c_before ⊑ demorgan_nor_use2c_after

theorem trunc_shl_ashr_var_proof : trunc_shl_ashr_var_before ⊑ trunc_shl_ashr_var_after

theorem slt_swap_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.sgt e e_1) ⊑
    icmp IntPred.ne e_1 (const? 8 127)

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 absdiff_proof : absdiff_before ⊑ absdiff_after

theorem or_signbit_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x ||| BitVec.ofInt 32 (-65536)) >>> 8#32 = x >>> 8#32 ||

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

theorem neg_eq_not_add_one (x : BitVec w) :
    -x = ~~~ x + 1#w

theorem exact_ashr_ne_exactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ BitVec.ofInt 8 (-80) >>> x <<< x ≠ BitVec.ofInt 8 (-80) ∨ x ≥ ↑8) →
    ofBool ((BitVec.ofInt 8 (-80)).sshiftRight' x != BitVec.ofInt 8 (-5)) = ofBool (x != 4#8)

theorem bitwise_and_logical_and_masked_icmp_allones_proof : bitwise_and_logical_and_masked_icmp_allones_before ⊑ bitwise_and_logical_and_masked_icmp_allones_after

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

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

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

theorem t1_sshr_proof : t1_sshr_before ⊑ t1_sshr_after

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

@[simp] theorem dropUntil_toCons : dropUntil (cons ty Γ) (Var.toCons v) = dropUntil Γ v

theorem select_icmp_ne_0_and_32_and_not_4096_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 32#32) = 1#1 → ¬ofBool (x_1 &&& 32#32 == 0#32) = 1#1 → x &&& BitVec.ofInt 32 (-4097) = x

theorem bitwise_and_logical_and_masked_icmp_allones_poison1_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 == x_1) = 1#1 →
    ¬ofBool (x_2 &&& (x_1 ||| 7#32) == x_1 ||| 7#32) = 1#1 → x &&& ofBool (x_2 &&& 7#32 == 7#32) = 0#1

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 logic_or_logic_and_3_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → 0#1 = 1#1

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

@[simp] theorem AttrDict.find_next (v : AttrValue φ)
  (l : List (AttrEntry φ)):
    AttrDict.find (AttrDict.mk (AttrEntry.mk n v :: l)) n' =
    if n == n' then some v else AttrDict.find (AttrDict.mk l) n'

theorem lt_unsigned_to_large_signed_thm (e : IntW 8) : icmp IntPred.slt (zext 32 e) (const? 32 1024) ⊑ const? 1 1

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

theorem shl_nsw_slt_1_proof : shl_nsw_slt_1_before ⊑ shl_nsw_slt_1_after

theorem test5_proof : test5_before ⊑ test5_after

theorem ashrslt_01_06_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 1)) (const? 4 6) ⊑ const? 1 1

theorem e_1919 :
    3 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 * ((a &&& b) |||  ~~~(b ||| c)) - 7 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 5 *  ~~~(a &&& (b ||| c)) - 3 * (c |||  ~~~(a ^^^ b)) + 1 * ((a &&& b) ^^^ (b |||  ~~~c)) + 1 * (b ^^^  ~~~(a &&& (b ||| c))) + 2 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 5 * (c ^^^ (a &&& ( ~~~b ||| c))) - 5 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) + 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 11 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 5 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 2 *  ~~~c - 11 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * (c &&&  ~~~(a &&& b)) - 5 * (c ^^^ (a ||| ( ~~~b &&& c))) + 7 * (b |||  ~~~(a |||  ~~~c)) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 * ( ~~~a ||| (b ||| c)) - 3 * b + 1 *  ~~~(a ^^^ c) + 1 * (a ||| c) + 3 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 2 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 4 * (c ||| (a &&& b)) + 3 * (c &&& (a |||  ~~~b)) + 2 * (b ^^^  ~~~(a ||| c)) - 6 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * (a &&& (b ||| c)) + 7 * (b ^^^ ( ~~~a ||| (b ||| c))) + 2 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 2 * (c ^^^ (a &&& b)) - 11 * (b ^^^ (a ||| (b ^^^ c))) + 4 * (b ^^^ (a ||| ( ~~~b ||| c))) + 3 *  ~~~(b ||| c) + 4 * ( ~~~a ||| ( ~~~b &&& c)) - 7 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 3 * (a &&& (b ^^^ c)) - 1 * (b &&& (a ||| c)) - 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 3 * (c &&&  ~~~(a &&&  ~~~b)) + 15 *  ~~~(a ||| (b ||| c)) + 6 *  ~~~(a ||| ( ~~~b ||| c)) + 26 *  ~~~( ~~~a ||| (b ||| c)) + 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 26 * ( ~~~a &&& ( ~~~b &&& c)) + 4 * ( ~~~a &&& (b &&& c)) - 7 * (a &&& ( ~~~b &&& c)) + 13 * (a &&& (b &&& c)) =  - 1 * ( ~~~b &&&  ~~~(a ^^^ c)) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c))

theorem test_sub_nuw__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))) { «nsw» := false, «nuw» := true }) ⊑
    sub (const? 32 (-2147483648)) (LLVM.or e (const? 32 (-2147483648))) { «nsw» := true, «nuw» := false }

theorem positive_samevar_lshrexact_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑8 ∨ x ≥ ↑8) → x_1 >>> x <<< x = x_1

theorem or_and_or_pat7_proof : or_and_or_pat7_before ⊑ or_and_or_pat7_after

@[grind =, simp]
lemma createSink_initials [LawfulBEq A] {m : RawCNFA A} : m.createSink.2.initials = m.initials.insert m.stateMax

theorem test16_thm.extracted_1._1 : ∀ (x : BitVec 16), 12#16 ≥ ↑16 ∨ 15#16 ≥ ↑16 → False

lemma CNFA.bv_recognizes_functional {m : CNFA n} :
    m.bv_recognizes L₁ → m.bv_recognizes L₂ → L₁ = L₂

theorem n8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 == 1#32) = 1#1 → ¬2#32 ≥ ↑32 → ofBool (x &&& 1#32 == 0#32) = 1#1 → x >>> 2#32 &&& 1#32 = 1#32

theorem mul_selectp2_x_non_const_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → ¬1#8 ≥ ↑8 → 2#8 * x = x <<< 1#8

theorem masked_and_notA_slightly_optimized_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (8#32 ≤ᵤ x) = 1#1 → ofBool (x &&& 39#32 != x) = ofBool (x &&& BitVec.ofInt 32 (-40) != 0#32)

theorem sub_ashr_or_i32_commute_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x.ssubOverflow x_1 = true ∨ 31#32 ≥ ↑32) →
    ¬ofBool (x <ₛ x_1) = 1#1 → x_1 ||

theorem multiuse2_proof : multiuse2_before ⊑ multiuse2_after

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 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 udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

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

theorem reassoc_x2_sub_nuw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.usubOverflow 4#32 = true ∨
        True ∧ x.usubOverflow 8#32 = true ∨ True ∧ (x_1 - 4#32).usubOverflow (x - 8#32) = true) →
    x_1 - 4#32 - (x - 8#32) = x_1 - x + 4#32

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

theorem test1_proof : test1_before ⊑ test1_after

theorem sub_const_const_sub_proof : sub_const_const_sub_before ⊑ sub_const_const_sub_after

theorem and_xor_commute4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x_1 = 0) → x_1 = 0 ∨ x = 0 → False

theorem e_302 :
     - 1 * x - 7 * (x |||  ~~~y) - 1 *  ~~~(x &&&  ~~~x) - 7 * (x ||| y) + 10 *  ~~~(x |||  ~~~y) + 16 * (x &&&  ~~~y) + 18 * (x &&& y) =  - 10 *  ~~~(x ||| y) + 2 *  ~~~(x &&&  ~~~y)

theorem e_1078 :
     - 2 *  ~~~z + 1 *  ~~~(z &&&  ~~~z) - 3 * z - 1 *  ~~~(z &&&  ~~~t) + 7 * (z ||| t) + 2 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) - 5 * (z &&&  ~~~t) =  - 7 * (z &&& t) + 11 * t

theorem logic_and_logic_or_5_proof : logic_and_logic_or_5_before ⊑ logic_and_logic_or_5_after

theorem test4_thm.extracted_1._1 : ∀ (x : BitVec 1023), 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 and_nosignbit_lshr_proof : and_nosignbit_lshr_before ⊑ and_nosignbit_lshr_after

@[simp]
theorem not_bne' {a b : Bool} : (!bne a b) = (a == b)

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

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

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

theorem neg_sgt_0_proof : neg_sgt_0_before ⊑ neg_sgt_0_after

theorem test33b_proof : test33b_before ⊑ test33b_after

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

theorem test8_proof : test8_before ⊑ test8_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 a_true_implies_b_false2_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬ofBool (x_1 == 10#8) = 1#1 → ¬ofBool (20#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) &&& x = 0#1

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

theorem foo2_proof : foo2_before ⊑ foo2_after

theorem select_xor_icmp_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

@[simp]
theorem eval_map (fsm : FSM arity) (f : arity → arity')
    (env' : arity' → BitStream):
    (fsm.map f).eval env' = fsm.eval (env' ∘ f)

theorem a_false_implies_b_true_proof : a_false_implies_b_true_before ⊑ a_false_implies_b_true_after

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

theorem t4_const_after_fold_lshr_shl_ne_thm (e e_1 e_2 : IntW 32) :
  icmp IntPred.ne (LLVM.and (shl e_2 (sub (const? 32 32) e_1)) (lshr e (add e_1 (const? 32 (-1))))) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and (lshr e (const? 32 31)) e_2) (const? 32 0)

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

theorem sge_swap_or_max_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ≤ₛ x) = 1#1 → 1#1 = ofBool (x_1 ≤ₛ x)

theorem not_xor_eq_and_sub_or_sub_one :
    ~~~ (x ^^^ y) = (x &&& y) - (x ||| y) - 1

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

@[simp, simp_sllvm]
theorem bind_eq (x : EffectM α) (f : α → EffectM β) (s) :
    (x >>= f) s = x s >>= (fun (x, s) => f x s)

theorem sgt_smin1_proof : sgt_smin1_before ⊑ sgt_smin1_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 udiv_i32_c_proof : udiv_i32_c_before ⊑ udiv_i32_c_after

theorem bv_AddSub_1043 :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.add (LLVM.add (LLVM.xor (LLVM.and e_1 e) e) (LLVM.const? w 1)) e_2 ⊑ LLVM.sub e_2 (LLVM.or e_1 (LLVM.not e))

theorem xor_notand_to_or_not2_proof : xor_notand_to_or_not2_before ⊑ xor_notand_to_or_not2_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 lshr_xor_or_good_mask_thm (e e_1 : IntW 8) :
  LLVM.or (lshr e_1 (const? 8 4)) (LLVM.xor (lshr e (const? 8 4)) (const? 8 48)) ⊑
    LLVM.or (lshr (LLVM.or e e_1) (const? 8 4)) (const? 8 48) { «disjoint» := true }

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

theorem a_false_implies_b_false2_comm_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (20#8 <ᵤ x_2) = 1#1 → ofBool (10#8 <ᵤ x_2) = 1#1 → x_1 ||

theorem test11_thm (e : IntW 737) :
  icmp IntPred.ne (LLVM.and e (const? 737 (-2147483648))) (const? 737 0) ⊑
    icmp IntPred.ugt e (const? 737 2147483647)

theorem test46_proof : test46_before ⊑ test46_after

@[aesop 50% unsafe]
theorem Std.HashMap.get?_none_not_mem [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] {m : Std.HashMap K V} {k : K} : m.get? k = none → k ∉ m

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

theorem f_thm (e : IntW 32) :
  select (icmp IntPred.slt e (const? 32 0)) (const? 1 1) (icmp IntPred.sgt e (ashr (const? 32 7) e)) ⊑
    select (icmp IntPred.slt e (const? 32 0)) (const? 1 1)
      (icmp IntPred.sgt e (lshr (const? 32 7) e))

theorem fold_sext_to_and_wrong6_proof : fold_sext_to_and_wrong6_before ⊑ fold_sext_to_and_wrong6_after

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

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 test46_thm (e e_1 : IntW 32) :
  LLVM.and e_1 (LLVM.or (LLVM.xor e_1 (const? 32 (-1))) e) ⊑ LLVM.and e_1 e

theorem addhshlhsdivhscalar2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((BitVec.ofInt 32 (-1073741824) == 0 || 32 != 1 && x == intMin 32 && BitVec.ofInt 32 (-1073741824) == -1) = true ∨
        30#32 ≥ ↑32) →
    ¬(1073741824#32 == 0 || 32 != 1 && x == intMin 32 && 1073741824#32 == -1) = true →
      x.sdiv (BitVec.ofInt 32 (-1073741824)) <<< 30#32 + x = x.srem 1073741824#32

theorem select_sub_icmp_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32), ofBool (x_2 == 0#32) = 1#1 → x_1 - x_2 = x_1

theorem sub_ule_sext_proof : sub_ule_sext_before ⊑ sub_ule_sext_after

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 sdiv400_yes_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2#32 ≥ ↑32 ∨ (100#32 == 0 || 32 != 1 && x >>> 2#32 == intMin 32 && 100#32 == -1) = true) →
    ¬400#32 = 0 → (x >>> 2#32).sdiv 100#32 = x / 400#32

theorem not_and_and_or_not_or_or_commute1_and_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 e_2) e_1) (const? 32 (-1))) ⊑
    LLVM.xor (LLVM.or (LLVM.xor e e_1) e_2) (const? 32 (-1))

theorem positive_sameconst_shlnsw_lshrexact_thm (e : IntW 8) :
  shl (lshr e (const? 8 3) { «exact» := true }) (const? 8 3) { «nsw» := true, «nuw» := false } ⊑ e

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

theorem e_253 :
    11 * (x ||| y) + 2 *  ~~~y - 1 * (x |||  ~~~y) + 4 * y - 3 *  ~~~(x ||| y) - 12 * (x &&&  ~~~y) - 14 * (x &&& y) = 17 *  ~~~(x |||  ~~~y) - 2 *  ~~~x

theorem bar_proof : bar_before ⊑ bar_after

theorem eq_umin2_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (select (icmp IntPred.ult e_1 e) e_1 e) e ⊑ icmp IntPred.ule e e_1

theorem zext_eq_sext_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (zeroExtend 32 x_1 == signExtend 32 x) = (x_1 ||| x) ^^^ 1#1

theorem orn_and_cmp_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 37),
  ¬ofBool (x_2 ≤ₛ x_1) = 1#1 → x = 1#1 → ofBool (x_1 <ₛ x_2) = x

theorem select_icmp_sgt_allones_smin_flipped_proof : select_icmp_sgt_allones_smin_flipped_before ⊑ select_icmp_sgt_allones_smin_flipped_after

theorem positive_samevar_shlnuwnsw_lshrexact_proof : positive_samevar_shlnuwnsw_lshrexact_before ⊑ positive_samevar_shlnuwnsw_lshrexact_after

theorem icmp_power2_and_icmp_shifted_mask_swapped_8_6_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 6)) (const? 32 6)) (icmp IntPred.ult e (const? 32 8)) ⊑
    icmp IntPred.ult e (const? 32 6)

theorem fsmZext_eval_eq
    (wnewFsm : NatFSM wcard tcard bcard ncard icard pcard (.ofDep wnew))
    {wenv : WidthExpr.Env wcard}
    {fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream}
    (hwnew : HNatFSMToBitstream wnewFsm)
    {tctx : Term.Ctx wcard tcard}
    (tenv : Term.Ctx.Env tctx wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (t : Term bcard ncard icard pcard tctx (.bv w))
    (tFsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm t))
    (ht : HTermFSMToBitStream tFsm)
    (htenv : HTermEnv fsmEnv tenv benv)
    :
    (fsmZext tFsm.toFsmZext wnewFsm.toFsm).eval fsmEnv = fun i =>
      ((BitStream.ofBitVecZext ((Term.zext t wnew).toBV benv nenv ienv penv tenv))) i

theorem t15_proof : t15_before ⊑ t15_after

theorem sext_sub_const_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 42#64 - signExtend 64 x = 43#64

theorem test_add_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 2147483647#32) = 1#1 → True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true → False

theorem select_icmp_and_2147483648_eq_0_xor_2147483648_proof : select_icmp_and_2147483648_eq_0_xor_2147483648_before ⊑ select_icmp_and_2147483648_eq_0_xor_2147483648_after

theorem test_eq_0_and_15_add_1_proof : test_eq_0_and_15_add_1_before ⊑ test_eq_0_and_15_add_1_after

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

theorem positive_samevar_ashrexact_proof : positive_samevar_ashrexact_before ⊑ positive_samevar_ashrexact_after

theorem PR42691_3_proof : PR42691_3_before ⊑ PR42691_3_after

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

theorem test5_proof : test5_before ⊑ test5_after

theorem lshr_eq_msb_low_last_zero_proof : lshr_eq_msb_low_last_zero_before ⊑ lshr_eq_msb_low_last_zero_after

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

theorem reassoc_sub_nuw_proof : reassoc_sub_nuw_before ⊑ reassoc_sub_nuw_after

theorem add_or_sub_comb_i64_commuted4_proof : add_or_sub_comb_i64_commuted4_before ⊑ add_or_sub_comb_i64_commuted4_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_after

theorem xor_ashr_not_fail_invalid_xor_constant_thm (e e_1 e_2 : IntW 8) :
  LLVM.xor (ashr e_2 e_1) (LLVM.xor (ashr e e_1) (const? 8 (-2))) ⊑
    LLVM.xor (ashr (LLVM.xor e e_2) e_1) (const? 8 (-2))

theorem test_thm (e : IntW 64) :
  ashr (shl e (const? 64 16)) (const? 64 16) ⊑ ashr (shl e (const? 64 16)) (const? 64 16) { «exact» := true }

theorem foo1_or_signbit_lshr_without_shifting_signbit_proof : foo1_or_signbit_lshr_without_shifting_signbit_before ⊑ foo1_or_signbit_lshr_without_shifting_signbit_after

theorem test_or_eq_a_b_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 ||

theorem udiv_ne_big_proof : udiv_ne_big_before ⊑ udiv_ne_big_after

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

theorem alive_AndOrXor_2113___A__B__A___A__B : alive_AndOrXor_2113___A__B__A___A__B_src ⊑ alive_AndOrXor_2113___A__B__A___A__B_tgt

theorem ne_nuw_rem_zero_thm (e : IntW 8) :
  icmp IntPred.ne (mul e (const? 8 5) { «nsw» := false, «nuw» := true }) (const? 8 (-126)) ⊑
    icmp IntPred.ne e (const? 8 26)

theorem fold_and_zext_icmp_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  zeroExtend 8 (ofBool (x_1 <ₛ x_2)) &&& zeroExtend 8 (ofBool (x_2 <ₛ x)) =
    zeroExtend 8 (ofBool (x_1 <ₛ x_2) &&& ofBool (x_2 <ₛ x))

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

theorem bitwise_or_logical_or_icmps_comm3_thm.extracted_1._9 : ∀ (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) ||

theorem n14_trunc_of_lshr_proof : n14_trunc_of_lshr_before ⊑ n14_trunc_of_lshr_after

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

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

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

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 icmp_eq_and_pow2_minus1_shl1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (1#32 <<< x &&& 15#32 == 0#32)) = zeroExtend 32 (ofBool (3#32 <ᵤ x))

theorem select_icmp_ne_pow2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 4#8 != 0#8) = 1#1 → x = x &&& BitVec.ofInt 8 (-5)

theorem p3_sgt_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 65534)) e (const? 32 65535) ⊑
    select (icmp IntPred.slt e_1 (const? 32 65535)) (const? 32 65535) e

theorem test_and_ne_a_b_proof : test_and_ne_a_b_before ⊑ test_and_ne_a_b_after

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

theorem lshr_shl_pow2_const_case2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 4#16 ≥ ↑16) → ofBool (x == 12#16) = 1#1 → 8192#16 >>> x <<< 4#16 &&& 32#16 = 32#16

theorem icmp_ne_sext_sgt_zero_nofold_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.sgt e (const? 32 0))) e ⊑
    icmp IntPred.ne e (sext 32 (icmp IntPred.sgt e (const? 32 0)))

theorem test12_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬x = 0 → ofBool (4#32 / x <ᵤ 2#32) = ofBool (2#32 <ᵤ x)

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

theorem positive_with_signbit_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.sgt e (const? 32 (-1))) (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem test_shl__all_are_safe_proof : test_shl__all_are_safe_before ⊑ test_shl__all_are_safe_after

theorem tryFactorization_add_nuw_mul_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 3#32 = true ∨ True ∧ (x * 3#32).uaddOverflow x = true) →
    ¬(True ∧ x <<< 2#32 >>> 2#32 ≠ x ∨ 2#32 ≥ ↑32) → x * 3#32 + x = x <<< 2#32

theorem tryFactorization_xor_lshr_ashr_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬(x ≥ ↑32 ∨ x ≥ ↑32) → x ≥ ↑32 → False

theorem positive_easyinvert_proof : positive_easyinvert_before ⊑ positive_easyinvert_after

theorem demo2 (x : BitVec 64) : BitVec.zeroExtend 64 (BitVec.truncate 32 x) = x &&& 4294967295#64

theorem select_icmp_ne_0_and_4096_xor_32_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 4096#32) = 1#1 → 7#32 ≥ ↑32 → False

theorem ashr_mul_times_3_div_2_exact_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 3#32 = true ∨ True ∧ (x * 3#32) >>> 1#32 <<< 1#32 ≠ x * 3#32 ∨ 1#32 ≥ ↑32) →
    ¬(True ∧ x >>> 1#32 <<< 1#32 ≠ x ∨ 1#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x.sshiftRight' 1#32) = true) →
      (x * 3#32).sshiftRight' 1#32 = x + x.sshiftRight' 1#32

theorem shl_and_and_proof : shl_and_and_before ⊑ shl_and_and_after

theorem e_191 :
     - 11 *  ~~~(x ^^^ y) + 11 * y + 5 * (x ||| y) + 4 *  ~~~(x ||| y) - 12 * (x &&&  ~~~y) - 5 * (x &&& y) =  - 7 *  ~~~(x &&& y) + 23 *  ~~~(x |||  ~~~y)

theorem test_cast_select_thm (e : IntW 1) :
  zext 32 (select e (const? 16 3) (const? 16 5)) ⊑ select e (const? 32 3) (const? 32 5)

theorem t0_proof : t0_before ⊑ t0_after

theorem test10_proof : test10_before ⊑ test10_after

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

theorem src_is_mask_sext_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 → x_1 ≥ ↑8 ∨ True ∧ (31#8 >>> x_1).msb = true → False

theorem sub_3_proof : sub_3_before ⊑ sub_3_after

theorem lshr_and_proof : lshr_and_before ⊑ lshr_and_after

theorem and_signbit_select_ashr_proof : and_signbit_select_ashr_before ⊑ and_signbit_select_ashr_after

@[simp]
lemma swapLastTwo_eq1' : swapLastTwo (n := n) (Fin.last (n + 1)) = n

theorem or_or_and_pat3_proof : or_or_and_pat3_before ⊑ or_or_and_pat3_after

theorem or_trunc_lshr_small_mask_proof : or_trunc_lshr_small_mask_before ⊑ or_trunc_lshr_small_mask_after

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_814 :
    7 * (z ||| t) - 7 *  ~~~(z ||| t) - 13 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) - 14 * (z &&& t) = 1 * (z ^^^ t) - 7 *  ~~~(z &&&  ~~~t)

theorem select_icmp_eq_and_32_0_xor_8_proof : select_icmp_eq_and_32_0_xor_8_before ⊑ select_icmp_eq_and_32_0_xor_8_after

theorem band_land_left2_proof : band_land_left2_before ⊑ band_land_left2_after

@[simp] theorem Hom.consMap_last {Γ Γ' : Ctxt Ty} (f : Hom Γ Γ') {t : Ty} :
    (f.consMap (Ctxt.Var.last Γ t)) = Ctxt.Var.last Γ' t

@[simp] theorem mapValuation_nil (mapOut : MatchVarResult lets v .nil w mapIn) (V) :
    mapOut.val.mapValuation V w = V v

@[simp] theorem pure_inf_eq      : min pure e = pure

theorem e_512 :
    4 *  ~~~(x &&&  ~~~x) - 1 *  ~~~x + 7 * y + 1 *  ~~~(x &&& y) - 1 * (x |||  ~~~y) + 7 *  ~~~(x &&&  ~~~y) - 10 *  ~~~(x ||| y) - 3 * (x &&&  ~~~y) - 17 * (x &&& y) = 17 *  ~~~(x |||  ~~~y) + 1 * (x ^^^ y)

theorem canonicalize_logic_first_and0_nsw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.saddOverflow 48#8 = true) → True ∧ (x &&& BitVec.ofInt 8 (-10)).saddOverflow 48#8 = true → False

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

theorem test1_proof : test1_before ⊑ test1_after

theorem unsigned_sign_bit_extract_with_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ofBool (truncate 32 (x >>> 63#64) != 0#32) = ofBool (x <ₛ 0#64)

theorem test18_proof : test18_before ⊑ test18_after

theorem getElem?_eq_toList_getElem? {i : Nat} : Γ[i]? = Γ.toList[i]?

theorem exact_ashr_ne_noexactdiv_proof : exact_ashr_ne_noexactdiv_before ⊑ exact_ashr_ne_noexactdiv_after

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 substitute_constant_and_eq_eq_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 e) (icmp IntPred.eq e_1 (const? 8 42)) (const? 1 0) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42))

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

theorem add_umin_constant_limit_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 41#32 = true) →
    ofBool (x + 41#32 <ᵤ 42#32) = 1#1 → ¬ofBool (x == 0#32) = 1#1 → x + 41#32 = 42#32

theorem test10_proof : test10_before ⊑ test10_after

theorem ofBitVecZext_eq_ofBitVecSext_of_lt (x : BitVec w)
    (h : i < w) :
    BitStream.ofBitVecZext x i =
    BitStream.ofBitVecSext x i

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

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 neg_nsw_slt_0_proof : neg_nsw_slt_0_before ⊑ neg_nsw_slt_0_after

theorem xor_or_xor_common_op_commute3_proof : xor_or_xor_common_op_commute3_before ⊑ xor_or_xor_common_op_commute3_after

theorem ne_umax1_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (select (icmp IntPred.ugt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.ult e_1 e

theorem shift_xor_multiuse_cmp_with_xor_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.xor e_2 (const? 32 2048)))
      (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.xor e_2 (const? 32 2048)) e_2)
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

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

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

theorem test16_thm (e : IntW 16) :
  sext 32 (icmp IntPred.eq (LLVM.and e (const? 16 8)) (const? 16 8)) ⊑
    sext 32 (ashr (shl e (const? 16 12)) (const? 16 15))

theorem t_0_10_thm (e : IntW 8) :
  LLVM.and (select (icmp IntPred.ugt e (const? 8 0)) e (const? 8 0)) (const? 8 10) ⊑
    LLVM.and e (const? 8 10)

theorem or_and_not_not_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ((x_2 ||| x_1) ^^^ -1#32) &&& x ||

theorem e_254 :
     - 7 * y - 6 *  ~~~(x &&&  ~~~y) - 7 * (x ^^^ y) - 1 *  ~~~(x ^^^ y) + 12 *  ~~~(x ||| y) + 25 *  ~~~(x |||  ~~~y) + 12 * (x &&&  ~~~y) =  - 19 * (x &&& y) + 5 *  ~~~(x &&&  ~~~x)

theorem reassoc_x2_sub_nuw_proof : reassoc_x2_sub_nuw_before ⊑ reassoc_x2_sub_nuw_after

theorem or_and2_proof : or_and2_before ⊑ or_and2_after

theorem slt_or_not_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.slt e_1 e) (const? 1 1) (icmp IntPred.ne e_1 (const? 8 127)) ⊑
    icmp IntPred.ne e_1 (const? 8 127)

theorem add_nuw_nsw_or_and_thm (e e_1 : IntW 32) :
  add (LLVM.or e_1 e) (LLVM.and e_1 e) { «nsw» := true, «nuw» := true } ⊑
    add e_1 e { «nsw» := true, «nuw» := true }

@[simp]
theorem Eqn.denoteFin_width_zero  (es : Eqn) (env : EnvFin 0 es.numVars) :
    Eqn.denoteFin es env = 0

theorem sgt_smax2_proof : sgt_smax2_before ⊑ sgt_smax2_after

theorem e_1426 :
     - 5 *  ~~~(z &&&  ~~~t) + 3 * (z ||| t) - 3 * t - 6 * (z |||  ~~~t) + 1 *  ~~~(z &&& t) - 1 *  ~~~t + 7 *  ~~~(z ^^^ t) + 1 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) + 1 * (z &&& t) =  - 3 *  ~~~(z &&&  ~~~z)

theorem ne_shift_in_zeros_proof : ne_shift_in_zeros_before ⊑ ne_shift_in_zeros_after

@[simp]
theorem inter_accepts (M : NFA α σ) (N : NFA α ς) :
    (M.inter 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

theorem or_simplify_ult_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 &&& BitVec.ofInt 8 (-5) <ᵤ x ||| 36#8 ||| x_1 &&& BitVec.ofInt 8 (-5)) =
    ofBool (x_1 &&& BitVec.ofInt 8 (-5) <ᵤ x ||| x_1 ||| 36#8)

theorem mul_splat_fold_no_nuw_proof : mul_splat_fold_no_nuw_before ⊑ mul_splat_fold_no_nuw_after

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

theorem ashrslt_02_13_exact_proof : ashrslt_02_13_exact_before ⊑ ashrslt_02_13_exact_after

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

theorem a_false_implies_b_false2_comm_thm.extracted_1._8 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬ofBool (20#8 <ᵤ x_2) = 1#1 → ¬ofBool (10#8 <ᵤ x_2) = 1#1 → x ||

theorem ne_21_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32) →
    ofBool (truncate 8 (x_1 >>> 16#32) != truncate 8 (x >>> 16#32)) = 1#1 → 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 → False

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

theorem test3_proof : test3_before ⊑ test3_after

theorem not_not_true_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x ^^^ 1#1 = 1#1 → ¬x = 1#1 → False

theorem test8_thm (e : IntW 27) : sub (mul (const? 27 9) e) e ⊑ shl e (const? 27 3)

theorem factorize3_proof : factorize3_before ⊑ factorize3_after

theorem test_ashr_exact__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) { «exact» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (ashr e_1 (const? 32 2)) (const? 32 (-536870897))) { «nneg» := true })

theorem urem_i32_multiuse_thm (e e_1 : IntW 8) :
  mul (urem (zext 32 e_1) (zext 32 e)) (add (zext 32 e_1) (zext 32 e)) ⊑
    mul (urem (zext 32 e_1) (zext 32 e)) (add (zext 32 e_1) (zext 32 e) { «nsw» := true, «nuw» := true })
      { «nsw» := true, «nuw» := true }

theorem or_not_xor_common_op_commute2_proof : or_not_xor_common_op_commute2_before ⊑ or_not_xor_common_op_commute2_after

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

theorem test1_logical_proof : test1_logical_before ⊑ test1_logical_after

@[bv_automata_nnf] theorem imp_self_eq (p : Prop) : (p → p) = True

theorem icmp_eq_sext_eq_zero_proof : icmp_eq_sext_eq_zero_before ⊑ icmp_eq_sext_eq_zero_after

theorem or_not_and_commute4_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.and (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor (LLVM.or e_1 e) (const? 32 (-1))))
      (LLVM.and (LLVM.xor (LLVM.or e_1 (LLVM.sdiv (const? 32 42) e_2)) (const? 32 (-1))) e) ⊑
    LLVM.and (LLVM.xor e (LLVM.sdiv (const? 32 42) e_2)) (LLVM.xor e_1 (const? 32 (-1)))

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

theorem add_of_selects_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1), x_1 = 1#1 → 0#32 + x = x

theorem n3_constmask_samemask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& 65280#32).saddOverflow (x &&& 65280#32) = true ∨
      True ∧ (x_1 &&& 65280#32).uaddOverflow (x &&& 65280#32) = true →
    False

theorem bools_logical_commute0_thm.extracted_1._13 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → x_1 = 1#1 → 1#1 = x

theorem test4_proof : test4_before ⊑ test4_after

theorem select_icmp_eq_0_and_1_or_1_proof : select_icmp_eq_0_and_1_or_1_before ⊑ select_icmp_eq_0_and_1_or_1_after

theorem t9_ashr_proof : t9_ashr_before ⊑ t9_ashr_after

theorem testtrunclowhigh_proof : testtrunclowhigh_before ⊑ testtrunclowhigh_after

theorem t1_thm (e : IntW 8) :
  icmp IntPred.sge (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.slt e (const? 8 1)

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

theorem add_signbit_shl_thm (e : IntW 32) :
  shl (add e (const? 32 (-65536))) (const? 32 8) ⊑ add (shl e (const? 32 8)) (const? 32 (-16777216))

theorem e_1689 :
    11 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 1 * (a ||| ( ~~~b &&& c)) - 1 * ( ~~~a ||| (b &&& c)) + 7 * (b |||  ~~~c) + 5 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 11 * ( ~~~a &&& ( ~~~b ||| c)) - 6 * ( ~~~a &&& (b ||| c)) + 1 * (b ||| (a &&& c)) + 11 * a - 1 *  ~~~(a ||| (b ^^^ c)) + 11 *  ~~~(a ^^^ ( ~~~b ||| c)) - 2 * (a &&&  ~~~c) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 7 * ((b &&& c) ||| (a &&& (b ||| c))) + 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 2 * ((a &&& b) |||  ~~~(b ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 3 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 7 * (b ^^^ ( ~~~a ||| (b ||| c))) - 18 *  ~~~(a ||| (b ||| c)) - 26 *  ~~~(a ||| ( ~~~b ||| c)) - 45 *  ~~~( ~~~a ||| (b ||| c)) - 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 2 * ( ~~~a &&& ( ~~~b &&& c)) - 7 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) - 21 * (a &&& (b &&& c)) =  - 1 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c)))

theorem sgt_and_min_logical_proof : sgt_and_min_logical_before ⊑ sgt_and_min_logical_after

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

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

theorem modulo32_thm (e : IntW 32) :
  add (select (icmp IntPred.slt (LLVM.srem e (const? 32 32)) (const? 32 0)) (const? 32 32) (const? 32 0))
      (LLVM.srem e (const? 32 32)) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and e (const? 32 31)

theorem e_408 :
     - 11 *  ~~~(x ^^^ y) - 5 *  ~~~(x &&&  ~~~y) + 7 * (x ||| y) + 5 * (x |||  ~~~y) + 18 *  ~~~(x ||| y) + 5 *  ~~~(x |||  ~~~y) - 5 * (x &&&  ~~~y) + 4 * (x &&& y) = 7 *  ~~~(x &&& y)

theorem eq_iff_EqualUpTo (x y : BitStream) :
  x = y ↔ (∀ w, EqualUpTo w x y)

theorem e_1323 :
     - 11 * (z ^^^ t) - 1 * (z |||  ~~~t) - 5 *  ~~~(z &&&  ~~~t) + 2 * (z ||| t) - 11 *  ~~~(z &&& t) + 24 *  ~~~(z ||| t) + 25 *  ~~~(z |||  ~~~t) + 20 * (z &&&  ~~~t) + 10 * (z &&& t) = 7 *  ~~~(z ^^^ t) - 1 * z

theorem not_ashr_bitwidth_mask_proof : not_ashr_bitwidth_mask_before ⊑ not_ashr_bitwidth_mask_after

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

theorem eq_umax3_proof : eq_umax3_before ⊑ eq_umax3_after

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

theorem ashr_ugt_3_proof : ashr_ugt_3_before ⊑ ashr_ugt_3_after

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

theorem ashrsgt_01_08_proof : ashrsgt_01_08_before ⊑ ashrsgt_01_08_after

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

theorem PR45977_f1_proof : PR45977_f1_before ⊑ PR45977_f1_after

theorem PR20945_proof : PR20945_before ⊑ PR20945_after

theorem PR1817_1_proof : PR1817_1_before ⊑ PR1817_1_after

theorem select_icmp_ne_0_and_32_and_not_4096_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 32))) e (LLVM.and e (const? 32 (-4097))) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 32)) (const? 32 0)) (LLVM.and e (const? 32 (-4097)))
      e

theorem or_logic_or_logic_and_6_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ||

theorem trunc_shl_1_i32_i64_proof : trunc_shl_1_i32_i64_before ⊑ trunc_shl_1_i32_i64_after

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

theorem e_557 :
    2 *  ~~~(x &&&  ~~~y) - 11 * x + 3 * y - 1 *  ~~~(x &&& y) + 2 * (x |||  ~~~y) - 7 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) + 10 * (x &&&  ~~~y) + 4 * (x &&& y) =  - 4 *  ~~~x

theorem shl_lshr_and_exact_proof : shl_lshr_and_exact_before ⊑ shl_lshr_and_exact_after

theorem t4_const_after_fold_lshr_shl_ne_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ x_1 + -1#32 ≥ ↑32) → 31#32 ≥ ↑32 → False

theorem ashr_ult_2_proof : ashr_ult_2_before ⊑ ashr_ult_2_after

theorem bools_logical_commute0_proof : bools_logical_commute0_before ⊑ bools_logical_commute0_after

@[simp, defeq] theorem entries_eqvVar : (eqvVarLeft mapOut).val.entries = mapOut.val.entries

theorem test9_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 1073741824)) (const? 32 0))
      (icmp IntPred.sgt e (const? 32 (-1))) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 (-1073741824))) (const? 32 1073741824)

theorem pr40493_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x * 12#32 &&& 4#32 == 0#32) = ofBool (x &&& 1#32 == 0#32)

theorem e_739 :
    5 * (x ^^^ y) + 7 *  ~~~(x ^^^ y) + 2 * x + 1 * y - 5 *  ~~~y - 2 *  ~~~(x &&& y) + 7 * (x ||| y) - 7 *  ~~~x + 2 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) - 22 * (x &&& y) =  - 5 * (x |||  ~~~y) + 12 * (x &&&  ~~~y)

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

theorem and_ranges_overlap_single_thm (e : IntW 8) :
  LLVM.and (LLVM.and (icmp IntPred.uge e (const? 8 5)) (icmp IntPred.ule e (const? 8 10)))
      (LLVM.and (icmp IntPred.uge e (const? 8 10)) (icmp IntPred.ule e (const? 8 20))) ⊑
    icmp IntPred.eq e (const? 8 10)

theorem e_2064 :
    1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * (e ^^^  ~~~(d |||  ~~~f)) + 11 * (f |||  ~~~(d |||  ~~~e)) - 1 *  ~~~(d ||| e) - 3 * (e ^^^  ~~~(d &&& f)) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * ( ~~~d ||| (e ^^^ f)) - 2 *  ~~~(e &&& f) + 1 * ( ~~~f ||| (d ^^^ e)) - 11 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 3 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 11 * (e ^^^ (d ||| (e ||| f))) - 3 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (f ^^^  ~~~(d ||| e)) - 7 * ((d &&& e) |||  ~~~(e ^^^ f)) - 7 * (e &&& (d |||  ~~~f)) + 1 * (f &&& (d |||  ~~~e)) + 5 * e + 2 * (e ^^^ (d &&& f)) + 11 * (d &&&  ~~~e) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (e ^^^ (d ||| (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 *  ~~~(d ^^^ (e ^^^ f)) + 11 * (f |||  ~~~(d ||| e)) + 9 *  ~~~(d ||| (e ||| f)) - 2 *  ~~~(d ||| ( ~~~e ||| f)) + 16 *  ~~~( ~~~d ||| (e ||| f)) + 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 3 * ( ~~~d &&& ( ~~~e &&& f)) - 34 * ( ~~~d &&& (e &&& f)) - 32 * (d &&& ( ~~~e &&& f)) + 15 * (d &&& (e &&& f)) = 1 *  ~~~(d &&& f)

protected theorem carry_eq_carry (x y : BitStream) (c : Bool)
    (x' y' : BitVec w)
    (hx : ∀ i, x'.getLsbD i = x i)
    (hy : ∀ i,  y'.getLsbD i = y i) :
    carry c x y n = (BitVec.carry (n + 1) x' y' c)

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

theorem e_1343 :
     - 1 *  ~~~(z &&&  ~~~z) - 7 * (z ^^^ t) + 5 *  ~~~(z &&& t) - 5 * (z ||| t) + 1 *  ~~~t - 1 * z + 4 *  ~~~(z ||| t) + 8 *  ~~~(z |||  ~~~t) + 11 * (z &&&  ~~~t) + 16 * (z &&& t) = 3 * (z |||  ~~~t) + 6 *  ~~~(z ^^^ t)

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)

theorem add_shl_same_amount_partial_nsw1_proof : add_shl_same_amount_partial_nsw1_before ⊑ add_shl_same_amount_partial_nsw1_after

theorem test_shl_nsw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨
          2#32 ≥ ↑32) →
      ¬(True ∧ ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨
            2#32 ≥ ↑32 ∨
              True ∧
                  ((x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32).sshiftRight' 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨
                2#32 ≥ ↑32) →
        BitVec.ofInt 32 (-335544316) * (x ||| BitVec.ofInt 32 (-83886080)) *
            (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 =
          (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 * (x ||| BitVec.ofInt 32 (-83886080)) *
            (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32

theorem or_logic_or_logic_and_3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → True → x_1 ||

theorem alive_Select_740 : forall (w : Nat) (A : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  w %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v1 %v7;
  %v9 := op:select w %v8;
  %v10 := op:const (-1) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  w %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub w %v14;
  %v16 := triple:%v12 %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 (A) %v0;
  %v2 := op:const (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  1 %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v1 %v7;
  %v9 := op:select 1 %v8;
  %v10 := op:const (-1) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  1 %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub 1 %v14;
  %v16 := triple:%v4 %v1 %v7;
  %v17 := op:select 1 %v16
  dsl_ret %v17
  ]

theorem ashr_eq_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-128)).sshiftRight' x == BitVec.ofInt 8 (-128)) = ofBool (x == 0#8)

theorem ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

theorem bools_logical_commute0_thm.extracted_1._11 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → False

@[simp] theorem Valuation.append_inj_left {V V' : Γ.Valuation} {W : Δ.Valuation} :
    (V ++ W) = (V' ++ W) ↔ V = V'

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

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

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

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

theorem lshr_lshr_pow2_const_negative_nopow2_2_proof : lshr_lshr_pow2_const_negative_nopow2_2_before ⊑ lshr_lshr_pow2_const_negative_nopow2_2_after

theorem uge_swap_or_max_logical_proof : uge_swap_or_max_logical_before ⊑ uge_swap_or_max_logical_after

theorem lor_lor_left2_thm (e e_1 : IntW 1) :
  select (select e_1 (const? 1 1) e) (const? 1 1) e ⊑ select e_1 (const? 1 1) e

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

@[simp]
theorem EnvFin.eq_elim0 (envFin : EnvFin w 0) : envFin = fun i => i.elim0

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

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

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

theorem test_shl_nuw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 >>> 2#32 ≠ x ||| BitVec.ofInt 32 (-83886080) ∨ 2#32 ≥ ↑32) →
      (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 * (x ||| BitVec.ofInt 32 (-83886080)) *
          (x ||| BitVec.ofInt 32 (-83886080)) <<< 2#32 =
        0#32

theorem shl_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬((42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨ 5#16 ≥ ↑16 ∨ 7#16 ≥ ↑16) →
    12#16 ≥ ↑16 ∨
        (42#16 == 0 || 16 != 1 && x_1 == intMin 16 && 42#16 == -1) = true ∨
          True ∧ (x_1.srem 42#16 <<< 7#16).sshiftRight' 7#16 ≠ x_1.srem 42#16 ∨ 7#16 ≥ ↑16 →
      False

theorem lshr_C1_add_A_C2_i32_proof : lshr_C1_add_A_C2_i32_before ⊑ lshr_C1_add_A_C2_i32_after

theorem shl_add_nuw_thm (e e_1 : IntW 8) :
  shl (LLVM.and e_1 (const? 8 63)) (LLVM.and e (const? 8 2)) ⊑
    shl (LLVM.and e_1 (const? 8 63)) (LLVM.and e (const? 8 2)) { «nsw» := false, «nuw» := true }

theorem e_2305 :
    4 * (e ^^^ (d ||| f)) - 6 * (d ||| (e ||| f)) - 11 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 11 * (d ||| ( ~~~e ||| f)) + 11 * (f ^^^ (d &&& e)) + 1 *  ~~~(d ^^^ (e ^^^ f)) - 1 * (e ^^^ (d &&&  ~~~f)) + 5 *  ~~~(d &&&  ~~~e) + 2 * (d &&&  ~~~f) + 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 11 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 4 * (f ^^^  ~~~(d |||  ~~~e)) - 6 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 4 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (f ^^^ (d &&&  ~~~e)) + 4 *  ~~~(e |||  ~~~f) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * (f &&& (d ||| e)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (d ^^^ ( ~~~e ||| f)) - 7 * ((d ^^^ e) &&& (d ^^^ f)) + 2 *  ~~~(e &&& f) + 1 *  ~~~e + 7 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * ( ~~~f ||| (d ^^^ e)) - 6 * (f ^^^  ~~~(d &&& (e &&& f))) + 3 * (d ^^^ f) + 5 * (e ^^^  ~~~(d &&& f)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 7 *  ~~~(d &&&  ~~~d) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 4 * e + 7 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 7 * ((d &&& e) ^^^ (e ||| f)) - 2 * (f ||| (d ^^^ e)) - 7 * (d ||| (e &&& f)) - 2 * (e &&& f) + 1 * (e ||| (d ^^^ f)) - 2 * (d &&&  ~~~e) - 3 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 7 * (f ||| (d &&&  ~~~e)) - 2 * f + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~f &&&  ~~~(d ^^^ e)) - 11 * (f ^^^ (d &&& (e ||| f))) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * ( ~~~d ||| (e &&& f)) - 4 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 22 * ( ~~~d &&& ( ~~~e &&& f)) + 12 * ( ~~~d &&& (e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) =  - 15 * (d &&& (e &&& f)) + 3 *  ~~~( ~~~d ||| (e ||| f))

theorem ashr_mul_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬8#20 ≥ ↑20 → True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 8#16 ≥ ↑16 → False

theorem mul_of_bool_no_lz_other_op_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& 1#32).smulOverflow (signExtend 32 x) = true ∨
        True ∧ (x_1 &&& 1#32).umulOverflow (signExtend 32 x) = true) →
    ofBool (127#32 <ₛ (x_1 &&& 1#32) * signExtend 32 x) = 0#1

theorem or_ranges_single_elem_right_proof : or_ranges_single_elem_right_before ⊑ or_ranges_single_elem_right_after

theorem tryFactorization_add_mul_nuw_mul_var_thm (e e_1 e_2 : IntW 32) :
  add (mul e_2 e_1 { «nsw» := false, «nuw» := true }) (mul e_2 e { «nsw» := false, «nuw» := true }) ⊑
    mul e_2 (add e_1 e)

theorem ashr_lshr_exact_both_proof : ashr_lshr_exact_both_before ⊑ ashr_lshr_exact_both_after

theorem and_not_or_commute2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    ¬(x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true →
      ((42#32).sdiv x_2 ||| x_1 &&& x ^^^ -1#32) &&& (x_1 &&& (42#32).sdiv x_2 ^^^ -1#32 ||| x) =
        (x ^^^ (42#32).sdiv x_2) &&& x_1 ^^^ -1#32

lemma CNFA.determinize_language {m : CNFA n} :
    m.recognizes L → m.determinize.recognizes L

theorem main3e_like_logical_thm.extracted_1._5 : ∀ (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 1#1

theorem test_ashr__exact_is_unsafe_proof : test_ashr__exact_is_unsafe_before ⊑ test_ashr__exact_is_unsafe_after

theorem shl_lshr_pow2_const_negative_overflow1_thm (e : IntW 16) :
  LLVM.and (lshr (shl (const? 16 4096) e) (const? 16 6)) (const? 16 8) ⊑ const? 16 0

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

theorem ult_x_impliesT_eq_umax_todo_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_1 <ᵤ x_2) = 1#1 → ofBool (-1#8 != x_1) = 1#1

theorem bv_AddSub_1043 :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.add (LLVM.add (LLVM.xor (LLVM.and e_1 e) e) (LLVM.const? w 1)) e_2 ⊑ LLVM.sub e_2 (LLVM.or e_1 (LLVM.not e))

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 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 sgt_and_not_min_logical_proof : sgt_and_not_min_logical_before ⊑ sgt_and_not_min_logical_after

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

theorem le_proof : le_before ⊑ le_after

theorem both_proof : both_before ⊑ both_after

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_rel_preserve_olds :
    s₂ ~[(processOneElem A S final s₁ st (a, sa)).rel] sa' →
    s₂ ∈ st.m.states → s₂ ~[st.rel] sa'

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

theorem ashr_ult_15_proof : ashr_ult_15_before ⊑ ashr_ult_15_after

theorem exact_ashr_eq_both_equal_proof : exact_ashr_eq_both_equal_before ⊑ exact_ashr_eq_both_equal_after

theorem main5f_like_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != x_2) ||

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

theorem or_xor_or_proof : or_xor_or_before ⊑ or_xor_or_after

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

theorem mul_constant_mismatch_wrap_eq_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (mul e_1 (const? 32 54) { «nsw» := true, «nuw» := false })
      (mul e (const? 32 54) { «nsw» := false, «nuw» := true }) ⊑
    icmp IntPred.eq (LLVM.and (LLVM.xor e_1 e) (const? 32 2147483647)) (const? 32 0)

theorem neg_slt_42_proof : neg_slt_42_before ⊑ neg_slt_42_after

theorem ne_smax3_proof : ne_smax3_before ⊑ ne_smax3_after

theorem n2_thm.extracted_1._8 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x_2 ^^^ 1#1 = 1#1 → 0#1 ^^^ 1#1 = ofBool (x_1 != x)

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

theorem add_or_and_commutative_proof : add_or_and_commutative_before ⊑ add_or_and_commutative_after

theorem map_map {A B C : α → Type*} {l : List α} (t : HVector A l)
    (f : ∀ a, A a → B a) (g : ∀ a, B a → C a) :
    (t.map f).map g = t.map (fun a v => g a (f a v))

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

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

theorem bv_AndOrXor_2607 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.or e (LLVM.xor e_1 (LLVM.const? w (-1)))) (LLVM.or (LLVM.xor e (LLVM.const? w (-1))) e_1) ⊑
        LLVM.xor e e_1

theorem shl_and_and_fail_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 4)) (LLVM.and (shl e (const? 8 5)) (const? 8 88)) ⊑
    LLVM.and (shl e_1 (const? 8 4)) (LLVM.and (shl e (const? 8 5)) (const? 8 64))

theorem e_890 :
     - 1 *  ~~~(z &&&  ~~~t) + 1 *  ~~~(z &&& t) + 1 *  ~~~t + 11 * z - 1 * (z |||  ~~~t) - 9 * (z &&& t) = 12 * (z &&&  ~~~t)

theorem mul_five (x : BitVec w) : 5 * x = x + x + x + x + x

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

theorem BitVec.even_mul_eq_shiftLeft_mul_of_eq_mul_two
    (w : Nat) (x : BitVec w) (n e : Nat) (he : e = n * 2) :
    (BitVec.ofNat w e) * x = (BitVec.ofNat w n) * (x <<< (1 : Nat))

@[simp]
theorem Term.toBV_ofNat
    {tctx : Term.Ctx wcard tcard}
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard)
    (nnenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (w : WidthExpr wcard) (n : Nat) :
  Term.toBV benv nenv ienv penv tenv (.ofNat w n) = BitVec.ofNat (w.toNat wenv) n

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

theorem alive_820   : alive_820_src ⊑ alive_820_tgt

theorem no_shift_xor_multiuse_cmp_with_and_proof : no_shift_xor_multiuse_cmp_with_and_before ⊑ no_shift_xor_multiuse_cmp_with_and_after

theorem test4_proof : test4_before ⊑ test4_after

theorem t0_thm.extracted_1._13 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 ^^^ 1#1 = 1#1 → x_2 = 1#1 → 0#1 = 1#1 → x_1 = x

theorem shl_add_and_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 1)) (add (shl e (const? 8 1)) (const? 8 123)) ⊑
    shl (LLVM.and e_1 (add e (const? 8 61))) (const? 8 1)

theorem trunc_shl_ashr_infloop_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(3#64 ≥ ↑64 ∨ 2#64 ≥ ↑64) → 1#64 ≥ ↑64 → False

@[simp, aesop 50% unsafe]
theorem evalFrom_mono (M : NFA α σ) (S₁ S₂ : Set σ) (x : List α) (h : S₁ ⊆ S₂) :
    M.evalFrom S₁ x ⊆ M.evalFrom S₂ x

theorem test8_proof : test8_before ⊑ test8_after

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

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

theorem nonexact_lshr_eq_proof : nonexact_lshr_eq_before ⊑ nonexact_lshr_eq_after

theorem add_const_const_sub_nsw_proof : add_const_const_sub_nsw_before ⊑ add_const_const_sub_nsw_after

theorem or_eq_with_diff_one_logical_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x == 13#8) = 1#1 → ofBool (x == 14#8) = ofBool (x + BitVec.ofInt 8 (-13) <ᵤ 2#8)

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

theorem p_commutative4_proof : p_commutative4_before ⊑ p_commutative4_after

theorem test17_proof : test17_before ⊑ test17_after

theorem xor_icmp_to_ne_proof : xor_icmp_to_ne_before ⊑ xor_icmp_to_ne_after

theorem alive_275_2   : alive_275_2_src ⊑ alive_275_2_tgt

@[simp]
theorem Expr.regArgs_mk {Γ : Ctxt d.Ty} {ty eff op}
    (ty_eq : ty = DialectSignature.returnTypes op)
    (eff_le : DialectSignature.effectKind op ≤ eff)
    (args : HVector (Var Γ) (DialectSignature.sig op)) (regArgs) :
    (Expr.mk op ty_eq eff_le args regArgs).regArgs = regArgs

theorem and_logic_and_logic_or_3_proof : and_logic_and_logic_or_3_before ⊑ and_logic_and_logic_or_3_after

theorem test_sdiv_canonicalize_op0_thm (e e_1 : IntW 32) :
  LLVM.sdiv (sub (const? 32 0) e_1 { «nsw» := true, «nuw» := false }) e ⊑
    sub (const? 32 0) (LLVM.sdiv e_1 e) { «nsw» := true, «nuw» := false }

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 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 e_1268 :
     - 5 *  ~~~(z &&&  ~~~z) - 3 *  ~~~z + 7 * (z ||| t) + 11 *  ~~~(z ^^^ t) - 11 * z + 11 * (z |||  ~~~t) - 14 *  ~~~(z ||| t) - 2 * (z &&&  ~~~t) - 16 * (z &&& t) = 2 *  ~~~(z |||  ~~~t) - 3 * t

theorem mul_mask_pow2_eq4_thm (e : IntW 8) :
  icmp IntPred.eq (LLVM.and (mul e (const? 8 44)) (const? 8 4)) (const? 8 4) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 1)) (const? 8 0)

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

theorem select_constants_and_icmp_eq0_common_bit_proof : select_constants_and_icmp_eq0_common_bit_before ⊑ select_constants_and_icmp_eq0_common_bit_after

theorem match_signed_thm (e : IntW 64) :
  add (add (LLVM.srem e (const? 64 299)) (mul (LLVM.srem (LLVM.sdiv e (const? 64 299)) (const? 64 64)) (const? 64 299)))
      (mul (LLVM.srem (LLVM.sdiv e (const? 64 19136)) (const? 64 9)) (const? 64 19136)) ⊑
    LLVM.srem e (const? 64 172224)

theorem tryFactorization_xor_ashr_lshr_proof : tryFactorization_xor_ashr_lshr_before ⊑ tryFactorization_xor_ashr_lshr_after

theorem AvoidCollision_getElem?_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
    (x.setWidth m)[i]? = if i < m then some (x.getLsbD i) else none

theorem main13_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) = 1#1 →
    ofBool (x &&& 32896#32 == 32896#32) = 1#1 → ¬ofBool (truncate 8 x <ₛ 0#8) = 1#1 → 1#32 = 2#32

theorem select_1_proof : select_1_before ⊑ select_1_after

theorem lshr_16_to_64_add_zext_basic_proof : lshr_16_to_64_add_zext_basic_before ⊑ lshr_16_to_64_add_zext_basic_after

theorem sub_ashr_and_i64_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 63#64 ≥ ↑64) →
    ¬ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 63#64 &&& x = 0#64

theorem samesign_different_sign_bittest2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x <ₛ 0#32) ||

theorem i_proof : i_before ⊑ i_after

theorem shl_shl_thm (e : IntW 32) : shl (shl e (const? 32 6)) (const? 32 28) ⊑ const? 32 0

theorem foo_proof : foo_before ⊑ foo_after

theorem sext_xor_sub_2_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 64 x_1 - (x ^^^ signExtend 64 x_1) = x

theorem test7_proof : test7_before ⊑ test7_after

theorem and_ne_with_one_bit_diff_constants3_thm (e : IntW 8) :
  LLVM.and (icmp IntPred.ne e (const? 8 65)) (icmp IntPred.ne e (const? 8 (-63))) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 127)) (const? 8 65)

theorem sub_from_constant_proof : sub_from_constant_before ⊑ sub_from_constant_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 fold_sext_to_and_wrong6_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and (sext 32 e) (const? 32 (-2147483647))) (const? 32 (-1)) ⊑ const? 1 1

theorem and_or2_commuted_proof : and_or2_commuted_before ⊑ and_or2_commuted_after

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_proof : negate_select_of_op_vs_negated_op_nsw_xyyx_before ⊑ negate_select_of_op_vs_negated_op_nsw_xyyx_after

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 ashrslt_02_15_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 2)) (const? 4 (-1)) ⊑ icmp IntPred.slt e (const? 4 (-4))

theorem sle_smax1_proof : sle_smax1_before ⊑ sle_smax1_after

theorem e_1990 :
    1 *  ~~~(a |||  ~~~b) - 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 2 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 6 * ((a &&& b) |||  ~~~(b ||| c)) - 7 * (c ^^^ (a ||| b)) - 3 * (b ^^^ (a ||| c)) + 1 * (c &&& (a ^^^ b)) - 7 * (c ^^^  ~~~(a &&&  ~~~b)) + 2 * (a |||  ~~~c) - 5 * (b ^^^ (a ||| (b ||| c))) + 2 *  ~~~( ~~~a ||| (b &&& c)) + 4 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 *  ~~~(a &&& (b &&& c)) + 4 *  ~~~(a &&&  ~~~b) - 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 7 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * (c ^^^ ( ~~~a ||| (b ||| c))) + 1 * ( ~~~a ||| (b ^^^ c)) - 2 * (b |||  ~~~(a |||  ~~~c)) - 1 *  ~~~(a &&& (b ||| c)) - 5 *  ~~~(a ^^^ (b ||| c)) + 2 * (a ^^^ ( ~~~b ||| c)) + 4 * ( ~~~b &&&  ~~~(a ^^^ c)) + 11 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 11 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 6 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * b + 3 *  ~~~a - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (c &&& (a ||| b)) - 2 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 3 * (b ^^^ (a ||| (b &&& c))) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 * ( ~~~c ||| (a ^^^ b)) - 3 * a + 2 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (a &&& c) + 7 * ( ~~~c &&& (a ^^^ b)) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 7 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 3 *  ~~~(a &&& (b ^^^ c)) + 7 *  ~~~(b |||  ~~~c) + 1 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 3 * (b ^^^ (a |||  ~~~c)) + 2 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 11 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 5 * (c ^^^  ~~~(a ||| b)) + 1 * (a &&&  ~~~c) + 5 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) - 14 *  ~~~( ~~~a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 26 * ( ~~~a &&& ( ~~~b &&& c)) - 20 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) - 5 * (a &&& (b &&& c)) =  - 1 * ( ~~~a ||| (b ||| c)) - 11 * ( ~~~b ||| (a ^^^ c))

theorem test42_thm (e : IntW 32) : zext 32 (trunc 8 e) ⊑ LLVM.and e (const? 32 255)

private lemma BitVec.sle_iff_slt_or_eq {w : ℕ} (bv1 bv2 : BitVec w):
    (bv1.sle bv2) = true ↔ (bv1.slt bv2) = true ∨ bv1 = bv2

theorem lshrult_02_11_exact_proof : lshrult_02_11_exact_before ⊑ lshrult_02_11_exact_after

theorem select_add_icmp_bad_proof : select_add_icmp_bad_before ⊑ select_add_icmp_bad_after

@[simp]
lemma enc_spec (bvs : BitVecs n) (i : Fin bvs.w) (k : Fin n) :
    (enc bvs)[i][k] = (bvs.bvs.get k)[i]

theorem src_is_mask_lshr_proof : src_is_mask_lshr_before ⊑ src_is_mask_lshr_after

theorem test15_thm (e : IntW 32) :
  sext 32 (icmp IntPred.ne (LLVM.and e (const? 32 16)) (const? 32 0)) ⊑
    ashr (shl e (const? 32 27)) (const? 32 31)

theorem test4_thm (e : IntW 37) : LLVM.xor e (LLVM.xor (const? 37 (-1)) e) ⊑ const? 37 (-1)

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

theorem test2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 &&& x &&& x_1 = x_1 &&& x

theorem main4b_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) &&& ofBool (x &&& 16#32 != 0#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 23#32 != 23#32))

theorem mul_of_udiv_fail_bad_remainder_proof : mul_of_udiv_fail_bad_remainder_before ⊑ mul_of_udiv_fail_bad_remainder_after

theorem xor_notand_to_or_not4_thm (e e_1 e_2 : IntW 3) :
  LLVM.xor (LLVM.xor (LLVM.and e_2 e_1) (const? 3 (-1))) (LLVM.or e e_2) ⊑
    LLVM.or (LLVM.and e_2 e_1) (LLVM.xor (LLVM.or e e_2) (const? 3 (-1)))

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

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

theorem e_2475 :
     - 2 * ( ~~~e &&& (d ^^^ f)) - 3 * (f ^^^ (d |||  ~~~e)) - 6 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * (e &&&  ~~~(d &&& f)) + 3 *  ~~~( ~~~d &&& (e ||| f)) - 11 * (e ^^^  ~~~(d &&&  ~~~f)) + 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 6 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * (f |||  ~~~(d ^^^ e)) - 5 * (f &&&  ~~~(d &&&  ~~~e)) + 4 *  ~~~(d ^^^ ( ~~~e &&& f)) - 2 * (e &&&  ~~~(d ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (f ||| (d &&&  ~~~e)) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 11 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 *  ~~~(e &&&  ~~~f) + 5 *  ~~~(e ||| f) - 1 * (f ^^^ (d ||| (e ||| f))) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 11 * (d &&& (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 * (d &&&  ~~~f) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 3 *  ~~~(d ||| (e &&& f)) + 4 *  ~~~(d ^^^ (e &&& f)) + 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * (e &&& f) - 7 *  ~~~(d ^^^ e) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 1 *  ~~~(d &&& e) - 1 *  ~~~(d &&& (e ^^^ f)) + 3 * (f ^^^ (d ||| e)) - 5 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * (e ^^^  ~~~(d |||  ~~~f)) - 7 * ( ~~~d &&& (e ^^^ f)) + 11 * (f ^^^ (d ||| ( ~~~e ||| f))) - 2 * ( ~~~d ||| (e &&& f)) - 11 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 7 * (e |||  ~~~(d ||| f)) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 7 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 5 *  ~~~e + 2 * ( ~~~d &&& ( ~~~e ||| f)) + 2 * (e ^^^ ( ~~~d &&& (e ||| f))) + 11 * (f ^^^ (d &&& (e ||| f))) + 1 *  ~~~(d &&& ( ~~~e ||| f)) + 7 * (e |||  ~~~(d |||  ~~~f)) + 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 5 * (e |||  ~~~(d ^^^ f)) + 5 *  ~~~(d ||| f) - 2 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * f - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 3 * (e ^^^ (d &&& (e ^^^ f))) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~( ~~~d ||| (e &&& f)) + 2 *  ~~~(d &&&  ~~~d) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) + 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 6 * (e ||| (d &&& f)) - 6 * (d ^^^ ( ~~~e &&& f)) - 7 *  ~~~(d ||| (e ||| f)) + 3 *  ~~~(d ||| ( ~~~e ||| f)) + 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 47 * ( ~~~d &&& ( ~~~e &&& f)) - 25 * ( ~~~d &&& (e &&& f)) + 39 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) =  - 23 *  ~~~( ~~~d ||| (e ||| f)) + 7 * (d |||  ~~~f)

theorem and_logic_and_logic_or_6_thm (e e_1 e_2 : IntW 1) :
  select (select e_2 e_1 (const? 1 0)) (const? 1 1) (LLVM.and e_1 e) ⊑ 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 select_icmp_eq_and_4096_0_or_4096_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 4096#32 == 0#32) = 1#1 → x ||

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

theorem trunc_sel_equal_zext_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → zeroExtend 32 (truncate 16 x) = x &&& 65535#32

theorem not_or_or_and_no_and_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_1 e_2) (const? 32 (-1))) ⊑
    LLVM.or (LLVM.and e (LLVM.xor e_1 (const? 32 (-1)))) (LLVM.xor e_2 (const? 32 (-1)))

theorem or_xor_commute2_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) ⊑
    LLVM.and (LLVM.udiv (const? 32 42) e_1) (LLVM.xor (LLVM.udiv (const? 32 42) e) (const? 32 (-1)))

theorem eq_3210_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.eq (trunc 8 (lshr e_1 (const? 32 24))) (trunc 8 (lshr e (const? 32 24))))
      (LLVM.and (icmp IntPred.eq (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16))))
        (LLVM.and (icmp IntPred.eq (trunc 8 e_1) (trunc 8 e))
          (icmp IntPred.eq (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8)))))) ⊑
    icmp IntPred.eq e_1 e

theorem sgt_negative_multip_rem_zero_thm (e : IntW 8) :
  icmp IntPred.sgt (mul e (const? 8 (-7)) { «nsw» := true, «nuw» := false }) (const? 8 21) ⊑
    icmp IntPred.slt e (const? 8 (-3))

theorem commutativity_constant_14_vary_thm (e : IntW 4) :
  LLVM.xor e (LLVM.and (LLVM.xor e (const? 4 (-2))) (const? 4 1)) ⊑ LLVM.and e (const? 4 (-2))

theorem trunc_shl_15_i16_i64_proof : trunc_shl_15_i16_i64_before ⊑ trunc_shl_15_i16_i64_after

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

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

theorem and_ne_with_diff_one_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 40#32) = 1#1 → 0#1 = ofBool (x + BitVec.ofInt 32 (-41) <ᵤ BitVec.ofInt 32 (-2))

theorem R.fromPoly_representatitive'_toFun (a : R q n) :
    (R.fromPoly (q := q) (n := n)).toFun (R.representative' q n a) = ↑a

theorem or_simplify_ule_thm (e e_1 : IntW 8) :
  icmp IntPred.ule (LLVM.or (LLVM.or e_1 (const? 8 1)) (LLVM.and e (const? 8 (-2)))) (LLVM.and e (const? 8 (-2))) ⊑
    icmp IntPred.ule (LLVM.or (LLVM.or e_1 e) (const? 8 1)) (LLVM.and e (const? 8 (-2)))

theorem lshrult_01_10_proof : lshrult_01_10_before ⊑ lshrult_01_10_after

theorem test30_thm (e : IntW 1) : LLVM.and (zext 32 e) (const? 32 1) ⊑ zext 32 e

theorem demorgan_nand_apint2_proof : demorgan_nand_apint2_before ⊑ demorgan_nand_apint2_after

theorem lor_band_left1_proof : lor_band_left1_before ⊑ lor_band_left1_after

theorem rev8_mul_and_lshr_thm (e : IntW 8) :
  trunc 8
      (lshr
        (mul
          (LLVM.or (LLVM.and (mul (zext 64 e) (const? 64 2050) { «nsw» := true, «nuw» := true }) (const? 64 139536))
            (LLVM.and (mul (zext 64 e) (const? 64 32800) { «nsw» := true, «nuw» := true }) (const? 64 558144)))
          (const? 64 65793) { «nsw» := true, «nuw» := true })
        (const? 64 16)) ⊑
    trunc 8
      (lshr
        (mul
          (LLVM.or (LLVM.and (mul (zext 64 e) (const? 64 2050) { «nsw» := true, «nuw» := true }) (const? 64 139536))
            (LLVM.and (mul (zext 64 e) (const? 64 32800) { «nsw» := true, «nuw» := true }) (const? 64 558144))
            { «disjoint» := true })
          (const? 64 65793) { «nsw» := true, «nuw» := true })
        (const? 64 16))

theorem test_mul_nsw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-83886080) == BitVec.ofInt 32 (-83886079)) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-83886080)).smulOverflow 9#32 = true) →
      BitVec.ofInt 32 (-754974711) = (x ||| BitVec.ofInt 32 (-83886080)) * 9#32

theorem test1_proof : test1_before ⊑ test1_after

theorem add_nuw_const_const_sub_nuw_thm (e : IntW 8) :
  sub (const? 8 (-127)) (add e (const? 8 1) { «nsw» := false, «nuw» := true }) { «nsw» := false, «nuw» := true } ⊑
    sub (const? 8 (-128)) e { «nsw» := false, «nuw» := true }

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

theorem e_63 :
     - 2 *  ~~~x + 11 *  ~~~(x &&&  ~~~x) - 5 * x - 9 *  ~~~(x |||  ~~~y) - 6 * (x &&& y) = 6 * (x &&&  ~~~y) + 9 *  ~~~(x ||| y)

theorem is_rem4_neg_i16_proof : is_rem4_neg_i16_before ⊑ is_rem4_neg_i16_after

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

theorem sub_const_sub_const_thm.extracted_1._1 : ∀ (x : BitVec 32), x - 8#32 - 2#32 = x + BitVec.ofInt 32 (-10)

theorem srem_common_dividend_defined_cond_proof : srem_common_dividend_defined_cond_before ⊑ srem_common_dividend_defined_cond_after

theorem neg_or_lshr_i32_proof : neg_or_lshr_i32_before ⊑ neg_or_lshr_i32_after

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

theorem trunc_shl_15_i16_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬15#32 ≥ ↑32 → ¬15#16 ≥ ↑16 → truncate 16 (x <<< 15#32) = truncate 16 x <<< 15#16

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 t9_proof : t9_before ⊑ t9_after

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

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

theorem positive_biggerLshr_lshrexact_thm (e : IntW 32) :
  lshr (shl e (const? 32 5)) (const? 32 10) { «exact» := true } ⊑
    LLVM.and (lshr e (const? 32 5) { «exact» := true }) (const? 32 4194303)

theorem select_sub_icmp_bad_2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 1#32) = 1#1 → x - x_1 = x + -1#32

theorem ashrsgt_02_11_exact_proof : ashrsgt_02_11_exact_before ⊑ ashrsgt_02_11_exact_after

theorem icmp_mul_nsw_slt_proof : icmp_mul_nsw_slt_before ⊑ icmp_mul_nsw_slt_after

theorem add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 + 16#32 ||| x) &&& 24#32 = (x_1 ^^^ 16#32 ||| x) &&& 24#32

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

theorem test_nuw_and_unsigned_pred_proof : test_nuw_and_unsigned_pred_before ⊑ test_nuw_and_unsigned_pred_after

theorem not_invert_signbit_splat_mask2_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬6#8 ≥ ↑8 →
    signExtend 16 (x_1.sshiftRight' 6#8 ^^^ -1#8) &&& x = x &&& signExtend 16 (x_1.sshiftRight' 6#8 ^^^ -1#8)

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 test_lshr__exact_is_unsafe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 63#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ True ∧ (x_1 >>> 2#32 &&& 15#32).msb = true ∨ zeroExtend 64 (x_1 >>> 2#32 &&& 15#32) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 >>> 2#32 &&& 15#32))

theorem zext_masked_bit_zero_to_smaller_bitwidth_proof : zext_masked_bit_zero_to_smaller_bitwidth_before ⊑ zext_masked_bit_zero_to_smaller_bitwidth_after

theorem test16_thm (e e_1 : IntW 8) :
  mul (LLVM.and (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) (LLVM.xor e e_1)) (LLVM.xor (LLVM.xor e_1 (const? 8 33)) e) ⊑
    mul (LLVM.and (LLVM.xor (LLVM.xor e_1 e) (const? 8 33)) (LLVM.xor e e_1))
      (LLVM.xor (LLVM.xor e_1 e) (const? 8 33))

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

theorem test16_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬1#32 ≥ ↑32 →
    ¬(1#32 ≥ ↑32 ∨ True ∧ (BitVec.ofInt 32 (-2)).usubOverflow (x >>> 1#32) = true) →
      4294967294#64 - zeroExtend 64 (x >>> 1#32) = zeroExtend 64 (BitVec.ofInt 32 (-2) - x >>> 1#32)

theorem bitwise_or_bitwise_or_icmps_comm1_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 test_shl__nuw_is_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
              zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem test6_proof : test6_before ⊑ test6_after

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 → True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64 → False

theorem mul_add_to_mul_6_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.smulOverflow x = true ∨
        True ∧ x_1.smulOverflow x = true ∨
          True ∧ (x_1 * x).smulOverflow 5#32 = true ∨ True ∧ (x_1 * x).saddOverflow (x_1 * x * 5#32) = true) →
    True ∧ x_1.smulOverflow x = true ∨ True ∧ (x_1 * x).smulOverflow 6#32 = true → False

theorem masked_or_allones_proof : masked_or_allones_before ⊑ masked_or_allones_after

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

@[simp] theorem Valuation.comap_cons_consMap {Γ Γ_out : Ctxt Ty}
    (V : Γ_out.Valuation) {t} (x : ⟦t⟧) (map : Γ.Hom Γ_out) :
    Valuation.comap (x ::ᵥ V) (Ctxt.Hom.consMap map)
    = (x ::ᵥ (Valuation.comap V map))

theorem and_not_or_or_not_or_xor_commute4_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    ¬(x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true →
      (42#32).sdiv x_2 &&& ((x_1 ||| x) ^^^ -1#32) ||

theorem bitwise_or_logical_or_icmps_comm1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬ofBool (x == 42#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 lshr_mul_times_3_div_2_exact_proof : lshr_mul_times_3_div_2_exact_before ⊑ lshr_mul_times_3_div_2_exact_after

theorem ashrslt_02_14_proof : ashrslt_02_14_before ⊑ ashrslt_02_14_after

theorem main6c_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 3#32) = 1#1 → True → 0#32 = zeroExtend 32 (ofBool (x &&& 55#32 == 19#32))

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

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

theorem test35_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (0#32 - x &&& 240#32).msb = true) →
    0#64 - zeroExtend 64 x &&& 240#64 = zeroExtend 64 (0#32 - x &&& 240#32)

theorem select_ashr_icmp_bad_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → ¬x_2 ≥ ↑32 → ¬1#32 ≥ ↑32 → x_1.sshiftRight' x_2 = x_1.sshiftRight' 1#32

theorem ashrslt_02_03_exact_proof : ashrslt_02_03_exact_before ⊑ ashrslt_02_03_exact_after

theorem eq_umax3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ᵤ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 == x) = ofBool (x ≤ᵤ x_1 + 3#32)

theorem n3_constmask_samemask_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) ⊑
    add (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) { «nsw» := true, «nuw» := true }

theorem test15a_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬x = 1#1 → ¬zeroExtend 53 1#8 ≥ ↑53 → 64#53 <<< zeroExtend 53 1#8 = 128#53

theorem or_ranges_single_elem_right_proof : or_ranges_single_elem_right_before ⊑ or_ranges_single_elem_right_after

theorem test_sub__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 ashrsgt_01_08_thm (e : IntW 4) : icmp IntPred.sgt (ashr e (const? 4 1)) (const? 4 (-8)) ⊑ const? 1 1

theorem lshrugt_03_06_exact_proof : lshrugt_03_06_exact_before ⊑ lshrugt_03_06_exact_after

theorem e_848 :
    2 *  ~~~(z &&& t) + 7 *  ~~~(z &&&  ~~~z) - 4 *  ~~~(z ||| t) - 9 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) - 2 * (z &&& t) = 5 *  ~~~(z ^^^ t)

theorem e_393 :
    4 *  ~~~(x &&& y) + 3 * (x ||| y) + 4 *  ~~~(x &&&  ~~~y) + 2 * (x |||  ~~~y) - 8 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) - 9 * (x &&& y) = 2 *  ~~~x

theorem ne_nuw_rem_nz_proof : ne_nuw_rem_nz_before ⊑ ne_nuw_rem_nz_after

theorem zext_nneg_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ (x &&& 32767#16).msb = true) →
    zeroExtend 24 (x &&& 32767#16) &&& 8388607#24 = zeroExtend 24 (x &&& 32767#16)

theorem or_not_xor_common_op_commute5_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  x_2 ^^^ x_1 ||

theorem t7_ugt_sgt_neg1_proof : t7_ugt_sgt_neg1_before ⊑ t7_ugt_sgt_neg1_after

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

theorem add_smin_simplify2_proof : add_smin_simplify2_before ⊑ add_smin_simplify2_after

theorem or_xor_tree_1001_proof : or_xor_tree_1001_before ⊑ or_xor_tree_1001_after

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

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

theorem select_non_const_sides_thm.extracted_1._3 : ∀ (x x_1 : BitVec 64) (x_2 : BitVec 1),
  x_2 = 1#1 → x_1 - zeroExtend 64 x_2 = x_1 + -1#64

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

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

theorem ashr_and_or_disjoint_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
        2#8 ≥ ↑8 ∨ True ∧ (x_1.srem 42#8 &&& (x.sshiftRight' 2#8 &&& 13#8) != 0) = true ∨ 2#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
        2#8 ≥ ↑8 ∨ True ∧ (x &&& 52#8 &&& x_1.srem 42#8 <<< 2#8 != 0) = true →
      False

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

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

theorem zext_nneg_redundant_and_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.msb = true) → zeroExtend 32 x &&& 127#32 = zeroExtend 32 x

theorem e_685 :
    7 *  ~~~y + 5 *  ~~~(x ^^^ y) - 2 * (x ^^^ y) - 1 *  ~~~x - 2 *  ~~~(x &&&  ~~~x) + 11 *  ~~~(x &&&  ~~~y) - 19 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) - 2 * (x &&&  ~~~y) - 14 * (x &&& y) = 1 *  ~~~(x &&& y)

theorem t3_ult_sgt_neg1_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult (add e_2 (const? 32 16)) (const? 32 144)) e_2
      (select (icmp IntPred.sgt e_2 (const? 32 (-17))) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e e_2)

theorem ashrsgt_02_04_exact_proof : ashrsgt_02_04_exact_before ⊑ ashrsgt_02_04_exact_after

theorem lshr_and_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → x ≥ ↑8 → False

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

theorem test2_proof : test2_before ⊑ test2_after

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

theorem urem_i32_c_multiuse_thm (e : IntW 8) :
  add (zext 32 e) (urem (zext 32 e) (const? 32 10)) ⊑
    add (urem (zext 32 e) (const? 32 10)) (zext 32 e) { «nsw» := true, «nuw» := true }

theorem syncMap2_flip {f : α → β → γ} :
  syncMap₂ f xs ys = syncMap₂ (fun y x => f x y) ys xs

theorem one_side_fold_sgt_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → False

theorem sgt_and_min_thm.extracted_1._1 : ∀ (x x_1 : BitVec 9),
  ofBool (x <ₛ x_1) &&& ofBool (x_1 == BitVec.ofInt 9 (-256)) = 0#1

theorem e_2084 :
    7 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * (e &&&  ~~~(d &&& f)) - 1 * (f ^^^ (d &&& e)) + 1 * (f ^^^ (d ||| ( ~~~e ||| f))) + 4 * (f ^^^ ( ~~~d ||| (e &&& f))) - 5 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) - 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 7 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 4 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 2 * e + 5 * ( ~~~f &&& (d ^^^ e)) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 *  ~~~(d ^^^ (e ^^^ f)) - 3 * ((d ||| e) &&& (e ^^^ f)) + 11 * (d &&&  ~~~e) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 6 * (d ^^^ (e ^^^ f)) - 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * (e ||| (d ^^^ f)) + 2 *  ~~~(d ||| ( ~~~e &&& f)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * (e ^^^ (d ||| f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 3 * (e ^^^ (d &&& f)) - 3 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (d &&&  ~~~f) + 2 * ((d &&& e) |||  ~~~(e ||| f)) - 8 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~(d ||| ( ~~~e ||| f)) - 16 *  ~~~( ~~~d ||| (e ||| f)) - 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) - 11 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) + 16 * (d &&& (e &&& f)) =  - 5 * (e &&&  ~~~f) + 2 * ((d &&& e) |||  ~~~(e |||  ~~~f))

theorem main5e_like_proof : main5e_like_before ⊑ main5e_like_after

theorem t_2_192_thm (e : IntW 8) :
  LLVM.and (select (icmp IntPred.ugt e (const? 8 2)) e (const? 8 2)) (const? 8 (-64)) ⊑
    LLVM.and e (const? 8 (-64))

theorem uge_or_not_max_logical_proof : uge_or_not_max_logical_before ⊑ uge_or_not_max_logical_after

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

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

theorem n10_wrong_pred2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (add e_1 e) e ⊑ icmp IntPred.eq e_1 (const? 8 0)

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

@[simp] theorem isPoison_value : isPoison (value a) = false

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

theorem test13_proof : test13_before ⊑ test13_after

theorem bitwise_and_logical_and_masked_icmp_allones_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 &&& 8#32 == 8#32) = 1#1 →
    ¬ofBool (x_1 &&& 15#32 == 15#32) = 1#1 → x &&& ofBool (x_1 &&& 7#32 == 7#32) = 0#1

theorem udiv_shl_shl_nuw_nsw2_thm (e e_1 e_2 : IntW 8) :
  LLVM.udiv (shl e_2 e_1 { «nsw» := true, «nuw» := true }) (shl e e_1 { «nsw» := true, «nuw» := false }) ⊑
    LLVM.udiv e_2 e

theorem e_930 :
    7 *  ~~~(z ^^^ t) + 2 * (z |||  ~~~t) + 1 * (z ||| t) - 9 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) - 17 * (z &&& t) = 3 * (z &&&  ~~~t) - 7 * 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_1190 :
     - 7 *  ~~~(z ^^^ t) - 2 *  ~~~t + 1 *  ~~~z + 3 * (z ^^^ t) + 20 *  ~~~(z ||| t) + 3 *  ~~~(z |||  ~~~t) + 11 * (z &&&  ~~~t) + 12 * (z &&& t) = 5 * (z |||  ~~~t) + 7 *  ~~~(z &&& t)

theorem icmp_eq_zext_ne_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x) = ofBool (x <ᵤ 2#32)

theorem shl_fold_or_disjoint_cnt_proof : shl_fold_or_disjoint_cnt_before ⊑ shl_fold_or_disjoint_cnt_after

theorem mul32_low_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32) →
    (x_1 >>> 16#32 * (x &&& 65535#32) + (x_1 &&& 65535#32) * x >>> 16#32) <<< 16#32 +
        (x_1 &&& 65535#32) * (x &&& 65535#32) =
      x * x_1

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem a_false_implies_b_false2_comm_proof : a_false_implies_b_false2_comm_before ⊑ a_false_implies_b_false2_comm_after

theorem and_sext_multiuse_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_2 <ₛ x_3) = 1#1 →
    (signExtend 32 (ofBool (x_2 <ₛ x_3)) &&& x_1) + (signExtend 32 (ofBool (x_2 <ₛ x_3)) &&& x) = x_1 + x

theorem different_size_zext_zext_sgt_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_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_after

theorem bv_AddSub_1624 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.sub (LLVM.or e e_1) (LLVM.xor e e_1) ⊑ LLVM.and e e_1

theorem lshrult_02_12_proof : lshrult_02_12_before ⊑ lshrult_02_12_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 gt_unsigned_to_small_unsigned_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (17#32 <ᵤ zeroExtend 32 x) = ofBool (17#8 <ᵤ x)

theorem ugt_zext_thm (e : IntW 8) (e_1 : IntW 1) :
  icmp IntPred.ugt (zext 8 e_1) e ⊑ LLVM.and (icmp IntPred.eq e (const? 8 0)) e_1

theorem sge_or_max_commute_proof : sge_or_max_commute_before ⊑ sge_or_max_commute_after

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

theorem lshrult_01_03_proof : lshrult_01_03_before ⊑ lshrult_01_03_after

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

theorem prove_exact_with_high_mask_limit_proof : prove_exact_with_high_mask_limit_before ⊑ prove_exact_with_high_mask_limit_after

theorem lshrugt_01_00_proof : lshrugt_01_00_before ⊑ lshrugt_01_00_after

theorem ripple_nsw3_proof : ripple_nsw3_before ⊑ ripple_nsw3_after

theorem lshr_and_add_fail_proof : lshr_and_add_fail_before ⊑ lshr_and_add_fail_after

theorem main7f_proof : main7f_before ⊑ main7f_after

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 ^^^ (x_1 ^^^ -1#32) &&& x = x_2 &&& x_1 ||

theorem sge_swap_and_max_commute_proof : sge_swap_and_max_commute_before ⊑ sge_swap_and_max_commute_after

theorem lshr_mul_times_3_div_2_exact_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 3#32 = true ∨ True ∧ (x * 3#32) >>> 1#32 <<< 1#32 ≠ x * 3#32 ∨ 1#32 ≥ ↑32) →
    ¬(True ∧ x >>> 1#32 <<< 1#32 ≠ x ∨ 1#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x >>> 1#32) = true) →
      (x * 3#32) >>> 1#32 = x + x >>> 1#32

theorem a_false_implies_b_true2_comm_thm.extracted_1._7 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ¬ofBool (x_2 <ᵤ 20#8) = 1#1 → ofBool (10#8 <ᵤ x_2) = 1#1 → x ||
</all_available_lemmas>

<local_ctx>
import LeanMLIR.Framework

import LeanMLIR.Util

import Mathlib.Tactic.Linarith

namespace Tensor1D

abbrev Index := ℕ

structure Tensor1d (α : Type) [Inhabited α] where
  size : Index
  val :  Index → α
  spec : ∀ (ix: Index), ix >= size -> val ix = default

def Tensor1d.extract [Inhabited α] (t: Tensor1d α)
  (left: Index) (len: Index) : Tensor1d α :=
  let right := if (left + len) < t.size then left + len else 0
  let size := right - left
  { size := size,
    val := fun ix =>
    if left + len < t.size
    then if (ix < len) then t.val (ix + left) else default
    else default,
    spec := by admit /- proof elided -/

def Tensor1d.insertslice  [Inhabited α] (t: Tensor1d α)
  (sliceix: Nat)
  (slice : Tensor1d α) : Tensor1d α where
  size := if sliceix > t.size then 0 else t.size + slice.size
  val := fun ix =>
    if sliceix > t.size then default 
    else if ix >= t.size + slice.size then default 
    else
      let go (ix: Nat) : α :=
        if ix < sliceix then t.val sliceix
        else if ix < sliceix + slice.size then slice.val (ix - sliceix)
        else t.val (ix - (sliceix + slice.size))
      go ix
  spec := by admit /- proof elided -/
</local_ctx>

<target_theorem>
theorem extractslice_insertslice [Inhabited α]
  (t: Tensor1d α)
  (sliceix: Nat)
  (slice: Tensor1d α)
  (CORRECT: ((t.insertslice sliceix slice).extract sliceix slice.size).size ≠ 0)
  : (t.insertslice sliceix slice).extract sliceix slice.size = slice :=
</target_theorem>

