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

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

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

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

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

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

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

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

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

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

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

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

open Set
open Mathlib
open SetRel

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

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

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

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

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

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

@[simp]
</local_ctx>

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

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

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

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

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

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

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

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

### Your task:
<all_available_defs>
Array in Init.Prelude
Array.emptyWithCapacity in Init.Prelude
Nat in Init.Prelude
BEq in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Repr in Init.Data.Repr
Std.HashMap in Std.Data.HashMap.Basic
Std.HashSet in Std.Data.HashSet.Basic
BitVec in Init.Prelude
Prod in Init.Prelude
Prod.mk in Init.Prelude
Bool in Init.Prelude
Classical.propDecidable in Init.Classical
Decidable in Init.Prelude
NFA in Mathlib.Computability.NFA
Set in Mathlib.Data.Set.Defs
SetRel in Mathlib.Data.Rel
List in Init.Prelude
Subtype in Init.Prelude
LawfulBEq in Init.Core
Function.Injective2 in Mathlib.Logic.Function.Basic
List.Nodup in Init.Data.List.Basic
FinEnum.toList in Mathlib.Data.FinEnum

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

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

abbrev State := Nat

def product (final? : Prop → Prop → Prop) (M N : NFA' n) : NFA' n where
  σ := _
  M := M.M.product final? N.M

structure NFA' (n : Nat) where
  σ : Type
  M : NFA (BitVec n) σ

def nfa : NFA A S where
  start := { sa | sa ∈ inits }
  accept := { sa | final sa }
  step sa a := { sa' | (a, sa') ∈ f sa }

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

axiom hashMap_missing : ∀ {P : Prop}, P

def icmp_equality_test_commute_icmp2_before := [llvm|
{
^0(%arg20 : i64, %arg21 : i64, %arg22 : i64):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "eq" %arg22, %arg20 : i64
  %3 = llvm.icmp "eq" %arg21, %arg22 : i64
  %4 = llvm.icmp "eq" %arg21, %arg20 : i64
  %5 = llvm.xor %3, %0 : i1
  %6 = "llvm.select"(%5, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = "llvm.select"(%2, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

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

instance : DialectSignature ExOp ExTy where
  signature
  | .add    => ⟨[.nat, .nat], [], .nat, .pure⟩
  | .runK _ => ⟨[.nat], [([.nat], .nat)], .nat, .pure⟩

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

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

instance : ToString (MOp φ) where
  toString
  | .and _      => "and"
  | .or _ _     => "or"
  | .not _      => "not"
  | .xor _      => "xor"
  | .shl _ _    => "shl"
  | .lshr _ _   => "lshr"
  | .ashr _ _   => "ashr"
  | .urem _     => "urem"
  | .srem _     => "srem"
  | .select _   => "select"
  | .add _ _    => "add"
  | .mul _ _    => "mul"
  | .sub _ _    => "sub"
  | .neg _      => "neg"
  | .copy _     => "copy"
  | .freeze _   => "freeze"
  | .trunc _ _ _  => "trunc"
  | .zext _ _ _ => "zext"
  | .sext _ _   => "sext"
  | .sdiv _ _   => "sdiv"
  | .udiv _ _   => "udiv"
  | .icmp ty _  => s!"icmp {ty}"
  | .const _ v  => s!"const {v}"

def test6_before := [llvm|
{
^0(%arg1 : i7):
  %0 = llvm.mlir.constant(23 : i7) : i7
  %1 = llvm.xor %arg1, %0 : i7
  %2 = llvm.xor %1, %0 : i7
  "llvm.return"(%2) : (i7) -> ()
}
]

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

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

def ashr_exact_add_nuw_before := [llvm|
{
^0(%arg62 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-4 : i32) : i32
  %2 = llvm.add %arg62, %0 overflow<nuw> : i32
  %3 = llvm.ashr exact %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

instance : Inhabited (
  {lets : Lets d Γstart .pure Γ} →
  State d lets →
  (com: Com d Γ .pure α) →
  { com' : Com d Γ .pure α // ∀ (V: Ctxt.Valuation Γ), com.denote V = com'.denote V }) where
  default := fun _s com => ⟨com, by admit /- proof elided -/
  ⟩

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

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

def t1_after := [llvm|
{
^0(%arg31 : i8):
  %0 = llvm.mlir.constant(31 : i8) : i8
  %1 = llvm.mlir.constant(-32 : i8) : i8
  %2 = llvm.add %arg31, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

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

def xor_ashr_not_fail_ashr_lshr_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.ashr %arg18, %arg20 : i8
  %2 = llvm.lshr %arg19, %arg20 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

def or_trunc_lshr_after := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(1 : i6) : i6
  %1 = llvm.mlir.constant(-32 : i6) : i6
  %2 = llvm.trunc %arg2 : i8 to i6
  %3 = llvm.lshr %2, %0 : i6
  %4 = llvm.or disjoint %3, %1 : i6
  "llvm.return"(%4) : (i6) -> ()
}
]

def ne_basic_equal_5_after := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(-6 : i8) : i8
  %1 = llvm.add %arg32, %0 : i8
  %2 = llvm.icmp "ult" %1, %arg33 : i8
  "llvm.return"(%2) : (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 test9b_after := [llvm|
{
^0(%arg109 : i32, %arg110 : i32):
  %0 = llvm.or %arg109, %arg110 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

instance : HasUB Option where
  throwUB := none

def negNumToTerm : TSyntax ``neg_num → MacroM Term
  | `(neg_num| $x:num) => `($x:num)
  | `(neg_num| -$x:num) => `(-$x:num)
  | _ => Macro.throwUnsupported

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

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

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

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

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

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

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

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

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

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

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

Min in Init.Prelude

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

def worklistRun'_spec :
    (worklistRun' A S final inits hinits f |>.Sim $ nfa inits final f) :=

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

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

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

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

def test9_after := [llvm|
{
^0(%arg5 : i1005):
  "llvm.return"(%arg5) : (i1005) -> ()
}
]

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

def Context (Ty : Type) : Type :=
  List (VarName × Ty)

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

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

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

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

IO.Error in Init.System.IOError

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

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

instance : Lean.ToExpr RegIndex := inherit

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

def univ [DecidableEq ι] [Fintype ι] (n : Nat) :
    { univ : Finset (Inputs ι n) // ∀ x : Inputs ι n, x ∈ univ } :=
  let ixs : Finset (Fin n) := Finset.univ
  let inputs : Finset ι := Finset.univ
  let out := ixs.biUnion
      (fun ix => inputs.map ⟨fun input => Inputs.mk ix input, by admit /- proof elided -/
      ⟩)
  ⟨out, by admit /- proof elided -/
  ⟩

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

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

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

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

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

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

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

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

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

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

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

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

def test19_after := [llvm|
{
^0(%arg15 : i37):
  %0 = llvm.mlir.constant(4 : i37) : i37
  %1 = llvm.icmp "ult" %arg15, %0 : i37
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def Tensor2d'.error (α : Type) : Tensor2d' α where
  dim₀ := 0
  dim₁ := 0
  mat := Matrix.of fun x _y => x.elim0

def select_icmp_eq_and_4096_0_or_4096_after := [llvm|
{
^0(%arg225 : i32, %arg226 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.and %arg225, %0 : i32
  %2 = llvm.or %arg226, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def sextbool_add_before := [llvm|
{
^0(%arg12 : i1, %arg13 : i32):
  %0 = llvm.sext %arg12 : i1 to i32
  %1 = llvm.add %0, %arg13 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def zext_ult_zext_before := [llvm|
{
^0(%arg159 : i1, %arg160 : i8):
  %0 = llvm.mul %arg160, %arg160 : i8
  %1 = llvm.zext %arg159 : i1 to i16
  %2 = llvm.zext %0 : i8 to i16
  %3 = llvm.icmp "ult" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def trunc_unsigned_nsw_sext_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i8):
  %0 = llvm.sext %arg31 : i8 to i32
  %1 = llvm.icmp "ult" %arg30, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

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

structure Item where
 name : String
 tac : Syntax

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

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

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

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

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

Std.Format.group in Init.Data.Format.Basic

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 test2_after := [llvm|
{
^0(%arg4 : i16, %arg5 : i16):
  %0 = llvm.add %arg4, %arg5 : i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

def getWidth (expr : Expr) : MetaM (Option Nat) := do
  match_expr expr with
  | BitVec n => getNatValue? n
  | _ => pure none

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

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

Std.Tactic.BVDecide.BVBinOp.add in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

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

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

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

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

def lshr_32_add_zext_basic_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.zext %arg25 : i32 to i64
  %2 = llvm.zext %arg26 : i32 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.lshr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

def not_sext_after := [llvm|
{
^0(%arg7 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg7, %0 : i1
  %2 = llvm.sext %1 : i1 to i999
  "llvm.return"(%2) : (i999) -> ()
}
]

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

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

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

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

def printAttributes: RISCV64.Op → String
  | .li imm => s! "\{immediate = { imm.toInt } : i64 }"
  | .addiw (imm : BitVec 12) => s!"\{immediate = { imm.toInt} : si12 }"
  | .lui (imm : BitVec 20) => s!"\{immediate = { imm.toInt} : ui20 } "
  | .auipc (imm : BitVec 20) => s!"\{immediate = { imm.toInt} : si20 }" 
  | .slliw (imm : BitVec 5) => s!"\{immediate = { imm.toNat} : ui5 }"
  | .srliw (imm : BitVec 5) => s!"\{immediate = { imm.toNat} : ui5 }"
  | .sraiw (imm : BitVec 5) => s!"\{immediate = { imm.toNat} : ui5 }"
  | .slli (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .srli (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .srai (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .addi (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .slti (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .sltiu (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .andi (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .ori (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .xori (imm : BitVec 12) => s!"\{immediate = { imm.toInt } : si12 }"
  | .bclri (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i6 }"
  | .bexti (imm : BitVec 6) =>s!"\{immediate = { imm.toInt} : i6 }"
  | .binvi (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i6 }"
  | .bseti (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i6 }"
  | .slliuw (imm : BitVec 6) => s!"\{immediate = { imm.toNat} : ui6 }"
  | .rori (imm : BitVec 6) => s!"\{immediate = { imm.toInt} : i5 }"
  | .roriw (imm : BitVec 5) => s!"\{immediate = { imm.toInt} : i5 }"
  | _ => ""

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

RV64.ctzw in RISCV.Instructions

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

def test_nuw_nsw_and_signed_pred_after := [llvm|
{
^0(%arg54 : i64):
  %0 = llvm.mlir.constant(7) : i64
  %1 = llvm.icmp "ugt" %arg54, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

RV64.sltiu in RISCV.Instructions

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

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

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

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

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

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

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

Int.lt in Init.Data.Int.Basic

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

Lean.Parser.termParser in Lean.Parser.Basic

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

def cadicalTimeoutSec : Nat := 1000

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

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

def p_constmask2_after := [llvm|
{
^0(%arg41 : i32, %arg42 : i32):
  %0 = llvm.mlir.constant(61440 : i32) : i32
  %1 = llvm.mlir.constant(-65281 : i32) : i32
  %2 = llvm.and %arg41, %0 : i32
  %3 = llvm.and %arg42, %1 : i32
  %4 = llvm.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

def parseRegionFromFile (fileName : String)
    (regionParseFun : MLIR.AST.Region 0 → Except ParseError α) : IO (Option α)  := do
  let ast ← runParser regionParser fileName
  match Option.map regionParseFun ast with
  | .some (.ok res) => return res
  | .some (.error msg) => throw <| IO.userError s!"Error parsing {fileName}:\n{msg}"; return none
  | .none => return none

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

def lt_signed_to_large_signed_before := [llvm|
{
^0(%arg52 : i8):
  %0 = llvm.mlir.constant(1024 : i32) : i32
  %1 = llvm.sext %arg52 : i8 to i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

partial def repeatDce {Γ : Ctxt d.Ty} {t}
    (com : Com d Γ .pure t) :
    { com' : Com d Γ .pure t //  ∀ (V : Γ.Valuation), com.denote V = com'.denote V} :=
  (go com)
where go (com : Com d Γ .pure t) : RepeatDCEType com :=
  let ⟨dceCom, h⟩ := dce' com
  if dceCom = com then
    ⟨dceCom, h⟩
  else
    let ⟨res, h_res⟩ := go dceCom
    ⟨res, by admit /- proof elided -/
    ⟩

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

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

def mainCmd := `[Cli|
    opt VIA runMainCmd;
    "opt: apply verified rewrites"
    FLAGS:
      verbose; "Prints verbose output for debugging using the Repr typeclass to print."
      passriscv64; "Lowering pass to a RISC-V 64 SSA-assembly IR"
      riscv; "Allows to parse a file as a RISC-V 64 SSA-assembly IR"
      passriscv64_optimized; "Allows to parse a file as a RISC-V 64 SSA-assembly IR"
      passriscv64_optimized_const; "Allows to parse a file as a RISC-V 64 SSA-assembly IR, including rewrites with constant matching"
      passriscv64_selectiondag; "Lowering pass to RISC-V 64 SSA-assembly IR applying optimizations from SelectionDAG"
    ARGS:
      file: String; "Input filename"
    ]

def udiv_i32_multiuse_after := [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 overflow<nsw,nuw> : i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def ashr_32_add_zext_basic_before := [llvm|
{
^0(%arg9 : i32, %arg10 : i32):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.zext %arg9 : i32 to i64
  %2 = llvm.zext %arg10 : i32 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.ashr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

def t0_basic_before := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.sub %arg24, %arg25 : i8
  %1 = llvm.icmp "ule" %0, %arg24 : 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 ule_swap_and_min_logical_after := [llvm|
{
^0(%arg196 : i8, %arg197 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg196, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

Lean.initSearchPath in Lean.Util.Path

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

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

def foo_after := [llvm|
{
^0(%arg0 : i1):
  "llvm.return"(%arg0) : (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 and_or3_commuted_after := [llvm|
{
^0(%arg164 : i1, %arg165 : i1, %arg166 : i32, %arg167 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ne" %arg166, %arg167 : i32
  %3 = "llvm.select"(%2, %0, %arg164) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%arg165, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def test3_before := [llvm|
{
^0(%arg24 : i97):
  %0 = llvm.mlir.constant(0 : i97) : i97
  %1 = llvm.sub %0, %arg24 : i97
  %2 = llvm.sub %0, %1 : i97
  "llvm.return"(%2) : (i97) -> ()
}
]

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

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

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

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

def ne_shift_in_zeros_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg32, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg32, %1 : i32
  %5 = llvm.trunc %4 : i32 to i24
  %6 = llvm.lshr %arg33, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg33, %1 : i32
  %9 = llvm.trunc %8 : i32 to i24
  %10 = llvm.icmp "ne" %3, %7 : i8
  %11 = llvm.icmp "ne" %5, %9 : i24
  %12 = llvm.or %11, %10 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

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

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

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

def llvm_const_lower_riscv_li_43 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_43, rhs:= liRiscv_43,
   correct := by admit /- proof elided -/

def test_simplify_decrement_invalid_ne_after := [llvm|
{
^0(%arg209 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg209, %0 : i8
  %2 = llvm.sext %1 : i1 to i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

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

def Sexpr.atomOf {α : Type} [ToFormat α] (x : α) : Sexpr :=
  Sexpr.atom (format x)

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

WithBot.recBotCoe in Mathlib.Order.TypeTags

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

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

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

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

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

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

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

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

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

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

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

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

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

def positive_biggershl_after := [llvm|
{
^0(%arg59 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(-64 : i8) : i8
  %2 = llvm.shl %arg59, %0 : i8
  %3 = llvm.and %2, %1 : i8
  "llvm.return"(%3) : (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 negate_add_with_single_negatible_operand_depth2_after := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.mlir.constant(-21 : i8) : i8
  %1 = llvm.sub %0, %arg21 : i8
  %2 = llvm.mul %1, %arg22 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

Zero in Init.Prelude

def t2_before := [llvm|
{
^0(%arg25 : i8, %arg26 : i1, %arg27 : i1):
  %0 = llvm.sext %arg26 : i1 to i8
  %1 = llvm.sext %arg27 : i1 to i8
  %2 = llvm.add %0, %arg25 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def scalar_i8_shl_uge_const_before := [llvm|
{
^0(%arg13 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg13, %0 : i8
  %3 = llvm.icmp "uge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

def add_nuw_or_and_after := [llvm|
{
^0(%arg9 : i32, %arg10 : i32):
  %0 = llvm.add %arg9, %arg10 overflow<nuw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

    |

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

def xor_andn_commute4_after := [llvm|
{
^0(%arg66 : i32, %arg67 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.udiv %0, %arg66 : i32
  %2 = llvm.udiv %0, %arg67 : i32
  %3 = llvm.or %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def mulMax' (a : BitVec o) (wmask : BitVec o) (b : BitVec o) (vmask : BitVec o) : BitVec o :=
    let max := mulMax'Mask wmask vmask
    (a * b) &&& max

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

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

def test_zext_nneg_before := [llvm|
{
^0(%arg25 : i32, %arg26 : i64, %arg27 : i64):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(-5) : i64
  %2 = llvm.xor %arg25, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  %4 = llvm.add %arg26, %1 : i64
  %5 = llvm.add %3, %arg27 : i64
  %6 = llvm.sub %4, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

def Hom.comp : Hom Γ Ξ :=
  fun _t v => g (f v)

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

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

def in_constant_varx_6_invmask_before := [llvm|
{
^0(%arg39 : i4, %arg40 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.mlir.constant(6 : i4) : i4
  %2 = llvm.xor %arg40, %0 : i4
  %3 = llvm.xor %arg39, %1 : i4
  %4 = llvm.and %3, %2 : i4
  %5 = llvm.xor %4, %1 : i4
  "llvm.return"(%5) : (i4) -> ()
}
]

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

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

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

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

private def attrVal8Alias : AttrVal := [mlir_attr_val| #"A" ]

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

def scalar_i16_shl_ult_const_before := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.mlir.constant(1024 : i16) : i16
  %2 = llvm.shl %arg16, %0 : i16
  %3 = llvm.icmp "ult" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def udiv400_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.lshr %arg5, %0 : i32
  %3 = llvm.udiv %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test12_after := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(1431655765 : i32) : i32
  %1 = llvm.and %arg46, %0 : i32
  %2 = llvm.sub %arg47, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

def sub_mask1_lshr_after := [llvm|
{
^0(%arg21 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(10 : i8) : i8
  %3 = llvm.shl %arg21, %0 : i8
  %4 = llvm.ashr %3, %1 : i8
  %5 = llvm.add %4, %2 overflow<nsw> : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def IntToString (i: Int): String := i.repr

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

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

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

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

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

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

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

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

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

def Pointer.offsetInBits (p : Pointer) : Nat :=
  8 * p.offset.toNat

instance : Trans (@ExtEq Op) ExtEq ExtEq := ⟨ExtEq.trans⟩

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

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

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

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

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

def test1_before := [llvm|
{
^0(%arg3 : i333):
  %0 = llvm.mlir.constant(70368744177664 : i333) : i333
  %1 = llvm.urem %arg3, %0 : i333
  "llvm.return"(%1) : (i333) -> ()
}
]

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

def shl_nsw_nuw_uge_Csle0_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(-120 : i8) : i8
  %1 = llvm.shl %arg10, %arg11 overflow<nsw,nuw> : i8
  %2 = llvm.icmp "uge" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

private def fhe_test_one_rhs := [poly q, n, h | {
  ^bb0(%a : !R):
    return %a : !R
  }]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@[simp_denote]
def llvm_sub_nuw_16 := [LV| {
  ^entry (%x: i16, %y: i16):
    %1 = llvm.sub %x, %y overflow<nuw> : i16
    llvm.return %1 : i16
  }]

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

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

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

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

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

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

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

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

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

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

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

HDiv in Init.Prelude

def eq_commuted_after := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(43 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sdiv %0, %arg3 : i8
  %3 = llvm.add %arg2, %1 : i8
  %4 = llvm.icmp "uge" %3, %2 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def ne_and_lshr_minval_before := [llvm|
{
^0(%arg31 : i8, %arg32 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mul %arg31, %arg31 : i8
  %2 = llvm.lshr %0, %arg32 : i8
  %3 = llvm.and %1, %2 : i8
  %4 = llvm.icmp "ne" %3, %2 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

Lean.addAndCompile in Lean.AddDecl

inductive BasicBlock
  | mk (label : BlockLabel) (args : List VarName) (body : Body)

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

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

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

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

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

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

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

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

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

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

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

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

def ashr_x_by_const_cmp_sge_x_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.ashr %arg6, %0 : i32
  %2 = llvm.icmp "sge" %1, %arg6 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

Int.sub in Init.Data.Int.Basic

def Expr.HasPureOp (e : Expr d Γ eff ty) : Prop :=
  DialectSignature.effectKind e.op = .pure

def p15_commutativity2_after := [llvm|
{
^0(%arg24 : i32, %arg25 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.icmp "ugt" %arg24, %0 : i32
  %3 = "llvm.select"(%2, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def fstVal {r} {Γ : Ctxt _} (a : Γ.Var (.valuetokenstream r))  : Expr (DC) Γ .pure (.valuestream r)  :=
  Expr.mk
    (op := .fstVal r)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

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

def fork (x : TokenStream) : TokenStream × TokenStream  :=
  Stream.corec₂ (β := TokenStream) x
    fun x => Id.run <| do
      (x 0, x 0, x.tail)

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

Lean.Expr.app in Lean.Expr

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

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

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

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

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

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

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

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

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

def test_mul_nuw__all_are_safe_before := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(17 : i32) : i32
  %2 = llvm.mlir.constant(9 : i32) : i32
  %3 = llvm.mlir.constant(153 : i32) : i32
  %4 = llvm.and %arg14, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.mul %4, %2 overflow<nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

RV64.sll in RISCV.Instructions

def llvm_udiv_lower_riscv_flag_32: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs := udiv_llvm_exact_32, rhs := udiv_riscv_32, correct := sorry }

RV64.sltu in RISCV.Instructions

def t9_nocse_after := [llvm|
{
^0(%arg9 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.shl %0, %arg9 overflow<nuw> : i8
  %3 = llvm.shl %1, %arg9 overflow<nsw> : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

def xor_with_or_disjoint_ab_after := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  "llvm.return"(%arg27) : (i32) -> ()
}
]

instance : DialectParse TestDialect 0 where
  mkTy
    | .undefined "int" => return .int
    | .undefined "int2" => return .int2
    | _ => throw .unsupportedType
  isValidReturn _ stx := return (stx.name == "return")
  mkExpr Γ opStx := do
    let op : TestDialect.Op ← match opStx.name with
      | "noop"     => pure .noop
      | "unpair"   => pure .unPair
      | "pair"     => pure .mkPair
      | opName => throw <| .unsupportedOp opName
    opStx.mkExprOf Γ op

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

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

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

def two_inst_concrete_stmt (e : LLVM.IntW w) :
    (LLVM.not e) ⊑ (LLVM.not e) :=

def or_or_logic_and_1_before := [llvm|
{
^0(%arg12 : i1, %arg13 : i1, %arg14 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.or %arg12, %arg13 : i1
  %2 = llvm.or %arg14, %arg12 : i1
  %3 = "llvm.select"(%1, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def llvm_ashr_lower_riscv_flag_8 : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 8), Ty.llvm (.bitvec 8)] where
  lhs := ashr_llvm_exact_flag_8
  rhs := ashr_riscv_8

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

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

def Lets.changeEffect {eff₁ eff₂ : EffectKind} (h : eff₁ ≤ eff₂) :
    Lets d Γ_in eff₁ Γ_out → Lets d Γ_in eff₂ Γ_out
  | .nil => .nil
  | .var body e => .var (body.changeEffect h) (e.changeEffect h)

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

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

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

def logical_or_cond_reuse_before := [llvm|
{
^0(%arg256 : i1, %arg257 : i1):
  %0 = "llvm.select"(%arg256, %arg256, %arg257) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

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

def test_negative_nuw_and_signed_pred_after := [llvm|
{
^0(%arg53 : i64):
  %0 = llvm.mlir.constant(7) : i64
  %1 = llvm.icmp "ugt" %arg53, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

instance : DecidableNFA' (NFA'.autMsbSet) where

List.length in Init.Prelude

def src_x_and_nmask_sge_fail_maybe_z_before := [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 : 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 test_add_zero_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %zero = mod_arith.constant 0 : !R
    %add = mod_arith.add %zero, %x : !R
    return %add : !R
}]

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

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

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

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

def scalar_i64_shl_ult_const_before := [llvm|
{
^0(%arg14 : i64):
  %0 = llvm.mlir.constant(25) : i64
  %1 = llvm.mlir.constant(8589934592) : i64
  %2 = llvm.shl %arg14, %0 : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def ex1_post_cse :
 { com' : Com Ex ∅ .pure [.nat] // ∀ V, ex1_pre_cse.denote V = com'.denote V } :=
   cse' ex1_pre_cse

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

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

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

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

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

def or_eq_notY_eq_0_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 liRiscv12 := [LV| {
  ^entry ():
    %0 = "li"() {imm = 12 : !i64} : (!i64) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def shl_xor_lshr_after := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.lshr %arg102, %arg101 : i32
  %1 = llvm.xor %0, %arg100 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

instance : Min EffectKind where
  min := inf

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

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

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

structure State where
  
  e2ix : Std.HashMap Expr Ix := {}

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

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

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

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

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

abbrev WidthExpr := Expr

def t9_ashr_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i16):
  %0 = llvm.mlir.constant(32 : i16) : i16
  %1 = llvm.mlir.constant(-2 : i16) : i16
  %2 = llvm.sub %0, %arg3 : i16
  %3 = llvm.zext %2 : i16 to i32
  %4 = llvm.ashr %arg2, %3 : i32
  %5 = llvm.trunc %4 : i32 to i16
  %6 = llvm.add %arg3, %1 : i16
  %7 = llvm.ashr %5, %6 : i16
  "llvm.return"(%7) : (i16) -> ()
}
]

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

def shift_xor_multiuse_cmp_and_before := [llvm|
{
^0(%arg28 : i32, %arg29 : i32, %arg30 : i32, %arg31 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg28, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.and %arg29, %2 : i32
  %6 = "llvm.select"(%4, %arg29, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg30, %arg31) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  %9 = llvm.mul %8, %5 : i32
  "llvm.return"(%9) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

def llvm_sext_lower_riscv_i16_to_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 16)] :=
  {lhs:= sext_llvm_i16_to_32, rhs:= sext_riscv_i16_to_32}

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

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

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

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

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

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

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

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

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

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

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

def sel_zext_after := [llvm|
{
^0(%arg89 : i32, %arg90 : i1):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.zext %arg89 : i32 to i64
  %2 = "llvm.select"(%arg90, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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

@[match_pattern] abbrev lshr (w : Nat) (flag : ExactFlag := {} ) : LLVM.Op := MOp.lshr (.concrete w) flag

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

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

structure NoWrapFlags where
  nsw : Bool := false
  nuw : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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

def n10_after := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.ashr %arg0, %0 : i64
  %3 = llvm.trunc %2 overflow<nsw> : i64 to i32
  %4 = llvm.add %3, %1 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

instance : DecidableEq BlockLabel :=

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

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

def positive_samevar_before := [llvm|
{
^0(%arg62 : i8, %arg63 : i8):
  %0 = llvm.lshr %arg62, %arg63 : i8
  %1 = llvm.shl %0, %arg63 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def shl_add_add_fail_before := [llvm|
{
^0(%arg166 : i8, %arg167 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.lshr %arg166, %0 : i8
  %3 = llvm.lshr %arg167, %0 : i8
  %4 = llvm.add %3, %1 : i8
  %5 = llvm.add %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

BitVec.sshiftRight' in Init.Data.BitVec.Basic

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

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

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

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

def DialectMorphism.preserves_regSig (op : d.Op) :
    DialectSignature.regSig (f.mapOp op) = (DialectSignature.regSig op).map f.mapTy :=

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

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

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

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

@[simps]
def complete (M : NFA α σ) : NFA α (σ ⊕ Unit) where
  start := { x | match x with | .inl x => x ∈ M.start | .inr () => True }
  accept := { x | match x with | .inl x => x ∈ M.accept | .inr () => False }
  step x a := { y |
    match x with
    | .inl x => match y with | .inl y => y ∈ M.step x a | .inr () => False
    | .inr () => y = .inr () }

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

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

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

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

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

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

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

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

def t9_ashr_exact_flag_preservation_after := [llvm|
{
^0(%arg25 : i32, %arg26 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.ashr exact %arg25, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

def foo_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.add %arg3, %arg2 overflow<nsw> : i32
  %1 = llvm.mul %0, %arg3 overflow<nsw> : i32
  %2 = llvm.mul %arg3, %arg3 overflow<nsw> : i32
  %3 = llvm.sub %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

def freeze_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_freeze_lower_riscv_64)
]

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

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

def ashr_exact_add_negative_shift_negative_before := [llvm|
{
^0(%arg49 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.add %arg49, %0 : i32
  %3 = llvm.ashr exact %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

RV64.sh2adduw in RISCV.Instructions

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

instance : ToString Ty where
  toString
  | Ty.bv => "!riscv.reg"

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

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

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

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

def negate_xor_after := [llvm|
{
^0(%arg142 : i4):
  %0 = llvm.mlir.constant(-6 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.xor %arg142, %0 : i4
  %3 = llvm.add %2, %1 : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

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

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

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

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

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

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

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

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

Lean.levelZero in Lean.Level

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

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

def test6_before := [llvm|
{
^0(%arg302 : i1):
  %0 = llvm.and %arg302, %arg302 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def t8_twoshifts3_before := [llvm|
{
^0(%arg24 : i32, %arg25 : i32, %arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %arg24, %arg25 : i32
  %3 = llvm.shl %0, %arg27 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def foo : Nat := 42

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

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

def isGteZeroCheck (expr : BoolExpr GenBVPred) : Bool :=
  match expr with
  | .literal (GenBVPred.bin _ BVBinPred.ult (GenBVExpr.shiftLeft (GenBVExpr.const bv) (GenBVExpr.bin (GenBVExpr.var _) BVBinOp.add (GenBVExpr.bin (GenBVExpr.const bv') BVBinOp.add (GenBVExpr.un BVUnOp.not (GenBVExpr.const bv'')))))) =>
          bv.toInt == 1 && bv'.toInt == 1 && bv''.toInt == 1
  | _ => false

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

Id in Init.Control.Id

inductive Op : Type _
  | comb (o : MLIR2Comb.Comb.Op)
  | hs (o : MLIR2Handshake.Handshake.Op)
  deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

def test7_before := [llvm|
{
^0(%arg202 : i32, %arg203 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.and %arg202, %0 : i32
  %3 = llvm.and %arg203, %1 : i32
  %4 = llvm.xor %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def fold_icmp_shl_nuw_c2_precondition3_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg0 overflow<nuw> : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def test14_before := [llvm|
{
^0(%arg36 : i1, %arg37 : i1):
  %0 = llvm.icmp "eq" %arg36, %arg37 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def add_constant_equal_with_the_top_bit_of_demandedbits_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 ashr_lshr_wrong_operands_before := [llvm|
{
^0(%arg77 : i32, %arg78 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "sge" %arg77, %0 : i32
  %2 = llvm.lshr %arg77, %arg78 : i32
  %3 = llvm.ashr %arg77, %arg78 : i32
  %4 = "llvm.select"(%1, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def tryFactorization_xor_lshr_ashr_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(-3 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.ashr %0, %arg39 : i32
  %3 = llvm.lshr %1, %arg39 : i32
  %4 = llvm.xor %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def zext_add_scalar_before := [llvm|
{
^0(%arg40 : i1):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.zext %arg40 : i1 to i32
  %2 = llvm.add %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

theorem test_slt_nuw_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(True ∧ signExtend 32 (truncate 8 x_1) ≠ x_1 ∨
        True ∧ zeroExtend 32 (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 <ₛ zeroExtend 32 x)

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

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

theorem zext_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 1#41 = zeroExtend 41 x

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

theorem ashrsgt_02_03_proof : ashrsgt_02_03_before ⊑ ashrsgt_02_03_after

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

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 64), zeroExtend 64 (truncate 32 x) = x &&& 4294967295#64

theorem bad_add1_proof : bad_add1_before ⊑ bad_add1_after

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

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

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

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

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

theorem shl_xor_thm (e e_1 : IntW 32) :
  shl (LLVM.xor (shl e_1 (const? 32 5)) e) (const? 32 7) ⊑
    LLVM.xor (shl e_1 (const? 32 12)) (shl e (const? 32 7))

theorem test25_proof : test25_before ⊑ test25_after

theorem test47_proof : test47_before ⊑ test47_after

theorem or_disjoint_with_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& x != 0) = true) → (x_1 ||| x) ^^^ x_1 = x

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

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

theorem zext_zext_ule_op0_wide_proof : zext_zext_ule_op0_wide_before ⊑ zext_zext_ule_op0_wide_after

theorem bools_multi_uses2_logical_thm.extracted_1._29 : ∀ (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 ^^^ x

theorem neg_mask_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow (signExtend 32 x) = true ∨
        15#16 ≥ ↑16 ∨ True ∧ (0#32).ssubOverflow (zeroExtend 32 (x >>> 15#16)) = true) →
    ofBool (x <ₛ 0#16) = 1#1 → True ∧ x_1.ssubOverflow (signExtend 32 x) = true → False

theorem fold_icmp_shl_nuw_c2_proof : fold_icmp_shl_nuw_c2_before ⊑ fold_icmp_shl_nuw_c2_after

theorem positive_biggerashr_shlnuw_proof : positive_biggerashr_shlnuw_before ⊑ positive_biggerashr_shlnuw_after

theorem ne_umin3_proof : ne_umin3_before ⊑ ne_umin3_after

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

theorem test8_thm (e : IntW 32) : LLVM.srem (shl e (const? 32 4)) (const? 32 8) ⊑ const? 32 0

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

theorem ashrsgt_03_06_proof : ashrsgt_03_06_before ⊑ ashrsgt_03_06_after

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

theorem e_2260 :
    7 * (e ||| f) + 5 * (d ||| ( ~~~e ||| f)) + 5 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (f ^^^  ~~~(d ||| e)) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (d ||| ( ~~~e &&& f)) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (e ^^^ (d &&&  ~~~f)) + 3 *  ~~~(d &&& e) - 5 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (e ^^^ (d &&& (e ^^^ f))) - 11 * (e ^^^  ~~~(d ||| f)) - 2 * f - 6 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 6 * (f ^^^ ( ~~~d ||| (e &&& f))) + 7 * (f ^^^ (d |||  ~~~e)) - 1 * (d ^^^ ( ~~~e &&& f)) - 2 * (e &&&  ~~~(d &&& f)) + 5 *  ~~~(d &&&  ~~~d) - 1 * (f ||| (d &&&  ~~~e)) - 7 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 2 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 3 * (f ^^^ (d &&& e)) + 11 *  ~~~(d ^^^ (e ^^^ f)) + 3 * (e &&& (d |||  ~~~f)) - 5 * (f ^^^  ~~~(d &&&  ~~~e)) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * ((d &&& e) |||  ~~~(e ||| f)) - 1 * (d &&& (e ||| f)) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 *  ~~~(d &&& ( ~~~e &&& f)) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * (d ^^^ ( ~~~e ||| f)) - 7 *  ~~~( ~~~d &&& (e ^^^ f)) + 7 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (f ^^^  ~~~(d &&& e)) + 7 * (e ^^^ (d &&& ( ~~~e ||| f))) + 7 * (f |||  ~~~(d ||| e)) + 7 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (d &&&  ~~~e) - 1 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 13 *  ~~~( ~~~d ||| (e ||| f)) + 13 * ( ~~~d &&& ( ~~~e &&& f)) - 27 * ( ~~~d &&& (e &&& f)) - 38 * (d &&& ( ~~~e &&& f)) + 14 * (d &&& (e &&& f)) =  - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f))

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

theorem t0_proof : t0_before ⊑ t0_after

theorem or_ranges_single_elem_left_proof : or_ranges_single_elem_left_before ⊑ or_ranges_single_elem_left_after

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

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

theorem neg_or_lshr_i32_commute_proof : neg_or_lshr_i32_commute_before ⊑ neg_or_lshr_i32_commute_after

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

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

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

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 sel_false_val_is_a_masked_shl_of_true_val2_thm.extracted_1._3 : ∀ (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 →
          False

lemma autOfTermUnop_bv_language op {t : Term} (m : CNFA (t.arity + 1)) :
    m.bv_recognizes t.language →
    (autOfTermUnop op m |>.bv_recognizes (op.subst_arity' ▸ (op.subst t).language))

theorem lt_signed_to_small_negative_proof : lt_signed_to_small_negative_before ⊑ lt_signed_to_small_negative_after

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

theorem test_shift_negative_thm (e e_1 : IntW 32) :
  icmp IntPred.slt
      (shl (LLVM.or e_1 (const? 32 (-2147483648))) (LLVM.and e (const? 32 7)) { «nsw» := true, «nuw» := false })
      (const? 32 0) ⊑
    const? 1 1

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

theorem  mkIndHypCycleBreaking_eval_eq_false_thm_aux
  {circs : KInductionCircuits fsm n}
  (hcircs : circs.IsLawful)
  (h : ∀ (env : _), (mkIndHypCycleBreaking circs).eval env = false) :
  (∀ (envBitstream : _) (s0 : _), (∀ (i : Nat) (j : Nat), i < j ∧ j ≤ n →
      (fsm.carryWith s0 envBitstream i) ≠ (fsm.carryWith s0 envBitstream j)) →
      (∀ (k : Nat), k < n + 1 → fsm.evalWith s0 envBitstream k = false) →
      (fsm.evalWith s0 envBitstream (n + 1) = false))

theorem t5_proof : t5_before ⊑ t5_after

theorem zext_zext_sgt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ zeroExtend 32 x_1) = ofBool (x <ᵤ x_1)

theorem sext_zext_apint2_thm.extracted_1._1 : ∀ (x : BitVec 11), signExtend 47 (zeroExtend 39 x) = zeroExtend 47 x

theorem and_orn_cmp_3_logical_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 72),
  ofBool (x_1 <ᵤ x_2) = 1#1 → ofBool (x_2 ≤ᵤ x_1) = 1#1 → 1#1 = ofBool (42#72 <ᵤ x)

theorem ashr_x_by_const_cmp_sge_x_thm (e : IntW 32) :
  icmp IntPred.sge (ashr e (const? 32 5)) e ⊑ icmp IntPred.slt e (const? 32 1)

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

theorem test12_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ x) &&& ofBool (x_1 ≤ᵤ x) = ofBool (x_1 <ᵤ x)

theorem ashrsgt_02_15_proof : ashrsgt_02_15_before ⊑ ashrsgt_02_15_after

theorem e_2270 :
    4 * ( ~~~d &&& (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * (e ||| (d &&& f)) - 11 * ( ~~~e &&&  ~~~(d ^^^ f)) - 7 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * (f ||| (d &&&  ~~~e)) - 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (d |||  ~~~e) + 1 * (f ^^^ (d |||  ~~~e)) + 3 * (d &&& f) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 7 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 4 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 7 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * ((d &&& e) |||  ~~~(e ||| f)) - 6 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (f ^^^ (d ||| e)) + 11 * ( ~~~d ||| (e &&& f)) + 4 * ((d &&& f) ^^^ (e ||| f)) - 3 * (e &&&  ~~~(d &&& f)) - 3 *  ~~~(d ^^^ e) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 1 * (d ^^^ ( ~~~e ||| f)) + 5 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 6 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 *  ~~~(d &&& f) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 5 *  ~~~(d ||| (e ^^^ f)) - 7 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 2 * (f &&&  ~~~(d &&& e)) - 1 * ( ~~~f &&& (d ^^^ e)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * (e ^^^ (d |||  ~~~f)) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 2 *  ~~~(d &&& e) + 11 * e - 1 * (d ||| f) - 6 * (f |||  ~~~(d ^^^ e)) - 5 * (f ^^^ (d ||| (e ||| f))) - 1 * (f ^^^  ~~~(d &&&  ~~~e)) - 6 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 5 * (d ^^^ e) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 3 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 20 *  ~~~(d ||| (e ||| f)) - 15 *  ~~~(d ||| ( ~~~e ||| f)) + 33 *  ~~~( ~~~d ||| (e ||| f)) - 7 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 23 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) = 6 * ( ~~~d &&& (e &&& f))

theorem ashr_ult_1_proof : ashr_ult_1_before ⊑ ashr_ult_1_after

theorem icmp_equality_test_wrong_and_proof : icmp_equality_test_wrong_and_before ⊑ icmp_equality_test_wrong_and_after

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

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

theorem t4_ugt_slt_65536_proof : t4_ugt_slt_65536_before ⊑ t4_ugt_slt_65536_after

theorem test19_proof : test19_before ⊑ test19_after

theorem and_xor_or8_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x_2 = 0 ∨ x = 0) → x_2 = 0 ∨ x_1 = 0 → False

@[simp] theorem toBitVec_ofBitVec (x : BitVec w) (w' : Nat) :
    toBitVec w' (ofBitVecSext x) = x.signExtend w'

theorem and_xor_or2_proof : and_xor_or2_before ⊑ and_xor_or2_after

theorem e_1447 :
     - 11 * z - 2 *  ~~~(z &&&  ~~~t) - 3 * (z ||| t) - 5 *  ~~~(z ^^^ t) + 1 * (z ^^^ t) + 4 *  ~~~z + 13 *  ~~~(z ||| t) - 1 *  ~~~(z |||  ~~~t) + 23 * (z &&&  ~~~t) + 21 * (z &&& t) = 11 *  ~~~t - 1 *  ~~~(z &&& t)

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

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

theorem sext_thm.extracted_1._1 : ∀ (x : BitVec 16),
  (zeroExtend 32 x ^^^ 32768#32) + BitVec.ofInt 32 (-32768) = signExtend 32 x

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

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

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 eq_umax3_proof : eq_umax3_before ⊑ eq_umax3_after

@[bv_multi_width_normalize] theorem ofBool_xor_ofBool (x y : Bool) :
  (BitVec.ofBool x ^^^ BitVec.ofBool y) = BitVec.ofBool (x ^^ y)

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

theorem demorgan_nand_apint2_proof : demorgan_nand_apint2_before ⊑ demorgan_nand_apint2_after

@[simp]
theorem Expr.pure_denoteOp_toPure (e : Expr d Γ eff ty) (h : e.HasPureOp) :
    pure ((e.toPure h).denoteOp V) = (e.denoteOp V)

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

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

theorem icmp_slt_0_or_icmp_eq_100_i32_fail_proof : icmp_slt_0_or_icmp_eq_100_i32_fail_before ⊑ icmp_slt_0_or_icmp_eq_100_i32_fail_after

theorem e_1336 :
     - 7 *  ~~~(z ^^^ t) - 6 * (z ||| t) + 7 * (z |||  ~~~t) + 2 *  ~~~(z &&& t) - 11 *  ~~~(z &&&  ~~~z) - 6 * z + 15 *  ~~~(z |||  ~~~t) + 14 * (z &&&  ~~~t) + 23 * (z &&& t) =  - 9 *  ~~~(z ||| t)

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

theorem shl_or_disjoint_lshr_comm_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑32 ∨ True ∧ (x_2 &&& x_1 <<< x != 0) = true ∨ x ≥ ↑32) →
    ¬(x ≥ ↑32 ∨ True ∧ (x_2 >>> x &&& x_1 != 0) = true) → (x_2 ||| x_1 <<< x) >>> x = x_2 >>> x ||

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

theorem udiv_c_i32_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬zeroExtend 32 x = 0 → ¬(x = 0 ∨ True ∧ (10#8 / x).msb = true) → 10#32 / zeroExtend 32 x = zeroExtend 32 (10#8 / x)

theorem shl_or_lshr_comm_thm (e e_1 e_2 : IntW 32) :
  lshr (LLVM.or e_2 (shl e_1 e { «nsw» := false, «nuw» := true })) e ⊑ LLVM.or (lshr e_2 e) e_1

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

theorem test_eq_0_and_15_add_1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 1#8 &&& 15#8 == 0#8) = ofBool (x &&& 15#8 == 15#8)

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

theorem ashrsgt_03_00_exact_proof : ashrsgt_03_00_exact_before ⊑ ashrsgt_03_00_exact_after

theorem lshr_neg_slt_zero_proof : lshr_neg_slt_zero_before ⊑ lshr_neg_slt_zero_after

theorem test_nuw_nsw_and_signed_pred_proof : test_nuw_nsw_and_signed_pred_before ⊑ test_nuw_nsw_and_signed_pred_after

theorem lt_unsigned_to_large_signed_proof : lt_unsigned_to_large_signed_before ⊑ lt_unsigned_to_large_signed_after

theorem e_1517 :
     - 11 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 5 * (c ^^^ (a ||| (b &&& c))) + 18 *  ~~~(a ||| (b ||| c)) + 11 *  ~~~(a ||| ( ~~~b ||| c)) + 12 *  ~~~( ~~~a ||| (b ||| c)) + 16 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 11 * ( ~~~a &&& (b &&& c)) + 7 * (a &&& ( ~~~b &&& c)) + 7 * (a &&& (b &&& c)) = 7 * (b ^^^  ~~~(a &&& (b &&& c)))

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

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

theorem xor_signbit_select_shl_proof : xor_signbit_select_shl_before ⊑ xor_signbit_select_shl_after

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

theorem icmp_eq_and_pow2_shl_pow2_negative1_proof : icmp_eq_and_pow2_shl_pow2_negative1_before ⊑ icmp_eq_and_pow2_shl_pow2_negative1_after

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

theorem ne_smax2_proof : ne_smax2_before ⊑ ne_smax2_after

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

theorem sdiv_ult_smin_proof : sdiv_ult_smin_before ⊑ sdiv_ult_smin_after

theorem samesign_inverted_commute1_proof : samesign_inverted_commute1_before ⊑ samesign_inverted_commute1_after

theorem test_with_1_proof : test_with_1_before ⊑ test_with_1_after

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

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

theorem or_signbit_select_shl_proof : or_signbit_select_shl_before ⊑ or_signbit_select_shl_after

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

theorem n12_wrong_bias_proof : n12_wrong_bias_before ⊑ n12_wrong_bias_after

theorem ashr_slt_exact_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 3) { «exact» := true }) (const? 8 10) ⊑
    icmp IntPred.slt e (const? 8 80)

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

theorem trunc_shl_nsw_nuw_31_i32_i64_proof : trunc_shl_nsw_nuw_31_i32_i64_before ⊑ trunc_shl_nsw_nuw_31_i32_i64_after

theorem or_nosignbit_lshr_proof : or_nosignbit_lshr_before ⊑ or_nosignbit_lshr_after

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

theorem sle_swap_and_min_logical_proof : sle_swap_and_min_logical_before ⊑ sle_swap_and_min_logical_after

theorem not_or_or_and_not_and_and_commute4_proof : not_or_or_and_not_and_and_commute4_before ⊑ not_or_or_and_not_and_and_commute4_after

theorem test_or2_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ≤ₛ -1#32) = 1#1 → ¬ofBool (x <ₛ 0#32) = 1#1 → False

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

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem test_with_neg_even_proof : test_with_neg_even_before ⊑ test_with_neg_even_after

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

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem test_proof : test_before ⊑ test_after

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

theorem lshrult_03_15_proof : lshrult_03_15_before ⊑ lshrult_03_15_after

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

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

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

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

theorem ashrsgt_01_10_exact_proof : ashrsgt_01_10_exact_before ⊑ ashrsgt_01_10_exact_after

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

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

theorem lshrult_01_08_proof : lshrult_01_08_before ⊑ lshrult_01_08_after

theorem sdiv_shl_pair3_proof : sdiv_shl_pair3_before ⊑ sdiv_shl_pair3_after

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

theorem bools2_logical_commute0_and2_proof : bools2_logical_commute0_and2_before ⊑ bools2_logical_commute0_and2_after

theorem test5_proof : test5_before ⊑ test5_after

theorem e_386 :
    2 *  ~~~(x &&& y) + 4 * (x ^^^ y) + 2 * (x |||  ~~~y) - 11 *  ~~~y - 1 *  ~~~(x &&&  ~~~y) + 8 *  ~~~(x ||| y) - 16 *  ~~~(x |||  ~~~y) - 12 * (x &&& y) =  - 3 * (x &&&  ~~~y) - 11 * y

theorem Term.toBV_of_KInductionCircuits
    {wcard tcard bcard ncard icard pcard : Nat}
    (tctx : Term.Ctx wcard tcard)
    (p : Term bcard ncard icard pcard tctx .prop)
    (pNondep : Nondep.Term)
    (_hpNondep : pNondep = (.ofDepTerm p))
    (fsm : TermFSM wcard tcard bcard ncard icard pcard pNondep)
    (_hfsm : fsm = mkTermFsmNondep wcard tcard bcard ncard icard pcard pNondep)
    (n : Nat)
    (circs : KInductionCircuits fsm.toFsmZext n)
    (hCircs : circs.IsLawful)
    (sCert : Lean.Elab.Tactic.BVDecide.Frontend.LratCert)
    (hs : Circuit.verifyCircuit (circs.mkSafetyCircuit) sCert = true)
    (indCert : Lean.Elab.Tactic.BVDecide.Frontend.LratCert)
    (hind : Circuit.verifyCircuit (circs.mkIndHypCycleBreaking) indCert = true)
    (wenv : WidthExpr.Env wcard)
    (penv : Predicate.Env pcard)
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    :
    p.toBV benv nenv ienv penv tenv

theorem ashr_slt_exact_near_pow2_cmpval_proof : ashr_slt_exact_near_pow2_cmpval_before ⊑ ashr_slt_exact_near_pow2_cmpval_after

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

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

theorem foo2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool
      (x_1 &&& BitVec.ofInt 32 (-2147483648) == x &&& BitVec.ofInt 32 (-2147483648) ^^^ BitVec.ofInt 32 (-2147483648)) =
    ofBool (x ^^^ x_1 <ₛ 0#32)

@[simp] theorem MatchVarM.liftM_eq_some_iff (x? : Option α) :
    (liftM x? : no_index MatchVarM Δ Γ α) mapIn = some (x, mapOut)
    ↔ x? = some x ∧ mapIn = mapOut

theorem test_sub__none_are_safe_proof : test_sub__none_are_safe_before ⊑ test_sub__none_are_safe_after

theorem not_or_or_and_not_and_and_commute1_proof : not_or_or_and_not_and_and_commute1_before ⊑ not_or_or_and_not_and_and_commute1_after

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

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

theorem exact_lshr_ne_proof : exact_lshr_ne_before ⊑ exact_lshr_ne_after

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

@[bv_automata_nnf]
theorem ult_iff_ule_eq_false {a b : BitVec w} : a.ule b = false ↔ b.ult a

theorem or_and_not_constant_commute2_proof : or_and_not_constant_commute2_before ⊑ or_and_not_constant_commute2_after

theorem neg_sgt_1_proof : neg_sgt_1_before ⊑ neg_sgt_1_after

theorem t0_proof : t0_before ⊑ t0_after

theorem e_234 :
     - 3 * (x ^^^ y) - 2 *  ~~~(x &&&  ~~~x) + 11 * (x |||  ~~~y) - 1 *  ~~~(x &&& y) - 8 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) - 10 * (x &&& y) =  - 1 * x + 6 * (x &&&  ~~~y)

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

theorem positive_with_signbit_logical_proof : positive_with_signbit_logical_before ⊑ positive_with_signbit_logical_after

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

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

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

theorem narrow_source_matching_signbits_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ ((-1#32) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠ -1#32 ∨ x &&& 7#32 ≥ ↑32) →
    signExtend 64 (truncate 8 ((-1#32) <<< (x &&& 7#32))) = signExtend 64 ((-1#32) <<< (x &&& 7#32))

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

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

theorem positive_biggerashr_proof : positive_biggerashr_before ⊑ positive_biggerashr_after

theorem foo3_proof : foo3_before ⊑ foo3_after

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

theorem icmp_shl_uge_2_proof : icmp_shl_uge_2_before ⊑ icmp_shl_uge_2_after

theorem or_nosignbit_select_ashr_proof : or_nosignbit_select_ashr_before ⊑ or_nosignbit_select_ashr_after

theorem narrow_zext_and_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (zeroExtend 32 x_1 &&& x) = x_1 &&& truncate 16 x

theorem ule_swap_or_min_proof : ule_swap_or_min_before ⊑ ule_swap_or_min_after

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

theorem PR23309_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 + BitVec.ofInt 32 (-4)).ssubOverflow x = true) →
    truncate 1 (x_1 + BitVec.ofInt 32 (-4) - x) = truncate 1 (x_1 - x)

theorem mul_select_zext_proof : mul_select_zext_before ⊑ mul_select_zext_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 exact_ashr_ne_noexactdiv_proof : exact_ashr_ne_noexactdiv_before ⊑ exact_ashr_ne_noexactdiv_after

theorem xor_icmp_true_unsigned_thm (e : IntW 32) :
  LLVM.xor (icmp IntPred.ugt e (const? 32 5)) (icmp IntPred.ult e (const? 32 6)) ⊑ const? 1 1

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_2_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0))
      (icmp IntPred.eq (LLVM.and e (const? 32 3)) (const? 32 0)) ⊑
    const? 1 1

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

theorem e_1913 :
    5 * ( ~~~a ||| ( ~~~b ||| c)) - 1 * ( ~~~a &&& ( ~~~b ||| c)) + 1 *  ~~~b - 5 * (b ||| (a &&& c)) + 2 * ((a &&& c) ||| (b &&&  ~~~c)) + 11 *  ~~~a - 1 * (b ^^^ (a |||  ~~~c)) + 5 *  ~~~( ~~~a ||| (b &&& c)) - 1 * (c ||| (a ^^^ b)) + 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 11 * ( ~~~b &&&  ~~~(a ^^^ c)) - 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 11 * (b |||  ~~~(a ||| c)) - 2 * ( ~~~c &&& (a ^^^ b)) - 5 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (a ^^^ ( ~~~b ||| c)) - 5 * (b ^^^  ~~~(a &&& (b ||| c))) + 3 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 7 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 4 *  ~~~(a |||  ~~~c) + 1 * (c &&& (a |||  ~~~b)) + 7 * (a &&& (b ^^^ c)) - 6 * (b |||  ~~~(a |||  ~~~c)) + 11 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 1 *  ~~~(a |||  ~~~b) - 1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 2 *  ~~~( ~~~a &&& (b ^^^ c)) + 3 * ( ~~~b &&& (a ^^^ c)) + 2 * (c ^^^  ~~~(a &&& (b &&& c))) - 3 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 1 *  ~~~(a ^^^ (b ^^^ c)) + 1 * (c &&&  ~~~(a &&& b)) - 2 * (b |||  ~~~(a ^^^ c)) + 7 * (c ^^^ ( ~~~a &&& (b ||| c))) + 11 * ( ~~~c |||  ~~~(a ^^^ b)) + 3 * (a ^^^ ( ~~~b &&& c)) + 1 * b - 3 * ((a &&& b) |||  ~~~(b ||| c)) + 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 7 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 21 *  ~~~(a ||| (b ||| c)) - 48 *  ~~~(a ||| ( ~~~b ||| c)) - 25 *  ~~~( ~~~a ||| (b ||| c)) - 25 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 45 * ( ~~~a &&& ( ~~~b &&& c)) - 24 * ( ~~~a &&& (b &&& c)) - 13 * (a &&& ( ~~~b &&& c)) - 13 * (a &&& (b &&& c)) = 3 * (a |||  ~~~b)

theorem land_lor_right1_proof : land_lor_right1_before ⊑ land_lor_right1_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 t1_proof : t1_before ⊑ t1_after

theorem xor_or_xor_thm.extracted_1._1 : ∀ (x : BitVec 8),
  (x ^^^ 33#8 ||| 7#8) ^^^ 12#8 = x &&& BitVec.ofInt 8 (-8) ^^^ 43#8

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

theorem alive_290__292 : alive_290__292_src ⊑ alive_290__292_tgt

theorem eq_invariant_fn
    (f : LoopBody t) (g : t → t) (hf : ∀ (i : Int) (v : t), f i v = g v) :
    LoopBody.IndexInvariant f ∧ atZero f = g

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

theorem test_sext_zext_thm (e : IntW 16) : sext 64 (zext 32 e) ⊑ zext 64 e

theorem select_bittest_to_shl_negative_test_proof : select_bittest_to_shl_negative_test_before ⊑ select_bittest_to_shl_negative_test_after

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

theorem select_icmp_ne_0_and_4096_or_32_proof : select_icmp_ne_0_and_4096_or_32_before ⊑ select_icmp_ne_0_and_4096_or_32_after

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

theorem or_and3_thm.extracted_1._5 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 ||

theorem e_108 :
     - 2 * x + 2 *  ~~~(x ^^^ y) - 11 *  ~~~x + 9 *  ~~~(x ||| y) + 22 *  ~~~(x |||  ~~~y) + 13 * (x &&&  ~~~y) =  - 11 * (x &&& y) + 11 * (x ||| y)

theorem xor_with_or_disjoint_ab_proof : xor_with_or_disjoint_ab_before ⊑ xor_with_or_disjoint_ab_after

theorem icmp_equality_test_proof : icmp_equality_test_before ⊑ icmp_equality_test_after

theorem ashr_eq_msb_low_second_zero_proof : ashr_eq_msb_low_second_zero_before ⊑ ashr_eq_msb_low_second_zero_after

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

theorem test2_proof : test2_before ⊑ test2_after

theorem lshrult_02_14_proof : lshrult_02_14_before ⊑ lshrult_02_14_after

theorem ne_umin1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ x) = 1#1 → ofBool (x != x_1) = ofBool (x <ᵤ x_1)

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

theorem test5_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬16#128 ≥ ↑128 → ¬16#32 ≥ ↑32 → truncate 32 (zeroExtend 128 x >>> 16#128) = x >>> 16#32

theorem lshrult_01_02_exact_proof : lshrult_01_02_exact_before ⊑ lshrult_01_02_exact_after

theorem icmp_sle2_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 (-127)) ⊑
    icmp IntPred.slt e (const? 8 (-63))

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

theorem e_1868 :
     - 5 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ^^^ (a ||| c)) - 1 * (b ^^^ (a ||| (b &&& c))) + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 5 * ((a ^^^ b) ||| (a ^^^ c)) - 2 * ((a &&& b) |||  ~~~(b ||| c)) - 1 *  ~~~(a ||| ( ~~~b &&& c)) - 7 * (a &&& c) + 7 * ((a &&& b) |||  ~~~(b ^^^ c)) + 5 * ((a ||| b) &&& (b ^^^ c)) + 11 * (b ^^^  ~~~(a &&& c)) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) - 1 *  ~~~(a |||  ~~~b) + 4 * (c ^^^ (a ||| (b &&& c))) - 1 * (b ^^^  ~~~(a |||  ~~~c)) + 7 *  ~~~(b &&& c) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 1 * ( ~~~a ||| (b &&& c)) - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) + 2 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 3 * (b &&& (a |||  ~~~c)) - 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 3 * ((a &&& c) |||  ~~~(b ||| c)) - 6 * (b |||  ~~~(a |||  ~~~c)) - 1 * ( ~~~a ||| ( ~~~b &&& c)) - 11 * (c &&&  ~~~(a &&& b)) + 4 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * b - 6 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 7 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 11 * (a ||| (b ^^^ c)) + 7 * (a |||  ~~~b) - 11 * ((a &&& c) ^^^ (b ||| c)) - 1 * (c ^^^ (a |||  ~~~b)) - 6 * (c ^^^ ( ~~~a &&& (b ||| c))) + 11 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 5 * (c ^^^ (a &&& ( ~~~b ||| c))) - 49 *  ~~~(a ||| (b ||| c)) - 6 *  ~~~(a ||| ( ~~~b ||| c)) - 18 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 30 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) - 15 * (a &&& (b &&& c)) =  - 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 22 * ( ~~~a &&& ( ~~~b &&& c))

theorem foo_thm.extracted_1._1 : ∀ (x : BitVec 32), 5#32 - x &&& 2#32 = 1#32 - x &&& 2#32

theorem uadd_sat_canon_nuw_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ult (add e_1 e { «nsw» := false, «nuw» := true }) e_1) (const? 32 (-1))
      (add e_1 e { «nsw» := false, «nuw» := true }) ⊑
    add e_1 e { «nsw» := false, «nuw» := true }

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

theorem e_1216 :
    7 *  ~~~t - 7 *  ~~~(z &&&  ~~~z) - 5 * t + 2 *  ~~~(z ^^^ t) - 5 *  ~~~(z &&&  ~~~t) - 6 * (z ^^^ t) + 23 *  ~~~(z |||  ~~~t) + 6 * (z &&&  ~~~t) + 15 * (z &&& t) =  - 3 *  ~~~(z ||| t)

theorem sgt_smin3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 3#32 <ₛ x) = 1#1 → ofBool (x_1 + 3#32 <ₛ x) = 0#1

theorem shrink_xor_thm (e : IntW 64) : trunc 32 (LLVM.xor e (const? 64 1)) ⊑ LLVM.xor (trunc 32 e) (const? 32 1)

theorem n2_proof : n2_before ⊑ n2_after

@[simp]
lemma RawCNFA.lift_processTrans_spec {m : CNFA n₁} {f : Fin n₁ → Fin n₂} :
    s' ∈ (lift.processTrans m.m f trs s₀ a).getD (s, b) ∅ ↔
      s' ∈ trs.getD (s, b) ∅ ∨ s = s₀ ∧ a = b ∧ s' ∈ m.m.tr s (b.transport f)

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

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_proof : icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_before ⊑ icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_after

theorem test_cast_select_proof : test_cast_select_before ⊑ test_cast_select_after

theorem t7_ugt_sgt_neg1_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 → x_1 = x

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

theorem wide_source_matching_signbits_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ ((-1#32) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠ -1#32 ∨ x &&& 7#32 ≥ ↑32) →
    ¬(True ∧ ((-1#32) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠ -1#32 ∨
          x &&& 7#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 24 ((-1#32) <<< (x &&& 7#32))) ≠ (-1#32) <<< (x &&& 7#32)) →
      signExtend 24 (truncate 8 ((-1#32) <<< (x &&& 7#32))) = truncate 24 ((-1#32) <<< (x &&& 7#32))

theorem ashr_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) →
    ¬x ≥ ↑8 →
      (BitVec.ofInt 8 (-64)).sshiftRight' x &&& (BitVec.ofInt 8 (-128)).sshiftRight' (x + 1#8) =
        (BitVec.ofInt 8 (-64)).sshiftRight' x

@[simp] lemma eval_bAnd :
    ∀ {s : List α} {f : α → Circuit β} {g : β → Bool},
      eval (bAnd s f) g ↔ ∀ a ∈ s, eval (f a) g

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

@[symm] theorem Bisim.symm {a b : Stream α} : a ~ b → b ~ a

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

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

theorem unsigned_sign_bit_extract_with_trunc_proof : unsigned_sign_bit_extract_with_trunc_before ⊑ unsigned_sign_bit_extract_with_trunc_after

theorem shr_umax_proof : shr_umax_before ⊑ shr_umax_after

theorem negative_with_uniform_bad_mask_logical_proof : negative_with_uniform_bad_mask_logical_before ⊑ negative_with_uniform_bad_mask_logical_after

theorem icmp_ne_zext_eq_zero_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x == 0#32)) != x) = 1#1

theorem bv_AddSub_1539_2 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.sub e e_1 ⊑ LLVM.add e (LLVM.neg e_1)

theorem sle_swap_and_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 == BitVec.ofInt 8 (-128)) = 1#1 → 0#1 = ofBool (x_1 == BitVec.ofInt 8 (-128))

theorem shl_add_add_proof : shl_add_add_before ⊑ shl_add_add_after

theorem e_1019 :
     - 2 *  ~~~(z ^^^ t) - 2 * (z ||| t) - 11 * z - 7 * (z ^^^ t) + 7 *  ~~~(z ||| t) + 9 *  ~~~(z |||  ~~~t) + 25 * (z &&&  ~~~t) = 5 * (z |||  ~~~t) - 20 * (z &&& t)

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

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

theorem BitVec.ofFn_getLsbD_true {w : Nat} {f : Fin w → Bool} {i : Nat} :
    (BitVec.ofFn f).getLsbD i = true ↔ ∃ (hlt : i < w), f ⟨i, hlt⟩ = true

@[simp]
lemma dec_enc' : dec (enc bvs) = bvs

theorem shl_mul_mask_wrong_mul_const_proof : shl_mul_mask_wrong_mul_const_before ⊑ shl_mul_mask_wrong_mul_const_after

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

theorem test15_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → ¬2#45 ≥ ↑45 → 1#45 <<< 2#45 = 4#45

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 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 e_1801 :
    1 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 3 * ((a &&& c) ||| (b &&&  ~~~c)) + 5 * ( ~~~a ||| (b ^^^ c)) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 6 * (a ^^^ (b ^^^ c)) - 7 * (a ^^^ (b ||| c)) + 7 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (a ^^^ c) - 6 * ( ~~~c ||| (a ^^^ b)) + 2 * (b ||| c) + 2 * ( ~~~a ||| (b ||| c)) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 2 * (b ^^^ (a &&& (b ||| c))) - 2 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 1 *  ~~~(a &&& (b ^^^ c)) + 11 * (b ||| (a ^^^ c)) - 2 * (c &&& (a |||  ~~~b)) + 5 * ((a &&& b) |||  ~~~(b ^^^ c)) + 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 * (c ||| (a ^^^ b)) - 3 *  ~~~(a ^^^ (b ^^^ c)) - 2 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 1 *  ~~~(a |||  ~~~b) + 5 *  ~~~(a &&& b) - 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 1 * (c ^^^  ~~~(a ||| b)) - 3 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 11 * ( ~~~a &&& ( ~~~b ||| c)) - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) + 11 *  ~~~(a ||| (b ||| c)) + 6 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) - 19 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& ( ~~~b &&& c)) + 10 * ( ~~~a &&& (b &&& c)) - 4 * (a &&& ( ~~~b &&& c)) - 14 * (a &&& (b &&& c)) = 11 * ((a &&& b) ^^^ (b |||  ~~~c))

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

theorem positive_sameconst_shlnuw_ashrexact_proof : positive_sameconst_shlnuw_ashrexact_before ⊑ positive_sameconst_shlnuw_ashrexact_after

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

theorem test1_proof : test1_before ⊑ test1_after

theorem lshrugt_03_05_exact_proof : lshrugt_03_05_exact_before ⊑ lshrugt_03_05_exact_after

@[simp] theorem cons_getElem_toCons (x : A a) (v : Var Γ u)
    (h : as = Γ.toList := by rfl) (h' : a :: as = (Γ.cons a).toList := by rfl) :
    (HVector.cons x xs)[v.toCons (t' := a)]'h' = xs[v]'h

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

theorem test5_proof : test5_before ⊑ test5_after

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

theorem test_ne_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1073741823#32 != 0#32) = 1#1 → 2#32 ≥ ↑32 → False

theorem not_select_bool_const1_proof : not_select_bool_const1_before ⊑ not_select_bool_const1_after

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

theorem or_shl_proof : or_shl_before ⊑ or_shl_after

theorem t3_exact_thm (e : IntW 64) :
  sub (const? 32 0) (trunc 32 (ashr e (const? 64 63) { «exact» := true })) ⊑
    trunc 32 (lshr e (const? 64 63) { «exact» := true }) { «nsw» := true, «nuw» := true }

omit [Fintype S] in
lemma processOneElem_spec {st : worklist.St A S} (s : State) (sa : S) (k : ℕ) :
    ∀ a sa', (f sa)[k]? = some (a, sa') →
    processOneElem_mot inits final f s sa k st →
    processOneElem_mot inits final f s sa (k+1) (processOneElem A S final s st (a, sa'))

theorem masked_and_notA_slightly_optimized_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.uge e (const? 32 8)) (icmp IntPred.ne (LLVM.and e (const? 32 39)) e) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 (-40))) (const? 32 0)

theorem PR51351_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(zeroExtend 64 x_1 ≥ ↑64 ∨ zeroExtend 64 x_1 ≥ ↑64 ∨ x_1 + BitVec.ofInt 32 (-33) ≥ ↑32) →
    x_1 + BitVec.ofInt 32 (-33) ≥ ↑32 → False

theorem test22_logical_proof : test22_logical_before ⊑ test22_logical_after

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

theorem e_787 :
    4 *  ~~~(z ^^^ t) + 1 *  ~~~t + 6 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 4 * (z &&& t) = 6 *  ~~~z - 1 *  ~~~(z ||| t)

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

theorem uaddo_commute4_proof : uaddo_commute4_before ⊑ uaddo_commute4_after

theorem ashrsgt_01_12_exact_proof : ashrsgt_01_12_exact_before ⊑ ashrsgt_01_12_exact_after

theorem no_shift_xor_multiuse_cmp_proof : no_shift_xor_multiuse_cmp_before ⊑ no_shift_xor_multiuse_cmp_after

theorem sub_select_sext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → x - signExtend 64 x_1 = x

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

theorem t3_ult_sgt_neg1_proof : t3_ult_sgt_neg1_before ⊑ t3_ult_sgt_neg1_after

theorem nonexact_lshr_ne_noexactlog_proof : nonexact_lshr_ne_noexactlog_before ⊑ nonexact_lshr_ne_noexactlog_after

theorem negate_lowbitmask_proof : negate_lowbitmask_before ⊑ negate_lowbitmask_after

theorem test48_thm (e : IntW 8) :
  zext 64 (LLVM.or (shl (zext 32 e) (const? 32 8)) (zext 32 e)) ⊑
    zext 64
      (LLVM.or (shl (zext 32 e) (const? 32 8) { «nsw» := true, «nuw» := true }) (zext 32 e) { «disjoint» := true })
      { «nneg» := true }

theorem e_2361 :
     - 7 * (d ||| ( ~~~e &&& f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~d &&& (e ||| f)) - 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * ((d &&& e) ^^^ (e ||| f)) - 3 * (e |||  ~~~f) + 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * (f &&&  ~~~(d &&&  ~~~e)) + 5 * ( ~~~d &&& (e ^^^ f)) - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 3 * (e &&& f) + 7 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 4 * (e ||| (d &&& f)) - 7 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 11 * (f &&& (d ||| e)) + 3 *  ~~~e - 6 * ((d &&& e) ||| (e ^^^ f)) - 6 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 2 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * (f &&&  ~~~(d &&& e)) - 11 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 *  ~~~(e &&& f) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e ^^^  ~~~(d &&& f)) - 5 * (e ^^^ (d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ( ~~~d ||| (e &&& f)) + 11 * ( ~~~d &&& ( ~~~e ||| f)) + 4 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 4 * (f ^^^ (d ||| (e &&& f))) - 6 *  ~~~(d &&& e) + 3 * (e ^^^ (d &&& (e ^^^ f))) - 2 *  ~~~(d ^^^ (e &&& f)) + 11 * ((d &&& f) |||  ~~~(e ||| f)) - 7 * (d |||  ~~~f) - 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 6 * ( ~~~f &&& (d ^^^ e)) - 2 * (f ^^^ (d &&& (e ||| f))) + 1 * (e &&&  ~~~(d ^^^ f)) + 1 * (e &&&  ~~~(d &&& f)) - 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 2 * (e ||| (d ^^^ f)) + 11 * ( ~~~e &&& (d ^^^ f)) - 2 * ( ~~~e ||| (d ^^^ f)) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 11 * (e ||| f) - 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 1 * (f &&& (d |||  ~~~e)) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 11 *  ~~~(e ||| f) - 6 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 7 *  ~~~(e ^^^ f) - 17 *  ~~~(d ||| (e ||| f)) + 38 *  ~~~(d ||| ( ~~~e ||| f)) + 16 *  ~~~( ~~~d ||| (e ||| f)) + 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 28 * ( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& ( ~~~e &&& f)) + 10 * (d &&& (e &&& f)) =  - 5 * (f &&& (d ^^^ e))

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

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

theorem t0_proof : t0_before ⊑ t0_after

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

theorem positive_with_signbit_proof : positive_with_signbit_before ⊑ positive_with_signbit_after

theorem no_shift_xor_multiuse_cmp_or_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (0#32 != x_2 &&& 4096#32) = 1#1 → ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → False

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

theorem test1_proof : test1_before ⊑ test1_after

theorem ult_rem_nz_nsw_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smulOverflow 5#8 = true ∨ True ∧ x.umulOverflow 5#8 = true) →
    ofBool (x * 5#8 <ᵤ 21#8) = ofBool (x <ᵤ 5#8)

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

theorem sub_ule_sext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 8),
  ofBool (x_2 - x_1 ≤ᵤ signExtend 8 x) = ofBool (x_2 == x_1) ||

theorem ugt_rem_nz_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.umulOverflow 5#8 = true) → ofBool (21#8 <ᵤ x * 5#8) = ofBool (4#8 <ᵤ x)

theorem bitwise_or_logical_or_icmps_comm1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 → ofBool (x == 42#8) = 1#1 → ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) ||

theorem lshrugt_02_06_proof : lshrugt_02_06_before ⊑ lshrugt_02_06_after

theorem no_shift_no_xor_multiuse_or_proof : no_shift_no_xor_multiuse_or_before ⊑ no_shift_no_xor_multiuse_or_after

theorem e_75 :
    1 *  ~~~(x &&&  ~~~y) + 1 * x - 12 *  ~~~(x ||| y) - 1 *  ~~~(x |||  ~~~y) - 2 * (x &&& y) =  - 11 *  ~~~y + 12 * (x &&&  ~~~y)

theorem PR42691_10_proof : PR42691_10_before ⊑ PR42691_10_after

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

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

theorem fold_mask_cmps_to_true_proof : fold_mask_cmps_to_true_before ⊑ fold_mask_cmps_to_true_after

theorem sdiv_shl_pair3_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        x_1 ≥ ↑32 ∨
          True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
            x ≥ ↑32 ∨ (x_2 <<< x == 0 || 32 != 1 && x_2 <<< x_1 == intMin 32 && x_2 <<< x == -1) = true) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32) → (x_2 <<< x_1).sdiv (x_2 <<< x) = 1#32 <<< x_1 >>> x

theorem add_const_add_const_thm (e : IntW 32) : add (add e (const? 32 8)) (const? 32 2) ⊑ add e (const? 32 10)

theorem ugt_or_not_min_proof : ugt_or_not_min_before ⊑ ugt_or_not_min_after

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

theorem PR45984_proof : PR45984_before ⊑ PR45984_after

theorem test1_thm (e : IntW 17) :
  trunc 17 (LLVM.or (lshr (zext 37 e) (const? 37 8)) (shl (zext 37 e) (const? 37 8))) ⊑
    LLVM.or (lshr e (const? 17 8)) (shl e (const? 17 8))

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

theorem both_sides_fold_slt_thm (e : IntW 32) (e_1 : IntW 1) :
  icmp IntPred.slt (select e_1 (const? 32 9) e) (select e_1 (const? 32 1) e) ⊑ const? 1 0

theorem test19_thm (e : IntW 32) : LLVM.and (shl e (const? 32 3)) (const? 32 (-2)) ⊑ shl e (const? 32 3)

theorem p0_proof : p0_before ⊑ p0_after

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

theorem t0_proof : t0_before ⊑ t0_after

theorem lor_land_right2_proof : lor_land_right2_before ⊑ lor_land_right2_after

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

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

theorem ne_umin3_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (add e_1 (const? 32 3))
      (select (icmp IntPred.ult (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.ugt (add e_1 (const? 32 3)) e

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

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

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

theorem trunc_ashr_trunc_outofrange_thm (e : IntW 64) :
  trunc 8 (ashr (trunc 32 e) (const? 32 25)) ⊑
    trunc 8 (ashr (trunc 32 e) (const? 32 25)) { «nsw» := true, «nuw» := false }

theorem icmp_eq_and_pow2_minus1_shl1_negative2_proof : icmp_eq_and_pow2_minus1_shl1_negative2_before ⊑ icmp_eq_and_pow2_minus1_shl1_negative2_after

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

@[bv_multi_width_normalize] theorem BitVec.le_eq_ule {x y : BitVec w} :
    (x ≤ y) = ((x.ule y) = true)

theorem ashr_xor_proof : ashr_xor_before ⊑ ashr_xor_after

theorem eq_21_logical_proof : eq_21_logical_before ⊑ eq_21_logical_after

theorem ashr_ugt_0_proof : ashr_ugt_0_before ⊑ ashr_ugt_0_after

theorem and_nosignbit_select_ashr_thm (e : IntW 32) (e_1 : IntW 1) :
  ashr (select e_1 (LLVM.and e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (LLVM.and (ashr e (const? 32 8)) (const? 32 8388352)) (ashr e (const? 32 8))

theorem logical_and_logical_and_icmps_comm1_proof : logical_and_logical_and_icmps_comm1_before ⊑ logical_and_logical_and_icmps_comm1_after

theorem PR38021_proof : PR38021_before ⊑ PR38021_after

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

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

theorem e_1642 :
    1 * c - 11 *  ~~~(a &&& ( ~~~b &&& c)) + 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * (a ||| ( ~~~b &&& c)) - 11 *  ~~~( ~~~a ||| (b ^^^ c)) + 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * (c &&& (a |||  ~~~b)) - 1 * ( ~~~a &&& ( ~~~b ||| c)) - 7 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 2 *  ~~~(a ^^^ c) + 1 * (a &&& c) - 6 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 2 * (c ^^^ (a &&&  ~~~b)) + 20 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) + 35 *  ~~~( ~~~a ||| (b ||| c)) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * ( ~~~a &&& (b &&& c)) - 11 * (a &&& ( ~~~b &&& c)) + 24 * (a &&& (b &&& c)) = 1 * (b ^^^  ~~~(a &&& (b ||| c)))

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 999), x &&& 0#999 = 0#999

@[simp] lemma composeUnary_eval
    (p : FSM Unit)
    {t : Term}
    (q : FSMTermSolution t)
    (x : Fin t.arity → BitStream) :
    (composeUnary p q).eval x = p.eval (λ _ => t.evalFin x)

theorem sge_swap_or_max_logical_proof : sge_swap_or_max_logical_before ⊑ sge_swap_or_max_logical_after

theorem or_ranges_adjacent_thm (e : IntW 8) :
  LLVM.or (LLVM.and (icmp IntPred.uge e (const? 8 5)) (icmp IntPred.ule e (const? 8 10)))
      (LLVM.and (icmp IntPred.uge e (const? 8 11)) (icmp IntPred.ule e (const? 8 20))) ⊑
    icmp IntPred.ult (add e (const? 8 (-5))) (const? 8 16)

theorem icmp_eq_and_pow2_shl_pow2_negative2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 14#32 == 0#32)) = zeroExtend 32 (ofBool (2#32 <ᵤ x))

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

theorem test15_proof : test15_before ⊑ test15_after

theorem isRefinedBy_iff (f : StateT σ m α) (g : StateT σ n β) :
    f ⊑ g ↔ ∀ s, f s ⊑ g s

theorem and_xor_or1_proof : and_xor_or1_before ⊑ and_xor_or1_after

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

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

theorem e_453 :
     - 11 * (x ^^^ y) - 2 * x - 3 *  ~~~x - 7 *  ~~~(x &&&  ~~~x) + 1 * y + 8 *  ~~~(x ||| y) + 18 *  ~~~(x |||  ~~~y) + 20 * (x &&&  ~~~y) + 6 * (x &&& y) =  - 2 *  ~~~(x &&&  ~~~y)

theorem bv_AndOrXor_709 :
    ∀ (e e_1 e_2 : LLVM.IntW w),
      LLVM.and (LLVM.icmp LLVM.IntPred.eq (LLVM.and e e_1) e_1) (LLVM.icmp LLVM.IntPred.eq (LLVM.and e e_2) e_2) ⊑
        LLVM.icmp LLVM.IntPred.eq (LLVM.and e (LLVM.or e_1 e_2)) (LLVM.or e_1 e_2)

theorem p_commutative2_thm (e e_1 e_2 : IntW 32) :
  LLVM.xor (LLVM.and (LLVM.xor e_2 (const? 32 (-1))) e_1) (LLVM.and e e_2) ⊑
    LLVM.or (LLVM.and e_1 (LLVM.xor e_2 (const? 32 (-1)))) (LLVM.and e e_2) { «disjoint» := true }

@[aesop 50% unsafe]
theorem Std.HashMap.insert_keys_perm_new [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] (m : Std.HashMap K V) (k : K) (v : V) :
    k ∉ m → (m.insert k v).keys.Perm (k :: m.keys)

theorem e_2396 :
     - 2 * (e ^^^ (d ||| f)) - 6 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * (e &&& (d ||| f)) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 11 *  ~~~(d ^^^ (e &&& f)) - 1 * (e ^^^ (d ||| (e ||| f))) + 7 * f - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 11 * (e ||| (d &&&  ~~~f)) - 11 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^  ~~~(d &&& f)) - 3 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (d ^^^ (e ^^^ f)) - 1 *  ~~~(e ^^^ f) + 11 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 3 *  ~~~(d |||  ~~~f) - 6 * (d ||| ( ~~~e &&& f)) + 11 * ( ~~~d ||| ( ~~~e ||| f)) + 5 * (f ^^^ ( ~~~d ||| (e &&& f))) - 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 1 * (f ||| (d &&& e)) + 1 * d + 5 * (f ^^^  ~~~(d ||| (e &&& f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 2 * (f |||  ~~~(d ||| e)) + 1 * (f &&& (d ^^^ e)) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ||| f) + 11 * (d ||| (e ^^^ f)) + 2 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 7 * (f ^^^ ( ~~~d &&& (e ||| f))) + 4 *  ~~~( ~~~d &&& (e ||| f)) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 *  ~~~(d &&& e) + 4 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 2 *  ~~~( ~~~d ||| (e ^^^ f)) - 2 * ( ~~~d &&& (e ^^^ f)) - 1 *  ~~~(e ||| f) + 2 * (e &&& (d ^^^ f)) + 3 * (f ^^^  ~~~(d |||  ~~~e)) + 4 *  ~~~(d ||| f) + 2 * (f ||| (d ^^^ e)) - 6 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~(d ^^^ f) - 6 * (f ^^^  ~~~(d &&& e)) - 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 7 * ((d &&& f) ^^^ (e ||| f)) + 4 *  ~~~(d ||| (e ||| f)) + 7 *  ~~~(d ||| ( ~~~e ||| f)) + 14 *  ~~~( ~~~d ||| (e ||| f)) + 34 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 4 * ( ~~~d &&& ( ~~~e &&& f)) - 31 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) + 7 * (d &&& (e &&& f)) = 1 * (e |||  ~~~(d ||| f))

theorem and_shl_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 <<< x_2 &&& (x_1 <<< x_2 &&& x) = (x_1 &&& x_3) <<< x_2 &&& x

theorem andcond.001.inv.outer.cond_proof : andcond.001.inv.outer.cond_before ⊑ andcond.001.inv.outer.cond_after

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

theorem e_2252 :
    2 * ( ~~~e ||| (d ^^^ f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 3 * (e ^^^  ~~~(d &&& f)) - 1 * (e |||  ~~~(d ||| f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 6 *  ~~~e + 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 6 * (d ^^^ ( ~~~e ||| f)) + 7 * (e |||  ~~~(d ^^^ f)) - 5 * (f &&& (d ||| e)) - 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 *  ~~~(d &&& (e ||| f)) + 7 * ( ~~~e &&& (d ^^^ f)) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 11 * (e ^^^  ~~~(d &&&  ~~~f)) + 4 *  ~~~(e &&& f) + 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 2 * (e ^^^ (d &&& (e ^^^ f))) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 2 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 2 * ( ~~~d ||| (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 3 * (f ||| (d &&&  ~~~e)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * ( ~~~d ||| (e ||| f)) + 7 * (d &&& f) + 3 * (e &&& (d ||| f)) - 2 * (e ^^^ (d ||| (e ^^^ f))) + 4 * (f ^^^  ~~~(d &&&  ~~~e)) - 1 *  ~~~(e ||| f) + 11 * (f ^^^ (d &&&  ~~~e)) - 3 *  ~~~(d |||  ~~~f) + 1 * (d &&& (e ||| f)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 2 * (f &&&  ~~~(d &&&  ~~~e)) - 5 *  ~~~(d &&& ( ~~~e ||| f)) + 11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * ( ~~~f &&& (d ^^^ e)) - 7 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 11 * (e ^^^  ~~~(d ||| f)) - 1 *  ~~~( ~~~d ||| (e &&& f)) + 7 * (e ^^^ (d |||  ~~~f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 *  ~~~(d ||| e) - 34 *  ~~~(d ||| (e ||| f)) - 11 *  ~~~(d ||| ( ~~~e ||| f)) - 30 *  ~~~( ~~~d ||| (e ||| f)) - 54 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 61 * ( ~~~d &&& ( ~~~e &&& f)) - 13 * ( ~~~d &&& (e &&& f)) - 47 * (d &&& ( ~~~e &&& f)) - 29 * (d &&& (e &&& f)) =  - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f))

theorem ashr_lshr_shift_wrong_pred2_proof : ashr_lshr_shift_wrong_pred2_before ⊑ ashr_lshr_shift_wrong_pred2_after

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

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

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

theorem lshrult_03_10_proof : lshrult_03_10_before ⊑ lshrult_03_10_after

theorem e_960 :
    3 *  ~~~(z ^^^ t) - 6 * (z ^^^ t) - 11 * t - 3 * z + 17 *  ~~~(z |||  ~~~t) + 12 * (z &&&  ~~~t) = 3 *  ~~~t - 11 * (z &&& t)

theorem lshrult_01_06_exact_proof : lshrult_01_06_exact_before ⊑ lshrult_01_06_exact_after

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

theorem bv_AndOrXor_1683_1 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.or (LLVM.icmp LLVM.IntPred.ugt e e_1) (LLVM.icmp LLVM.IntPred.eq e e_1) ⊑ LLVM.icmp LLVM.IntPred.uge e e_1

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

lemma eval_assignVars [DecidableEq α] : ∀ {c : Circuit α}
    {f : ∀ (a : α) (_ha : a ∈ c.vars), β ⊕ Bool} {g : β → Bool},
    eval (assignVars c f) g = evalv c (λ a ha => Sum.elim g id (f a ha))

theorem add_nsw_const_const_sub_nsw_proof : add_nsw_const_const_sub_nsw_before ⊑ add_nsw_const_const_sub_nsw_after

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

theorem bools_multi_uses1_logical_proof : bools_multi_uses1_logical_before ⊑ bools_multi_uses1_logical_after

theorem ashrsgt_02_05_exact_proof : ashrsgt_02_05_exact_before ⊑ ashrsgt_02_05_exact_after

theorem shl_bad_sub2_i32_proof : shl_bad_sub2_i32_before ⊑ shl_bad_sub2_i32_after

@[simp]
lemma carry_and_xor_false : carry i (a &&& b) (a ^^^ b) false = false

theorem narrow_sext_add_proof : narrow_sext_add_before ⊑ narrow_sext_add_after

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 p0_thm (e : IntW 8) :
  icmp IntPred.sge (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 4)

theorem ult_to_sgt_proof : ult_to_sgt_before ⊑ ult_to_sgt_after

theorem and_not_or_commute3_proof : and_not_or_commute3_before ⊑ and_not_or_commute3_after

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

theorem p0_proof : p0_before ⊑ p0_after

theorem e_1041 :
     - 5 *  ~~~z - 11 *  ~~~(z ^^^ t) + 1 * (z ||| t) - 2 * (z |||  ~~~t) + 6 *  ~~~(z |||  ~~~t) + 3 * (z &&&  ~~~t) + 14 * (z &&& t) =  - 20 *  ~~~(z ||| t) + 2 *  ~~~(z &&&  ~~~z)

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

theorem e_1830 :
    2 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 1 *  ~~~(a &&& (b ^^^ c)) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 11 *  ~~~a - 6 * (c |||  ~~~(a |||  ~~~b)) + 1 * (c ||| (a ^^^ b)) - 2 * ( ~~~c ||| (a ^^^ b)) - 2 * ( ~~~(a ||| b) ||| (b ^^^ c)) + 4 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * (b |||  ~~~(a ^^^ c)) + 4 * ( ~~~a ||| (b ||| c)) + 7 * (a &&& ( ~~~b ||| c)) - 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 5 * (b ^^^  ~~~(a ||| c)) - 1 * (a ^^^ (b &&& c)) - 3 * (a ||| ( ~~~b ||| c)) - 7 * (c ^^^ (a &&& b)) + 2 * (b ^^^ (a ||| (b ||| c))) + 4 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 3 * (c ^^^  ~~~(a &&& (b &&& c))) - 7 *  ~~~( ~~~a ||| (b &&& c)) + 1 * ( ~~~c &&& (a ^^^ b)) - 2 * ((a &&& b) |||  ~~~(b ||| c)) - 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 2 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 3 * (c &&& (a ^^^ b)) - 1 * (b ^^^ (a &&& c)) + 2 * (b &&&  ~~~(a &&& c)) - 1 * (b &&&  ~~~(a ^^^ c)) - 5 *  ~~~( ~~~a &&& (b ^^^ c)) - 5 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 3 * (b ||| (a &&&  ~~~c)) + 31 *  ~~~(a ||| (b ||| c)) + 13 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 26 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 20 * ( ~~~a &&& ( ~~~b &&& c)) + 41 * ( ~~~a &&& (b &&& c)) + 28 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) =  - 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c)))

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

theorem ashr_ult_8_proof : ashr_ult_8_before ⊑ ashr_ult_8_after

theorem sub_ashr_or_i64_proof : sub_ashr_or_i64_before ⊑ sub_ashr_or_i64_after

theorem ashrslt_03_15_exact_proof : ashrslt_03_15_exact_before ⊑ ashrslt_03_15_exact_after

theorem test15e_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x &&& 128#32 != 0#32) = 1#1 → 1#32 ≥ ↑32 → 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 or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem foo1_and_signbit_lshr_without_shifting_signbit_both_sides_proof : foo1_and_signbit_lshr_without_shifting_signbit_both_sides_before ⊑ foo1_and_signbit_lshr_without_shifting_signbit_both_sides_after

theorem PR44545_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 0#32) = 1#1 →
    ¬(True ∧ (truncate 16 0#32).saddOverflow (-1#16) = true) → truncate 16 0#32 + -1#16 = -1#16

theorem t1_flags_nuw_only_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ x_2.usubOverflow x_1 = true ∨ True ∧ (x_2 - x_1).usubOverflow x = true) →
    ¬(True ∧ x_1.uaddOverflow x = true ∨ True ∧ x_2.usubOverflow (x_1 + x) = true) → x_2 - x_1 - x = x_2 - (x_1 + x)

theorem e_204 :
     - 2 *  ~~~x - 2 * (x ^^^ y) - 11 *  ~~~(x ^^^ y) + 13 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) + 2 * (x &&&  ~~~y) =  - 11 * (x &&& y)

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

theorem n2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬15#32 ≥ ↑32 → zeroExtend 32 x <<< 15#32 &&& BitVec.ofInt 32 (-2147483648) = 0#32

theorem test3_thm (e : IntW 32) : LLVM.xor e e ⊑ const? 32 0

@[simp]
theorem BitVec.zero_concat (b : Bool) : (0#0).concat b = BitVec.ofBool b

theorem ne_umax1_proof : ne_umax1_before ⊑ ne_umax1_after

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

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

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

theorem sub_ashr_and_i16_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 15#16 ≥ ↑16) →
    ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 15#16 &&& x = x

@[simp]
theorem replicate_one_eq_allOnes {w : Nat} : BitVec.replicate w 1#1 = BitVec.cast (by simp) (allOnes w)

theorem zext_zext_sle_op0_narrow_thm (e : IntW 16) (e_1 : IntW 8) :
  icmp IntPred.sle (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.uge e (zext 16 e_1)

theorem shl_lshr_pow2_const_case1_proof : shl_lshr_pow2_const_case1_before ⊑ shl_lshr_pow2_const_case1_after

theorem ashrslt_03_00_proof : ashrslt_03_00_before ⊑ ashrslt_03_00_after

theorem select_icmp_ne_0_and_8_xor_1073741824_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ofBool (0#8 != x_1 &&& 8#8) = 1#1 → ofBool (x_1 &&& 8#8 == 0#8) = 1#1 → x = x ^^^ 1073741824#32

theorem trunc_ashr_trunc_exact_proof : trunc_ashr_trunc_exact_before ⊑ trunc_ashr_trunc_exact_after

theorem ashr_ugt_2_proof : ashr_ugt_2_before ⊑ ashr_ugt_2_after

theorem one_side_fold_sgt_thm.extracted_1._10 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  ¬x_3 = 1#1 → ¬x_3 ^^^ 1#1 = 1#1 → ofBool (x <ₛ x_1) = 0#1

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

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

theorem AvoidCollision_cast_setWidth (h : v = v') (x : BitVec w) :
    (x.setWidth v).cast h = x.setWidth v'

theorem substitute_constant_and_eq_eq_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e_1 e) (const? 1 0) ⊑
    select (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42)) (const? 1 0)

theorem test_and1_logical_proof : test_and1_logical_before ⊑ test_and1_logical_after

theorem select_icmp_eq_and_32_0_xor_8_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 32#32 == 0#32) = 1#1 → ¬2#32 ≥ ↑32 → x ^^^ 8#32 = x ^^^ x_1 >>> 2#32 &&& 8#32

theorem bitwise_and_logical_and_icmps_thm (e e_1 e_2 : IntW 8) :
  LLVM.and
      (select (icmp IntPred.eq e_2 (const? 8 42)) (icmp IntPred.ne (LLVM.and e_1 (const? 8 1)) (const? 8 0))
        (const? 1 0))
      (icmp IntPred.ne (LLVM.and e_1 (shl (const? 8 1) e)) (const? 8 0)) ⊑
    select (icmp IntPred.eq e_2 (const? 8 42))
      (icmp IntPred.eq (LLVM.and e_1 (LLVM.or (shl (const? 8 1) e { «nsw» := false, «nuw» := true }) (const? 8 1)))
        (LLVM.or (shl (const? 8 1) e { «nsw» := false, «nuw» := true }) (const? 8 1)))
      (const? 1 0)

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

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

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 carry_incr (x : Unit → BitStream) : ∀ (n : ℕ),
    incr.carry x (n+1) = fun _ => (BitStream.incrAux (x ()) n).2

theorem e_2313 :
     - 1 * (f ^^^  ~~~(d &&& e)) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * (e &&&  ~~~(d &&&  ~~~f)) + 1 * (e &&& (d |||  ~~~f)) + 3 * (e ^^^  ~~~(d |||  ~~~f)) - 3 *  ~~~(d &&& ( ~~~e ||| f)) + 5 * (e ^^^ ( ~~~d &&& (e ||| f))) + 4 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 4 *  ~~~(d &&& (e ^^^ f)) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 11 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 11 *  ~~~(d |||  ~~~e) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 3 * (e ||| (d &&& f)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) - 5 * (f ^^^  ~~~(d ||| e)) - 7 * ( ~~~d &&& (e ||| f)) - 5 * (f ^^^ (d ||| (e ||| f))) - 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (e ^^^ (d ||| (e ||| f))) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) + 5 * (f ^^^ (d &&&  ~~~e)) + 1 * (d ^^^ e) - 11 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 11 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f ^^^ (d &&& e)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 6 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 11 * ( ~~~e |||  ~~~(d ^^^ f)) - 2 * (d ||| (e ^^^ f)) + 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 *  ~~~(d &&& (e ||| f)) - 2 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 5 * (d ||| (e &&& f)) + 7 *  ~~~( ~~~d &&& (e ||| f)) + 3 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * (e &&& f) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * (d ^^^ f) - 1 * (e &&&  ~~~(d &&& f)) - 5 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * (e ^^^ (d &&&  ~~~f)) - 7 *  ~~~(d ^^^ e) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 7 * ((d |||  ~~~e) &&& (e ^^^ f)) - 5 * ((d ||| e) &&& (e ^^^ f)) + 1 * ((d &&& e) ^^^ (e ||| f)) + 11 *  ~~~(d ||| (e ||| f)) + 20 *  ~~~(d ||| ( ~~~e ||| f)) - 5 *  ~~~( ~~~d ||| (e ||| f)) + 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 20 * ( ~~~d &&& ( ~~~e &&& f)) - 12 * ( ~~~d &&& (e &&& f)) - 8 * (d &&& ( ~~~e &&& f)) - 10 * (d &&& (e &&& f)) =  - 7 * ((e &&& f) ||| (d &&& (e ||| f)))

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

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

theorem main4c_logical_proof : main4c_logical_before ⊑ main4c_logical_after

theorem test19_thm.extracted_1._1 : ∀ (x x_1 : BitVec 39), x_1 - x + x = x_1

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

theorem different_size_sext_sext_sle_proof : different_size_sext_sext_sle_before ⊑ different_size_sext_sext_sle_after

theorem absdiff_proof : absdiff_before ⊑ absdiff_after

theorem scalar1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 4),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 4 (-2) &&& (x &&& 1#4) != 0) = true) →
    (x_1 ^^^ x) &&& BitVec.ofInt 4 (-2) ^^^ x = x_1 &&& BitVec.ofInt 4 (-2) ||

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

theorem sdiv_icmp2_proof : sdiv_icmp2_before ⊑ sdiv_icmp2_after

theorem p0_proof : p0_before ⊑ p0_after

theorem icmp_sgt4_proof : icmp_sgt4_before ⊑ icmp_sgt4_after

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

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

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

theorem icmp_select_var_pred_ult_proof : icmp_select_var_pred_ult_before ⊑ icmp_select_var_pred_ult_after

theorem test_with_neg_even_proof : test_with_neg_even_before ⊑ test_with_neg_even_after

theorem e_614 :
     - 2 * y - 2 *  ~~~(x ^^^ y) - 3 *  ~~~(x &&& y) + 7 * (x ^^^ y) - 2 *  ~~~x + 2 *  ~~~y - 2 * (x ||| y) + 5 *  ~~~(x ||| y) + 2 *  ~~~(x |||  ~~~y) + 2 * (x &&& y) = 8 * (x &&&  ~~~y) - 4 * x

theorem not_cond_proof : not_cond_before ⊑ not_cond_after

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem and_shl_proof : and_shl_before ⊑ and_shl_after

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

theorem e_2333 :
     - 3 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 5 *  ~~~(d |||  ~~~f) - 2 * (f &&& (d ^^^ e)) - 7 * (d ^^^ (e ||| f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 11 * (f ^^^ (d |||  ~~~e)) - 2 *  ~~~(e ||| f) + 11 * ( ~~~f &&& (d ^^^ e)) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 *  ~~~(d &&& (e ||| f)) - 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 11 *  ~~~d - 7 *  ~~~(d ^^^ e) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 *  ~~~(d &&&  ~~~f) + 3 * f - 2 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (e ^^^ ( ~~~d &&& (e ||| f))) - 2 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 6 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 3 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * ( ~~~f ||| (d ^^^ e)) + 7 * ((d ||| e) &&& (e ^^^ f)) + 1 * ( ~~~d &&& (e ^^^ f)) + 2 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 4 * (f |||  ~~~(d |||  ~~~e)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 1 * ( ~~~d ||| ( ~~~e &&& f)) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 2 * (e ^^^ f) - 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 11 *  ~~~(d ||| (e &&& f)) + 5 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 *  ~~~( ~~~d &&& (e ||| f)) + 3 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * e - 6 *  ~~~(d ||| f) - 1 * (d ^^^ ( ~~~e &&& f)) - 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 3 * ((d &&& f) |||  ~~~(e ||| f)) + 5 *  ~~~(d ^^^ (e ^^^ f)) - 1 * (f ^^^  ~~~(d &&& e)) + 2 * ( ~~~d &&& (e ||| f)) - 2 * (f ^^^  ~~~(d ||| (e &&& f))) - 6 * (e &&& f) + 2 * (e &&& (d ||| f)) + 4 * (e |||  ~~~(d ^^^ f)) - 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 49 *  ~~~(d ||| (e ||| f)) - 24 *  ~~~(d ||| ( ~~~e ||| f)) + 30 *  ~~~( ~~~d ||| (e ||| f)) + 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) + 44 * ( ~~~d &&& (e &&& f)) - 21 * (d &&& ( ~~~e &&& f)) =  - 11 * (e ^^^  ~~~(d |||  ~~~f))

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

theorem PR42691_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ₛ 0#32) = 1#1 → 1#1 = ofBool (2147483646#32 <ᵤ x)

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

theorem PR42691_10_logical_proof : PR42691_10_logical_before ⊑ PR42691_10_logical_after

theorem select_1_thm.extracted_1._12 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  ¬x_4 = 1#1 → ¬x_1 = 1#1 → x ^^^ 123#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-124)

theorem ashr_can_be_lshr_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x >>> 16#32 <<< 16#32 ≠ x ∨
        16#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 16 (x.sshiftRight' 16#32)) ≠ x.sshiftRight' 16#32) →
    True ∧ x >>> 16#32 <<< 16#32 ≠ x ∨ 16#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 16 (x >>> 16#32)) ≠ x >>> 16#32 →
      False

theorem test1_proof : test1_before ⊑ test1_after

theorem select_icmp_and_8_eq_0_xor_8_proof : select_icmp_and_8_eq_0_xor_8_before ⊑ select_icmp_and_8_eq_0_xor_8_after

theorem com_ty : com.2.2.1 = [.bitvec 32]

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

theorem test17_proof : test17_before ⊑ test17_after

theorem src_is_notmask_x_xor_neg_x_proof : src_is_notmask_x_xor_neg_x_before ⊑ src_is_notmask_x_xor_neg_x_after

theorem fold_add_udiv_urem_commuted_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 10#32 = 0 ∨ 4#32 ≥ ↑32) →
    ¬(10#32 = 0 ∨ True ∧ (x / 10#32).umulOverflow 6#32 = true) →
      x % 10#32 + (x / 10#32) <<< 4#32 = x / 10#32 * 6#32 + x

theorem bar_proof : bar_before ⊑ bar_after

theorem lor_bor_right1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x_1 ||

theorem orn_and_cmp_1_logical_thm (e : IntW 1) (e_1 e_2 : IntW 37) :
  select (icmp IntPred.sle e_2 e_1) (const? 1 1) (select e (icmp IntPred.sgt e_2 e_1) (const? 1 0)) ⊑
    select (icmp IntPred.sle e_2 e_1) (const? 1 1) e

theorem ugt_swap_and_min_commute_proof : ugt_swap_and_min_commute_before ⊑ ugt_swap_and_min_commute_after

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

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

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

theorem or_not_and_and_not_and_xor_commute2_proof : or_not_and_and_not_and_xor_commute2_before ⊑ or_not_and_and_not_and_xor_commute2_after

theorem test_sub_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true → False

theorem shl_add_thm (e e_1 : IntW 8) :
  lshr (add (shl e_1 (const? 8 2)) e) (const? 8 2) ⊑ LLVM.and (add (lshr e (const? 8 2)) e_1) (const? 8 63)

theorem zext_zext_eq_proof : zext_zext_eq_before ⊑ zext_zext_eq_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 ashr_thm (e : IntW 32) :
  add (LLVM.xor (lshr e (const? 32 5)) (const? 32 67108864)) (const? 32 (-67108864)) ⊑ ashr e (const? 32 5)

theorem ne_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 trunc_shl_ashr_var_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(x ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬(x ≥ ↑64 ∨ 2#32 ≥ ↑32) → truncate 32 (x_1.sshiftRight' x <<< 2#64) = truncate 32 (x_1.sshiftRight' x) <<< 2#32

theorem merge_left_shift (hu : u >= r) (hts : t > s) (htq : t > q) :
  (bw r (shlMax (bw u (shlMax (bw p a) (bw q b))) (bw s c)))  =
  (bw r (shlMax (bw p a) (bw t (addMax (bw q b) (bw s c)))))

theorem xor_and_logic_or1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x_2 &&& x_1 ^^^ 1#1 = x_1 ^^^ 1#1

theorem test37_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (truncate 8 (x >>> 31#32 ||| 512#32) == 11#8) = 0#1

theorem positive_and_odd_ne_proof : positive_and_odd_ne_before ⊑ positive_and_odd_ne_after

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

theorem test_add_nuw__nuw_is_safe_proof : test_add_nuw__nuw_is_safe_before ⊑ test_add_nuw__nuw_is_safe_after

theorem dec_mask_commute_neg_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
        (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
    ¬((x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true ∨
          True ∧ ((42#32).sdiv x).saddOverflow (-1#32) = true ∨
            (x == 0 || 32 != 1 && 42#32 == intMin 32 && x == -1) = true) →
      ((42#32).sdiv x &&& 0#32 - (42#32).sdiv x) + -1#32 = (42#32).sdiv x + -1#32 &&& ((42#32).sdiv x ^^^ -1#32)

theorem sub_to_xor_proof : sub_to_xor_before ⊑ sub_to_xor_after

theorem e_507 :
     - 6 * x - 1 *  ~~~(x ^^^ y) - 2 * (x ^^^ y) + 1 * (x ||| y) - 2 *  ~~~y + 8 *  ~~~(x ||| y) + 5 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) + 5 * (x &&& y) = 5 *  ~~~x - 1 * y

theorem not_and_and_or_not_or_or_commute4_proof : not_and_and_or_not_or_or_commute4_before ⊑ not_and_and_or_not_or_or_commute4_after

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

theorem 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 icmp_eq_and_pow2_lshr_pow2_case2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (4#32 >>> x &&& 8#32 == 0#32)) = 1#32

theorem scalar_i32_udiv_and_negC_eq_X_is_constant3_proof : scalar_i32_udiv_and_negC_eq_X_is_constant3_before ⊑ scalar_i32_udiv_and_negC_eq_X_is_constant3_after

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

theorem test5_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 19), x_2 - (x_1 - x) = x - x_1 + x_2

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

theorem p0_ult_65536_proof : p0_ult_65536_before ⊑ p0_ult_65536_after

theorem slt_swap_and_not_max_logical_proof : slt_swap_and_not_max_logical_before ⊑ slt_swap_and_not_max_logical_after

theorem PR60818_ne_thm (e : IntW 32) :
  icmp IntPred.ne (sub (const? 32 0) e) e ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 2147483647)) (const? 32 0)

theorem trunc_sandwich_big_sum_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(21#32 ≥ ↑32 ∨ 11#12 ≥ ↑12) → truncate 12 (x >>> 21#32) >>> 11#12 = 0#12

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

theorem test3_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true) →
    ¬ofBool (x_1 - x == 0#32) = 1#1 → ofBool (x_1 == x) = 1#1 → ofBool (x_1 - x == 31#32) = 1#1

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

theorem udiv_shl_pair3_proof : udiv_shl_pair3_before ⊑ udiv_shl_pair3_after

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

theorem lshrugt_03_00_exact_proof : lshrugt_03_00_exact_before ⊑ lshrugt_03_00_exact_after

theorem test2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), x_1 ||

theorem C0zero_thm.extracted_1._5 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 + 10#8 <ᵤ 0#8) = 1#1 → ofBool (x_1 <ₛ BitVec.ofInt 8 (-10)) = 1#1 → False

theorem t0_shl_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬signExtend 32 x ≥ ↑32 →
    ¬(True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32) → x_1 <<< signExtend 32 x = x_1 <<< zeroExtend 32 x

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

theorem add_or_sub_comb_i8_negative_xor_instead_or_proof : add_or_sub_comb_i8_negative_xor_instead_or_before ⊑ add_or_sub_comb_i8_negative_xor_instead_or_after

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

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

theorem and_not_or_commute8_proof : and_not_or_commute8_before ⊑ and_not_or_commute8_after

theorem test_negative_nsw_and_unsigned_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).ssubOverflow x = true) → ofBool (10#64 - x <ᵤ 3#64) = ofBool (x + BitVec.ofInt 64 (-8) <ᵤ 3#64)

theorem lshrult_03_11_exact_proof : lshrult_03_11_exact_before ⊑ lshrult_03_11_exact_after

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

theorem thisdoesnotloop_proof : thisdoesnotloop_before ⊑ thisdoesnotloop_after

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

theorem and_ne_with_one_bit_diff_constants2_thm.extracted_1._1 : ∀ (x : BitVec 19),
  ofBool (x != 65#19) &&& ofBool (x != 193#19) = ofBool (x &&& BitVec.ofInt 19 (-129) != 65#19)

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8),
  ofBool (x_2 != 0#8) = 1#1 →
    ¬(True ∧ x_1.umulOverflow x_2 = true ∨ True ∧ x.umulOverflow x_2 = true) →
      ofBool (x_2 == 0#8) = 1#1 → ofBool (x * x_2 <ᵤ x_1 * x_2) = 1#1

theorem n5_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8), ofBool (x_2 &&& 1#8 == 2#8) = 1#1 → x_1 = x

theorem test_sdiv_canonicalize_op0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    ¬((x == 0 || 32 != 1 && x_1 == intMin 32 && x == -1) = true ∨ True ∧ (0#32).ssubOverflow (x_1.sdiv x) = true) →
      (0#32 - x_1).sdiv x = 0#32 - x_1.sdiv x

theorem bv_AddSub_1176 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.add e (LLVM.sub (LLVM.const? w 0) e_1) ⊑ LLVM.sub e e_1

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

theorem t0_thm (e : IntW 16) (e_1 : IntW 32) :
  ashr (trunc 16 (ashr e_1 (zext 32 (sub (const? 16 32) e)))) (add e (const? 16 (-1))) ⊑
    trunc 16 (ashr e_1 (const? 32 31)) { «nsw» := true, «nuw» := false }

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

theorem PR42691_4_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.uge e (const? 32 (-2147483648))) (icmp IntPred.eq e (const? 32 0)) ⊑
    icmp IntPred.slt e (const? 32 1)

theorem t0_const_lshr_shl_ne_proof : t0_const_lshr_shl_ne_before ⊑ t0_const_lshr_shl_ne_after

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

theorem sub_shl_same_amount_partial_nuw1_proof : sub_shl_same_amount_partial_nuw1_before ⊑ sub_shl_same_amount_partial_nuw1_after

theorem e_564 :
    2 * (x |||  ~~~y) + 3 *  ~~~(x &&& y) + 1 * x + 2 * (x ||| y) - 2 * y - 11 *  ~~~(x &&&  ~~~y) + 4 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) + 8 * (x &&& y) =  - 6 *  ~~~(x ||| y) - 4 * (x ^^^ y)

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

theorem lshr_neg_sgt_minus_1_proof : lshr_neg_sgt_minus_1_before ⊑ lshr_neg_sgt_minus_1_after

theorem urem_c_i32_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬zeroExtend 32 x = 0 → x = 0 ∨ True ∧ (10#8 % x).msb = true → False

theorem scalar_i64_shl_and_signbit_eq_thm (e e_1 : IntW 64) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 64 (-9223372036854775808))) (const? 64 0) ⊑
    icmp IntPred.sgt (shl e_1 e) (const? 64 (-1))

theorem ashr_mul_thm (e e_1 : IntW 8) :
  trunc 16 (ashr (mul (sext 20 e_1) (sext 20 e)) (const? 20 8)) ⊑
    ashr (mul (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 8)

theorem test_shl_nuw__all_are_safe_proof : test_shl_nuw__all_are_safe_before ⊑ test_shl_nuw__all_are_safe_after

theorem ripple_nsw6_proof : ripple_nsw6_before ⊑ ripple_nsw6_after

theorem e_1672 :
    7 * (b ^^^ ( ~~~a ||| (b ||| c))) + 11 * (c ^^^ (a ||| ( ~~~b ||| c))) + 5 *  ~~~(a &&& (b ||| c)) - 6 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * (b ^^^ (a ||| ( ~~~b &&& c))) + 4 *  ~~~(a &&& b) + 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) - 7 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 * (c ^^^  ~~~(a ||| b)) + 3 * (a ^^^ ( ~~~b ||| c)) - 2 * (b ^^^ (a &&& (b ||| c))) - 5 * ( ~~~c &&& (a ^^^ b)) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 4 * (b ^^^ c) - 1 *  ~~~(b ||| c) + 4 * (b ^^^ (a |||  ~~~c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) + 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 36 *  ~~~(a ||| (b ||| c)) - 15 *  ~~~(a ||| ( ~~~b ||| c)) - 26 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 31 * ( ~~~a &&& ( ~~~b &&& c)) - 12 * ( ~~~a &&& (b &&& c)) - 22 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) = 29 *  ~~~( ~~~a ||| (b ||| c)) - 11 *  ~~~(a &&&  ~~~a)

theorem src_srem_shl_demand_max_mask_hit_demand_proof : src_srem_shl_demand_max_mask_hit_demand_before ⊑ src_srem_shl_demand_max_mask_hit_demand_after

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

theorem select_or_disjoint_or_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(4#32 ≥ ↑32 ∨ True ∧ (0#32 &&& x <<< 4#32 != 0) = true) →
      4#32 ≥ ↑32 ∨
          True ∧ (0#32 &&& x <<< 4#32 != 0) = true ∨
            True ∧ (0#32 ||| x <<< 4#32).saddOverflow 4#32 = true ∨
              True ∧ (0#32 ||| x <<< 4#32).uaddOverflow 4#32 = true →
        False

theorem zext_or_eq_ult_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32) ||| ofBool (x == 5#32)) =
    zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32))

theorem t7_ashr_proof : t7_ashr_before ⊑ t7_ashr_after

theorem n15_wrong_comparison_predicate_and_constant_proof : n15_wrong_comparison_predicate_and_constant_before ⊑ n15_wrong_comparison_predicate_and_constant_after

theorem sub_from_constant_proof : sub_from_constant_before ⊑ sub_from_constant_after

theorem shl_sub_lshr_reverse_nsw_on_op1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨
        True ∧ x_1 <<< x >>> x ≠ x_1 ∨
          x ≥ ↑32 ∨
            True ∧ x_2.usubOverflow (x_1 <<< x) = true ∨
              True ∧ (x_2 - x_1 <<< x) >>> x <<< x ≠ x_2 - x_1 <<< x ∨ x ≥ ↑32) →
    True ∧ x_2 >>> x <<< x ≠ x_2 ∨ x ≥ ↑32 ∨ True ∧ (x_2 >>> x).usubOverflow x_1 = true → False

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

theorem lshrult_03_14_proof : lshrult_03_14_before ⊑ lshrult_03_14_after

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

theorem icmp_ne_sext_ne_allones_proof : icmp_ne_sext_ne_allones_before ⊑ icmp_ne_sext_ne_allones_after

theorem mul9_low_proof : mul9_low_before ⊑ mul9_low_after

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

theorem test2_proof : test2_before ⊑ test2_after

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

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

theorem test17_proof : test17_before ⊑ test17_after

theorem lshr_32_add_known_32_leading_zeroes_proof : lshr_32_add_known_32_leading_zeroes_before ⊑ lshr_32_add_known_32_leading_zeroes_after

@[simp]
theorem if_then_poison_isRefinedBy_iff  :
    (if c then poison else a? : no_index _) ⊑ b? ↔ ¬c → a? ⊑ b?

theorem test14_proof : test14_before ⊑ test14_after

theorem test_shl__nsw_is_safe_proof : test_shl__nsw_is_safe_before ⊑ test_shl__nsw_is_safe_after

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

theorem main3c_logical_thm.extracted_1._3 : ∀ (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 xor_logic_and_or1_proof : xor_logic_and_or1_before ⊑ xor_logic_and_or1_after

theorem e_706 :
    4 *  ~~~(x &&& y) + 4 * (x ^^^ y) + 4 *  ~~~x + 11 * (x |||  ~~~y) - 7 * y + 4 *  ~~~(x &&&  ~~~y) - 16 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) - 8 * (x &&& y) = 7 *  ~~~y

theorem e_1075 :
     - 11 *  ~~~(z &&& t) + 5 *  ~~~(z &&&  ~~~t) - 11 * z + 4 *  ~~~(z &&&  ~~~z) - 3 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) =  - 2 * (z &&& t) - 5 *  ~~~z

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

theorem shl_nuw_eq_0_proof : shl_nuw_eq_0_before ⊑ shl_nuw_eq_0_after

@[simp]
lemma RawCNFA.autSignedCmp_m_wf : autSignedCmp.m.1 |>.WF

theorem or_signbit_select_ashr_proof : or_signbit_select_ashr_before ⊑ or_signbit_select_ashr_after

theorem or_not_and_and_not_and_xor_commute4_proof : or_not_and_and_not_and_xor_commute4_before ⊑ or_not_and_and_not_and_xor_commute4_after

theorem e_1544 :
     - 7 *  ~~~(a ^^^ b) + 7 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 5 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 3 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 3 *  ~~~(b ^^^ c) - 8 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& ( ~~~b &&& c)) - 9 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) =  - 7 * ((a &&& c) ^^^ (b ||| c))

theorem exact_lshr_eq_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 7)

theorem xor_nosignbit_select_ashr_proof : xor_nosignbit_select_ashr_before ⊑ xor_nosignbit_select_ashr_after

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

theorem lowmask_or_zext_commute_proof : lowmask_or_zext_commute_before ⊑ lowmask_or_zext_commute_after

theorem icmp_select_var_proof : icmp_select_var_before ⊑ icmp_select_var_after

theorem test14_thm (e e_1 : IntW 32) :
  add (add e_1 (const? 32 1) { «nsw» := true, «nuw» := false })
      (LLVM.xor (LLVM.or e (const? 32 (-1431655767))) (const? 32 1431655766)) { «nsw» := true, «nuw» := false } ⊑
    sub e_1 (LLVM.and e (const? 32 1431655766))

lemma product.f_spec {m₁ m₂ : CNFA n} {s₁ : m₁.m.states} {s₂ : m₂.m.states} :
    ∀ a s₁' s₂',
      (a, (s₁', s₂')) ∈ f m₁ m₂ (s₁, s₂) ↔ s₁'.val ∈ m₁.m.tr s₁ a ∧ s₂'.val ∈ m₂.m.tr s₂ a

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

theorem test_nuw_nsw_and_signed_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).ssubOverflow x = true ∨ True ∧ (10#64).usubOverflow x = true) →
    ofBool (10#64 - x <ₛ 3#64) = ofBool (7#64 <ᵤ x)

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

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

theorem t5_c2_thm (e e_1 : IntW 8) : sub (sub e_1 e) (const? 8 42) ⊑ add (sub e_1 e) (const? 8 (-42))

theorem lshr_and_or_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 ∨ 2#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨ 2#8 ≥ ↑8 → False

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

theorem ashr_ult_2_proof : ashr_ult_2_before ⊑ ashr_ult_2_after

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

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

@[simp]
theorem flipAccept_accepts (M : NFA α σ) (hc : M.Complete) (hdet : M.Deterministic) :
    M.flipAccept.accepts = M.acceptsᶜ

theorem corec₂_eq_corec_of_corec₂ (streamInt: DCOp.ValueStream Int) :
    (corec₂ streamInt fun x => (x 0, x 0, x.tail)).1 ≈
    corec
      ((corec₂ streamInt fun (x : DCOp.ValueStream Int) =>
            (match x 0 with
              | some val => (x 0, some (), x.tail)
              | none => (none, none, x.tail))).1,
        (corec₂
            (corec₂ streamInt fun x =>
                (match x 0 with
                  | some val => (x 0, some (), x.tail)
                  | none => (none, none, x.tail))).2
            fun x => Id.run (x 0, x 0, tail x)).1)
      fun x =>
      match x.1 0, x.2 0 with

theorem test0_thm (e : IntW 1) : LLVM.xor e (const? 1 0) ⊑ e

theorem basic_com_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), x_1 + (x ^^^ -1#8) ^^^ -1#8 = x - x_1

theorem not_not_true_proof : not_not_true_before ⊑ not_not_true_after

theorem sge_or_max_proof : sge_or_max_before ⊑ sge_or_max_after

theorem fold_sext_to_and_wrong8_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& 128#32 != BitVec.ofInt 32 (-2147483648)) = 1#1

theorem e_627 :
     - 2 *  ~~~(x &&&  ~~~x) - 2 * x + 4 *  ~~~(x ^^^ y) - 2 * (x ^^^ y) + 7 *  ~~~y + 7 *  ~~~(x &&& y) - 5 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) + 11 * (x &&& y) = 11 *  ~~~(x &&&  ~~~y)

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

theorem icmp_equality_test_constant_samesign_thm.extracted_1._2 : ∀ (x x_1 : BitVec 42),
  ¬ofBool (x_1 == BitVec.ofInt 42 (-42)) = 1#1 →
    ¬ofBool (x == BitVec.ofInt 42 (-42)) ^^^ 1#1 = 1#1 → 0#1 = ofBool (x_1 == x)

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

theorem test_sub_nuw__all_are_safe_proof : test_sub_nuw__all_are_safe_before ⊑ test_sub_nuw__all_are_safe_after

@[simp] theorem pure_def : pure = @value α

theorem t3_exact_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) →
    ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 ∨
              True ∧ zeroExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64) →
      0#32 - truncate 32 (x.sshiftRight' 63#64) = truncate 32 (x >>> 63#64)

@[simp_denote] theorem HVector.cons_inj {α : Type u_1} {f : α → Type u_2}
    {as : List α} {a : α}  (x y : f a) (xs ys : HVector f as) :
    @Eq (no_index _) (x ::ₕ xs) (y ::ₕ ys) ↔ (x = y ∧ xs = ys)

theorem icmp_eq_x_invertable_y2_todo_proof : icmp_eq_x_invertable_y2_todo_before ⊑ icmp_eq_x_invertable_y2_todo_after

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

theorem slt_zero_eq_ne_0_thm (e : IntW 32) :
  icmp IntPred.eq (zext 32 (icmp IntPred.ne e (const? 32 0))) (lshr e (const? 32 31)) ⊑
    icmp IntPred.slt e (const? 32 1)

theorem e_594 :
     - 3 *  ~~~y - 5 * (x ^^^ y) + 11 * y + 7 *  ~~~x + 7 *  ~~~(x &&&  ~~~x) + 2 *  ~~~(x &&&  ~~~y) - 13 *  ~~~(x ||| y) - 11 *  ~~~(x |||  ~~~y) + 12 * (x &&&  ~~~y) - 9 * (x &&& y) = 11 * (x ||| y)

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

theorem e_2140 :
    1 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 5 * (d ||| ( ~~~e &&& f)) + 1 * (e ||| (d &&&  ~~~f)) - 7 * (d &&& (e ||| f)) - 1 * ((d &&& e) ||| (e ^^^ f)) - 7 *  ~~~(d &&& (e ||| f)) + 7 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 5 *  ~~~(d ||| e) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ||| f) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 *  ~~~(d &&&  ~~~f) - 5 * ( ~~~d &&& (e ||| f)) - 2 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (e ^^^ ( ~~~d &&& (e ||| f))) + 2 * (f ^^^ (d ||| e)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 11 * (f &&&  ~~~(d &&&  ~~~e)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * (d &&& (e ^^^ f)) + 11 * (e &&&  ~~~(d &&& f)) - 5 * (e &&& (d ||| f)) + 7 *  ~~~( ~~~d ||| (e &&& f)) + 3 *  ~~~f + 11 * (e ||| (d ^^^ f)) + 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 *  ~~~(d &&& e) + 3 *  ~~~(d ||| f) - 1 * (f &&& (d ||| e)) - 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * ((d &&& f) ^^^ (e ||| f)) + 11 * (f &&&  ~~~(d &&& e)) + 18 *  ~~~(d ||| (e ||| f)) - 19 *  ~~~(d ||| ( ~~~e ||| f)) - 16 *  ~~~( ~~~d ||| (e ||| f)) - 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 2 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) - 23 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) = 7 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f)))

theorem band_lor_right1_proof : band_lor_right1_before ⊑ band_lor_right1_after

theorem icmp_ne_zext_eq_zero_proof : icmp_ne_zext_eq_zero_before ⊑ icmp_ne_zext_eq_zero_after

@[simp]
lemma CNFA.SignedCmp_states cmp : s ∈ (autSignedCmp cmp).m.states ↔  s < 5

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

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 ult_umin3_proof : ult_umin3_before ⊑ ult_umin3_after

theorem a_true_implies_b_false2_comm_thm.extracted_1._6 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 8),
  ofBool (x_2 == 10#8) = 1#1 → ¬ofBool (20#8 <ᵤ x_2) = 1#1 → x_1 &&& ofBool (20#8 <ᵤ x_2) = 0#1

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

theorem sdiv_shl_shl_nsw2_nuw_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        x_1 ≥ ↑8 ∨
          True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨
            True ∧ x <<< x_1 >>> x_1 ≠ x ∨
              x_1 ≥ ↑8 ∨ (x <<< x_1 == 0 || 8 != 1 && x_2 <<< x_1 == intMin 8 && x <<< x_1 == -1) = true) →
    ¬(x == 0 || 8 != 1 && x_2 == intMin 8 && x == -1) = true → (x_2 <<< x_1).sdiv (x <<< x_1) = x_2.sdiv x

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

theorem e_737 :
     - 7 *  ~~~(x &&&  ~~~y) - 5 * (x |||  ~~~y) - 6 *  ~~~(x ^^^ y) - 2 * (x ^^^ y) + 11 * y - 6 *  ~~~x - 2 *  ~~~(x &&&  ~~~x) + 26 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) + 20 * (x &&&  ~~~y) + 20 * (x &&& y) = 11 * x

theorem test_shl_nuw__none_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨
          True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
            zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
      x = x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

theorem ult_umin1_proof : ult_umin1_before ⊑ ult_umin1_after

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

theorem xor_nosignbit_shl_thm (e : IntW 32) :
  shl (LLVM.xor e (const? 32 2147418112)) (const? 32 8) ⊑
    LLVM.xor (shl e (const? 32 8)) (const? 32 (-16777216))

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

theorem AvoidCollision_toFin_setWidth {x : BitVec w} :
    (x.setWidth v).toFin = Fin.ofNat (2^v) x.toNat

theorem sle_smax3_proof : sle_smax3_before ⊑ sle_smax3_after

theorem no_masks_with_logical_or2_thm.extracted_1._3 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 != -1#32) = 1#1 → ofBool (x_2 &&& x != -1#32) = 1#1 → 1#1 ||

theorem thisdoesnotloop_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ₛ BitVec.ofInt 32 (-128)) = 1#1 → truncate 8 128#32 = BitVec.ofInt 8 (-128)

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

theorem ashr_ashr_proof : ashr_ashr_before ⊑ ashr_ashr_after

theorem sub_ashr_and_i64_proof : sub_ashr_and_i64_before ⊑ sub_ashr_and_i64_after

theorem uge_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.uge e_1 e) ⊑ const? 1 1

theorem n11_uge_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ 129#32) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → False

theorem c_0_1_0_proof : c_0_1_0_before ⊑ c_0_1_0_after

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

theorem lshr_lshr_thm (e : IntW 232) : lshr (lshr e (const? 232 231)) (const? 232 1) ⊑ const? 232 0

theorem ashr_lowmask_thm (e : IntW 32) : LLVM.and (ashr e (const? 32 24)) (const? 32 255) ⊑ lshr e (const? 32 24)

theorem shl_add_proof : shl_add_before ⊑ shl_add_after

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

theorem logical_and_implies_folds_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (42#32 <ᵤ x) = 1#1 → 0#1 = ofBool (42#32 <ᵤ x)

theorem e_1800 :
     - 1 * (b ^^^ (a |||  ~~~c)) - 6 * (c ||| (a &&& b)) + 3 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 *  ~~~(b |||  ~~~c) - 1 *  ~~~(b &&&  ~~~c) + 5 *  ~~~(a ||| b) + 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * (c ^^^ (a &&& b)) - 11 * (c ^^^ (a &&&  ~~~b)) - 2 * (c ^^^ (a ||| (b &&& c))) - 11 * ((b &&& c) ||| (a &&& (b ||| c))) + 4 * (b ^^^ (a &&&  ~~~c)) - 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (b &&& (a ||| c)) - 1 * (b &&&  ~~~c) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * ( ~~~a ||| (b ||| c)) - 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 2 *  ~~~b + 5 *  ~~~(a |||  ~~~c) + 4 * (b ^^^  ~~~(a |||  ~~~c)) - 2 * (b ^^^ (a ||| c)) + 4 * (a &&& ( ~~~b ||| c)) - 3 * ((a &&& b) |||  ~~~(b ||| c)) + 3 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (a &&&  ~~~b) - 1 * (c &&&  ~~~(a ^^^ b)) + 5 * ((a ||| b) &&& (b ^^^ c)) + 2 *  ~~~(a &&& ( ~~~b ||| c)) + 3 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 7 * (a ||| (b &&& c)) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) + 17 *  ~~~( ~~~a ||| (b ||| c)) + 25 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 35 * ( ~~~a &&& (b &&& c)) + 30 * (a &&& ( ~~~b &&& c)) + 29 * (a &&& (b &&& c)) =  - 27 * ( ~~~a &&& ( ~~~b &&& c))

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

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 ashr_ult_9_proof : ashr_ult_9_before ⊑ ashr_ult_9_after

theorem mul_of_sdiv_fail_ub_proof : mul_of_sdiv_fail_ub_before ⊑ mul_of_sdiv_fail_ub_after

theorem main8_proof : main8_before ⊑ main8_after

theorem alive_AddSub_1619  (w : Nat)   : alive_AddSub_1619_src w  ⊑ alive_AddSub_1619_tgt w

theorem t7_ashr_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 >>> (32#32 - x) <<< (32#32 - x) ≠ x_1 ∨ 32#32 - x ≥ ↑32 ∨ x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    ¬30#32 ≥ ↑32 → (x_1.sshiftRight' (32#32 - x)).sshiftRight' (x + BitVec.ofInt 32 (-2)) = x_1.sshiftRight' 30#32

theorem positive_with_mask_logical_proof : positive_with_mask_logical_before ⊑ positive_with_mask_logical_after

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

theorem or_not_xor_common_op_commute3_proof : or_not_xor_common_op_commute3_before ⊑ or_not_xor_common_op_commute3_after

theorem sub_ule_sext_proof : sub_ule_sext_before ⊑ sub_ule_sext_after

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

theorem shl_nsw_sgt_n1_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (shl e_1 e { «nsw» := true, «nuw» := false }) (const? 8 (-1)) ⊑
    icmp IntPred.sgt e_1 (const? 8 (-1))

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

theorem slt_to_ult_thm (e e_1 : IntW 8) :
  icmp IntPred.slt (LLVM.xor e_1 (const? 8 (-128))) (LLVM.xor e (const? 8 (-128))) ⊑
    icmp IntPred.ult e_1 e

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

theorem icmp_shl_ne_2_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.sdiv (const? 8 42) e) (shl (LLVM.sdiv (const? 8 42) e) (const? 8 1)) ⊑
    icmp IntPred.ne (LLVM.sdiv (const? 8 42) e) (const? 8 0)

theorem test35_with_trunc_proof : test35_with_trunc_before ⊑ test35_with_trunc_after

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

theorem e_8 :
    1 * (x |||  ~~~y) - 1 * (x ||| y) - 2 *  ~~~(x ||| y) - 1 * (x &&& y) =  - 1 *  ~~~(x &&&  ~~~y)

theorem ofBitVec_one_eqTo_ofNat : @ofBitVecSext w 1 ≈ʷ ofNat 1

theorem main7e_logical_proof : main7e_logical_before ⊑ main7e_logical_after

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

theorem is_ascii_alphabetic_inverted_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 (-91)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (icmp IntPred.ult (add e (const? 32 (-123)) { «nsw» := true, «nuw» := false }) (const? 32 (-26)))
      (const? 1 0) ⊑
    icmp IntPred.ult (add (LLVM.and e (const? 32 (-33))) (const? 32 (-91))) (const? 32 (-26))

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

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

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

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)

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

@[simp] theorem get_map (xs : HVector A as) (f : (a : α) → A a → B a) :
    (xs.map f).get i = f _ (xs.get i)

theorem test11_proof : test11_before ⊑ test11_after

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

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

theorem nonexact_ashr_ne_exactdiv_proof : nonexact_ashr_ne_exactdiv_before ⊑ nonexact_ashr_ne_exactdiv_after

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

theorem lshr_lshr_pow2_const_negative_nopow2_1_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 6#16 ≥ ↑16) → x ≥ ↑16 → False

theorem negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_proof : negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_before ⊑ negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_after

theorem a_true_implies_b_true2_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ofBool (10#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) &&& x = x

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

theorem R.trimTensor_trimTensor (tensor : List Int) :
  trimTensor (trimTensor tensor) = trimTensor tensor

@[simp] theorem dropUntilHom_last : dropUntilHom (v := Var.last Γ ty) = Hom.id.consRight

theorem test_add_nuw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 3#32) = 1#1 → 4#32 = x + 1#32

theorem add_select_not_zext_proof : add_select_not_zext_before ⊑ add_select_not_zext_after

theorem no_shift_xor_multiuse_and_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 4096#32) = 1#1 →
    ofBool (x_1 &&& 4096#32 == 0#32) = 1#1 →
      x * (x &&& BitVec.ofInt 32 (-4097)) = (x &&& BitVec.ofInt 32 (-4097)) * (x &&& BitVec.ofInt 32 (-4097))

theorem positive_with_signbit_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 (-1))) (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256))
      (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem bool_add_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → (zeroExtend 2 x_1 + zeroExtend 2 x) >>> 1#2 = zeroExtend 2 (x_1 &&& x)

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

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

theorem test_mul_nsw__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 268435457#32 == 268435456#32) = 1#1 →
    ¬(True ∧ (x &&& 268435457#32).umulOverflow 9#32 = true) →
      BitVec.ofInt 32 (-1879048192) = (x &&& 268435457#32) * 9#32

theorem or_not_xor_common_op_commute2_proof : or_not_xor_common_op_commute2_before ⊑ or_not_xor_common_op_commute2_after

theorem lshrugt_01_06_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 1)) (const? 4 6) ⊑ icmp IntPred.ugt e (const? 4 (-3))

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

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

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

theorem 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 andn_or_cmp_4_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == x) = 1#1 → ¬ofBool (x_1 != x) = 1#1 → True → ofBool (x_1 != x) = 0#1

theorem ule_umax2_proof : ule_umax2_before ⊑ ule_umax2_after

theorem scalar_i8_shl_ult_const_3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → ofBool (x <<< 7#8 <ᵤ 64#8) = ofBool (x &&& 1#8 == 0#8)

theorem test6_thm (e : IntW 1023) :
  select (icmp IntPred.ne (LLVM.and e (const? 1023 64)) (const? 1023 0)) (const? 1023 64) (const? 1023 0) ⊑
    LLVM.and e (const? 1023 64)

theorem shl1_nsw_not_exact_proof : shl1_nsw_not_exact_before ⊑ shl1_nsw_not_exact_after

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||

theorem and_or3_thm.extracted_1._5 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 &&& ofBool (x_2 == x_1) = 1#1 → ¬x_3 = 1#1 → x = 0#1

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

theorem PR42691_8_logical_proof : PR42691_8_logical_before ⊑ PR42691_8_logical_after

theorem neg_test_icmp_non_equality_proof : neg_test_icmp_non_equality_before ⊑ neg_test_icmp_non_equality_after

theorem or_and_or_pat6_proof : or_and_or_pat6_before ⊑ or_and_or_pat6_after

theorem shl1_nsw_thm (e e_1 : IntW 8) :
  LLVM.sdiv e_1 (shl (const? 8 1) e { «nsw» := true, «nuw» := false }) { «exact» := true } ⊑
    ashr e_1 e { «exact» := true }

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

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

theorem lshrugt_03_10_exact_proof : lshrugt_03_10_exact_before ⊑ lshrugt_03_10_exact_after

theorem and_ranges_overlap_single_proof : and_ranges_overlap_single_before ⊑ and_ranges_overlap_single_after

theorem e_1904 :
    1 *  ~~~(b &&& c) - 7 * ( ~~~a ||| (b ^^^ c)) + 11 * ((a &&& b) ^^^ (b |||  ~~~c)) + 4 * (a ^^^ ( ~~~b &&& c)) - 2 * (c ^^^ (a &&& b)) - 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b ^^^ c)) - 1 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 5 *  ~~~(a ^^^ (b ||| c)) + 2 * (b ^^^ (a ||| (b ||| c))) - 7 *  ~~~(a &&& ( ~~~b &&& c)) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 3 * (b &&&  ~~~(a ^^^ c)) - 2 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 3 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 3 * ( ~~~a ||| ( ~~~b &&& c)) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * (b |||  ~~~c) + 2 * (a |||  ~~~c) - 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 3 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * (b ||| (a &&&  ~~~c)) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * (b &&&  ~~~(a &&& c)) - 11 * ((a ||| b) &&& (b ^^^ c)) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 1 * (a ^^^ c) + 7 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 5 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 2 * (c &&&  ~~~(a &&& b)) + 2 * (b ^^^ (a |||  ~~~c)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) - 5 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~a ||| ( ~~~b ||| c)) + 3 * ((a &&& b) ^^^ (b ||| c)) - 5 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 23 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) - 6 *  ~~~( ~~~a ||| (b ||| c)) + 56 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 23 * ( ~~~a &&& (b &&& c)) + 11 * (a &&& ( ~~~b &&& c)) + 31 * (a &&& (b &&& c)) = 7 * (b &&& (a ||| c))

@[simp] lemma eval_and (x : Bool → BitStream) : and.eval x = (x true) &&& (x false)

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

theorem slt_0_proof : slt_0_before ⊑ slt_0_after

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

theorem test5_proof : test5_before ⊑ test5_after

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

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

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

theorem carry_sub (x : Bool → BitStream) : ∀ (n : ℕ), sub.carry x (n+1) =
    fun _ => (BitStream.subAux (x true) (x false) n).2

theorem test_and3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x <ₛ x_1 &&& 2147483647#32) &&& ofBool (0#32 ≤ₛ x) = ofBool (x <ᵤ x_1 &&& 2147483647#32)

theorem test_add_nuw_nsw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 3#32) = 1#1 → 4#32 = x + 1#32

theorem prove_exact_with_high_mask_proof : prove_exact_with_high_mask_before ⊑ prove_exact_with_high_mask_after

theorem test1_thm (e : IntW 32) :
  icmp IntPred.uge e (const? 32 1) ⊑ icmp IntPred.ne e (const? 32 0)

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

theorem test1_proof : test1_before ⊑ test1_after

theorem lshr_C1_add_A_C2_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 →
    ¬x &&& 65535#32 ≥ ↑32 → 6#32 <<< ((x &&& 65535#32) + 5#32) = 192#32 <<< (x &&& 65535#32)

theorem lowmask_sub_zext_commute_proof : lowmask_sub_zext_commute_before ⊑ lowmask_sub_zext_commute_after

theorem icmp_select_var_both_fold_proof : icmp_select_var_both_fold_before ⊑ icmp_select_var_both_fold_after

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem e_1432 :
    2 * (z |||  ~~~t) - 1 * (z ^^^ t) + 3 *  ~~~(z &&& t) - 7 *  ~~~z - 1 *  ~~~t - 3 * z + 3 * t - 2 *  ~~~(z ^^^ t) + 3 *  ~~~(z ||| t) - 2 * (z &&& t) =  - 2 *  ~~~(z &&&  ~~~z) + 2 * (z &&&  ~~~t)
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Fintype.Prod

import Blase.AutoStructs.Worklist

import Mathlib.Tactic.ApplyFun

open SetRel

section sink

variable {A : Type} [BEq A] [Hashable A] [DecidableEq A] [FinEnum A]

end sink

section generic_prod

variable {α} [BEq α] [Hashable α] [LawfulBEq α]

variable {β} [BEq β] [Hashable β] [LawfulBEq β]

variable {S₁ : Finset α} {S₂ : Finset β}

variable {γ} (f : S₁ → S₂ → γ) (hinj : Function.Injective2 f)

variable {m₁ : Std.HashSet α} (hm₁ : ∀ s₁ ∈ m₁, s₁ ∈ S₁)

variable {m₂ : Std.HashSet β} (hm₂ : ∀ s₂ ∈ m₂, s₂ ∈ S₂)

@[inline]
def product.prodArray' (a : Array γ) :=
  m₁.attachWith _ hm₁ |>.fold (init := a) fun is s1 =>
    m₂.attachWith _ hm₂ |>.fold (init := is) fun is s2 =>
      is.push (f s1 s2)

@[inline]
def product.prodArray := prodArray' f hm₁ hm₂ (Array.emptyWithCapacity <| m₁.size * m₂.size)

end generic_prod

section product

variable {A : Type} [BEq A] [LawfulBEq A] [Hashable A] [DecidableEq A] [FinEnum A]

def product.inits (m₁ m₂ : CNFA n) :=
  product.prodArray Prod.mk @m₁.wf.initials_lt @m₂.wf.initials_lt

def product (final? : Bool → Bool → Bool) (m₁ m₂ : CNFA n) : CNFA n :=
  worklistRun (m₁.m.states × m₂.m.states) final (product.inits m₁ m₂)
    (by admit /- proof elided -/
    ) f
where final (ss : m₁.m.states × m₂.m.states) := final? (ss.1 ∈ m₁.m.finals) (ss.2 ∈ m₂.m.finals)
      f (ss : m₁.m.states × m₂.m.states) :=
        let (s1, s2) := ss
        (FinEnum.toList (α := BitVec n)).foldl (init := Array.empty) fun as a =>
          product.prodArray' (λ s₁ s₂ ↦ (a, (s₁, s₂)))
            (fun s' => m₁.wf.trans_tgt_lt (s := s1) (a := a)) (fun s' => m₂.wf.trans_tgt_lt (s := s2) (a := a)) as

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

<target_theorem>
lemma product.sim {m1 m2 : CNFA n}:
    m1.Sim M1 → m2.Sim M2 →
    (nfa (product.inits m1 m2) (final final? m1 m2) (f m1 m2)).Bisim (M1.M.product (to_prop final?) M2.M) :=
</target_theorem>

