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>
String in Init.Prelude
BEq in Init.Prelude
ite in Init.Prelude
Repr in Init.Data.Repr
List in Init.Prelude
Vector in Init.Data.Vector.Basic
Bool in Init.Prelude
Int in Init.Data.Int.Basic
bool in Init.Control.Basic
Computation in Mathlib.Data.Seq.Computation
DecidableEq in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Nat in Init.Prelude
List.map in Init.Prelude
LawfulMonad in Init.Control.Lawful.Basic
PUnit in Init.Prelude
Id in Init.Control.Id
Pure in Init.Prelude
Fin in Init.Prelude
Inhabited in Init.Prelude
BitVec in Init.Prelude
id in Init.Prelude
Subtype in Init.Prelude
Subtype.mk in Init.Prelude
Option in Init.Prelude
Prod in Init.Prelude
Sigma in Init.Core
Sigma.mk in Init.Core
Subtype.val in Init.Prelude

syntax "llvm.and"     : MLIR.Pretty.uniform_op

syntax "llvm.ashr"    : MLIR.Pretty.exact_op

syntax "llvm.add"     : MLIR.Pretty.overflow_op

syntax "llvm.return"  : MLIR.Pretty.uniform_op

notation:50 x " ≤ₛ " y => BitVec.sle x y

notation:50 x " >ᵤ " y => BitVec.ult y x

notation:50 x " ≥ᵤ " y => BitVec.ule y x

notation:50 x " <ᵤ " y => BitVec.ult x y

notation:50 x " ≥ₛ " y => BitVec.sle y x

notation:50 x " <ₛ " y => BitVec.slt x y

notation:50 x " >ₛ " y => BitVec.slt y x

notation:50 x " ≤ᵤ " y => BitVec.ule x y

macro_rules
  | `(mlir_op| $resName:mlir_op_operand = $name:InstCombine.cmp_op_name $x, $y $[: $t]?) => do
    let some opName := extractOpName name.raw
      | Macro.throwUnsupported
    let t ← t.getDM `(mlir_type| _)
    `(mlir_op| $resName:mlir_op_operand = $opName ($x, $y) : ($t, $t) -> (i1) )

macro_rules
  | `(mlir_op| $resName:mlir_op_operand = $name:InstCombine.int_cast_op $x : $t to $t') => do
    let some opName := extractOpName name.raw
      | Macro.throwUnsupported
    `(mlir_op| $resName:mlir_op_operand = $opName ($x) : ($t) -> $t')

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant( $x $[: $inner_type]?)
      $[: $outer_type]? ) => do
       
      let outer_type ← outer_type.getDM `(mlir_type| _)
      let inner_type := inner_type.getD outer_type
      `(mlir_op| $res:mlir_op_operand = "llvm.mlir.constant"()
          {value = $x:neg_num : $inner_type} : () -> ($outer_type) )
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant( ${ $x:term }) $[: $t]?) => do
      let t ← t.getDM `(mlir_type| _)
      let x ← `(MLIR.AST.AttrValue.int $x [mlir_type| $t])
      `(mlir_op| $res:mlir_op_operand = "llvm.mlir.constant"() {value = $$($x) } : () -> ($t) )

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (true) $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (1 : i1) : i1)
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (false) $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant (0 : i1) : i1)
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant $x $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant($x $[: $t]?) $[: $t]?)
  | `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant ${ $x:term } $[: $t]?) =>
      `(mlir_op| $res:mlir_op_operand = llvm.mlir.constant($$($x) $[: $t]?) $[: $t]?)

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.icmp $p $x, $y $[: $t]?) => do
    let t ← t.getDM `(mlir_type| _)
    match p.getString with
      | "eq" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.eq" ($x, $y) : ($t, $t) -> (i1))
      | "ne" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ne" ($x, $y) : ($t, $t) -> (i1))
      | "slt" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.slt" ($x, $y) : ($t, $t) -> (i1))
      | "sle" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.sle" ($x, $y) : ($t, $t) -> (i1))
      | "sgt" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.sgt" ($x, $y) : ($t, $t) -> (i1))
      | "sge" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.sge" ($x, $y) : ($t, $t) -> (i1))
      | "ult" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ult" ($x, $y) : ($t, $t) -> (i1))
      | "ule" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ule" ($x, $y) : ($t, $t) -> (i1))
      | "ugt" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.ugt" ($x, $y) : ($t, $t) -> (i1))
      | "uge" => `(mlir_op| $res:mlir_op_operand = "llvm.icmp.uge" ($x, $y) : ($t, $t) -> (i1))
      | _ => Macro.throwErrorAt p s!"unexpected predicate {p.getString}"

macro_rules
  | `(mlir_op| $res:mlir_op_operand = llvm.select $c, $x, $y $[: $t]?) => do
    let t ← t.getDM `(mlir_type| _)
    `(mlir_op| $res:mlir_op_operand = "llvm.select" ($c, $x, $y) : (i1, $t, $t) -> ($t))

inductive Lets (Γ_in : Ctxt d.Ty) (eff : EffectKind) :
    (Γ_out : Ctxt d.Ty) → Type where
  | nil : Lets Γ_in eff Γ_in
  | var (body : Lets Γ_in eff Γ_out) (e : Expr d Γ_out eff t) : Lets Γ_in eff e.outContext

protected instance Expr.decidableEq [DecidableEq d.Op] [DecidableEq d.Ty] :
    {Γ : Ctxt d.Ty} → {ty : List d.Ty} → DecidableEq (Expr d Γ eff ty)
  | Γ, _, .mk op₁ rfl eff_le₁ arg₁ regArgs₁, .mk op₂ eq eff_le₂ arg₂ regArgs₂ =>
    if ho : op₁ = op₂ then by
      subst ho
      letI := HVector.decidableEq arg₁ arg₂
      letI := HVector.decidableEqReg regArgs₁ regArgs₂
      exact decidable_of_iff (arg₁ = arg₂ ∧ regArgs₁ = regArgs₂) (by admit /- proof elided -/
      )
    else isFalse (by admit /- proof elided -/
    )

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

structure Ctxt (Ty : Type) : Type where
  ofList :: toList : List Ty
  
  deriving Repr, Lean.ToExpr, DecidableEq

def Valuation.nil : Ctxt.Valuation (∅ : Ctxt Ty) := fun _ v => v.emptyElim

inductive EffectKind
| pure 
| impure 
deriving Repr, DecidableEq, Lean.ToExpr

inductive Com : Ctxt d.Ty → EffectKind → List d.Ty → Type where
  | rets {Γ} {tys} {eff : EffectKind} (vs : HVector Γ.Var tys) : Com Γ eff tys
  | var (e : Expr Γ eff ty) (body : Com (ty ++ Γ) eff β) : Com Γ eff β

structure FlatCom (d : Dialect) [DialectSignature d]  (Γ_in : Ctxt d.Ty) (eff : EffectKind)
    (Γ_out : Ctxt d.Ty) (ts : List d.Ty) where
  lets : Lets d Γ_in eff Γ_out
  rets : HVector Γ_out.Var ts

protected instance HVector.decidableEqReg [DecidableEq d.Op] [DecidableEq d.Ty] :
    ∀ {l : RegionSignature d.Ty}, DecidableEq (HVector (fun t => Com d t.1 .impure t.2) l)
  | _, .nil, .nil => isTrue rfl
  | _, .cons x₁ v₁, .cons x₂ v₂ =>
    letI := HVector.decidableEqReg v₁ v₂
    letI := Com.decidableEq x₁ x₂
    decidable_of_iff (x₁ = x₂ ∧ v₁ = v₂) (by admit /- proof elided -/
    )

def Var (Γ : Ctxt Ty) (t : Ty) : Type :=
  { i : Nat // Γ[i]? = some t }

def Hom.with [DecidableEq Ty] {Γ₁ Γ₂ : Ctxt Ty} (f : Γ₁.Hom Γ₂) {ts}
    (v₁ : HVector Γ₁.Var ts) (v₂ : HVector Γ₂.Var ts) : Γ₁.Hom Γ₂ :=
  fun _ w =>
    match v₁.idxOf? w with
    | none => f w
    | some ⟨i, h⟩ => (v₂.get i).cast h

abbrev Hom (Γ Γ' : Ctxt Ty) := ⦃t : Ty⦄ → Γ.Var t → Γ'.Var t

class TyDenote (β : Type) : Type 1 where
  toType : β → Type

@[simp]
instance Valuation.instAppendHVector (Γ : Ctxt Ty) (ts : List Ty) :
    HAppend (HVector toType ts) (Valuation Γ) (Valuation <| ⟨ts⟩ ++ Γ) where
  hAppend vals V :=
    (Valuation.ofHVector vals) ++ V

def map (f : Ty₁ → Ty₂) : Ctxt Ty₁ → Ctxt Ty₂ :=
  ofList ∘ (List.map f) ∘ toList

def Com.outContextHom (com : Com d Γ eff t) : Γ.Hom com.outContext :=
  com.outContextDiff.toHom

def Com.outContext {Γ} : Com d Γ eff ts → Ctxt d.Ty :=
  Com.rec' (motive := fun _ => Ctxt d.Ty)
    (@fun Γ _ => Γ) 
    (fun _ _ r => r)

def Com.rec' {Γ} (com : Com d Γ eff t) : motive com :=
   
  Com.rec
    (motive_1 := fun _ _ _ _ => PUnit)
    (motive_2 := fun _ eff' t' c =>
      (h₁ : eff = eff') → (h₂ : t = t') → motive (h₁ ▸ h₂ ▸ c))
    (motive_3 := fun _ _ => PUnit)
    (fun _ _ _ _ _ _ => ⟨⟩) 
    (fun v h₁ h₂ => 
      cast (by admit /- proof elided -/
      ) <| rets (h₂ ▸ v))
    (fun e' body' _ r' h₁ h₂ => 
      let e := h₁ ▸ e'
      let body : Com _ _ eff t := cast (by admit /- proof elided -/
      ) body'
      let r : motive body := cast (by admit /- proof elided -/
      ) (r' h₁ h₂)
      cast (by admit /- proof elided -/
      ) <| var e body r)
    ⟨⟩
    (fun _ _ _ _ => ⟨⟩)
    com
    rfl
    rfl

def Valuation.cast {Γ Δ : Ctxt Ty} (h : Γ = Δ) (V : Valuation Γ) : Valuation Δ :=
  fun _ v => V <| v.castCtxt h.symm

def Com.outContextDiff (com : Com d Γ eff ts) : Γ.Diff com.outContext :=
  ⟨com.bvars, by admit /- proof elided -/
      ⟩

abbrev Expr.outContext (_ : Expr d Γ eff ts) : Ctxt d.Ty :=
  ts ++ Γ

@[simp, grind=] def Expr.bvars (e : Expr d Γ eff Δ) : Nat :=
  (DialectSignature.returnTypes e.op).length

def returnTypes  := Signature.returnTypes ∘ s.signature

structure Signature (Ty : Type) where
  mkEffectful ::
  sig         : List Ty
  regSig      : RegionSignature Ty
  returnTypes : List Ty
  effectKind  : EffectKind := .pure

class DialectSignature (d : Dialect) where
  signature : d.Op → Signature d.Ty

def Com.bvars : Com d Γ eff t → Nat :=
  Com.rec'
           (fun _ => 0)
      (fun e _body bodySize => e.bvars + bodySize)

def Diff (Γ₁ Γ₂ : Ctxt Ty) : Type :=
  {d : Nat // Diff.Valid Γ₁ Γ₂ d}

@[simp]
abbrev Diff.Valid (Γ₁ Γ₂ : Ctxt Ty) (d : Nat) : Prop :=
  ∀ {i t}, Γ₁[i]? = some t → Γ₂[i+d]? = some t

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

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

def Com.denoteLets : (com : Com d Γ eff ty) → (Γv : Valuation Γ) →
    eff.toMonad d.m (com.outContext.Valuation)
  | .rets _, V => pure V
  | .var e body, V =>
      e.denote V >>= body.denoteLets >>= fun V =>
        return V.cast (by admit /- proof elided -/
        )

class DialectDenote (d : Dialect) [TyDenote d.Ty] [DialectSignature d] where
  denote : (op : d.Op) → HVector toType (DialectSignature.sig op) →
    (HVector (fun t : Ctxt d.Ty × List d.Ty =>
      t.1.Valuation
      → EffectKind.impure.toMonad d.m (HVector toType t.2))
            (DialectSignature.regSig op)) →
    ((DialectSignature.effectKind op).toMonad d.m
      (HVector toType <| DialectSignature.returnTypes op))

def Lets.denote [DialectSignature d] [DialectDenote d] {Γ₂}
    (lets : Lets d Γ₁ eff Γ₂) (V : Valuation Γ₁) : (eff.toMonad d.m <| Valuation Γ₂) :=
  match lets with
  | .nil          => return V
  | .var lets' e  => lets'.denote V >>= e.denote

def sig          := Signature.sig ∘ s.signature

def regSig       := Signature.regSig ∘ s.signature

abbrev RegionSignature Ty := List (Ctxt Ty × List Ty)

inductive Ty (q : Nat) (n : Nat)
  | index : Ty q n
  | integer : Ty q n
  | tensor : Ty q n
  | polynomialLike : Ty q n
  deriving DecidableEq, Repr

def effectKind   := Signature.effectKind ∘ s.signature

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

inductive Op (q : Nat) (n : Nat)
  | add : Op q n
  | sub : Op q n
  | mul : Op q n
  | mul_constant : Op q n
    
    
  | leading_term : Op q n
  | monomial : Op q n
  | monomial_mul : Op q n
  | from_tensor : Op q n
  | to_tensor : Op q n
  | const (c : R q n) : Op q n
  | const_int (c : Int) : Op q n
  | const_idx (i : Nat) : Op q n

def HVector.denote :
    {l : RegionSignature d.Ty} → (T : HVector (fun t => Com d t.1 .impure t.2) l) →
    HVector (fun t => t.1.Valuation → EffectKind.impure.toMonad d.m (HVector toType t.2)) l
  | _, .nil => HVector.nil
  | _, .cons v vs => HVector.cons (v.denote) (HVector.denote vs)

@[simp] abbrev FlatCom.denote [DialectDenote d]
    (flatCom : FlatCom d Γ eff Γ_out ts)
    (V : Γ.Valuation) : eff.toMonad d.m (HVector toType ts) :=
  flatCom.lets.denote V >>= (return flatCom.rets.map ·)

def RegionSignature.map (f : Ty → Ty') : RegionSignature Ty → RegionSignature Ty' :=
  List.map fun ⟨Γ, ty⟩ => (Γ.map f, ty.map f)

def Signature.map (f : Ty → Ty') : Signature Ty → Signature Ty' :=
  fun sig => {
    sig         := sig.sig.map f
    regSig      := sig.regSig.map f
    returnTypes := sig.returnTypes.map f
  }

def Expr.denote {ty} (e : Expr d Γ eff ty) (V : Valuation Γ) :
    eff.toMonad d.m (e.outContext.Valuation) :=
  match e with
  | ⟨op, ty_eq, heff, args, regArgs⟩ => do
      let argsDenote := args.map V
      let val ← EffectKind.liftEffect heff <| DialectDenote.denote op argsDenote regArgs.denote
      return (val ++ V).cast (by admit /- proof elided -/
      )

def Expr.op {Γ : Ctxt d.Ty} {eff : EffectKind} {ty} (e : Expr d Γ eff ty) : d.Op :=
  Expr.casesOn e (fun op _ _ _ _ => op)

def liftEffect [Pure m] {e1 e2 : EffectKind} {α : Type}
    (hle : e1 ≤ e2) (v1 : e1.toMonad m α) : e2.toMonad m α :=
  match e1, e2, hle with
    | .pure, .pure, _ | .impure, .impure, _ => v1
    | .pure, .impure, _ => Pure.pure v1

def toMonad (e : EffectKind) (m : Type → Type) : Type → Type :=
  match e with
  | pure => Id
  | impure => m

def Com.denote : Com d Γ eff ty → (Γv : Valuation Γ) →
    eff.toMonad d.m (HVector toType ty)
  | .rets vs, Γv     => pure (vs.map Γv)
  | .var e body, V => e.denote V >>= body.denote

def Com.ty : Com d Γ eff [t] → d.Ty := fun _ => t

def Valuation.cons {Γ : Ctxt Ty} {t : Ty} (x : toType t) (V : Γ.Valuation) :
    (Γ.cons t).Valuation :=

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

def cast (h₁ : Γ = Γ') (h₂ : Δ = Δ') : Diff Γ Δ → Diff Γ' Δ'
  | ⟨n, h⟩ => ⟨n, by admit /- proof elided -/
  ⟩

def Com.castPureToEff (eff : EffectKind) : Com d Γ .pure t → Com d Γ eff t :=
  changeEffect (EffectKind.pure_le eff)

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

def Expr.changeEffect {eff₁ eff₂ : EffectKind} (h : eff₁ ≤ eff₂) :
    Expr d Γ eff₁ t → Expr d Γ eff₂ t
  | Expr.mk op ty_eq eff_le args regArgs =>
    have heff : DialectSignature.effectKind op ≤ eff₂ := by admit /- proof elided -/

def Expr.args {Γ ts} (e : Expr d Γ eff ts) :
    HVector (Var Γ) (DialectSignature.sig e.op) :=
  Expr.casesOn e (fun _ _ _ args _ => args)

def Expr.regArgs {Γ ts} (e : Expr d Γ eff ts) :
    Regions d (DialectSignature.regSig e.op) :=
  Expr.casesOn e (fun _ _ _ _ regArgs => regArgs)

abbrev Regions (regSig : RegionSignature d.Ty) : Type :=
  HVector (fun t => Com d t.1 .impure t.2) regSig

def com := mkCom (d := InstCombine.MetaLLVM 0) bb0 |>.toOption |>.get (by admit /- proof elided -/
)

def bb0 : Region 0 := [mlir_region|
{
  ^bb0(%arg0: i32):
    %0 = llvm.mlir.constant(8) : i32
    %1 = llvm.mlir.constant(31) : i32
    %2 = llvm.ashr %arg0, %1 : i32
    %3 = llvm.and %2, %0 : i32
    %4 = llvm.add %3, %2 : i32
    llvm.return %4 : i32
  }]

structure Region where
  (name: String)
  (args: List <| TypedSSAVal φ)
  (ops: List Op)

abbrev MetaLLVM (φ : Nat) : Dialect where
  Op := MOp φ
  Ty := MTy φ

@[deprecated "Use `LLVM.Ty` instead" (since:="2025-04-30")] abbrev Ty := LLVM.Ty

@[deprecated "Use `LLVM.Op` instead" (since:="2025-04-30")] abbrev Op := LLVM.Op

inductive MOp (φ : Nat) : Type
  | unary   (w : Width φ) (op : MOp.UnaryOp φ) :  MOp φ
  | binary  (w : Width φ) (op : MOp.BinaryOp) :  MOp φ
  | select  (w : Width φ) : MOp φ
  | icmp    (c : IntPred) (w : Width φ) : MOp φ
   
  | const (w : Width φ) (val : ℤ) : MOp φ
deriving Repr, DecidableEq, Inhabited, Lean.ToExpr

@[match_pattern] abbrev binary (w : Nat) (op : MOp.BinaryOp) : LLVM.Op :=
  MOp.binary (.concrete w) op

inductive MOp.BinaryOp : Type
  | and
  | or   (disjoint : DisjointFlag := {disjoint := false} )
  | xor
  | shl  (nswnuw : NoWrapFlags := {nsw := false, nuw := false} )
  | lshr (exact : ExactFlag := {exact := false} )
  | ashr (exact : ExactFlag := {exact := false} )
  | urem
  | srem
  | add  (nswnuw : NoWrapFlags := {nsw := false, nuw := false} )
  | mul  (nswnuw : NoWrapFlags := {nsw := false, nuw := false} )
  | sub  (nswnuw : NoWrapFlags := {nsw := false, nuw := false} )
  | sdiv (exact : ExactFlag := {exact := false} )
  | udiv (exact : ExactFlag := {exact := false} )
deriving DecidableEq, Inhabited, Lean.ToExpr

def LLVM : Dialect where
  Op := MOp 0
  Ty := MTy 0

inductive MTy (φ : Nat)
  | bitvec (w : Width φ) : MTy φ
  deriving DecidableEq, Inhabited, Lean.ToExpr

abbrev Width φ := ConcreteOrMVar Nat φ

inductive ConcreteOrMVar (α : Type u) (φ : Nat)
  | concrete (a : α)
  | mvar (i : Fin φ)
  deriving DecidableEq, Repr, Inhabited, Lean.ToExpr

@[match_pattern] abbrev const (w : Nat) (val : ℤ) : LLVM.Op        := MOp.const (.concrete w) val

inductive MOp.UnaryOp (φ : Nat) : Type
  | neg
  | not
  | copy
  | freeze
  | trunc (w' : Width φ) (noWrapFlags : NoWrapFlags := {nsw := false, nuw := false} )
  | zext  (w' : Width φ) (nneg : NonNegFlag := {nneg := false} )
  | sext  (w' : Width φ)
deriving Repr, DecidableEq, Inhabited, Lean.ToExpr

@[simp_llvm_option]
def select {w : Nat} (c? : IntW 1) (x? y? : IntW w ) : IntW w := do
  let c ← c?
  if c = 1#1 then x? else y?

def IntW w := PoisonOr <| BitVec w

structure PoisonOr (α : Type) where
  val : α
  poisonous : Bool
deriving Inhabited, DecidableEq

@[simp_llvm_option]
def icmp {w : Nat} (c : IntPred) (x y : IntW w) : IntW 1 := do
  let x' ← x
  let y' ← y
  icmp? c x' y'

@[simp_llvm]
def icmp? {w : Nat} (c : IntPred) (x y : BitVec w) : IntW 1 :=
  .value ↑(icmp' c x y)

inductive IntPred where
  | eq
  | ne
  | ugt
  | uge
  | ult
  | ule
  | sgt
  | sge
  | slt
  | sle
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

@[simp_llvm]
def icmp' {w : Nat} (c : IntPred) (x y : BitVec w) : Bool :=
  match c with
    | .eq => (x == y)
    | .ne => (x != y)
    | .sgt => (x >ₛ y)
    | .sge => (x ≥ₛ y)
    | .slt => (x <ₛ y)
    | .sle => (x ≤ₛ y)
    | .ugt => (x >ᵤ y)
    | .uge => (x ≥ᵤ y)
    | .ult => (x <ᵤ y)
    | .ule => (x ≤ᵤ y)

def mkCom [TransformTy d φ] [TransformExpr d φ] [TransformReturn d φ]
  (reg : MLIR.AST.Region φ) :
  ExceptM d (Σ (Γ : Ctxt d.Ty) (eff : EffectKind) (ty : _), Com d Γ eff ty) :=
  match reg.ops with
  | [] => throw <| .generic "Ill-formed region (empty)"
  | coms => BuilderM.runWithEmptyMapping <| do
    let Γ ← declareBindings ∅ reg.args
    let com ← mkComHelper Γ coms
    return ⟨Γ, com⟩

def FlatCom.denoteLets (flatCom : FlatCom d Γ eff Γ_out t) (Γv : Γ.Valuation) :
    eff.toMonad d.m <| Γ_out.Valuation :=
  flatCom.lets.denote Γv

def Com.toLets (com : Com d Γ eff t) : Lets d Γ eff com.outContext :=
  Lets.nil.addComToEnd com

def Lets.castPureToEff (eff : EffectKind) : Lets d Γ_in .pure Γ_out → Lets d Γ_in eff Γ_out
  | .nil => .nil
  | .var body e => .var (body.castPureToEff eff) (e.castPureToEff eff)

def Expr.castPureToEff (eff : EffectKind) : Expr d Γ .pure t → Expr d Γ eff t :=
  changeEffect (EffectKind.pure_le eff)

def Expr.returnVars (e : Expr d Γ eff tys) : HVector e.outContext.Var tys :=
  .ofFn _ _ <| fun i => (Var.ofFin i).appendInl

def ofFin (i : Fin Γ.length) : Γ.Var (Γ[i]) :=
  ⟨i.val, by admit /- proof elided -/
  ⟩

def Com.returnVars : (com : Com d Γ eff ts) → HVector (Var com.outContext) ts
  | .rets vs => vs
  | .var _ body => body.returnVars

def Valuation.comap {Γi Γo : Ctxt Ty} (Γiv: Γi.Valuation) (hom : Ctxt.Hom Γo Γi) : Γo.Valuation :=
  fun _to vo => Γiv (hom vo)

def map (f : ∀ (a : α), A a → B a) :
    ∀ {l : List α}, HVector A l → HVector B l
  | [],   .nil        => .nil
  | t::_, .cons a as  => .cons (f t a) (map f as)

structure HVectorLiteral where
  u : Level
  v : Level
  α : Q(Type $u)
  A : Q($α → Type $v)
  elems : Array ((a : Q($α)) × Q($A $a))

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

def Lets.denoteIntoSubtype (lets : Lets d Γ_in eff Γ_out) (Γv : Valuation Γ_in) :
    eff.toMonad d.m lets.ValidDenotation :=
  match lets with
    | .nil => return ⟨Γv, by admit /- proof elided -/
    ⟩
    | @Lets.var _ _ _ _ Γ_out eTy body e => do
        let ⟨Vout, h⟩ ← body.denoteIntoSubtype Γv
        let Ve ← e.denoteOpIntoSubtype Vout
        return ⟨Ve.val ++ Vout, by admit /- proof elided -/
        ⟩

def Expr.denoteOpIntoSubtype (e : Expr d Γ_in eff tys) (Γv : Valuation Γ_in) :
    eff.toMonad d.m {x // e.IsDenotationForPureE Γv x} :=
  match h_pure : e.toPure? with
    | some ePure => pure ⟨ePure.denoteOp Γv, by admit /- proof elided -/
    ⟩
    | none => (Subtype.mk · (by admit /- proof elided -/
    )) <$> (e.denoteOp Γv)

abbrev Expr.IsDenotationForPureE (e : Expr d Γ eff tys) (Γv : Valuation Γ)
    (x : HVector toType tys) : Prop :=
  ∀ (ePure : Expr d Γ .pure tys), e.toPure? = some ePure → ePure.denoteOp Γv = x

@[elab_as_elim]
def appendCases
    {motive : (Γ ++ Δ).Var t → Sort u}
    (left : (v : Var Γ t) → motive (appendInl v))
    (right : (v : Var Δ t) → motive (appendInr v)) :
    (v : (Γ ++ Δ).Var t) → motive v
  | ⟨idx, h⟩ =>
    if hv : idx < Γ.length then
      left ⟨idx, by admit /- proof elided -/
      ⟩
    else
      let v' : Var _ _ := ⟨idx - Γ.length, by admit /- proof elided -/
      ⟩
      have eq : v'.appendInr = ⟨idx, h⟩ := by admit /- proof elided -/

def Expr.toPure? (e : Expr d Γ eff ty) : Option (Expr d Γ .pure ty) :=
  if h : e.HasPureOp then
    some <| e.toPure h
  else
    none

def Expr.toPure (e : Expr d Γ eff ty) (h : e.HasPureOp) : Expr d Γ .pure ty :=
  ⟨e.op, e.ty_eq, EffectKind.le_of_eq h, e.args, e.regArgs⟩

def Expr.ty : Expr d Γ eff [t] → d.Ty := fun _ => t

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

infixr:50 "::ₕ" => HVector.cons

notation "⟦" x "⟧" => TyDenote.toType x

infixr:67 "::ᵥ" => Valuation.cons

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

def HashSet.inter [BEq A] [Hashable A] (m1 m2 : Std.HashSet A) : Std.HashSet A :=
  m1.fold (init := ∅) fun mi x => if m2.contains x then mi.insert x else mi

def t1_flags_nuw_second_before := [llvm|
{
^0(%arg36 : i8, %arg37 : i8, %arg38 : i8):
  %0 = llvm.sub %arg36, %arg37 : i8
  %1 = llvm.sub %0, %arg38 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def test12_after := [llvm|
{
^0(%arg292 : i32, %arg293 : i32):
  %0 = llvm.icmp "ult" %arg292, %arg293 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def select_1_after := [llvm|
{
^0(%arg87 : i1, %arg88 : i8, %arg89 : i8, %arg90 : i1, %arg91 : i8, %arg92 : i8):
  %0 = llvm.mlir.constant(-46 : i8) : i8
  %1 = llvm.mlir.constant(-124 : i8) : i8
  %2 = llvm.xor %arg88, %arg89 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %arg92, %1 : i8
  %5 = "llvm.select"(%arg90, %arg91, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = "llvm.select"(%arg87, %3, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

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

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

def and_ranges_overlap_after := [llvm|
{
^0(%arg256 : i8):
  %0 = llvm.mlir.constant(-7 : i8) : i8
  %1 = llvm.mlir.constant(4 : i8) : i8
  %2 = llvm.add %arg256, %0 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

inductive MLIRType (φ : Nat) : Type _ where
  | int: Signedness -> Width φ -> MLIRType φ
  | float: Nat -> MLIRType φ
  | tensor1d: MLIRType φ 
  | tensor2d: MLIRType φ 
  | tensor4d: MLIRType φ 
  | index:  MLIRType φ
  | undefined: String → MLIRType φ
  deriving Repr, DecidableEq

def positive_samevar_shlnuw_lshrexact_before := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.lshr exact %arg32, %arg33 : i8
  %1 = llvm.shl %0, %arg33 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def fold_inverted_icmp_preds_reverse_before := [llvm|
{
^0(%arg93 : i32, %arg94 : i32, %arg95 : i32, %arg96 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "slt" %arg93, %arg94 : i32
  %2 = "llvm.select"(%1, %0, %arg95) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.icmp "sge" %arg93, %arg94 : i32
  %4 = "llvm.select"(%3, %0, %arg96) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def shl_nsw_add_negative_invalid_constant3_after := [llvm|
{
^0(%arg39 : i4):
  %0 = llvm.mlir.constant(-8 : i4) : i4
  %1 = llvm.mlir.constant(2 : i4) : i4
  %2 = llvm.xor %arg39, %0 : i4
  %3 = llvm.shl %1, %2 overflow<nsw> : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

def test43_after := [llvm|
{
^0(%arg145 : i8):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.zext %arg145 : i8 to i32
  %2 = llvm.add %1, %0 overflow<nsw> : i32
  %3 = llvm.sext %2 : i32 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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 test1_logical_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "eq" %arg6, %0 : i32
  %4 = llvm.xor %arg6, %arg7 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = "llvm.select"(%3, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

def ashrslt_01_04_after := [llvm|
{
^0(%arg265 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 toString : GenBVExpr w → String
  | .var idx => s!"var{idx}#{w}"
  | .const val => ToString.toString val
  | .extract start len expr => s!"{expr.toString}[{start}, {len}]"
  | .bin lhs op rhs => s!"({lhs.toString} {op.toString} {rhs.toString})"
  | .un op operand => s!"({op.toString} {toString operand})"
  | .append lhs rhs _ => s!"({toString lhs} ++ {toString rhs})"
  | .replicate n expr _ => s!"(replicate {n} {toString expr})"
  | .shiftLeft lhs rhs => s!"({lhs.toString} << {rhs.toString})"
  | .shiftRight lhs rhs => s!"({lhs.toString} >> {rhs.toString})"
  | .arithShiftRight lhs rhs => s!"({lhs.toString} >>a {rhs.toString})"
  | .signExtend v expr => s!"(signExtend {v} {toString expr}})"
  | .zeroExtend v expr => s!"(zeroExtend {v} {toString expr}})"
  | .truncate v expr => s!"(truncate {v} {toString expr}})"

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

@[simp] abbrev Com.pdenote :
    Com d Γ .pure ty → Γ.Valuation → (HVector toType ty) :=
  Com.denote

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 RawCNFA.transBV (m : RawCNFA A) (s : m.states) (a : A) : BitVec m.stateMax :=
  let ts := m.trans.getD (s, a) ∅
  BitVec.ofFn (fun n => n ∈ ts)

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

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

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

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

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 narrow_zext_xor_after := [llvm|
{
^0(%arg46 : i16, %arg47 : i32):
  %0 = llvm.trunc %arg47 : i32 to i16
  %1 = llvm.xor %arg46, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

Lean.Elab.Term.mkFreshBinderName in Lean.Elab.Term.TermElabM

def add_shl_sext_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32)] where
  lhs := add_shl_sext_llvm
  rhs := add_shl_sext_riscv

def neg_not_signbit2_after := [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 nneg %2 : i8 to i32
  %4 = llvm.sub %1, %3 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def 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 lshr_and_and_after := [llvm|
{
^0(%arg49 : i8, %arg50 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(52 : i8) : i8
  %3 = llvm.srem %arg49, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg50, %2 : i8
  %6 = llvm.and %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def add_negative_high_bound_accept_test: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_negative_high_bound_accept_llvm
  rhs := add_negative_high_bound_accept_riscv

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

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 test3_after := [llvm|
{
^0(%arg11 : i23):
  %0 = llvm.mlir.constant(0 : i23) : i23
  "llvm.return"(%0) : (i23) -> ()
}
]

def NFA'.autUnsignedCmpSA (q : NFA.unsignedCmpState) : BVRel :=
  match q with
  | .eq => fun _ bv1 bv2 => bv1 = bv2
  | .lt => fun _ bv1 bv2 => bv1.ult bv2
  | .gt => fun _ bv1 bv2 => bv2.ult bv1

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

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

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

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

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

def test6_before := [llvm|
{
^0(%arg103 : i64):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg103 : i64 to i128
  %2 = llvm.lshr %1, %0 : i128
  %3 = llvm.trunc %2 : i128 to 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) -> ()
}
]

structure MemoryState where
  mem : Std.HashMap BlockId Block
  deriving Inhabited

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

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

def mul_of_pow2s_before := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(128 : i32) : i32
  %3 = llvm.and %arg79, %0 : i32
  %4 = llvm.and %arg80, %1 : i32
  %5 = llvm.mul %3, %4 : i32
  %6 = llvm.or %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

BitVec.nil in Init.Data.BitVec.Basic

structure RISCVPeepholeRewrite (Γ : List Ty) where
  lhs : Com LLVMPlusRiscV Γ .pure [Ty.riscv .bv]
  rhs : Com LLVMPlusRiscV Γ .pure [Ty.riscv .bv]
  correct : lhs.denote = rhs.denote := by admit /- proof elided -/

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

instance {n} : ShiftRight (BitVec n) := ⟨fun x y => x >>> y.toNat⟩

@[simp]
def TermUnop.openTerm_arity' (op : TermUnop) : op.openTerm.arity + 1 = 2 :=

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

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

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

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

def t1_flags_nuw_nsw_second_before := [llvm|
{
^0(%arg30 : i8, %arg31 : i8, %arg32 : i8):
  %0 = llvm.sub %arg30, %arg31 : i8
  %1 = llvm.sub %0, %arg32 overflow<nsw,nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

instance {n} : ShiftLeft (BitVec n) := ⟨fun x y => x <<< y.toNat⟩

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 test69_after := [llvm|
{
^0(%arg158 : i32, %arg159 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.lshr %arg158, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %arg159, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

def test13commuted_before := [llvm|
{
^0(%arg83 : i32, %arg84 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg83, %0 : i32
  %2 = llvm.xor %arg84, %0 : i32
  %3 = llvm.and %2, %arg83 : i32
  %4 = llvm.xor %1, %3 : i32
  "llvm.return"(%4) : (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) -> ()
}
]

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

instance :
      HydrableSolve ParsedFpExpr FpPredicate FpExpr where

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

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

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

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

def rewritePeephole_go (fuel : ℕ) (pr : PeepholeRewrite d Γ t)
    (ix : ℕ) (target : Com d Γ₂ eff t₂) : (Com d Γ₂ eff t₂) :=
  match fuel with
  | 0 => target
  | fuel' + 1 =>
     let target' := rewritePeepholeAt pr ix target
     rewritePeephole_go fuel' pr (ix + 1) target'

def scalar_i8_shl_ult_const_2_before := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(64 : i8) : i8
  %2 = llvm.shl %arg18, %0 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def and_orn_xor_after := [llvm|
{
^0(%arg80 : i4, %arg81 : i4):
  %0 = llvm.mlir.constant(-1 : i4) : i4
  %1 = llvm.xor %arg80, %0 : i4
  %2 = llvm.and %arg81, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

def neg_mask_after := [llvm|
{
^0(%arg1 : i32, %arg2 : i16):
  %0 = llvm.mlir.constant(0 : 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.icmp "slt" %arg2, %0 : i16
  %5 = "llvm.select"(%4, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

def 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 demorgan_and_apint2_before := [llvm|
{
^0(%arg56 : i129, %arg57 : i129):
  %0 = llvm.mlir.constant(-1 : i129) : i129
  %1 = llvm.xor %arg56, %0 : i129
  %2 = llvm.xor %arg57, %0 : i129
  %3 = llvm.and %1, %2 : i129
  "llvm.return"(%3) : (i129) -> ()
}
]

def test_const_shr_exact_and_1_ne_0_after := [llvm|
{
^0(%arg6 : 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, %arg6 overflow<nuw> : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "ne" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def zext_sext_add_icmp_sgt_1_before := [llvm|
{
^0(%arg92 : i1, %arg93 : i1):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.zext %arg92 : i1 to i8
  %2 = llvm.sext %arg93 : i1 to i8
  %3 = llvm.add %1, %2 : i8
  %4 = llvm.icmp "sgt" %3, %0 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def lshr_16_to_64_add_zext_basic_before := [llvm|
{
^0(%arg17 : i16, %arg18 : i16):
  %0 = llvm.mlir.constant(16) : i64
  %1 = llvm.zext %arg17 : i16 to i64
  %2 = llvm.zext %arg18 : i16 to i64
  %3 = llvm.add %1, %2 : i64
  %4 = llvm.lshr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def test16_after := [llvm|
{
^0(%arg38 : i32, %arg39 : i32):
  %0 = llvm.mlir.constant(1431655766 : i32) : i32
  %1 = llvm.or %arg38, %0 : i32
  %2 = llvm.sub %arg39, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def test2_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i8):
  %0 = llvm.mlir.constant(65536 : i32) : i32
  %1 = llvm.and %arg8, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def lshr_shl_demand3_after := [llvm|
{
^0(%arg7 : i8):
  %0 = llvm.mlir.constant(28 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.lshr %0, %arg7 : i8
  %3 = llvm.shl %2, %1 overflow<nuw> : i8
  %4 = llvm.or disjoint %3, %1 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def shl_and_and_fail_after := [llvm|
{
^0(%arg170 : i8, %arg171 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.mlir.constant(64 : i8) : i8
  %3 = llvm.shl %arg170, %0 : i8
  %4 = llvm.shl %arg171, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.and %3, %5 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

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

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

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

def test25_before := [llvm|
{
^0(%arg271 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.icmp "sge" %arg271, %0 : i32
  %3 = llvm.icmp "slt" %arg271, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def sext? {w: Nat} (w': Nat) (x: BitVec w) : IntW w' := do
  .value <| (BitVec.signExtend w' x)

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

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

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

@[simp_riscv]
def zextb_pseudo (rs1_val : BitVec 64) : BitVec 64 :=
  RV64.andi 255 rs1_val

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

Sigma.mk in Init.Core

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

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

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

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

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 test12_before := [llvm|
{
^0(%arg61 : i32, %arg62 : i32):
  %0 = llvm.mlir.constant(31 : i128) : i128
  %1 = llvm.zext %arg61 : i32 to i128
  %2 = llvm.zext %arg62 : i32 to i128
  %3 = llvm.and %2, %0 : i128
  %4 = llvm.lshr %1, %3 : i128
  %5 = llvm.trunc %4 : i128 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

RV64.slliuw in RISCV.Instructions

def test_sext1_after := [llvm|
{
^0(%arg49 : i1, %arg50 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg50, %arg49, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.sext %1 : i1 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg34 : i32, %arg35 : i32):
  %0 = llvm.icmp "ugt" %arg35, %arg34 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

def isSuccess : DecideIfZerosOutput → Bool
  | .safetyFailure _ => false
  | .exhaustedIterations _ => false
  | .provenByKIndCycleBreaking .. => true

def bools2_logical_commute0_and1_and2_after := [llvm|
{
^0(%arg55 : i1, %arg56 : i1, %arg57 : i1):
  %0 = "llvm.select"(%arg57, %arg55, %arg56) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def t0_commutative_after := [llvm|
{
^0(%arg36 : i1, %arg37 : i8, %arg38 : i8, %arg39 : i8, %arg40 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "ne" %arg37, %arg38 : i8
  %2 = "llvm.select"(%1, %0, %arg36) <{"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) -> ()
}
]

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

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

def fold_inverted_icmp_preds_before := [llvm|
{
^0(%arg97 : i32, %arg98 : i32, %arg99 : i32, %arg100 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "slt" %arg97, %arg98 : i32
  %2 = "llvm.select"(%1, %arg99, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.icmp "sge" %arg97, %arg98 : i32
  %4 = "llvm.select"(%3, %arg100, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.or %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

private def variable_order2 : Com LLVM ⟨[bitvec 2, bitvec 1]⟩ .pure [bitvec 2] := [llvm()| {
    ^bb0(%arg1: i1, %arg2 : i2):
      "llvm.return"(%arg2) : (i2) -> ()
  }]

def fake_sext_before := [llvm|
{
^0(%arg166 : i3):
  %0 = llvm.mlir.constant(17 : i18) : i18
  %1 = llvm.sext %arg166 : i3 to i18
  %2 = llvm.lshr %1, %0 : i18
  "llvm.return"(%2) : (i18) -> ()
}
]

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

def t3_ult_sgt_neg1_before := [llvm|
{
^0(%arg69 : i32, %arg70 : i32, %arg71 : i32):
  %0 = llvm.mlir.constant(-17 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(144 : i32) : i32
  %3 = llvm.icmp "sgt" %arg69, %0 : i32
  %4 = "llvm.select"(%3, %arg71, %arg70) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = llvm.add %arg69, %1 : i32
  %6 = llvm.icmp "ult" %5, %2 : i32
  %7 = "llvm.select"(%6, %arg69, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def test3_before := [llvm|
{
^0(%arg0 : i59, %arg1 : i1):
  %0 = llvm.mlir.constant(70368744177664 : i59) : i59
  %1 = llvm.mlir.constant(4096 : i59) : i59
  %2 = "llvm.select"(%arg1, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i59, i59) -> i59
  %3 = llvm.urem %arg0, %2 : i59
  "llvm.return"(%3) : (i59) -> ()
}
]

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

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

def test1_after := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(8 : i8) : i8
  %1 = llvm.and %arg0, %0 : i8
  %2 = llvm.zext nneg %1 : i8 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def sub_to_xor_or_commuted_before := [llvm|
{
^0(%arg7 : i32, %arg8 : i32):
  %0 = llvm.or %arg8, %arg7 : i32
  %1 = llvm.and %arg7, %arg8 : i32
  %2 = llvm.sub %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

Fin.castLT in Init.Data.Fin.Basic

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

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

def Region.WellTyped : UnTyped.Region Op VarName → RegionType Ty → Prop
  | ⟨entry, _⟩ => BasicBlock.WellTyped entry

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

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

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

private noncomputable def R.representative' :
    R q n → (ZMod q)[X] := Function.surjInv (R.surjective_fromPoly q n)

def uge_or_max_commute_after := [llvm|
{
^0(%arg170 : i8, %arg171 : i8):
  %0 = llvm.icmp "uge" %arg170, %arg171 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

@[match_pattern] abbrev ExpTy.bits w := isl (.bits w)

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

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

instance : CoeOut (Var (Γ.dropUntil v) ty) (Var Γ ty) where
  coe v := dropUntilDiff.toHom v

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

def icmp_shl_ne_2_before := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.sdiv %0, %arg4 : i8
  %3 = llvm.shl %2, %1 : i8
  %4 = llvm.icmp "ne" %2, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

Std.HashSet in Std.Data.HashSet.Basic

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

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

noncomputable def TV_sub_sub_lhs_rhs_lhs : PeepholeRewrite (ModArith q) [.modLike, .modLike] .modLike :=
{
  lhs := test_sub_sub_lhs_rhs_lhs_LHS,
  rhs := test_sub_sub_lhs_rhs_lhs_RHS,
  correct := by admit /- proof elided -/

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

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

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

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

def udiv_eq_umax_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.udiv %arg42, %arg43 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

Lean.initSearchPath in Lean.Util.Path

def ashrslt_03_11_exact_after := [llvm|
{
^0(%arg10 : i4):
  %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 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 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) -> ()
}
]

instance (p : Predicate) :
    Decidable (∀ (n : ℕ) (x : Fin p.arity → BitStream) , p.evalFin x n = false) :=
  decidable_of_iff
    (decideIfZeros (predicateEvalEqFSM p).toFSM) $ by
  rw [decideIfZeros_correct]
  simp only [FSM.eval_simplify]
  rw [← (predicateEvalEqFSM p).good]

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

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

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

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

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

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

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

HMul in Init.Prelude

def beqBoolInstExpr : Expr := mkApp2 (.const ``instBEqOfDecidableEq [levelZero]) (mkConst ``Bool) (mkConst ``instDecidableEqBool)

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

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

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

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

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

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

def foo1_and_commuted_before := [llvm|
{
^0(%arg172 : i32, %arg173 : i32, %arg174 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mul %arg172, %arg172 : i32
  %3 = llvm.shl %0, %arg173 : i32
  %4 = llvm.shl %0, %arg174 : i32
  %5 = llvm.and %2, %3 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %4, %2 : i32
  %8 = llvm.icmp "eq" %7, %1 : i32
  %9 = llvm.or %6, %8 : i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def icmp_ugt_32_before := [llvm|
{
^0(%arg18 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.mlir.constant(4294967295) : i64
  %2 = llvm.shl %arg18, %0 overflow<nuw> : i64
  %3 = llvm.icmp "ugt" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def ashrslt_02_09_exact_before := [llvm|
{
^0(%arg28 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.ashr exact %arg28, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "llvm.return"(%3) : (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 test_with_1_before := [llvm|
{
^0(%arg317 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg317 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

Inhabited in Init.Prelude

noncomputable def dropLeadingNones (x : Stream α) (not_stuck : x ≠ stuck α) : Stream α:=
  x.drop (nonesUntilSome x not_stuck)

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

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

Prod.snd in Init.Prelude

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

def substNatEqualities (g : MVarId) : MetaM (Option MVarId) := g.withContext do
  let gs ← g.casesRec fun localDecl => do
    let some (ty, _lhs, _rhs) := localDecl.type.eq?
      | return false
    return ty == mkConst ``Nat
  ensureAtMostOne gs

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

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

def sub_ashr_or_i32_before := [llvm|
{
^0(%arg35 : i32, %arg36 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.sub %arg36, %arg35 overflow<nsw> : i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.or %2, %arg35 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def icmp_slt_riscv_eq_icmp_slt_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_slt_llvm_32, rhs:= icmp_slt_riscv_32}

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

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

def testi16i8_com_after := [llvm|
{
^0(%arg11 : i16):
  %0 = llvm.mlir.constant(128 : i16) : i16
  %1 = llvm.mlir.constant(256 : i16) : i16
  %2 = llvm.add %arg11, %0 : i16
  %3 = llvm.icmp "ult" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

def test_zext4_after := [llvm|
{
^0(%arg35 : i1, %arg36 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg36, %0 : i1
  %2 = "llvm.select"(%1, %0, %arg35) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def test1_trunc_after := [llvm|
{
^0(%arg53 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.mlir.constant(65280 : i32) : i32
  %3 = llvm.lshr %arg53, %0 : i32
  %4 = llvm.lshr %arg53, %1 : i32
  %5 = llvm.and %4, %2 : i32
  %6 = llvm.or disjoint %3, %5 : i32
  %7 = llvm.trunc %6 overflow<nuw> : i32 to i16
  "llvm.return"(%7) : (i16) -> ()
}
]

def test44_after := [llvm|
{
^0(%arg144 : i8):
  %0 = llvm.mlir.constant(1234 : i16) : i16
  %1 = llvm.zext %arg144 : i8 to i16
  %2 = llvm.or %1, %0 : i16
  %3 = llvm.zext nneg %2 : i16 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def Deleted.deleteAppend (Γ : Ctxt Ty) (αs : List Ty) :
    Deleted (⟨αs⟩ ++ Γ) (DeleteRange.full ⟨αs⟩).appendInr Γ :=

def t8_twoshifts3_after := [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 overflow<nuw> : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

@[simp_denote]
def shl_llvm_nsw_8 := [LV| {
  ^entry (%x: i8, %y: i8):
    %1 = llvm.shl %x, %y overflow<nsw> : i8
    llvm.return %1 : i8
  }]

def mul_after := [llvm|
{
^0(%arg17 : i32, %arg18 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mul %arg17, %arg18 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

RV64.rol in RISCV.Instructions

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

instance : Sub Term := ⟨sub⟩

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

def shl_mask_wrong_shl_const_after := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.and %arg5, %0 : i32
  %3 = llvm.shl %2, %1 overflow<nsw,nuw> : i32
  %4 = llvm.or %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

def t0_before := [llvm|
{
^0(%arg42 : i32, %arg43 : i32, %arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg42, %arg43 : i32
  %2 = llvm.icmp "eq" %arg44, %arg45 : i32
  %3 = llvm.or %2, %1 : i1
  %4 = llvm.xor %3, %0 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def uge_zext_before := [llvm|
{
^0(%arg170 : i1, %arg171 : i8):
  %0 = llvm.zext %arg170 : i1 to i8
  %1 = llvm.icmp "uge" %0, %arg171 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def LLVMIR_identity_combines_32 : List (Σ Γ, LLVMPeepholeRewriteRefine 32 Γ) := anyext_trunc_fold

def Expr.mk {Γ} {ty}
    (varName : VarName)
    (op : Op) (ty_eq : ty = (signature op).returnType)
    (args : VarList Γ (signature op).arguments)
    (regions : RegionList Op (signature op).regions) :
    Expr Op Γ ty :=
  ⟨⟨varName, op, args.val, regions.val⟩, by admit /- proof elided -/
  ⟩

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

def t0_before := [llvm|
{
^0(%arg41 : i1, %arg42 : i8, %arg43 : i8, %arg44 : i8, %arg45 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "eq" %arg42, %arg43 : i8
  %3 = llvm.xor %arg41, %0 : i1
  %4 = "llvm.select"(%3, %2, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = "llvm.select"(%4, %arg44, %arg45) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def icmp_select_var_commuted_after := [llvm|
{
^0(%arg86 : i8, %arg87 : i8, %arg88 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.udiv %0, %arg88 : i8
  %4 = llvm.icmp "eq" %arg86, %1 : i8
  %5 = llvm.icmp "eq" %arg87, %3 : i8
  %6 = "llvm.select"(%4, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

@[simp_denote]
def add64_accept_riscv := [LV| {
  ^entry (%arg: i64):
  %0 = "builtin.unrealized_conversion_cast" (%arg) : (i64) -> (!i64)
  %1 = addi %0, 2047 : !i64
  %2 = addi %1, 952 : !i64
  %3 =  "builtin.unrealized_conversion_cast" (%2) : (!i64) -> (i64)
  llvm.return %3 : i64
}]

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

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

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

@[simp] def Predicate.arity : Predicate → Nat
| .width _ _ => 0
| .binary .eq t1 t2 => max t1.arity t2.arity
| .binary .neq t₁ t₂ => max t₁.arity t₂.arity
| .binary .ult t₁ t₂ => max t₁.arity t₂.arity
| .binary .ule t₁ t₂ => t₁.arity ⊔ t₂.arity ⊔ (t₁.arity ⊔ t₂.arity)
| .binary .slt t₁ t₂ => (t₁.arity ⊔ t₂.arity ⊔ (t₁.arity ⊔ t₂.arity))
| .binary .sle t₁ t₂ => (t₁.arity ⊔ t₂.arity ⊔ (t₁.arity ⊔ t₂.arity) ⊔ (t₁.arity ⊔ t₂.arity))
| .lor p q => max p.arity q.arity
| .land p q => max p.arity q.arity

def test5_before := [llvm|
{
^0(%arg95 : i32, %arg96 : i8):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.zext %arg96 : i8 to i32
  %2 = llvm.shl %0, %1 : i32
  %3 = llvm.urem %arg95, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def t0_sub_of_trueval_before := [llvm|
{
^0(%arg13 : i1, %arg14 : i8, %arg15 : i8):
  %0 = "llvm.select"(%arg13, %arg14, %arg15) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %1 = llvm.sub %0, %arg14 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

def rawspeed_signbit_before := [llvm|
{
^0(%arg0 : i64, %arg1 : i32):
  %0 = llvm.mlir.constant(64 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.sub %0, %arg1 overflow<nsw> : i32
  %5 = llvm.zext %4 : i32 to i64
  %6 = llvm.lshr %arg0, %5 : i64
  %7 = llvm.trunc %6 : i64 to i32
  %8 = llvm.add %arg1, %1 overflow<nsw> : i32
  %9 = llvm.shl %2, %8 : i32
  %10 = llvm.and %9, %7 : i32
  %11 = llvm.icmp "eq" %10, %3 : i32
  "llvm.return"(%11) : (i1) -> ()
}
]

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

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

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

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

structure HWidthEnv {wcard tcard : Nat}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (wenv : Fin wcard → Nat) : Prop where
    heq_width : ∀ (v : Fin wcard),
      fsmEnv (StateSpace.widthVar v) = BitStream.ofNatUnary (wenv v)

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

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

def multiRewritePeephole (fuel : ℕ)
    (prs : List (Σ Γ, Σ ty, PeepholeRewrite d Γ ty)) (target : Com d Γ₂ eff t₂) : (Com d Γ₂ eff t₂) :=
  multiRewritePeepholeAt fuel prs 0 target

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

def shl_trunc_smaller_ashr_before := [llvm|
{
^0(%arg41 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(13 : i24) : i24
  %2 = llvm.ashr %arg41, %0 : i32
  %3 = llvm.trunc %2 : i32 to i24
  %4 = llvm.shl %3, %1 : i24
  "llvm.return"(%4) : (i24) -> ()
}
]

def xor_to_xor4_before := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.or %arg79, %arg80 : i32
  %1 = llvm.and %arg80, %arg79 : i32
  %2 = llvm.xor %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def finRange (n : Nat) : LengthIndexedList (Fin n) n :=
  match n with
    | 0 => LengthIndexedList.nil
    | m + 1 =>
      let coeFun : Fin m → Fin (m + 1) := Fin.coeLt (Nat.le_succ m)
    LengthIndexedList.cons ⟨m, Nat.lt_succ_self m⟩
      (LengthIndexedList.map coeFun (LengthIndexedList.finRange m))

instance {Γ} : GetElem (HVector A as) (Var Γ a) (A a) (fun _ _ => as = Γ.toList) where
  getElem xs i h := (cast · <| xs.get <| i.toFin.cast <| by admit /- proof elided -/
  ) <| by
    subst h
    congr 1
    rcases i with ⟨i, h⟩
    simpa [Ctxt.Var.toFin, List.getElem_eq_iff] using h

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

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

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

Matrix in Mathlib.LinearAlgebra.Matrix.Defs

def ofList (vals : List (Option α)) : Stream α :=
  fun i => (vals[i]?).join

def mul128_low_after := [llvm|
{
^0(%arg18 : i128, %arg19 : i128):
  %0 = llvm.mul %arg18, %arg19 : i128
  "llvm.return"(%0) : (i128) -> ()
}
]

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

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

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

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

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

def mul64_low_after := [llvm|
{
^0(%arg20 : i64, %arg21 : i64):
  %0 = llvm.mul %arg20, %arg21 : i64
  "llvm.return"(%0) : (i64) -> ()
}
]

private def mkAxiomLikeMessage (kind : String) (id : Name) (levelParams : List Name) (type : Expr) (safety : DefinitionSafety) : MetaM MessageData := do
  mkHeader kind id levelParams type safety

def ashrslt_01_09_exact_after := [llvm|
{
^0(%arg44 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 signed_sign_bit_extract_trunc_before := [llvm|
{
^0(%arg1 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.ashr %arg1, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

def canonicalize_logic_first_and0_nswnuw_after := [llvm|
{
^0(%arg26 : i8):
  %0 = llvm.mlir.constant(-10 : i8) : i8
  %1 = llvm.mlir.constant(48 : i8) : i8
  %2 = llvm.and %arg26, %0 : i8
  %3 = llvm.add %2, %1 overflow<nsw,nuw> : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def alive_AddSub_1295_src :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.and %a, %b : i64
  %v2 = llvm.xor %a, %b : i64
  %v3 = llvm.add %v1, %v2 : i64
  llvm.return %v3 : i64
}]

def demorgan_nand_apint2_after := [llvm|
{
^0(%arg34 : i117, %arg35 : i117):
  %0 = llvm.mlir.constant(-1 : i117) : i117
  %1 = llvm.xor %arg35, %0 : i117
  %2 = llvm.or %arg34, %1 : i117
  "llvm.return"(%2) : (i117) -> ()
}
]

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

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

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

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

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

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

def and_xor_or7_after := [llvm|
{
^0(%arg655 : i64, %arg656 : i64, %arg657 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg656 : i64
  %2 = llvm.udiv %0, %arg657 : i64
  %3 = llvm.or %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def icmp_ule_riscv_eq_icmp_ule_llvm_64 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs:= icmp_ule_llvm_64, rhs:= icmp_ule_riscv_64}

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

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 cadicalTimeoutSec : Nat := 1000

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

def shl_mask_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg6, %0 : i32
  %3 = llvm.shl %2, %1 overflow<nsw,nuw> : i32
  %4 = llvm.or disjoint %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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 test_before := [llvm|
{
^0(%arg0 : i31):
  %0 = llvm.mlir.constant(16384 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.sext %arg0 : i31 to i32
  %3 = llvm.add %2, %0 : i32
  %4 = llvm.lshr %3, %1 : i32
  %5 = llvm.trunc %4 : i32 to i16
  "llvm.return"(%5) : (i16) -> ()
}
]

Dvd in Init.Prelude

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

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

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

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

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

def bVal : DCOp.ValueStream (BitVec 32) := ofList [none, some 1#32, none, some 2#32, some 5#32]

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

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

instance :  OrOp BitStream := ⟨map₂ Bool.or⟩

def test6_before := [llvm|
{
^0(%arg3 : i16):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.zext %arg3 : i16 to i32
  %2 = llvm.shl %1, %0 : i32
  %3 = llvm.ashr %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def llvm_const_lower_riscv_li39 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM39, rhs:= liRiscv39,
   correct := by admit /- proof elided -/

def do_not_add_annotation_to_existing_instr_after := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.add %arg15, %arg16 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

@[simp_denote]
def icmp_neq_riscv_64 := [LV| {
  ^entry (%lhs: i64, %rhs: i64):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i64) -> (!i64)
    %rhsr = "builtin.unrealized_conversion_cast"(%rhs) : (i64) -> (!i64)
    %0 = xor    %lhsr, %rhsr : !i64
    %c0 = li (0) : !i64
    %1 = sltu %c0, %0 : !i64
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i1)
    llvm.return %2 : i1
  }]

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 alive_Select_1105_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%Y : _, %X : _):
  %v1 = llvm.mlir.constant 0 :  i1
  %v2 = llvm.select %v1,%X, %Y
  llvm.return %v2
}]

def zext_eq_sext_before := [llvm|
{
^0(%arg4 : i1, %arg5 : i1):
  %0 = llvm.zext %arg4 : i1 to i32
  %1 = llvm.sext %arg5 : i1 to i32
  %2 = llvm.icmp "eq" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

def EnvFin.getNonLsbs {w : Nat} (env : EnvFin (w + 1) n) : EnvFin w n := fun n => (env n).extractLsb' 1 w

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

instance : Monad SLLVM.m :=

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

HMod in Init.Prelude

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

def 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 xor_sext_sext_before := [llvm|
{
^0(%arg48 : i8, %arg49 : i4):
  %0 = llvm.sext %arg48 : i8 to i16
  %1 = llvm.sext %arg49 : i4 to i16
  %2 = llvm.xor %0, %1 : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

def supp (c : ValueStream (BitVec 1)) (x : TokenStream) : TokenStream := (branch c x).snd

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

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

@[simp_denote]
def sext_riscv_i8_to_64 := [LV| {
  ^entry (%arg: i8):
    %0 = "builtin.unrealized_conversion_cast"(%arg) : (i8) -> (!i64)
    %1 = sext.b %0 : !i64
    %res = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i64)
    llvm.return %res : i64
  }]

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

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

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

def and_not_or_or_not_or_xor_commute3_after := [llvm|
{
^0(%arg316 : i32, %arg317 : i32, %arg318 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg317, %arg318 : i32
  %2 = llvm.xor %arg318, %arg317 : i32
  %3 = llvm.or %2, %arg316 : i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.xor %4, %0 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

@[match_pattern] def copy   (w : Width φ) : MOp φ := .unary w .copy

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

def test9_before := [llvm|
{
^0(%arg14 : i42):
  %0 = llvm.mlir.constant(3 : i42) : i42
  %1 = llvm.mul %0, %arg14 : i42
  %2 = llvm.sub %arg14, %1 : i42
  "llvm.return"(%2) : (i42) -> ()
}
]

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

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

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

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

def test2_before := [llvm|
{
^0(%arg2 : i499):
  %0 = llvm.mlir.constant(4096 : i499) : i499
  %1 = llvm.mlir.constant(111 : i499) : i499
  %2 = llvm.shl %0, %1 : i499
  %3 = llvm.urem %arg2, %2 : i499
  "llvm.return"(%3) : (i499) -> ()
}
]

noncomputable def TV_mul_mul_const : PeepholeRewrite (ModArith q) [.modLike] .modLike :=
{
  lhs := test_mul_mul_const_LHS,
  rhs := test_mul_mul_const_RHS,
  correct := by admit /- proof elided -/

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

def sel_false_val_is_a_masked_ashr_of_true_val2_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(-536870897 : i32) : i32
  %2 = llvm.ashr %arg0, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg1, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def select_icmp_ne_pow2_flipped_after := [llvm|
{
^0(%arg9 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.or %arg9, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def ugt_rem_zero_before := [llvm|
{
^0(%arg167 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(21 : i8) : i8
  %2 = llvm.mul %arg167, %0 overflow<nuw> : i8
  %3 = llvm.icmp "ugt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def lshr_lshr_pow2_const_negative_overflow_before := [llvm|
{
^0(%arg61 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.mlir.constant(4 : i16) : i16
  %3 = llvm.lshr %0, %arg61 : i16
  %4 = llvm.lshr %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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

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

def multiRewritePeepholeAt (fuel : ℕ) (prs : List (Σ Γ, Σ ty, PeepholeRewrite d Γ ty))
    (ix : ℕ) (target : Com d Γ₂ eff t₂) : Com d Γ₂ eff t₂ :=
  match fuel with
  | 0 => target
  | fuel' + 1 =>
    let target' := prs.foldl (fun acc ⟨_Γ, _ty, pr⟩ => rewritePeepholeAt pr ix acc) target
    multiRewritePeepholeAt fuel' prs (ix + 1) target'

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

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

def or_and_not_not_commute5_after := [llvm|
{
^0(%arg410 : i32, %arg411 : i32, %arg412 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg412, %arg411 : i32
  %2 = llvm.or %1, %arg410 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def ult_rem_nz_before := [llvm|
{
^0(%arg172 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(21 : i8) : i8
  %2 = llvm.mul %arg172, %0 overflow<nuw> : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def emptyElim {α : Sort _} {t : Ty} : Ctxt.Var ∅ t → α :=
  fun ⟨_, h⟩ => by admit /- proof elided -/

def ripple_nsw5_before := [llvm|
{
^0(%arg15 : i16, %arg16 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(-10923 : i16) : i16
  %2 = llvm.or %arg16, %0 : i16
  %3 = llvm.or %arg15, %1 : i16
  %4 = llvm.add %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

def packSelect := [DC_com| {
  ^entry(%0: !ValueStream_Int, %1: !ValueStream_Int, %2: !ValueStream_Int, %3: !ValueStream_Bool):
    %unpack0 = "DC.unpack" (%0) : (!ValueStream_Int) -> (!ValueTokenStream_Int)
    %unpack1 = "DC.unpack" (%1) : (!ValueStream_Int) -> (!ValueTokenStream_Int)
    %unpack2 = "DC.unpack" (%2) : (!ValueStream_Int) -> (!ValueTokenStream_Int)
    %unpack01 = "DC.fstVal" (%unpack0) : (!ValueTokenStream_Int) -> (!ValueStream_Int)
    %unpack02 = "DC.sndVal" (%unpack0) : (!ValueTokenStream_Int) -> (!TokenStream)
    %unpack11 = "DC.fstVal" (%unpack1) : (!ValueTokenStream_Int) -> (!ValueStream_Int)
    %unpack12 = "DC.sndVal" (%unpack1) : (!ValueTokenStream_Int) -> (!TokenStream)
    %unpack21 = "DC.fstVal" (%unpack2) : (!ValueTokenStream_Int) -> (!ValueStream_Int)
    %unpack22 = "DC.sndVal" (%unpack2) : (!ValueTokenStream_Int) -> (!TokenStream)
    
    
    
    %pack1 = "DC.pack" (%3, %unpack02) : (!ValueStream_Bool, !TokenStream) -> (!ValueStream_Bool)
    %select = "DC.select" (%unpack22, %unpack12, %pack1) : (!TokenStream, !TokenStream, !ValueStream_Bool) -> (!TokenStream)
    %pack2 = "DC.pack" (%unpack21, %select) : (!ValueStream_Int, !TokenStream) -> (!ValueStream_Int)
    "return" (%pack2) : (!ValueStream_Int) -> ()
  }]

Lean.Meta.Simp.Step in Lean.Meta.Tactic.Simp.Types

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

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

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

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

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

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

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

inductive BinaryPredicate
| eq
| neq
| ult
| ule
| slt
| sle
deriving Repr, Lean.ToExpr

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

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

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

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

def n7_wrong_pred2_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.sub %arg10, %arg11 : i8
  %1 = llvm.icmp "eq" %0, %arg10 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

def n3_constmask_samemask_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(65280 : i32) : i32
  %1 = llvm.and %arg0, %0 : i32
  %2 = llvm.and %arg1, %0 : i32
  %3 = llvm.add %1, %2 overflow<nsw,nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def 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 two_inst_concrete_stmt (e : LLVM.IntW w) :
    (LLVM.not e) ⊑ (LLVM.not e) :=

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

def src_fv_eq_after := [llvm|
{
^0(%arg32 : i1, %arg33 : i8, %arg34 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.xor %arg32, %0 : i1
  %3 = llvm.icmp "eq" %arg33, %1 : i8
  %4 = llvm.and %3, %2 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def and_not_or_wrong_c_before := [llvm|
{
^0(%arg432 : i32, %arg433 : i32, %arg434 : i32, %arg435 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg432, %arg433 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %2, %arg434 : i32
  %4 = llvm.and %arg432, %arg435 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.or %5, %arg433 : i32
  %7 = llvm.and %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def test8_before := [llvm|
{
^0(%arg15 : i27):
  %0 = llvm.mlir.constant(9 : i27) : i27
  %1 = llvm.mul %0, %arg15 : i27
  %2 = llvm.sub %1, %arg15 : i27
  "llvm.return"(%2) : (i27) -> ()
}
]

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

def t7_twoshifts2_before := [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 : 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 ashr_ashr_after := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.ashr %arg7, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

instance : ToString Ty where
  toString t := repr t |>.pretty

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

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

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

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

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

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

def const_sub_add_const_after := [llvm|
{
^0(%arg30 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.sub %0, %arg30 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

RV64.sllw in RISCV.Instructions

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

def sgt_and_min_logical_before := [llvm|
{
^0(%arg350 : i9, %arg351 : i9):
  %0 = llvm.mlir.constant(-256 : i9) : i9
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg350, %arg351 : i9
  %3 = llvm.icmp "eq" %arg350, %0 : i9
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def select_icmp_ne_0_and_32_or_4096_after := [llvm|
{
^0(%arg203 : i32, %arg204 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(4096 : i32) : i32
  %2 = llvm.shl %arg203, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.or %arg204, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def Op.appendRegion {φ} (o : Op φ) (r : Region φ) : Op φ :=
  match o with
  | Op.mk name res args regions attrs =>
      Op.mk name res args (regions ++ [r]) attrs

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

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

@[simp_denote]
def add_b32_riscv_i64_ZBS :=
  [LV| {
    ^entry (%x: i64):
    %zero ="li"() {imm = 0 : !i64} : (!i64) -> (!i64)
    %a1 = bseti %zero, 32 : !i64
    %a0 = "builtin.unrealized_conversion_cast" (%x) : (i64) -> (!i64)
    %0 = sub %a0, %a1 : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def logical_and_logical_and_icmps_comm1_before := [llvm|
{
^0(%arg205 : i8, %arg206 : i8, %arg207 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.icmp "eq" %arg206, %0 : i8
  %5 = llvm.and %arg205, %1 : i8
  %6 = llvm.shl %1, %arg207 : i8
  %7 = llvm.and %arg205, %6 : i8
  %8 = llvm.icmp "ne" %5, %2 : i8
  %9 = llvm.icmp "ne" %7, %2 : i8
  %10 = "llvm.select"(%4, %8, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = "llvm.select"(%9, %10, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%11) : (i1) -> ()
}
]

def select_icmp_ne_0_and_32_xor_4096_after := [llvm|
{
^0(%arg199 : i32, %arg200 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(4096 : i32) : i32
  %2 = llvm.shl %arg199, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %arg200 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

Lean.Meta.evalExpr in Lean.Meta.Eval

RV64.adduw in RISCV.Instructions

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

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

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

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

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

def fold_add_udiv_urem_or_disjoint_after := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.udiv %arg5, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  %4 = llvm.add %3, %arg5 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

def or_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_noflag_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_disjoint_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_noflag_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_disjoint_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_noflag_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_disjoint_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_noflag_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_or_lower_riscv_disjoint_64)
]

structure ParsedBVExpr where
  width : Nat
  bvExpr: GenBVExpr width
  symVars: Std.HashMap Nat BVExpr.PackedBitVec
  inputVars : Std.HashMap Nat HydraVariable

def mkBoolLit (b : Bool) : Expr :=
  match b with
  | true => mkConst ``true
  | false => mkConst ``false

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

def test5_before := [llvm|
{
^0(%arg0 : i399, %arg1 : i399):
  %0 = llvm.mlir.constant(274877906943 : i399) : i399
  %1 = llvm.mlir.constant(-1 : i399) : i399
  %2 = llvm.mlir.constant(18446742974197923840 : i399) : i399
  %3 = llvm.xor %0, %1 : i399
  %4 = llvm.and %arg1, %2 : i399
  %5 = llvm.add %arg0, %4 : i399
  %6 = llvm.and %5, %3 : i399
  %7 = llvm.and %arg0, %0 : i399
  %8 = llvm.or %6, %7 : i399
  "llvm.return"(%8) : (i399) -> ()
}
]

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

def logical_or_logical_or_icmps_comm3_after := [llvm|
{
^0(%arg151 : i8, %arg152 : i8, %arg153 : 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" %arg152, %0 : i8
  %4 = llvm.shl %1, %arg153 overflow<nuw> : i8
  %5 = llvm.or %4, %1 : i8
  %6 = llvm.and %arg151, %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 lshrult_02_01_before := [llvm|
{
^0(%arg350 : i4):
  %0 = llvm.mlir.constant(2 : i4) : i4
  %1 = llvm.mlir.constant(1 : i4) : i4
  %2 = llvm.lshr %arg350, %0 : i4
  %3 = llvm.icmp "ult" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def mkExpr (Γ : Ctxt _) (opStx : MLIR.AST.Op 0) :
    MLIR.AST.ReaderM HSxComb (Σ eff ty, Expr HSxComb Γ eff ty) := do
  let args ← opStx.parseArgs Γ
  let mkExprOf := opStx.mkExprOf (args? := args) Γ
  
  match (opStx.name).splitOn "_" with
  
  | ["HSxComb.fst"] | ["HSxComb.snd"] | ["HSxComb.fork"] | ["HSxComb.sink"] =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, opStx.name with
      | .stream2 t, "HSxComb.fst" =>  mkExprOf <| Op.hs (MLIR2Handshake.Op.fst t)
      | .stream2 t, "HSxComb.snd" =>  mkExprOf <| Op.hs (MLIR2Handshake.Op.snd t)
      | .stream t, "HSxComb.fork" =>  mkExprOf <| Op.hs (MLIR2Handshake.Op.fork t)
      | .stream t, "HSxComb.sink" =>  mkExprOf <| Op.hs (MLIR2Handshake.Op.sink t)
      | _, _ => throw <| .generic s!"type mismatch at {repr opStx.args}"
    | _ => throw <| .generic s!"expected one operand, found #'{opStx.args.length}' in '{repr opStx.args}'"
  
  | ["HSxComb.merge"] | ["HSxComb.altMerge"] | ["HSxComb.controlMerge"] | ["HSxComb.join"] | ["HSxComb.sync"] | ["HSxComb.branch"] =>
    match opStx.args with
    | v₁Stx::v₂Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
      match ty₁, ty₂, opStx.name with
      | .stream t₁, .stream t₂, "HSxComb.merge" =>
        if t₁ = t₂ then mkExprOf <| Op.hs (MLIR2Handshake.Op.merge t₁)
        else throw <| .generic s!"type mismatch in {repr opStx.args}"
      | .stream t₁, .stream t₂, "HSxComb.altMerge" =>
        if t₁ = t₂ then mkExprOf <| Op.hs (MLIR2Handshake.Op.altMerge t₁)
        else throw <| .generic s!"type mismatch in {repr opStx.args}"
      | .stream t₁, .stream t₂, "HSxComb.controlMerge" =>
        if t₁ = t₂ then mkExprOf <| Op.hs (MLIR2Handshake.Op.controlMerge t₁)
        else throw <| .generic s!"type mismatch in {repr opStx.args}"
      | .stream t₁, .stream t₂, "HSxComb.join" =>
        if t₁ = t₂ then mkExprOf <| Op.hs (MLIR2Handshake.Op.join t₁)
        else throw <| .generic s!"type mismatch in {repr opStx.args}"
      | .stream t₁, .stream t₂, "HSxComb.sync" =>
        if t₁ = t₂ then mkExprOf <| Op.hs (MLIR2Handshake.Op.sync t₁)
        else throw <| .generic s!"type mismatch in {repr opStx.args}"
      | .stream t₁, .stream (.bitvec 1), "HSxComb.branch" => mkExprOf <| Op.hs (MLIR2Handshake.Op.branch t₁)
      | _, _, _ => throw <| .generic s!"type mismatch in {repr opStx.args}"
    | _ => throw <| .generic s!"expected two operands, found #'{opStx.args.length}' in '{repr opStx.args}'"
  
  | ["HSxComb.mux"] =>
      match opStx.args with
      | v₁Stx::v₂Stx::v₃Stx::[] =>
        let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
        let ⟨ty₂, v₂⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₂Stx
        let ⟨ty₃, v₃⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₃Stx
        match ty₁, ty₂, ty₃, opStx.name with
        | .stream t₁, .stream t₂, .stream (.bitvec 1), "HSxComb.mux" =>
          if t₁ = t₂ then  mkExprOf <| Op.hs (MLIR2Handshake.Op.mux t₁)
          else throw <| .generic s!"type mismatch in {repr opStx.args}"
        | _, _, _, _=> throw <| .generic s!"type mismatch in the args of '{repr opStx.args}'"
      | _ => throw <| .generic s!"expected three operands, found #'{opStx.args.length}' in '{repr opStx.args}'"
  | ["HSxComb.parity"] =>
    match opStx.args with
    | v₁Stx::[] =>
      let ⟨ty₁, v₁⟩ ← MLIR.AST.TypedSSAVal.mkVal Γ v₁Stx
      match ty₁, opStx.name with
      | .stream (.bitvec w), "HSxComb.parity" => mkExprOf <| Op.comb (MLIR2Comb.Op.parity w)
      | _, _ => throw <| .generic s!"type mismatch in the args of '{repr opStx.args}'"
    | _ => throw <| .generic s!"expected one operand, found #'{opStx.args.length}' in '{repr opStx.args}'"
  
  | ["HSxComb.add"] | ["HSxComb.and"] | ["HSxComb.mul"] | ["HSxComb.or"] | ["HSxComb.xor"] =>
      let args ← opStx.args.mapM (MLIR.AST.TypedSSAVal.mkVal Γ)
      if hl: args.length ≤ 0 then
        throw <| .generic s!"empty list of arguments for '{repr opStx.args}'"
      else
        have hl' : (0 : Nat) < args.length := by admit /- proof elided -/

def test_or3_logical_after := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(2147483647 : i32) : i32
  %1 = llvm.and %arg27, %0 : i32
  %2 = llvm.icmp "uge" %arg26, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

def sextinreg_after := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.shl %arg14, %0 : i32
  %2 = llvm.ashr exact %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

instance : Complement BitStream := ⟨map Bool.not⟩

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

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

def icmp_select_var_commuted_after := [llvm|
{
^0(%arg86 : i8, %arg87 : i8, %arg88 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.udiv %0, %arg88 : i8
  %4 = llvm.icmp "eq" %arg86, %1 : i8
  %5 = llvm.icmp "eq" %arg87, %3 : i8
  %6 = "llvm.select"(%4, %2, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

def test6_after := [llvm|
{
^0(%arg3 : i16):
  %0 = llvm.sext %arg3 : i16 to i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

def Tensor1d.empty [Inhabited α] : Tensor1d α where
  size := 0
  val := fun _ => default
  spec := by admit /- proof elided -/

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

def x : DCOp.ValueStream Int := ofList [some 1, none, some 2, some 5, none]

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

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

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

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

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

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 fold_select_trunc_nuw_false_before := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.trunc %arg8 overflow<nuw> : i8 to i1
  %1 = "llvm.select"(%0, %arg9, %arg8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def shl_add_lshr_flag_preservation_after := [llvm|
{
^0(%arg157 : i32, %arg158 : i32, %arg159 : i32):
  %0 = llvm.lshr exact %arg159, %arg158 : i32
  %1 = llvm.add %0, %arg157 overflow<nsw,nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def test1_after := [llvm|
{
^0(%arg26 : i23):
  %0 = llvm.mlir.constant(0 : i23) : i23
  "llvm.return"(%0) : (i23) -> ()
}
]

def or_and_or_pat3_after := [llvm|
{
^0(%arg30 : i8, %arg31 : i8, %arg32 : i8, %arg33 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg32 : i8
  %2 = llvm.or %arg33, %arg30 : i8
  %3 = llvm.and %arg31, %2 : i8
  %4 = llvm.or %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

@[simp_denote]
def icmp_ule_riscv_32 := [LV| {
  ^entry (%lhs: i32, %rhs: i32):
    %lhsr = "builtin.unrealized_conversion_cast"(%lhs) : (i32) -> (!i64)
    %rhsr = "builtin.unrealized_conversion_cast"(%rhs) : (i32) -> (!i64)
    %0 = sltu %rhsr, %lhsr : !i64
    %1 = xori %0, 1 : !i64
    %2 = "builtin.unrealized_conversion_cast"(%1) : (!i64) -> (i1)
    llvm.return %2 : i1
  }]

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

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

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

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

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

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

def sub_shl_same_amount_partial_nuw2_after := [llvm|
{
^0(%arg2 : i6, %arg3 : i6, %arg4 : i6):
  %0 = llvm.sub %arg2, %arg3 : i6
  %1 = llvm.shl %0, %arg4 : i6
  "llvm.return"(%1) : (i6) -> ()
}
]

def foo_before := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(223 : i32) : i32
  %1 = llvm.mlir.constant(29 : i32) : i32
  %2 = llvm.mlir.constant(-784568073 : i32) : i32
  %3 = llvm.mlir.constant(1874836915 : i32) : i32
  %4 = llvm.mlir.constant(221 : i32) : i32
  %5 = llvm.mlir.constant(1 : i32) : i32
  %6 = llvm.mlir.constant(1533579450 : i32) : i32
  %7 = llvm.mlir.constant(-2147483648 : i32) : i32
  %8 = llvm.mlir.constant(749011377 : i32) : i32
  %9 = llvm.and %arg0, %0 : i32
  %10 = llvm.xor %9, %1 : i32
  %11 = llvm.add %10, %2 overflow<nuw> : i32
  %12 = llvm.or %10, %3 : i32
  %13 = llvm.and %10, %4 : i32
  %14 = llvm.xor %13, %3 : i32
  %15 = llvm.xor %12, %14 : i32
  %16 = llvm.shl %15, %5 overflow<nsw,nuw> : i32
  %17 = llvm.sub %11, %16 : i32
  %18 = llvm.add %17, %6 overflow<nsw> : i32
  %19 = llvm.or %18, %7 : i32
  %20 = llvm.xor %19, %8 : i32
  "llvm.return"(%20) : (i32) -> ()
}
]

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

def narrow_zext_add_after := [llvm|
{
^0(%arg42 : i16, %arg43 : i32):
  %0 = llvm.trunc %arg43 : i32 to i16
  %1 = llvm.add %arg42, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

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

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

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

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

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

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

def test4_before := [llvm|
{
^0(%arg0 : i9, %arg1 : i9):
  %0 = llvm.zext %arg0 : i9 to i64
  %1 = llvm.zext %arg1 : i9 to i64
  %2 = llvm.add %0, %1 : i64
  %3 = llvm.trunc %2 : i64 to i9
  "llvm.return"(%3) : (i9) -> ()
}
]

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

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

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

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

def narrow_zext_ashr_keep_trunc2_after := [llvm|
{
^0(%arg6 : i9, %arg7 : i9):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.zext %arg6 : i9 to i16
  %2 = llvm.zext %arg7 : i9 to i16
  %3 = llvm.add %1, %2 overflow<nsw,nuw> : i16
  %4 = llvm.lshr %3, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

@[simp]
def Formula.Tautology (φ : Formula) := φ.language = ⊤

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 sdiv_eq_smin_before := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.sdiv %arg28, %arg29 : i8
  %2 = llvm.icmp "eq" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def join (x y : TokenStream) : TokenStream  :=
  syncMap₂ (xs := x) (ys := y) (f := sendReadySignal)

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

def add_mask_ashr27_i32_after := [llvm|
{
^0(%arg0 : i32):
  %0 = llvm.mlir.constant(27 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.ashr %arg0, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.add %3, %2 overflow<nsw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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 ugt_and_not_min_before := [llvm|
{
^0(%arg78 : i8, %arg79 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ugt" %arg78, %arg79 : i8
  %2 = llvm.icmp "ne" %arg78, %0 : i8
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]
</all_available_defs>

<all_available_lemmas>
...

theorem Com.denoteLets_eq {com : Com d Γ eff t} : com.denoteLets = com.toLets.denote

@[simp] theorem Lets.denote_var {lets : Lets d Γ_in eff Γ_out} {e : Expr d Γ_out eff t} :
    (lets.var e).denote = fun V_in => lets.denote V_in >>= e.denote

@[simp, grind=] theorem castCtxt_rfl (h : Γ = Γ) : v.castCtxt h = v

@[simp] theorem Com.returnVars_castPureToEff (eff : _) (com : Com d Γ .pure tys) :
    (com.castPureToEff eff).returnVars = com.returnVars.map (fun _ v => v.castCtxt (by simp))

@[simp] theorem Valuation.comap_apply {Γi Γo : Ctxt Ty}
    (V : Γi.Valuation) (f : Ctxt.Hom Γo Γi) (v : Γo.Var t) :
    V.comap f v = V (f v)

@[simp] theorem Com.denoteLets_castPureToEff {com : Com d Γ .pure ty} :
    denoteLets (com.castPureToEff eff)
    = fun V => pure (com.denoteLets V |>.comap fun _ v => v.castCtxt (by simp))

@[simp] theorem Com.denoteLets_returnVars (c : Com d Γ .pure tys) (V : Valuation Γ) :
    c.returnVars.map (c.denoteLets V) = c.denote V

theorem Id.bind_eq' (x : Id α) (f : α → id β) : x >>= f = f x

theorem Id.pure_eq' (a : α) : (pure a : Id α) = a

@[simp] theorem Ctxt.Valuation.comap_outContextHom_denoteLets {com : Com d Γ .pure ty} {V} :
    Valuation.comap (com.denoteLets V) com.outContextHom = V

@[simp] theorem Com.bvars_castPureToEff {com : Com d Γ .pure ty} :
    (com.castPureToEff eff).bvars = com.bvars

@[simp] theorem Valuation.comap_with [DecidableEq Ty] {Γ Δ : Ctxt Ty}
    {V : Valuation Γ} {map : Δ.Hom Γ} {vs : HVector Δ.Var ty} {ws : HVector Γ.Var ty} :
    V.comap (map.with vs ws) = (V.comap map).reassignVars vs (ws.map V)

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

@[simp, grind=] theorem castCtxt_castCtxt (h₁ : Γ = Δ) (h₂ : Δ = Ξ) :
    (v.castCtxt h₁).castCtxt h₂ = v.castCtxt (by simp [*])

theorem Lets.denote_eq_denoteIntoSubtype (lets : Lets d Γ_in eff Γ_out) (Γv : Valuation Γ_in) :
    lets.denote Γv = Subtype.val <$> (lets.denoteIntoSubtype Γv)

theorem Expr.denoteOp_eq_denoteOpIntoSubtype (e : Expr d Γ eff tys) (V : Valuation Γ) :
    e.denoteOp V = Subtype.val <$> e.denoteOpIntoSubtype V

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

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

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

theorem xor_notand_to_or_not2_proof : xor_notand_to_or_not2_before ⊑ xor_notand_to_or_not2_after

theorem neg_slt_42_proof : neg_slt_42_before ⊑ neg_slt_42_after

theorem ashr_or_proof : ashr_or_before ⊑ ashr_or_after

theorem or_not_xor_common_op_commute6_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  x_2 ^^^ x_1 ||

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

theorem badimm3_thm.extracted_1._4 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬14#16 ≥ ↑16 →
        ¬ofBool (x + 128#16 <ᵤ 256#16) = 1#1 →
          14#16 ≥ ↑16 ∨ True ∧ signExtend 16 (truncate 8 (x.sshiftRight' 14#16)) ≠ x.sshiftRight' 14#16 → False

theorem t9_ashr_exact_flag_preservation_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1 >>> (32#32 - x) <<< (32#32 - x) ≠ x_1 ∨
        32#32 - x ≥ ↑32 ∨
          True ∧
              x_1.sshiftRight' (32#32 - x) >>> (x + BitVec.ofInt 32 (-2)) <<< (x + BitVec.ofInt 32 (-2)) ≠
                x_1.sshiftRight' (32#32 - x) ∨
            x + BitVec.ofInt 32 (-2) ≥ ↑32) →
    True ∧ x_1 >>> 30#32 <<< 30#32 ≠ x_1 ∨ 30#32 ≥ ↑32 → False

theorem e_66 :
    4 * y - 11 *  ~~~(x &&&  ~~~x) + 4 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) =  - 7 * (x |||  ~~~y)

theorem orn_and_cmp_2_logical_thm.extracted_1._4 : ∀ (x x_1 : BitVec 16) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → 0#1 = 1#1 → 1#1 = ofBool (x_1 <ₛ x)

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

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

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

theorem t0_proof : t0_before ⊑ t0_after

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

lemma mem_varsFinset [DecidableEq α] {c : Circuit α} :
    ∀ {x : α}, x ∈ c.varsFinset ↔ x ∈ c.vars

theorem masked_icmps_mask_notallzeros_bmask_mixed_2_proof : masked_icmps_mask_notallzeros_bmask_mixed_2_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_2_after

theorem and_not_or_or_not_or_xor_commute5_proof : and_not_or_or_not_or_xor_commute5_before ⊑ and_not_or_or_not_or_xor_commute5_after

theorem fold_icmp_shl_nuw_c2_proof : fold_icmp_shl_nuw_c2_before ⊑ fold_icmp_shl_nuw_c2_after

theorem eval_fst {α β : Type _} [DecidableEq α] [DecidableEq β]
    (c : Circuit (α ⊕ β)) (g : α → Bool) :
    c.fst.eval g ↔ ∃ g' : β → Bool, c.eval (Sum.elim g g')

theorem sub_select_sext_op_swapped_non_const_args_proof : sub_select_sext_op_swapped_non_const_args_before ⊑ sub_select_sext_op_swapped_non_const_args_after

theorem neg_slt_42_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ofBool (0#128 - x <ₛ 42#128) = ofBool (BitVec.ofInt 128 (-43) <ₛ x + -1#128)

theorem sub_from_variable_of_sub_from_constant_proof : sub_from_variable_of_sub_from_constant_before ⊑ sub_from_variable_of_sub_from_constant_after

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

theorem fold_sext_to_and_wrong6_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) != -1#32) = 1#1

theorem uadd_sat_flipped_wrong_bounds6_proof : uadd_sat_flipped_wrong_bounds6_before ⊑ uadd_sat_flipped_wrong_bounds6_after

theorem select_icmp_eq_and_1_0_lshr_fv_proof : select_icmp_eq_and_1_0_lshr_fv_before ⊑ select_icmp_eq_and_1_0_lshr_fv_after

theorem masked_bit_clear_commute_proof : masked_bit_clear_commute_before ⊑ masked_bit_clear_commute_after

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

theorem trunc_shl_nsw_31_i32_i64_thm (e : IntW 64) :
  trunc 32 (shl e (const? 64 31) { «nsw» := true, «nuw» := false }) ⊑ shl (trunc 32 e) (const? 32 31)

theorem ripple_nsw3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  True ∧ (x_1 &&& BitVec.ofInt 16 (-21845)).saddOverflow (x &&& 21843#16) = true ∨
      True ∧ (x_1 &&& BitVec.ofInt 16 (-21845)).uaddOverflow (x &&& 21843#16) = true →
    False

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

theorem shl_and_lshr_comm_proof : shl_and_lshr_comm_before ⊑ shl_and_lshr_comm_after

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

theorem or_not_and_commute7_proof : or_not_and_commute7_before ⊑ or_not_and_commute7_after

theorem test13_proof : test13_before ⊑ test13_after

theorem e_2087 :
     - 11 * (e ^^^ (d &&& f)) - 3 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 1 * (d |||  ~~~f) + 5 *  ~~~(d ^^^ ( ~~~e ||| f)) + 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 5 * (e ^^^ (d |||  ~~~f)) + 4 * (d ||| (e ||| f)) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 *  ~~~(d &&& (e ||| f)) + 4 * (f ^^^ (d &&& (e ||| f))) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 4 * (e ^^^ (d ||| (e ||| f))) - 7 *  ~~~(d ^^^ (e ||| f)) - 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * ( ~~~e &&& (d ^^^ f)) - 2 *  ~~~(d ||| (e ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (e |||  ~~~f) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 3 * (d ^^^ f) - 2 *  ~~~(d ^^^ ( ~~~e &&& f)) - 11 * (f ^^^  ~~~(d ||| e)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 4 * (e ^^^  ~~~(d ||| f)) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * (f &&&  ~~~(d ^^^ e)) - 5 *  ~~~(d &&&  ~~~d) + 7 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& f) - 6 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 9 *  ~~~(d ||| ( ~~~e ||| f)) - 15 *  ~~~( ~~~d ||| (e ||| f)) + 10 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 5 * ( ~~~d &&& ( ~~~e &&& f)) + 32 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 8 * (d &&& (e &&& f)) =  - 1 * (d &&& (e ||| f)) - 37 *  ~~~(d ||| (e ||| f))

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

theorem test9_proof : test9_before ⊑ test9_after

theorem or_eq_with_one_bit_diff_constants1_proof : or_eq_with_one_bit_diff_constants1_before ⊑ or_eq_with_one_bit_diff_constants1_after

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

theorem bool_eq0_proof : bool_eq0_before ⊑ bool_eq0_after

theorem tryFactorization_xor_ashr_ashr_proof : tryFactorization_xor_ashr_ashr_before ⊑ tryFactorization_xor_ashr_ashr_after

theorem ashr_lshr2_i128_thm (e e_1 : IntW 128) :
  select (icmp IntPred.sgt e_1 (const? 128 5)) (lshr e_1 e) (ashr e_1 e { «exact» := true }) ⊑ ashr e_1 e

theorem zext_sext_add_icmp_eq_1_proof : zext_sext_add_icmp_eq_1_before ⊑ zext_sext_add_icmp_eq_1_after

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

theorem no_masks_with_logical_or_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (select (icmp IntPred.ne e_2 (const? 32 0)) (const? 1 1) (icmp IntPred.ne e_1 (const? 32 63)))
      (icmp IntPred.ne e (const? 32 0)) ⊑
    select (icmp IntPred.ne (LLVM.or e_2 e) (const? 32 0)) (const? 1 1)
      (icmp IntPred.ne e_1 (const? 32 63))

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

theorem test11_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    True ∧ (x &&& 31#32).msb = true ∨
        True ∧
            (zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)).sshiftRight' (zeroExtend 64 (x &&& 31#32)) ≠
              zeroExtend 64 x_1 ∨
          True ∧ zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32) >>> zeroExtend 64 (x &&& 31#32) ≠ zeroExtend 64 x_1 ∨
            zeroExtend 64 (x &&& 31#32) ≥ ↑64 →
      False

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

theorem and_xor_not_common_op_proof : and_xor_not_common_op_before ⊑ and_xor_not_common_op_after

theorem e_2114 :
     - 7 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (d ||| ( ~~~e &&& f)) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 2 * (d &&& e) + 3 * (e ^^^ ( ~~~d ||| (e ||| f))) + 1 * (e ^^^ (d ||| (e &&& f))) - 5 * ( ~~~f &&& (d ^^^ e)) - 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * (f &&& (d |||  ~~~e)) + 7 * (e |||  ~~~(d ||| f)) + 4 *  ~~~d + 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^ (d ||| (e ||| f))) - 6 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * ( ~~~d ||| ( ~~~e &&& f)) + 2 *  ~~~( ~~~d ||| (e ^^^ f)) - 1 * d - 1 *  ~~~f - 3 * (e &&&  ~~~(d &&&  ~~~f)) + 7 * ( ~~~f ||| (d ^^^ e)) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 3 * (f &&&  ~~~(d &&& e)) - 2 *  ~~~( ~~~d ||| (e &&& f)) + 7 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 4 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 2 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * (f ^^^  ~~~(d &&&  ~~~e)) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 6 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * (e &&& f) + 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 3 * (d ||| (e ^^^ f)) + 4 * ((d &&& e) ^^^ (e ||| f)) - 19 *  ~~~(d ||| (e ||| f)) - 12 *  ~~~(d ||| ( ~~~e ||| f)) - 12 *  ~~~( ~~~d ||| (e ||| f)) - 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 27 * ( ~~~d &&& (e &&& f)) - 18 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) =  - 5 * (f ^^^  ~~~(d &&& ( ~~~e ||| f)))

theorem n12_wrong_bias_thm (e : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e (const? 8 15)) (const? 8 0)) e
      (LLVM.and (add e (const? 8 32)) (const? 8 (-16))) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 8 15)) (const? 8 0)) e
      (add (LLVM.and e (const? 8 (-16))) (const? 8 32))

theorem bools_logical_commute0_and2_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 → x_2 &&& x = x_1

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

theorem e_907 :
    11 *  ~~~(z &&&  ~~~z) + 1 * (z ||| t) - 5 *  ~~~t + 2 *  ~~~z - 8 *  ~~~(z ||| t) - 7 * (z &&&  ~~~t) = 14 *  ~~~(z |||  ~~~t) + 12 * (z &&& t)

theorem emod_eq_of_neg {a b : Int} (H1 : a < 0) (H2 : 0 ≤ a + b.natAbs) :
    a % b = b.natAbs + a

theorem e_160 :
    7 *  ~~~(x &&& y) + 7 * x - 5 * y - 2 *  ~~~(x |||  ~~~y) - 14 * (x &&&  ~~~y) - 2 * (x &&& y) = 7 *  ~~~(x ||| y)

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

theorem test12_proof : test12_before ⊑ test12_after

theorem t0_thm (e : IntW 8) : sext 16 (trunc 4 (lshr e (const? 8 4))) ⊑ sext 16 (ashr e (const? 8 4))

theorem shiftl1 {v : Nat} (x : BitVec v) :
    x <<< 5 = x <<< 3 <<< 2

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

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

theorem unsigned_sign_bit_extract_with_trunc_proof : unsigned_sign_bit_extract_with_trunc_before ⊑ unsigned_sign_bit_extract_with_trunc_after

theorem test10_thm (e : IntW 19) :
  shl (lshr e (const? 19 18)) (const? 19 18) ⊑ LLVM.and e (const? 19 (-262144))

theorem e_2229 :
     - 1 *  ~~~f + 11 *  ~~~(e |||  ~~~f) + 1 * (e ^^^ (d |||  ~~~f)) - 7 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * (d &&& (e ||| f)) - 7 * (e ^^^ (d &&& (e ^^^ f))) + 1 * (e &&&  ~~~(d ^^^ f)) + 7 *  ~~~(d &&& ( ~~~e ||| f)) - 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 1 * (e ||| (d ^^^ f)) - 1 * (e ^^^ (d ||| (e ^^^ f))) - 6 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 4 * ( ~~~d ||| (e ||| f)) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * (d |||  ~~~f) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (d ||| e) - 3 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * (e ^^^ (d ||| ( ~~~e ||| f))) + 3 * (e ^^^ ( ~~~d ||| (e ||| f))) - 5 * (e |||  ~~~(d ||| f)) + 2 * (f ^^^ (d ||| (e &&& f))) - 5 * (e ^^^  ~~~(d ||| f)) + 3 * (d ^^^ ( ~~~e &&& f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) + 5 * e + 4 *  ~~~(d &&& e) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 3 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 5 * (d ||| f) - 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (f &&&  ~~~(d &&& e)) + 11 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 *  ~~~(d ^^^ (e ||| f)) + 1 * (e ^^^ f) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 4 *  ~~~(d ||| ( ~~~e ||| f)) + 3 *  ~~~( ~~~d ||| (e ||| f)) + 19 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 26 * ( ~~~d &&& ( ~~~e &&& f)) - 6 * ( ~~~d &&& (e &&& f)) - 19 * (d &&& ( ~~~e &&& f)) - 18 * (d &&& (e &&& f)) =  - 11 * (f ||| (d ^^^ e)) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f)))

theorem xor_logic_and_logic_or2_proof : xor_logic_and_logic_or2_before ⊑ xor_logic_and_logic_or2_after

theorem in_constant_mone_vary_thm.extracted_1._1 : ∀ (x : BitVec 4), (x ^^^ -1#4) &&& 1#4 ^^^ x = x ||

theorem positive_with_icmp_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 512#32) = 1#1 → 0#1 = ofBool (x <ᵤ 128#32)

theorem mul16_low_miss_shift_amount_proof : mul16_low_miss_shift_amount_before ⊑ mul16_low_miss_shift_amount_after

theorem test_ule_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.ule (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.uge (LLVM.xor e e_1) e_1

theorem and_umax_less_proof : and_umax_less_before ⊑ and_umax_less_after

@[simp] theorem bind_poison : a? >>= (fun _ => @poison β) = poison

theorem tryFactorization_add_nuw_mul_nuw_int_max_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 2147483647#32 = true ∨ True ∧ (x * 2147483647#32).uaddOverflow x = true) →
    True ∧ x <<< 31#32 >>> 31#32 ≠ x ∨ 31#32 ≥ ↑32 → False

theorem sel_false_val_is_a_masked_ashr_of_true_val2_thm.extracted_1._4 : ∀ (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) →
          x.sshiftRight' (zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483588)).sshiftRight' 2#32)) =
            x.sshiftRight' (zeroExtend 64 (x_1.sshiftRight' 2#32 &&& BitVec.ofInt 32 (-536870897)))

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

theorem ashr_ne_both_equal_proof : ashr_ne_both_equal_before ⊑ ashr_ne_both_equal_after

theorem test_shl_nuw_nsw__all_are_safe_proof : test_shl_nuw_nsw__all_are_safe_before ⊑ test_shl_nuw_nsw__all_are_safe_after

theorem scalar_i32_shl_and_negC_eq_proof : scalar_i32_shl_and_negC_eq_before ⊑ scalar_i32_shl_and_negC_eq_after

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

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

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

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

theorem fold_sext_to_and_wrong9_proof : fold_sext_to_and_wrong9_before ⊑ fold_sext_to_and_wrong9_after

theorem icmp_slt_0_or_icmp_sgt_0_i32_proof : icmp_slt_0_or_icmp_sgt_0_i32_before ⊑ icmp_slt_0_or_icmp_sgt_0_i32_after

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

theorem test_add__all_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    ¬(True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true) →
      4#32 = (x &&& 1073741823#32) + 1#32

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

theorem ashr_ugt_5_proof : ashr_ugt_5_before ⊑ ashr_ugt_5_after

theorem t6_no_extrause_proof : t6_no_extrause_before ⊑ t6_no_extrause_after

theorem set_to_clear_decomposebittest_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x <ₛ 0#8) = 1#1 → BitVec.ofInt 8 (-125) = x &&& BitVec.ofInt 8 (-128) ^^^ BitVec.ofInt 8 (-125)

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

theorem icmp_eq_or_z_or_pow2orz_proof : icmp_eq_or_z_or_pow2orz_before ⊑ icmp_eq_or_z_or_pow2orz_after

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

theorem sub_const_const_sub_proof : sub_const_const_sub_before ⊑ sub_const_const_sub_after

@[simp]
lemma List.Vector.ofFn_0 {f : Fin 0 → α} : ofFn f = .nil

theorem test21_proof : test21_before ⊑ test21_after

theorem sub_to_and_and_commuted_proof : sub_to_and_and_commuted_before ⊑ sub_to_and_and_commuted_after

theorem shl_trunc_bigger_shl_proof : shl_trunc_bigger_shl_before ⊑ shl_trunc_bigger_shl_after

theorem com_ty : com.2.2.1 = [.bitvec 32]

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

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

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

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

theorem alive_AndOrXor_2595 : alive_AndOrXor_2595_src ⊑ alive_AndOrXor_2595_tgt

theorem trunc_shl_1_i32_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬1#64 ≥ ↑64 → 1#32 ≥ ↑32 → False

theorem icmp_slt_0_and_icmp_sge_neg1_i64_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → x >>> 63#64 &&& zeroExtend 64 (ofBool (-1#64 ≤ₛ x)) = zeroExtend 64 (ofBool (x == -1#64))

theorem t3_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 2),
  signExtend 8 x_1 + x ^^^ signExtend 8 x_1 = x + signExtend 8 x_1 ^^^ signExtend 8 x_1

@[bv_multi_width_normalize]
theorem iff_eq_double_impl (a b : Prop) : (a ↔ b) = ((a → b) ∧ (b → a))

theorem trunc_shl_zext_64_proof : trunc_shl_zext_64_before ⊑ trunc_shl_zext_64_after

theorem test15a_proof : test15a_before ⊑ test15a_after

theorem test14_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.saddOverflow 1#32 = true ∨
        True ∧ (x_1 + 1#32).saddOverflow ((x ||| BitVec.ofInt 32 (-1431655767)) ^^^ 1431655766#32) = true) →
    x_1 + 1#32 + ((x ||| BitVec.ofInt 32 (-1431655767)) ^^^ 1431655766#32) = x_1 - (x &&& 1431655766#32)

theorem icmp_ult_x_y_proof : icmp_ult_x_y_before ⊑ icmp_ult_x_y_after

theorem lshr_ne_both_equal_proof : lshr_ne_both_equal_before ⊑ lshr_ne_both_equal_after

theorem e_1464 :
    2 * (z ||| t) + 2 * (z ^^^ t) - 11 * t + 1 *  ~~~(z &&& t) + 3 *  ~~~t + 2 *  ~~~(z &&&  ~~~t) - 7 *  ~~~z - 7 * z - 1 *  ~~~(z &&&  ~~~z) + 12 *  ~~~(z |||  ~~~t) + 26 * (z &&& t) =  - 13 *  ~~~(z ||| t) + 11 *  ~~~(z ^^^ t)

theorem mul_of_bool_proof : mul_of_bool_before ⊑ mul_of_bool_after

theorem a_thm (e : IntW 32) :
  LLVM.and (sub (const? 32 8) e) (const? 32 7) ⊑ LLVM.and (sub (const? 32 0) e) (const? 32 7)

theorem lt_unsigned_to_large_unsigned_proof : lt_unsigned_to_large_unsigned_before ⊑ lt_unsigned_to_large_unsigned_after

theorem fold_or_zext_icmp_proof : fold_or_zext_icmp_before ⊑ fold_or_zext_icmp_after

theorem tryFactorization_add_nuw_mul_thm (e : IntW 32) :
  add (mul e (const? 32 3) { «nsw» := false, «nuw» := true }) e ⊑ shl e (const? 32 2)

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

theorem lshr_shl_pow2_const_xor_proof : lshr_shl_pow2_const_xor_before ⊑ lshr_shl_pow2_const_xor_after

theorem negative_trunc_not_arg_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x_1) = 1#1 →
    ofBool (x_1 &&& 128#32 == 0#32) = 1#1 → 0#1 = ofBool (x + 128#32 <ᵤ 256#32)

theorem test_logical_or_eq_a_b_proof : test_logical_or_eq_a_b_before ⊑ test_logical_or_eq_a_b_after

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

theorem ne_rem_zero_nonuw_proof : ne_rem_zero_nonuw_before ⊑ ne_rem_zero_nonuw_after

theorem e_2240 :
     - 1 * (e &&& f) - 7 * (d |||  ~~~e) - 3 * (e |||  ~~~(d ^^^ f)) + 4 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * (d &&& (e ||| f)) + 2 * (e ||| (d &&& f)) + 4 * (d &&&  ~~~e) + 2 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * ( ~~~d &&& (e ||| f)) - 5 * (e &&&  ~~~(d &&& f)) + 2 * (d ^^^ (e ||| f)) + 3 * (e ^^^  ~~~(d &&&  ~~~f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 *  ~~~(d ^^^ e) + 7 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * ( ~~~e &&& (d ^^^ f)) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) - 6 *  ~~~(d ||| f) - 2 * (f ^^^ (d &&& e)) + 11 * (d ^^^ e) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * (e &&&  ~~~f) + 2 * ( ~~~f ||| (d ^^^ e)) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 6 * (f ||| (d ^^^ e)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) - 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 * (d &&& e) + 1 *  ~~~(d &&& e) - 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (d ^^^ f) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 11 * f + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 7 *  ~~~(e |||  ~~~f) + 5 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 7 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&& e) ^^^ (e ||| f)) - 1 * ( ~~~d ||| (e ||| f)) - 12 *  ~~~(d ||| (e ||| f)) - 16 *  ~~~(d ||| ( ~~~e ||| f)) - 9 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 37 * ( ~~~d &&& ( ~~~e &&& f)) - 20 * ( ~~~d &&& (e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) + 26 * (d &&& (e &&& f)) = 20 *  ~~~( ~~~d ||| (e ||| f))

theorem lshrugt_03_01_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 3)) (const? 4 1) ⊑ const? 1 0

theorem bitwise_or_bitwise_or_icmps_comm2_thm (e e_1 e_2 : IntW 8) :
  LLVM.or
      (LLVM.or (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 0)) (icmp IntPred.eq e_1 (const? 8 42)))
      (icmp IntPred.eq (LLVM.and e_2 (shl (const? 8 1) e)) (const? 8 0)) ⊑
    LLVM.or
      (icmp IntPred.ne (LLVM.and e_2 (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)))
      (icmp IntPred.eq e_1 (const? 8 42))

theorem bools2_logical_commute1_proof : bools2_logical_commute1_before ⊑ bools2_logical_commute1_after

theorem test0_proof : test0_before ⊑ test0_after

theorem t0_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(zeroExtend 32 (32#16 - x) ≥ ↑32 ∨ x + BitVec.ofInt 16 (-24) ≥ ↑16) →
    ¬8#16 ≥ ↑16 →
      truncate 16 (x_1 <<< zeroExtend 32 (32#16 - x)) <<< (x + BitVec.ofInt 16 (-24)) = truncate 16 x_1 <<< 8#16

theorem alive_AndOrXor_2285  (w : Nat)   : alive_AndOrXor_2285_src w  ⊑ alive_AndOrXor_2285_tgt w

theorem ne_21_proof : ne_21_before ⊑ ne_21_after

theorem ashr_ugt_1_proof : ashr_ugt_1_before ⊑ ashr_ugt_1_after

theorem lshrugt_03_11_exact_proof : lshrugt_03_11_exact_before ⊑ lshrugt_03_11_exact_after

theorem or_ranges_overlap_proof : or_ranges_overlap_before ⊑ or_ranges_overlap_after

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

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

theorem PR42691_3_proof : PR42691_3_before ⊑ PR42691_3_after

theorem R.representative'_zero_elem :
    ∃ (k : (ZMod q)[X]), R.representative' q n 0 = k * (f q n)

theorem trunc_ashr_trunc_exact_proof : trunc_ashr_trunc_exact_before ⊑ trunc_ashr_trunc_exact_after

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

theorem and_signbit_select_shl_proof : and_signbit_select_shl_before ⊑ and_signbit_select_shl_after

theorem scanOr_false_iff (s : BitStream) (n : Nat) : s.scanOr n = false ↔ ∀ (i : Nat), (hi : i ≤ n) → s i = false

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

theorem ashr_shl_constants_proof : ashr_shl_constants_before ⊑ ashr_shl_constants_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 positive_biggershl_shlnsw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ True ∧ (x >>> 3#8 <<< 6#8).sshiftRight' 6#8 ≠ x >>> 3#8 ∨ 6#8 ≥ ↑8) →
    ¬(True ∧ (x <<< 3#8).sshiftRight' 3#8 ≠ x ∨ True ∧ x <<< 3#8 >>> 3#8 ≠ x ∨ 3#8 ≥ ↑8) →
      x >>> 3#8 <<< 6#8 = x <<< 3#8 &&& 64#8

theorem select_xor_icmp_bad_5_proof : select_xor_icmp_bad_5_before ⊑ select_xor_icmp_bad_5_after

theorem ashrslt_02_10_exact_proof : ashrslt_02_10_exact_before ⊑ ashrslt_02_10_exact_after

theorem sgt_swap_and_not_min_proof : sgt_swap_and_not_min_before ⊑ sgt_swap_and_not_min_after

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

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

theorem testi8i8_thm (e : IntW 8) :
  LLVM.xor (ashr e (const? 8 7)) (const? 8 127) ⊑
    select (icmp IntPred.sgt e (const? 8 (-1))) (const? 8 127) (const? 8 (-128))

theorem urem_i32_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 → ¬x = 0 → zeroExtend 32 x_1 % zeroExtend 32 x = zeroExtend 32 (x_1 % x)

theorem no_shift_xor_multiuse_cmp_with_xor_thm.extracted_1._5 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 → x_2 * x_1 = (x_3 &&& 4096#32 ^^^ x_2 ^^^ 4096#32) * x

theorem lshrugt_02_06_proof : lshrugt_02_06_before ⊑ lshrugt_02_06_after

theorem test18_proof : test18_before ⊑ test18_after

theorem positive_biggerLshr_thm (e : IntW 32) :
  lshr (shl e (const? 32 5)) (const? 32 10) ⊑ LLVM.and (lshr e (const? 32 5)) (const? 32 4194303)

theorem ashr_ult_7_proof : ashr_ult_7_before ⊑ ashr_ult_7_after

theorem ashrslt_01_14_proof : ashrslt_01_14_before ⊑ ashrslt_01_14_after

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

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

theorem sext_zext_apint2_thm (e : IntW 11) : sext 47 (zext 39 e) ⊑ zext 47 e

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

@[simp]
theorem instantiate_mvar_zero {hφ : List.length (w :: ws) = φ} {h0 : 0 < φ} :
    ConcreteOrMVar.instantiate (Subtype.mk (w :: ws) hφ)  (ConcreteOrMVar.mvar ⟨0, h0⟩) = w

theorem or_nosignbit_select_ashr_proof : or_nosignbit_select_ashr_before ⊑ or_nosignbit_select_ashr_after

theorem test12_proof : test12_before ⊑ test12_after

theorem test25_proof : test25_before ⊑ test25_after

theorem test20_thm (e : IntW 1) : icmp IntPred.slt (zext 32 e) (const? 32 (-1)) ⊑ const? 1 0

theorem mult_assoc_4 (hq : (r + s) <= q) (hu : (p + r) <= u) :
  (bw t (mulMax (bw u (mulMax (bw p a) (bw r b))) (bw s c))) =
  (bw t (mulMax (bw p a) (bw q (mulMax (bw r b) (bw s c)))))

theorem negative_trunc_not_arg_logical_proof : negative_trunc_not_arg_logical_before ⊑ negative_trunc_not_arg_logical_after

theorem ugt_swap_and_min_proof : ugt_swap_and_min_before ⊑ ugt_swap_and_min_after

theorem or_or_and_complex_proof : or_or_and_complex_before ⊑ or_or_and_complex_after

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

theorem ule_and_min_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 0)) (icmp IntPred.ule e_1 e) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

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

theorem mul_selectp2_x_propegate_nuw_thm (e : IntW 8) (e_1 : IntW 1) :
  mul (select e_1 (const? 8 2) (const? 8 4)) e { «nsw» := true, «nuw» := true } ⊑
    shl e (select e_1 (const? 8 1) (const? 8 2)) { «nsw» := false, «nuw» := true }

theorem e_2433 :
    11 *  ~~~(d &&&  ~~~f) - 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 7 *  ~~~(d ^^^ (e &&& f)) + 5 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (d |||  ~~~e) - 1 * (d ^^^ f) + 1 * (e &&& (d |||  ~~~f)) + 5 *  ~~~( ~~~d &&& (e ^^^ f)) - 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 11 * (f |||  ~~~(d ^^^ e)) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~e ||| (d ^^^ f)) + 1 * ( ~~~f ||| (d ^^^ e)) + 4 * (d &&& (e ||| f)) + 3 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) + 3 * (d &&& f) - 2 * (e ^^^ ( ~~~d &&& (e ||| f))) - 1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 4 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 7 * (d ||| (e ^^^ f)) - 6 * (d ^^^ ( ~~~e ||| f)) + 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 3 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~(d ||| (e &&& f))) - 5 *  ~~~(d ^^^ (e ||| f)) + 3 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) + 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (d ||| f) + 11 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 7 * (f ^^^ ( ~~~d &&& (e ||| f))) - 6 * (e &&&  ~~~f) - 5 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 11 * ((d &&& e) |||  ~~~(e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 4 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 11 * (f ^^^  ~~~(d &&& e)) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 3 * (f ^^^ (d &&& (e ||| f))) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * (e &&&  ~~~(d &&& f)) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) + 2 *  ~~~(d &&& (e ^^^ f)) - 1 * (d &&& (e ^^^ f)) + 7 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 11 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (f |||  ~~~(d ||| e)) - 6 * (e |||  ~~~(d ||| f)) + 2 * (e ^^^  ~~~(d ||| f)) + 7 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 5 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(e &&& f) - 14 *  ~~~(d ||| (e ||| f)) - 21 *  ~~~(d ||| ( ~~~e ||| f)) - 18 *  ~~~( ~~~d ||| (e ||| f)) + 56 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 12 * ( ~~~d &&& (e &&& f)) - 38 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) =  - 20 * ( ~~~d &&& ( ~~~e &&& f))

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_3b_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 15#32 == 0#32) = 1#1 → 1#1 = ofBool (x &&& 15#32 == 0#32) ||

theorem icmp_ne_sext_slt_otherwise_nofold_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x <ₛ 2#32)) != x) = ofBool (x != signExtend 32 (ofBool (x <ₛ 2#32)))

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

theorem test2_thm (e : IntW 32) :
  add (LLVM.and e (const? 32 7)) (LLVM.and e (const? 32 32)) ⊑ LLVM.and e (const? 32 39)

theorem ult_umin4_proof : ult_umin4_before ⊑ ult_umin4_after

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

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

theorem test8_proof : test8_before ⊑ test8_after

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

theorem icmp_shl_ne_2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬((x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true ∨
        (x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true ∨ 1#8 ≥ ↑8) →
    ¬(x == 0 || 8 != 1 && 42#8 == intMin 8 && x == -1) = true →
      ofBool ((42#8).sdiv x != (42#8).sdiv x <<< 1#8) = ofBool ((42#8).sdiv x != 0#8)

theorem foo2_thm (e e_1 : IntW 1) : mul e_1 e ⊑ LLVM.and e_1 e

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

theorem lshr_or_or_no_const_proof : lshr_or_or_no_const_before ⊑ lshr_or_or_no_const_after

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

@[simp] lemma eval_single [DecidableEq α] {s : List α} (x : ∀ a ∈ s, Bool) (g : α → Bool):
  eval (single x) g ↔ (∀ a (ha : a ∈ s), g a = x a (by simpa))

theorem select_xor_icmp_bad_6_proof : select_xor_icmp_bad_6_before ⊑ select_xor_icmp_bad_6_after

theorem shl_or_disjoint_lshr_proof : shl_or_disjoint_lshr_before ⊑ shl_or_disjoint_lshr_after

theorem add_smax_simplify2_proof : add_smax_simplify2_before ⊑ add_smax_simplify2_after

theorem scalar_zext_slt_proof : scalar_zext_slt_before ⊑ scalar_zext_slt_after

theorem t0_proof : t0_before ⊑ t0_after

theorem n3_constmask_samemask_proof : n3_constmask_samemask_before ⊑ n3_constmask_samemask_after

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

theorem and_zext_demanded_proof : and_zext_demanded_before ⊑ and_zext_demanded_after

theorem ashrsgt_03_00_exact_proof : ashrsgt_03_00_exact_before ⊑ ashrsgt_03_00_exact_after

theorem sgt_positive_multip_rem_nz_proof : sgt_positive_multip_rem_nz_before ⊑ sgt_positive_multip_rem_nz_after

theorem slt_zero_eq_i1_fail_proof : slt_zero_eq_i1_fail_before ⊑ slt_zero_eq_i1_fail_after

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

theorem scalar_i32_signbit_lshr_and_eq_proof : scalar_i32_signbit_lshr_and_eq_before ⊑ scalar_i32_signbit_lshr_and_eq_after

theorem pv_proof : pv_before ⊑ pv_after

theorem and_sext_sext_thm (e : IntW 8) (e_1 : IntW 4) :
  LLVM.and (sext 16 e_1) (sext 16 e) ⊑ sext 16 (LLVM.and e (sext 8 e_1))

theorem icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_proof : icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_before ⊑ icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_after

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

theorem ripple_nsw5_proof : ripple_nsw5_before ⊑ ripple_nsw5_after

theorem select_icmp_ne_0_and_8_xor_1073741824_proof : select_icmp_ne_0_and_8_xor_1073741824_before ⊑ select_icmp_ne_0_and_8_xor_1073741824_after

theorem eq_optimized_highbits_cmp_proof : eq_optimized_highbits_cmp_before ⊑ eq_optimized_highbits_cmp_after

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

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

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

theorem match_signed_proof : match_signed_before ⊑ match_signed_after

theorem min_of_max_proof : min_of_max_before ⊑ min_of_max_after

theorem or_and2_commuted_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

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 ne_3210_proof : ne_3210_before ⊑ ne_3210_after

theorem t0_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 8) (x_3 : BitVec 1),
  x_3 ^^^ 1#1 = 1#1 → x_3 = 1#1 → ofBool (x_2 == x_1) = 1#1 → False

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem mul_splat_fold_no_nuw_thm (e : IntW 32) :
  lshr (mul e (const? 32 65537) { «nsw» := true, «nuw» := false }) (const? 32 16) ⊑
    add e (lshr e (const? 32 16)) { «nsw» := true, «nuw» := false }

theorem e_1553 :
     - 6 *  ~~~(a ^^^ c) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 5 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * (b ||| (a ^^^ c)) - 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 5 * ( ~~~a &&& (b ||| c)) - 5 * ((a &&& c) ||| (b &&&  ~~~c)) + 12 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~(a ||| ( ~~~b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& (b &&& c)) + 13 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) =  - 2 * ( ~~~a &&& ( ~~~b &&& c)) + 1 *  ~~~(a ^^^ b)

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

theorem test_sub_nuw__none_are_safe_proof : test_sub_nuw__none_are_safe_before ⊑ test_sub_nuw__none_are_safe_after

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

theorem smear_set_bit_thm (e : IntW 32) :
  sext 32 (ashr (trunc 8 e) (const? 8 7)) ⊑ ashr (shl e (const? 32 24)) (const? 32 31)

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

theorem lshr_neg_sgt_minus_1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (-1#8 <ₛ BitVec.ofInt 8 (-17) >>> x) = ofBool (x != 0#8)

@[simp] theorem Hom.castDomain_apply {h : Δ = Δ'} {f : Γ.Hom Δ} {v : Γ.Var t} :
    f.castCodomain h v = (f v).castCtxt h

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

theorem eq_rem_zero_nonuw_proof : eq_rem_zero_nonuw_before ⊑ eq_rem_zero_nonuw_after

theorem or_min_31_30_proof : or_min_31_30_before ⊑ or_min_31_30_after

theorem ult_x_impliesT_eq_umax_todo_proof : ult_x_impliesT_eq_umax_todo_before ⊑ ult_x_impliesT_eq_umax_todo_after

theorem alive_AndOrXor_716 : alive_AndOrXor_716_src ⊑ alive_AndOrXor_716_tgt

theorem neg_sgt_1_proof : neg_sgt_1_before ⊑ neg_sgt_1_after

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → x_1 % 70368744177664#599 = x_1 &&& 70368744177663#599

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

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

theorem ashrslt_03_01_proof : ashrslt_03_01_before ⊑ ashrslt_03_01_after

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

theorem ult_rem_nz_nsw_proof : ult_rem_nz_nsw_before ⊑ ult_rem_nz_nsw_after

theorem t14_x_is_one_thm (e e_1 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (shl e_1 (sub (const? 32 32) e)) (trunc 32 (lshr (const? 64 1) (zext 64 (add e (const? 32 (-16)))))))
      (const? 32 0) ⊑
    const? 1 0

theorem Eqn.denoteFin_eq_add {w : Nat} (eqn : Eqn) (env : EnvFin (w + 1) eqn.numVars) :
    eqn.denoteFin env = 2 * eqn.denoteFin env.getNonLsbs + eqn.denoteFin env.getLsb

theorem e_1784 :
     - 3 * (c ^^^ (a ||| b)) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 1 *  ~~~(b ||| c) + 1 * ( ~~~a ||| (b ||| c)) + 1 * (b ^^^ (a ||| c)) - 7 *  ~~~(a ^^^ b) - 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 5 * (b ^^^ (a |||  ~~~c)) + 2 * (c ^^^ (a ||| ( ~~~b &&& c))) - 11 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 6 * ((a &&& b) ||| (b ^^^ c)) + 1 *  ~~~(a ||| ( ~~~b &&& c)) + 4 * (b |||  ~~~(a ||| c)) - 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 11 * (b &&& (a ||| c)) + 11 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * ( ~~~b ||| (a ^^^ c)) + 4 * (c &&& (a ||| b)) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) + 2 * (b ^^^  ~~~(a &&& (b ||| c))) - 7 * ((a &&& b) ^^^ (b |||  ~~~c)) + 3 * ( ~~~c &&& (a ^^^ b)) - 2 * (c ^^^ (a &&& b)) + 11 * (a |||  ~~~c) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 5 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 7 * (b ^^^  ~~~(a &&& c)) + 2 *  ~~~(a ||| (b ||| c)) - 10 *  ~~~(a ||| ( ~~~b ||| c)) + 18 *  ~~~( ~~~a ||| (b ||| c)) - 14 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 30 * ( ~~~a &&& ( ~~~b &&& c)) - 16 * ( ~~~a &&& (b &&& c)) + 3 * (a &&& ( ~~~b &&& c)) - 2 * (a &&& (b &&& c)) = 3 * (a &&& (b ||| c))

theorem trunc_ashr_trunc_outofrange_proof : trunc_ashr_trunc_outofrange_before ⊑ trunc_ashr_trunc_outofrange_after

@[simp]
theorem eval_shiftLeft (k : Nat) (env : Unit → BitStream) (i : Nat) :
    (shiftLeft k).eval env i = ((decide (k ≤ i)) && ((env ()) (i - k)))

theorem gt_unsigned_to_small_signed_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (17#32 <ₛ zeroExtend 32 x) = ofBool (17#8 <ᵤ x)

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

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

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

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

theorem PR1817_2_logical_proof : PR1817_2_logical_before ⊑ PR1817_2_logical_after

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

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

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

lemma ite_def (cond t f : Circuit α) :
  Circuit.ite cond t f = (cond &&& t) ||

theorem logical_and_logical_and_icmps_comm2_proof : logical_and_logical_and_icmps_comm2_before ⊑ logical_and_logical_and_icmps_comm2_after

theorem test21_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬2#32 ≥ ↑32 → zeroExtend 32 (ofBool (x &&& 4#32 != 0#32)) = x >>> 2#32 &&& 1#32

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

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

theorem positive_biggerashr_ashrexact_thm (e : IntW 8) :
  shl (ashr e (const? 8 6) { «exact» := true }) (const? 8 3) ⊑ ashr e (const? 8 3) { «exact» := true }

theorem uge_and_max_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 (-1))) (icmp IntPred.uge e_1 e) (const? 1 0) ⊑
    icmp IntPred.eq e_1 (const? 8 (-1))

theorem bitwise_or_bitwise_or_icmps_comm3_proof : bitwise_or_bitwise_or_icmps_comm3_before ⊑ bitwise_or_bitwise_or_icmps_comm3_after

theorem icmp_select_implied_cond_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (select (icmp IntPred.eq e_1 (const? 8 0)) (const? 8 0) e) e_1 ⊑
    select (icmp IntPred.eq e_1 (const? 8 0)) (const? 1 1) (icmp IntPred.eq e e_1)

theorem and_not_or_commute7_proof : and_not_or_commute7_before ⊑ and_not_or_commute7_after

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

theorem mul_selectp2_x_propegate_nuw_thm.extracted_1._4 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 →
    ¬(True ∧ (4#8).smulOverflow x = true ∨ True ∧ (4#8).umulOverflow x = true) →
      ¬(True ∧ x <<< 2#8 >>> 2#8 ≠ x ∨ 2#8 ≥ ↑8) → 4#8 * x = x <<< 2#8

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

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

theorem t0_proof : t0_before ⊑ t0_after

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

theorem e_1417 :
     - 2 * (z |||  ~~~t) - 5 *  ~~~(z &&&  ~~~t) - 1 * z - 11 *  ~~~t - 5 *  ~~~z - 6 *  ~~~(z &&& t) + 3 * (z ^^^ t) + 29 *  ~~~(z ||| t) + 18 *  ~~~(z |||  ~~~t) + 17 * (z &&&  ~~~t) = 5 * t - 13 * (z &&& t)

theorem narrow_zext_add_thm (e : IntW 32) (e_1 : IntW 16) : trunc 16 (add (zext 32 e_1) e) ⊑ add e_1 (trunc 16 e)

theorem neg_mask2_lshr_proof : neg_mask2_lshr_before ⊑ neg_mask2_lshr_after

theorem positive_sameconst_shlnuwnsw_proof : positive_sameconst_shlnuwnsw_before ⊑ positive_sameconst_shlnuwnsw_after

theorem test_shl__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 t3_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 64),
  ¬(x ≥ ↑32 ∨ zeroExtend 64 (4#32 <<< x) = 0) → True ∧ (x + 2#32).msb = true ∨ zeroExtend 64 (x + 2#32) ≥ ↑64 → False

theorem e_970 :
     - 1 *  ~~~t - 6 *  ~~~(z &&& t) + 1 * z - 7 *  ~~~(z ^^^ t) + 14 *  ~~~(z ||| t) + 6 *  ~~~(z |||  ~~~t) + 6 * (z &&& t) =  - 6 * (z &&&  ~~~t)

theorem ashr_exact_proof : ashr_exact_before ⊑ ashr_exact_after

theorem PR75692_1_thm.extracted_1._1 : ∀ (x : BitVec 32), (x ^^^ 4#32) &&& (x ^^^ BitVec.ofInt 32 (-5)) = 0#32

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

theorem zext_sext_add_icmp_ne_1_proof : zext_sext_add_icmp_ne_1_before ⊑ zext_sext_add_icmp_ne_1_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 bools_logical_commute0_and1_proof : bools_logical_commute0_and1_before ⊑ bools_logical_commute0_and1_after

theorem PR42691_7_logical_thm (e : IntW 32) :
  select (icmp IntPred.uge e (const? 32 (-2147483647))) (const? 1 1) (icmp IntPred.eq e (const? 32 0)) ⊑
    icmp IntPred.slt (add e (const? 32 (-1))) (const? 32 0)

theorem ashrslt_02_00_exact_proof : ashrslt_02_00_exact_before ⊑ ashrslt_02_00_exact_after

theorem not_lshr_const_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → 42#8 >>> x ^^^ -1#8 = (BitVec.ofInt 8 (-43)).sshiftRight' x

theorem n2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 ^^^ 1#1 ||

theorem main7f_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 t1_ult_slt_0_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ 65536#32) = 1#1 → ofBool (x_1 <ₛ 0#32) = 1#1 → ofBool (65535#32 <ₛ x_1) = 1#1 → False

@[simp]
theorem R.representative_mul (a b : R q n) :
    (a * b).representative = (a.representative * b.representative) %ₘ (f q n)

theorem test_thm.extracted_1._1_1 : ∀ (x : BitVec 31),
  ¬15#32 ≥ ↑32 → True ∧ (zeroExtend 32 x).uaddOverflow 16384#32 = true ∨ 15#32 ≥ ↑32 → False

@[simp]
lemma Fin.castSucc_neq_last (x : Fin n) : x.castSucc ≠ Fin.last n

@[simp] theorem head_stuck (α : Type) : (stuck α).head = none

theorem e_1410 :
     - 6 * z - 3 *  ~~~z - 11 * (z ^^^ t) - 5 *  ~~~(z &&&  ~~~t) - 1 * t - 1 *  ~~~(z &&& t) + 7 *  ~~~(z ||| t) + 21 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t)

@[simp]
lemma env_dec_image : enc '' (dec '' S) = S

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_3_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 15)) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8)

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 e_729 :
    2 * (x ||| y) + 2 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x &&& y) + 1 *  ~~~(x &&&  ~~~y) + 1 * x + 7 * y - 1 *  ~~~y + 3 *  ~~~x + 1 *  ~~~(x ||| y) + 2 * (x &&&  ~~~y) - 13 * (x &&& y) = 9 *  ~~~(x |||  ~~~y)

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

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem test13_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 → True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64 → False

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

theorem factorize3_proof : factorize3_before ⊑ factorize3_after

theorem e_2115 :
    5 * (e |||  ~~~(d ^^^ f)) - 6 * (e ^^^  ~~~(d &&& f)) + 2 * (e &&&  ~~~f) + 3 * (d &&& e) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 11 * (f ^^^  ~~~(d &&& (e &&& f))) + 11 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 *  ~~~f - 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (d ^^^ (e &&& f)) - 3 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 * (d ||| ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ (e &&& f)) + 5 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 3 * (e ^^^  ~~~(d ||| f)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 7 * (f &&& (d |||  ~~~e)) + 1 * (e |||  ~~~f) + 1 * (d &&& (e ^^^ f)) + 3 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 5 * ( ~~~d ||| (e &&& f)) + 7 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f &&&  ~~~(d ^^^ e)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&& ( ~~~e &&& f)) - 6 * (f |||  ~~~(d |||  ~~~e)) - 11 * e - 6 * (d ||| (e &&& f)) + 5 * (f ^^^ (d &&& (e ||| f))) + 1 * (e ^^^ (d &&& (e ^^^ f))) + 2 *  ~~~( ~~~d ||| (e ^^^ f)) - 2 *  ~~~(e ||| f) - 17 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~(d ||| ( ~~~e ||| f)) + 7 *  ~~~( ~~~d ||| (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 3 * ( ~~~d &&& ( ~~~e &&& f)) + 9 * ( ~~~d &&& (e &&& f)) - 13 * (d &&& ( ~~~e &&& f)) + 2 * (d &&& (e &&& f)) =  - 11 *  ~~~(e &&&  ~~~f)

theorem simplify_and_common_op_commute2_proof : simplify_and_common_op_commute2_before ⊑ simplify_and_common_op_commute2_after

theorem ashrsgt_03_10_proof : ashrsgt_03_10_before ⊑ ashrsgt_03_10_after

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

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

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_map (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s : State) :
  (processOneElem A S final s st (a, sa)).map[sa']? =
    match st.map[sa']? with

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

@[simp]
theorem Term.toBV_boolVar {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (v : Fin bcard) :
  Term.toBV benv nenv ienv penv tenv (.boolVar v) = benv v

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

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

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

theorem n14_trunc_of_lshr_thm (e e_1 : IntW 32) (e_2 : IntW 64) :
  icmp IntPred.ne
      (LLVM.and (trunc 32 (lshr e_2 (zext 64 (sub (const? 32 32) e_1)))) (shl e (add e_1 (const? 32 (-1)))))
      (const? 32 0) ⊑
    icmp IntPred.ne
      (LLVM.and (shl e (add e_1 (const? 32 (-1))))
        (trunc 32 (lshr e_2 (zext 64 (sub (const? 32 32) e_1) { «nneg» := true }))))
      (const? 32 0)

theorem e_2398 :
    2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * (e ^^^ (d ||| ( ~~~e ||| f))) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~d ||| (e ||| f)) - 7 * ((d &&& e) |||  ~~~(e ^^^ f)) - 3 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 11 * (f ^^^ (d ||| ( ~~~e ||| f))) + 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 11 *  ~~~(d &&&  ~~~d) + 1 *  ~~~(d ^^^ f) - 1 * (e ^^^ (d &&& f)) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 5 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (e ||| (d &&& f)) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 3 *  ~~~(d &&& (e ||| f)) + 11 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d ^^^ e) &&& (d ^^^ f)) + 11 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~d &&& (e ^^^ f)) - 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 5 *  ~~~(d &&& (e &&& f)) + 1 * (d ||| (e ||| f)) + 5 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 5 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * (f ^^^ (d &&& (e ||| f))) + 1 * (d ||| ( ~~~e &&& f)) + 4 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (f &&&  ~~~(d &&& e)) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) - 6 * ((d &&& e) ||| (e ^^^ f)) - 1 * e + 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (d |||  ~~~e) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 *  ~~~(d ^^^ e) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 3 * (d ^^^ (e &&& f)) + 1 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * (f ^^^ (d &&& e)) - 7 *  ~~~(d ^^^ (e ||| f)) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) - 3 * ( ~~~e ||| (d ^^^ f)) - 2 * ( ~~~e &&& (d ^^^ f)) - 7 *  ~~~(d &&& f) + 11 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 5 * (f &&& (d ^^^ e)) + 1 * (f ||| (d &&& e)) + 3 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 4 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * (f ^^^ (d ||| (e &&& f))) + 7 * ((d &&& e) |||  ~~~(e ||| f)) - 6 * (f ^^^  ~~~(d ||| e)) + 44 *  ~~~(d ||| (e ||| f)) + 20 *  ~~~(d ||| ( ~~~e ||| f)) + 30 *  ~~~( ~~~d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) + 16 * ( ~~~d &&& (e &&& f)) + 22 * (d &&& ( ~~~e &&& f)) + 22 * (d &&& (e &&& f)) = 11 * (e ^^^ (d ||| (e ||| f)))

theorem badimm1_proof : badimm1_before ⊑ badimm1_after

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

theorem src_x_and_nmask_eq_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → ofBool (0#8 == x &&& 0#8) = 1#1

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

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 positive_samevar_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬(x ≥ ↑32 ∨ x ≥ ↑32) → x ≥ ↑32 → False

theorem n4_thm (e : IntW 16) :
  LLVM.and (shl (zext 32 e) (const? 32 16)) (const? 32 (-1073741824)) ⊑
    LLVM.and (shl (zext 32 e) (const? 32 16) { «nsw» := false, «nuw» := true }) (const? 32 (-1073741824))

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

@[simp] theorem Lets.denote_addComToEnd
    {lets : Lets d Γ_in eff Γ_out} {com : Com d Γ_out eff t} :
    Lets.denote (lets.addComToEnd com) = fun V => (do
        let Vlets ← lets.denote V
        let Vbody ← com.denoteLets Vlets
        return Vbody
      )

theorem test34_thm (e : IntW 16) : trunc 16 (lshr (zext 32 e) (const? 32 8)) ⊑ lshr e (const? 16 8)

theorem e_204 :
     - 2 *  ~~~x - 2 * (x ^^^ y) - 11 *  ~~~(x ^^^ y) + 13 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) + 2 * (x &&&  ~~~y) =  - 11 * (x &&& y)

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

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

theorem t1_flags_nuw_nsw_second_thm (e e_1 e_2 : IntW 8) :
  sub (sub e_2 e_1) e { «nsw» := true, «nuw» := true } ⊑ sub e_2 (add e_1 e)

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

theorem pow2_or_zero_is_negative_commute_thm (e : IntW 8) :
  icmp IntPred.slt (LLVM.and (sub (const? 8 0) (mul (const? 8 42) e)) (mul (const? 8 42) e)) (const? 8 0) ⊑
    icmp IntPred.eq (mul e (const? 8 42)) (const? 8 (-128))

theorem or_and_xor_not_constant_commute1_proof : or_and_xor_not_constant_commute1_before ⊑ or_and_xor_not_constant_commute1_after

theorem lshr_and_and_proof : lshr_and_and_before ⊑ lshr_and_and_after

theorem masked_or_A_slightly_optimized_logical_proof : masked_or_A_slightly_optimized_logical_before ⊑ masked_or_A_slightly_optimized_logical_after

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 main6_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 3#32) &&& ofBool (x &&& 48#32 == 16#32) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x &&& 55#32 != 19#32))

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

theorem icmp_eq_or_z_or_pow2orz_fail_logic_or_proof : icmp_eq_or_z_or_pow2orz_fail_logic_or_before ⊑ icmp_eq_or_z_or_pow2orz_fail_logic_or_after

theorem e_569 :
    3 * x - 11 * y + 3 *  ~~~(x &&&  ~~~y) - 11 *  ~~~(x &&&  ~~~x) + 2 *  ~~~y + 7 * (x ||| y) + 6 *  ~~~(x ||| y) + 12 *  ~~~(x |||  ~~~y) + 9 * (x &&& y) = 1 * (x &&&  ~~~y)

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

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

theorem t1_proof : t1_before ⊑ t1_after

theorem e_1675 :
    1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 11 * (b ^^^ (a &&& ( ~~~b ||| c))) - 1 *  ~~~(b ^^^ c) + 2 *  ~~~(a &&&  ~~~a) + 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 6 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 6 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 *  ~~~( ~~~a &&& (b ||| c)) - 2 * b + 1 * (a ||| (b &&& c)) - 7 * (a &&& (b ||| c)) + 1 * (b ^^^ ( ~~~a ||| (b ||| c))) - 11 * (c |||  ~~~(a ^^^ b)) - 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 3 * (c &&&  ~~~(a &&&  ~~~b)) - 1 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 2 * (c &&&  ~~~(a ^^^ b)) + 22 *  ~~~(a ||| (b ||| c)) - 8 *  ~~~(a ||| ( ~~~b ||| c)) + 4 *  ~~~( ~~~a ||| (b ||| c)) + 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 17 * ( ~~~a &&& (b &&& c)) + 22 * (a &&& ( ~~~b &&& c)) + 32 * (a &&& (b &&& c)) = 6 * (c &&& (a ^^^ b)) - 2 *  ~~~(a ^^^ ( ~~~b &&& c))

theorem add_of_selects_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → BitVec.ofInt 32 (-2) + 2#32 = 0#32

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

theorem test_invalid_simplify_sub2_proof : test_invalid_simplify_sub2_before ⊑ test_invalid_simplify_sub2_after

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

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

theorem test4_thm (e e_1 : IntW 108) : sub e_1 (sub (const? 108 0) e) ⊑ add e_1 e

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

theorem zext_masked_bit_zero_to_larger_bitwidth_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x_1 ≥ ↑32 → x_1 ≥ ↑32 ∨ True ∧ ((x ^^^ -1#32) >>> x_1 &&& 1#32).msb = true → False

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

theorem t0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x ≥ ↑8 → (x_1 ^^^ -1#8).sshiftRight' x = x_1.sshiftRight' x ^^^ -1#8

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

theorem neg_sgt_42_proof : neg_sgt_42_before ⊑ neg_sgt_42_after

theorem n11_uge_slt_proof : n11_uge_slt_before ⊑ n11_uge_slt_after

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

theorem t20_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬x ≥ ↑16 → x_1 - truncate 8 (BitVec.ofInt 16 (-42) <<< x) = x_1 + truncate 8 (42#16 <<< x)

theorem e_55 :
    11 * (x |||  ~~~y) - 1 *  ~~~y - 2 *  ~~~(x &&&  ~~~x) - 8 *  ~~~(x ||| y) - 8 * (x &&&  ~~~y) =  - 2 *  ~~~(x |||  ~~~y) + 9 * (x &&& y)

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

theorem or_or_xor_commute1_proof : or_or_xor_commute1_before ⊑ or_or_xor_commute1_after

@[simp] theorem map_poison : f <$> poison = poison

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

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

theorem or_simplify_uge_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x ||| BitVec.ofInt 8 (-127) ||| x_1 &&& 127#8 ≤ᵤ x_1 &&& 127#8) = 0#1

theorem src_x_or_mask_ne_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (0#8 ||| x ^^^ -1#8 != -1#8) = ofBool (0#8 <ᵤ x)

theorem bool_add_ashr_proof : bool_add_ashr_before ⊑ bool_add_ashr_after

theorem p0_ult_65536_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ 65536#32) = 1#1 → ofBool (65535#32 <ᵤ x_1) = 1#1 → x = 65535#32

theorem e_1757 :
     - 5 *  ~~~( ~~~a &&& (b ||| c)) - 6 * (b &&&  ~~~(a &&&  ~~~c)) + 2 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 6 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 11 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 2 * (c ^^^ (a &&& ( ~~~b ||| c))) - 1 * (c &&& (a ^^^ b)) + 1 * ( ~~~c |||  ~~~(a ^^^ b)) + 2 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 1 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 11 * (a ^^^ c) - 1 * (a ^^^ b) + 5 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 3 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 5 * (a &&&  ~~~c) + 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 11 * (b ^^^ (a &&& ( ~~~b ||| c))) - 1 * (b &&&  ~~~(a ^^^ c)) - 3 *  ~~~c - 2 * (b ^^^ (a ||| (b &&& c))) - 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 7 * (b ^^^ ( ~~~a ||| (b &&& c))) - 1 *  ~~~(a &&& (b ^^^ c)) + 11 * (c ^^^ (a &&& b)) + 7 * (a ||| b) + 4 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 13 *  ~~~(a ||| (b ||| c)) + 6 *  ~~~(a ||| ( ~~~b ||| c)) - 2 *  ~~~( ~~~a ||| (b ||| c)) - 10 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) - 14 * ( ~~~a &&& (b &&& c)) - 21 * (a &&& ( ~~~b &&& c)) + 4 * (a &&& (b &&& c)) =  - 3 * ( ~~~b ||| (a ^^^ c))

theorem mul_constant_eq_proof : mul_constant_eq_before ⊑ mul_constant_eq_after

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

theorem lshr_exact_add_negative_shift_positive_proof : lshr_exact_add_negative_shift_positive_before ⊑ lshr_exact_add_negative_shift_positive_after

theorem sle_or_not_min_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-128))) (icmp IntPred.sle e_1 e) ⊑ const? 1 1

theorem t1_ult_slt_0_proof : t1_ult_slt_0_before ⊑ t1_ult_slt_0_after

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

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

theorem sge_to_ugt_thm (e : IntW 8) :
  icmp IntPred.sge (LLVM.xor e (const? 8 (-128))) (const? 8 15) ⊑
    icmp IntPred.ugt e (const? 8 (-114))

theorem src_is_mask_and_fail_mixed_proof : src_is_mask_and_fail_mixed_before ⊑ src_is_mask_and_fail_mixed_after

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

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

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

theorem tryFactorization_xor_ashr_lshr_proof : tryFactorization_xor_ashr_lshr_before ⊑ tryFactorization_xor_ashr_lshr_after

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

theorem PR2539_B_proof : PR2539_B_before ⊑ PR2539_B_after

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

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

@[grind =, simp]
lemma RawCNFA.addInitial_finals {m : RawCNFA A} : (m.addInitial s).finals = m.finals

theorem select_icmp_eq_0_and_1_or_1_proof : select_icmp_eq_0_and_1_or_1_before ⊑ select_icmp_eq_0_and_1_or_1_after

theorem shift_xor_multiuse_cmp_with_xor_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 testi64i32_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → ¬ofBool (-1#64 <ₛ x) = 1#1 → truncate 32 (x.sshiftRight' 63#64) ^^^ 127#32 = BitVec.ofInt 32 (-128)

theorem PR2539_B_thm (e : IntW 1) : icmp IntPred.slt e (const? 1 1) ⊑ const? 1 0

theorem test4_proof : test4_before ⊑ test4_after

theorem e_7 :
    11 *  ~~~(x &&&  ~~~y) - 11 * x + 11 * (x &&&  ~~~y) + 11 * (x &&& y) = 11 *  ~~~(x ||| y) + 11 * y

theorem bv_AndOrXor_2663 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.icmp LLVM.IntPred.ule e e_1) (LLVM.icmp LLVM.IntPred.ne e e_1) ⊑ LLVM.icmp LLVM.IntPred.uge e e_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 lshrult_03_05_thm.extracted_1._1 : ∀ (x : BitVec 4), ¬3#4 ≥ ↑4 → ofBool (x >>> 3#4 <ᵤ 5#4) = 1#1

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

theorem ashr_and_or_disjoint_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
        2#8 ≥ ↑8 ∨ True ∧ (x_1.srem 42#8 &&& (x.sshiftRight' 2#8 &&& 13#8) != 0) = true ∨ 2#8 ≥ ↑8) →
    ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
          2#8 ≥ ↑8 ∨ True ∧ (x &&& 52#8 &&& x_1.srem 42#8 <<< 2#8 != 0) = true) →
      (x_1.srem 42#8 ||| x.sshiftRight' 2#8 &&& 13#8) <<< 2#8 = x &&& 52#8 ||

theorem test69_proof : test69_before ⊑ test69_after

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

theorem or_and_not_constant_commute3_proof : or_and_not_constant_commute3_before ⊑ or_and_not_constant_commute3_after

theorem bool_add_ashr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → True ∧ (zeroExtend 2 x_1).uaddOverflow (zeroExtend 2 x) = true ∨ 1#2 ≥ ↑2 → False

theorem e_2179 :
    2 * (f ^^^ ( ~~~d ||| (e ||| f))) + 5 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (f ^^^  ~~~(d &&& e)) - 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 6 * (f ^^^ (d &&& e)) + 7 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 11 * (d ^^^ e) + 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 *  ~~~(e ^^^ f) - 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 2 * (f |||  ~~~(d ^^^ e)) + 11 * (d ||| (e &&& f)) - 6 *  ~~~(e ||| f) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 11 * (d ^^^ (e ||| f)) + 1 * (f &&& (d ^^^ e)) + 4 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 11 * (e ^^^ (d &&& (e ^^^ f))) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 2 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) + 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 5 *  ~~~(d ^^^ f) + 7 * (f ^^^ (d &&&  ~~~e)) + 4 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 4 *  ~~~(d &&& (e ^^^ f)) - 5 *  ~~~(d &&& (e &&& f)) - 7 * (d ||| f) + 2 * (f &&&  ~~~(d &&&  ~~~e)) - 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 3 * (f &&& (d ||| e)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 3 * ((d &&& e) ^^^ (e |||  ~~~f)) - 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 1 *  ~~~(d &&&  ~~~e) + 11 * ( ~~~e &&& (d ^^^ f)) + 1 * ( ~~~d ||| ( ~~~e ||| f)) + 5 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~(d ||| ( ~~~e ||| f)) - 57 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 27 * ( ~~~d &&& (e &&& f)) + 13 * (d &&& ( ~~~e &&& f)) + 20 * (d &&& (e &&& f)) =  - 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f))

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

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

theorem e_1928 :
     - 1 * (a &&&  ~~~c) + 1 * (a &&& (b ||| c)) + 1 *  ~~~( ~~~a &&& (b &&& c)) - 11 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 1 * b + 7 * ( ~~~a ||| (b &&& c)) + 11 *  ~~~(b |||  ~~~c) + 2 * (b |||  ~~~(a ||| c)) - 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 5 *  ~~~(a ^^^ b) + 1 * (b ||| (a &&& c)) + 3 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 11 * (b ||| (a ^^^ c)) + 4 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 3 * ((a ^^^ b) &&& (a ^^^ c)) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) - 3 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 6 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 3 * (c ^^^ (a &&& b)) + 5 * ((a &&& b) ^^^ (b ||| c)) - 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 7 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 3 * (a &&& b) + 1 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 1 *  ~~~(a ||| (b &&& c)) - 2 * (c ^^^  ~~~(a &&& (b &&& c))) - 1 * ((a |||  ~~~b) &&& (b ^^^ c)) - 1 * (b ^^^  ~~~(a &&& (b ||| c))) + 11 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 3 * (a ^^^ ( ~~~b &&& c)) - 6 * (b ||| c) + 3 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) + 3 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 * (a &&& ( ~~~b ||| c)) - 1 * ((a &&& c) ^^^ (b ||| c)) - 11 * (b ^^^ (a &&& (b ^^^ c))) - 1 * (b &&&  ~~~(a &&& c)) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 5 * (c ^^^ (a &&& ( ~~~b ||| c))) - 2 * (a ^^^ c) + 2 * (c ^^^  ~~~(a &&& (b ||| c))) - 22 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) - 19 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 31 * ( ~~~a &&& ( ~~~b &&& c)) - 13 * ( ~~~a &&& (b &&& c)) - 11 * (a &&& ( ~~~b &&& c)) - 36 * (a &&& (b &&& c)) =  - 11 * (b ^^^  ~~~(a ||| c)) + 3 *  ~~~( ~~~a ||| ( ~~~b &&& c))

theorem and_add_bool_to_select_proof : and_add_bool_to_select_before ⊑ and_add_bool_to_select_after

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

theorem trunc_lshr_trunc_thm (e : IntW 64) : trunc 8 (lshr (trunc 32 e) (const? 32 8)) ⊑ trunc 8 (lshr e (const? 64 8))

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

theorem e_711 :
    4 *  ~~~(x &&&  ~~~y) + 7 * (x |||  ~~~y) - 6 *  ~~~(x &&& y) + 4 *  ~~~(x ^^^ y) + 1 * (x ^^^ y) - 1 *  ~~~x - 2 * x - 2 *  ~~~y - 6 *  ~~~(x ||| y) + 2 * (x &&&  ~~~y) - 11 * (x &&& y) = 2 * y - 4 *  ~~~(x |||  ~~~y)

theorem src_proof : src_before ⊑ src_after

theorem shl_add_add_no_const_thm (e e_1 e_2 e_3 : IntW 8) :
  add (shl e_3 e_2) (add (shl e_1 e_2) e) ⊑ add (shl (add e_1 e_3) e_2) e

theorem nonexact_lshr_eq_noexactlog_thm (e : IntW 8) : icmp IntPred.eq (lshr (const? 8 90) e) (const? 8 30) ⊑ const? 1 0

theorem not_not_true_proof : not_not_true_before ⊑ not_not_true_after

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

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

theorem tryFactorization_add_mul_nuw_thm (e : IntW 32) :
  add (mul e (const? 32 3)) e { «nsw» := false, «nuw» := true } ⊑ shl e (const? 32 2)

theorem zext_sext_add_icmp_slt_1_proof : zext_sext_add_icmp_slt_1_before ⊑ zext_sext_add_icmp_slt_1_after

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

lemma one_shiftLeft_mul_eq_shiftLeft {A B : BitVec w} :
    (1 <<< B * A) = (A <<< B)

theorem test_add_nsw__nsw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true) →
      0#32 = (x ||| BitVec.ofInt 32 (-2147483648)) + 1#32

theorem ashr_eq_noexact_proof : ashr_eq_noexact_before ⊑ ashr_eq_noexact_after

theorem test55_proof : test55_before ⊑ test55_after

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

theorem fold_select_trunc_nsw_true_thm.extracted_1._2 : ∀ (x x_1 : BitVec 128),
  ¬(True ∧ signExtend 128 (truncate 1 x_1) ≠ x_1) → truncate 1 x_1 = 1#1 → x_1 = -1#128

theorem eq_nsw_rem_zero_thm (e : IntW 8) :
  icmp IntPred.eq (mul e (const? 8 (-5)) { «nsw» := true, «nuw» := false }) (const? 8 20) ⊑
    icmp IntPred.eq e (const? 8 (-4))

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

theorem t1_proof : t1_before ⊑ t1_after

theorem ashr_proof : ashr_before ⊑ ashr_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_5_after

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

theorem mul_constant_partial_nuw_eq_proof : mul_constant_partial_nuw_eq_before ⊑ mul_constant_partial_nuw_eq_after

theorem main12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) ||

theorem icmp_power2_and_icmp_shifted_mask_swapped_2147483648_805306368_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 805306368#32 != 805306368#32) &&& ofBool (x <ᵤ 1073741824#32) = ofBool (x <ᵤ 805306368#32)

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

theorem alive_Select_637 : forall (w : Nat) (Y C : Bitvec 1)
(X : Bitvec w)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (X) %v0;
  %v2 := op:const (C) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp eq  w %v3;
  %v5 := op:const (Y) %v0;
  %v6 := triple:%v4 %v1 %v5;
  %v7 := op:select w %v6
  dsl_ret %v7
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (X) %v0;
  %v2 := op:const (C) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp eq  w %v3;
  %v5 := op:const (Y) %v0;
  %v6 := triple:%v4 %v2 %v5;
  %v7 := op:select w %v6
  dsl_ret %v7
  ]

theorem n2_proof : n2_before ⊑ n2_after

theorem testi64i32_proof : testi64i32_before ⊑ testi64i32_after

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

theorem test8_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬32#128 ≥ ↑128 →
    ¬(True ∧ zeroExtend 64 x_1 <<< 32#64 >>> 32#64 ≠ zeroExtend 64 x_1 ∨
          32#64 ≥ ↑64 ∨ True ∧ (zeroExtend 64 x_1 <<< 32#64 &&& zeroExtend 64 x != 0) = true) →
      truncate 64 (zeroExtend 128 x_1 <<< 32#128 ||| zeroExtend 128 x) =
        zeroExtend 64 x_1 <<< 32#64 ||

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

theorem test_slt_proof : test_slt_before ⊑ test_slt_after

theorem scalar_i64_shl_and_signbit_eq_proof : scalar_i64_shl_and_signbit_eq_before ⊑ scalar_i64_shl_and_signbit_eq_after

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

theorem e_1781 :
    11 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 * (c |||  ~~~(a |||  ~~~b)) - 2 * (c ^^^ (a &&& (b ||| c))) - 2 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 3 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * ( ~~~a &&& (b ||| c)) + 3 *  ~~~(a |||  ~~~b) + 1 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 11 * (b |||  ~~~(a ||| c)) + 7 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 *  ~~~(a &&& (b ^^^ c)) - 2 * (a ^^^ ( ~~~b ||| c)) + 2 * (b ||| (a &&& c)) - 5 * (c &&&  ~~~(a &&&  ~~~b)) + 11 * (a ||| (b ^^^ c)) - 1 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 7 * ( ~~~b |||  ~~~(a ^^^ c)) + 3 * ((a &&& b) |||  ~~~(b ||| c)) - 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 5 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 11 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 4 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * ( ~~~b ||| (a ^^^ c)) + 2 * (a ||| (b &&& c)) - 5 *  ~~~(a ||| (b ||| c)) - 34 *  ~~~(a ||| ( ~~~b ||| c)) - 49 *  ~~~( ~~~a ||| (b ||| c)) - 30 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& ( ~~~b &&& c)) - 28 * ( ~~~a &&& (b &&& c)) - 35 * (a &&& ( ~~~b &&& c)) - 23 * (a &&& (b &&& c)) =  - 2 * (b ^^^ (a |||  ~~~c)) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c))

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

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

theorem e_997 :
     - 11 *  ~~~t - 2 * (z ^^^ t) - 3 *  ~~~(z ^^^ t) + 3 *  ~~~(z &&& t) - 8 *  ~~~(z |||  ~~~t) + 10 * (z &&&  ~~~t) - 4 * (z &&& t) =  - 7 *  ~~~(z &&&  ~~~t) - 4 *  ~~~(z ||| t)

theorem select_of_symmetric_selects_thm (e e_1 : IntW 32) (e_2 e_3 : IntW 1) :
  select e_3 (select e_2 e_1 e) (select e_2 e e_1) ⊑ select (LLVM.xor e_2 e_3) e e_1

theorem c_proof : c_before ⊑ c_after

theorem PR42691_4_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (BitVec.ofInt 32 (-2147483648) ≤ᵤ x) = 1#1 → ofBool (x == 0#32) = ofBool (x <ₛ 1#32)

theorem icmp_sgt8_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 125) ⊑
    icmp IntPred.eq e (const? 8 63)

lemma bisimul_eval (hsim : Bisimul R M₁ M₂) w :
    R.set_eq Q₁ Q₂ → R.set_eq (M₁.evalFrom Q₁ w) (M₂.evalFrom Q₂ w)

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → 46#599 ≥ ↑599 → False

theorem slt_zero_eq_ne_0_fail2_proof : slt_zero_eq_ne_0_fail2_before ⊑ slt_zero_eq_ne_0_fail2_after

theorem t1_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ x ≥ ↑16) → ¬15#16 - x ≥ ↑16 → 1#16 <<< x + -1#16 ||

theorem ashrslt_02_15_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 2)) (const? 4 (-1)) ⊑ icmp IntPred.slt e (const? 4 (-4))

theorem positive_samevar_shlnuwnsw_proof : positive_samevar_shlnuwnsw_before ⊑ positive_samevar_shlnuwnsw_after

theorem drop_nsw_trunc_proof : drop_nsw_trunc_before ⊑ drop_nsw_trunc_after

theorem test17_proof : test17_before ⊑ test17_after

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

theorem fold_sext_to_and_wrong2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-2147483647) == 128#32) = 0#1

theorem ashrslt_02_07_exact_proof : ashrslt_02_07_exact_before ⊑ ashrslt_02_07_exact_after

theorem main3d_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0))
        (icmp IntPred.eq (LLVM.and e (const? 32 16)) (const? 32 16)))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.eq (LLVM.and e (const? 32 23)) (const? 32 0))

theorem test12commuted_proof : test12commuted_before ⊑ test12commuted_after

theorem or_ne_notY_eq_1s_proof : or_ne_notY_eq_1s_before ⊑ or_ne_notY_eq_1s_after

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

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

theorem cmpeq_xor_cst1_proof : cmpeq_xor_cst1_before ⊑ cmpeq_xor_cst1_after

theorem a_proof : a_before ⊑ a_after

theorem sext_shl_trunc_smaller_proof : sext_shl_trunc_smaller_before ⊑ sext_shl_trunc_smaller_after

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

theorem rem_euclid_pow2_true_arm_folded_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ¬ofBool (x.srem 2#32 <ₛ 0#32) = 1#1 → x.srem 2#32 = x &&& 1#32

theorem masked_icmps_mask_notallzeros_bmask_mixed_4_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_4_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_4_logical_after

theorem narrow_sext_sub_proof : narrow_sext_sub_before ⊑ narrow_sext_sub_after

theorem e_124 :
    11 *  ~~~(x &&&  ~~~y) + 2 *  ~~~(x &&&  ~~~x) - 7 * (x ||| y) - 6 * x - 6 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) = 13 *  ~~~(x ||| y)

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

theorem test_uge_xor_proof : test_uge_xor_before ⊑ test_uge_xor_after

theorem zext_sext_add_icmp_slt_minus1_thm (e e_1 : IntW 1) :
  icmp IntPred.slt (add (zext 8 e_1) (sext 8 e)) (const? 8 (-1)) ⊑ const? 1 0

theorem sub_inc_proof : sub_inc_before ⊑ sub_inc_after

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

theorem wrongimm_proof : wrongimm_before ⊑ wrongimm_after

theorem e_1707 :
    7 *  ~~~( ~~~a &&& (b ||| c)) + 4 * (b ||| (a &&& c)) + 2 *  ~~~(a &&& (b ||| c)) - 5 * ((a ^^^ b) &&& (a ^^^ c)) - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ||| (a ^^^ c)) + 5 * (c ^^^ (a ||| ( ~~~b ||| c))) - 6 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * (b ^^^ (a |||  ~~~c)) - 2 * (a &&& ( ~~~b ||| c)) + 3 * (a |||  ~~~c) - 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 2 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * (c &&&  ~~~(a &&& b)) + 2 *  ~~~a + 3 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 6 * (a ^^^ c) - 2 * ((b &&& c) ||| (a &&& (b ||| c))) + 2 * (a ||| c) + 1 *  ~~~c - 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) + 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 3 *  ~~~(a ||| c) - 29 *  ~~~(a ||| (b ||| c)) - 25 *  ~~~(a ||| ( ~~~b ||| c)) - 17 *  ~~~( ~~~a ||| (b ||| c)) - 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 5 * ( ~~~a &&& (b &&& c)) - 16 * (a &&& ( ~~~b &&& c)) = 13 * (a &&& (b &&& c))

theorem alive_AndOrXor_2118___A__B__A___A__B : alive_AndOrXor_2118___A__B__A___A__B_src ⊑ alive_AndOrXor_2118___A__B__A___A__B_tgt

theorem alive_276_2 : alive_276_2_src ⊑ alive_276_2_tgt

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

theorem test_lshr__exact_is_unsafe_proof : test_lshr__exact_is_unsafe_before ⊑ test_lshr__exact_is_unsafe_after

theorem zext_ult_zext_proof : zext_ult_zext_before ⊑ zext_ult_zext_after

theorem uge_swap_or_not_max_commute_logical_proof : uge_swap_or_not_max_commute_logical_before ⊑ uge_swap_or_not_max_commute_logical_after

theorem zext_nneg_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ (x &&& 32767#16).msb = true) →
    zeroExtend 24 (x &&& 32767#16) &&& 8388607#24 = zeroExtend 24 (x &&& 32767#16)

theorem urem_illegal_type_c_proof : urem_illegal_type_c_before ⊑ urem_illegal_type_c_after

theorem narrow_sext_xor_proof : narrow_sext_xor_before ⊑ narrow_sext_xor_after

theorem sub_shl_same_amount_nuw_proof : sub_shl_same_amount_nuw_before ⊑ sub_shl_same_amount_nuw_after

theorem falseIffEq_eq_false_iff (n i : Nat) :
    falseIffEq n i = false ↔ i = n

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

theorem test35_with_trunc_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬ofBool (0#32 ≤ₛ truncate 32 x) = 1#1 → ofBool (x &&& 2147483648#64 == 0#64) = 1#1 → 100#32 = 60#32

theorem alive_fixed_size_integer: TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 8)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt 8 4) %v0
  dsl_ret %v1
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 8)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt 8 4) %v0
  dsl_ret %v1
  ]

theorem and_lshr_and_proof : and_lshr_and_before ⊑ and_lshr_and_after

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

theorem PR2844_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) = 1#1 →
    ¬True → 0#32 = zeroExtend 32 (ofBool (x != 0#32) &&& ofBool (BitVec.ofInt 32 (-638208502) <ₛ x))

omit [Fintype S] [LawfulBEq A] in
lemma processOneElem_preserves_map (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s s' : State) :
    let st' := processOneElem _ _  final s st (a, sa')
    st.map[sa]? = some s' →
    st'.map[sa]? = some s'

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

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

theorem fold_xor_zext_icmp_proof : fold_xor_zext_icmp_before ⊑ fold_xor_zext_icmp_after

theorem test95_thm (e : IntW 32) :
  zext 32 (LLVM.or (LLVM.and (lshr (trunc 8 e) (const? 8 6)) (const? 8 2)) (const? 8 40)) ⊑
    zext 32 (LLVM.or (LLVM.and (lshr (trunc 8 e) (const? 8 6)) (const? 8 2)) (const? 8 40) { «disjoint» := true })
      { «nneg» := true }

theorem eq_nsw_rem_nz_proof : eq_nsw_rem_nz_before ⊑ eq_nsw_rem_nz_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 test27_proof : test27_before ⊑ test27_after

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

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

theorem AvoidCollision_getLsbD_setWidth (m : Nat) (x : BitVec n) (i : Nat) :
    getLsbD (setWidth m x) i = (decide (i < m) && getLsbD x i)

theorem test7_proof : test7_before ⊑ test7_after

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

theorem test15i_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2#32 != 0#32) = 1#1 → ofBool (x &&& 2#32 == 0#32) = 1#1 → 577#32 = 1089#32

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

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

theorem e_1488 :
     - 6 * t - 1 *  ~~~z - 2 *  ~~~(z &&&  ~~~z) - 1 * (z ||| t) + 7 *  ~~~(z ^^^ t) + 1 *  ~~~(z &&& t) - 6 * (z ^^^ t) - 11 * (z |||  ~~~t) + 20 *  ~~~(z |||  ~~~t) + 19 * (z &&&  ~~~t) + 18 * (z &&& t) = 5 *  ~~~(z &&&  ~~~t) - 11 *  ~~~(z ||| t)

theorem add_const_const_sub_proof : add_const_const_sub_before ⊑ add_const_const_sub_after

theorem alive_AndOrXor_1253_A__AB___A__B  (w : Nat)   : alive_AndOrXor_1253_A__AB___A__B_src w  ⊑ alive_AndOrXor_1253_A__AB___A__B_tgt w

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

theorem t2_proof : t2_before ⊑ t2_after

theorem test15j_proof : test15j_before ⊑ test15j_after

theorem e_1810 :
     - 1 * (c ^^^  ~~~(a &&&  ~~~b)) + 4 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 11 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 7 * (c ^^^  ~~~(a &&& (b &&& c))) + 2 * (a ||| ( ~~~b &&& c)) - 2 * (b |||  ~~~(a ^^^ c)) + 4 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 2 * (a &&& c) + 2 *  ~~~(a ^^^ (b ||| c)) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 3 * (b &&& (a ||| c)) + 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 11 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 5 *  ~~~(a &&&  ~~~b) - 6 * (a ||| (b &&& c)) + 4 * (c |||  ~~~(a ||| b)) + 3 *  ~~~(a ||| ( ~~~b &&& c)) - 11 *  ~~~(a &&&  ~~~c) - 3 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 1 * ((a &&& c) |||  ~~~(b ||| c)) + 2 * (c ^^^ (a ||| (b &&& c))) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 11 * (a ||| (b ||| c)) + 11 * (b |||  ~~~(a |||  ~~~c)) + 1 * (b ^^^ (a &&&  ~~~c)) + 7 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 7 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 * (c ^^^ (a &&& (b ||| c))) - 18 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) - 9 *  ~~~( ~~~a ||| (b ||| c)) - 22 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 28 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * ( ~~~a &&& (b &&& c)) + 25 * (a &&& ( ~~~b &&& c)) - 22 * (a &&& (b &&& c)) =  - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 *  ~~~(a ||| (b &&& c))

theorem slt_zero_proof : slt_zero_before ⊑ slt_zero_after

theorem test_invalid_simplify_eq2_proof : test_invalid_simplify_eq2_before ⊑ test_invalid_simplify_eq2_after

theorem n13_overshift_proof : n13_overshift_before ⊑ n13_overshift_after

theorem lshrult_01_00_exact_proof : lshrult_01_00_exact_before ⊑ lshrult_01_00_exact_after

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

theorem test11f_proof : test11f_before ⊑ test11f_after

theorem add_shl_same_amount_partial_nsw1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨ x_1 ≥ ↑6 ∨ True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 + x <<< x_1 = (x_2 + x) <<< x_1

theorem select_icmp_x_and_8_ne_0_y_xor_8_proof : select_icmp_x_and_8_ne_0_y_xor_8_before ⊑ select_icmp_x_and_8_ne_0_y_xor_8_after

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

theorem sgt_swap_or_not_min_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-128))) (icmp IntPred.slt e e_1) ⊑
    icmp IntPred.ne e_1 (const? 8 (-128))

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

theorem mul_sel_op0_proof : mul_sel_op0_before ⊑ mul_sel_op0_after

theorem or_not_xor_common_op_commute5_proof : or_not_xor_common_op_commute5_before ⊑ or_not_xor_common_op_commute5_after

theorem pr33078_3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬12#16 ≥ ↑16 →
    12#16 ≥ ↑16 ∨ True ∧ zeroExtend 16 (truncate 4 (signExtend 16 x >>> 12#16)) ≠ signExtend 16 x >>> 12#16 → False

@[grind =, simp]
lemma mem_addTrans_tr (m : RawCNFA A) [LawfulBEq A] (a : A) (s1 s2 : State) :
    s' ∈ (m.addTrans a s1 s2).tr s b ↔
      (s = s1 ∧ s' = s2 ∧ b = a) ∨ s' ∈ m.tr s b

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

theorem test9_thm (e : IntW 1005) : LLVM.and e (const? 1005 (-1)) ⊑ e

theorem xor_ashr_not_fail_lshr_ashr_proof : xor_ashr_not_fail_lshr_ashr_before ⊑ xor_ashr_not_fail_lshr_ashr_after

theorem fork_hs_dc_equiv_snd (x : DCOp.TokenStream):
    (DCOp.fork (x)).snd ~ (HandshakeOp.fork (x)).snd

theorem multiuse3_proof : multiuse3_before ⊑ multiuse3_after

theorem par_proof : par_before ⊑ par_after

theorem ashrsgt_01_02_exact_proof : ashrsgt_01_02_exact_before ⊑ ashrsgt_01_02_exact_after

theorem gt_signed_to_small_signed_proof : gt_signed_to_small_signed_before ⊑ gt_signed_to_small_signed_after

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

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

theorem test4b_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(63#64 ≥ ↑64 ∨ 63#64 ≥ ↑64) → ofBool (x.sshiftRight' 63#64 ||| (0#64 - x) >>> 63#64 <ₛ 1#64) = ofBool (x <ₛ 1#64)

theorem nonexact_lshr_eq_noexactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (80#8 >>> x == 31#8) = 0#1

theorem or_xor_xor_normal_variant3_proof : or_xor_xor_normal_variant3_before ⊑ or_xor_xor_normal_variant3_after

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

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

theorem testi8i8_proof : testi8i8_before ⊑ testi8i8_after

theorem trunc_equality_nuw_proof : trunc_equality_nuw_before ⊑ trunc_equality_nuw_after

theorem trunc_shl_lshr_infloop_proof : trunc_shl_lshr_infloop_before ⊑ trunc_shl_lshr_infloop_after

@[simp] theorem Expr.args_toPure     : (e.toPure h).args = e.args

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

theorem src_x_and_nmask_uge_proof : src_x_and_nmask_uge_before ⊑ src_x_and_nmask_uge_after

theorem test17_thm (e : IntW 106) :
  icmp IntPred.eq (lshr e (const? 106 3)) (const? 106 1234) ⊑
    icmp IntPred.eq (LLVM.and e (const? 106 (-8))) (const? 106 9872)

theorem test1_proof : test1_before ⊑ test1_after

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

theorem icmp_equality_test_commute_icmp2_thm (e e_1 e_2 : IntW 64) :
  select (icmp IntPred.eq e_2 e_1) (icmp IntPred.eq e e_2)
      (select (LLVM.xor (icmp IntPred.eq e e_2) (const? 1 1)) (icmp IntPred.eq e e_1) (const? 1 0)) ⊑
    icmp IntPred.eq e e_1

theorem e_554 :
     - 2 *  ~~~(x ^^^ y) + 4 *  ~~~(x &&&  ~~~x) - 5 *  ~~~(x &&&  ~~~y) - 6 * y + 1 * x - 1 * (x ^^^ y) + 19 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) + 8 * (x &&& y) = 11 *  ~~~x - 14 *  ~~~(x ||| y)

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

theorem p_commutative4_proof : p_commutative4_before ⊑ p_commutative4_after

theorem n4_proof : n4_before ⊑ n4_after

@[simp]
lemma CNFA.SignedCmp_stateMax cmp : (autSignedCmp cmp).m.stateMax = 5

theorem xor_of_icmps_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (x == 1#64) ^^^ ofBool (0#64 <ₛ x) = ofBool (1#64 <ₛ x)

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

theorem sdiv_eq_smin_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.sdiv e_1 e) (const? 8 (-128)) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 (-128))) (icmp IntPred.eq e (const? 8 1))

theorem e_1865 :
     - 1 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 5 * (a ^^^ ( ~~~b &&& c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 2 *  ~~~(a |||  ~~~c) + 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 7 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 3 *  ~~~(a &&& (b ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 4 * (a ^^^ ( ~~~b ||| c)) + 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 11 *  ~~~a + 11 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 11 * (a &&& (b ^^^ c)) + 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 1 *  ~~~(a ^^^ c) + 11 *  ~~~(a &&& b) + 5 * (a &&& (b ||| c)) + 5 *  ~~~( ~~~a &&& (b &&& c)) - 3 * (a &&& c) - 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 4 * (a ||| (b ^^^ c)) - 7 * (b ^^^ (a ||| (b ^^^ c))) + 3 * (b ||| (a &&& c)) - 3 * (b &&& (a |||  ~~~c)) - 1 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 * ((a &&& c) ^^^ (b ||| c)) - 7 * ( ~~~c &&&  ~~~(a ^^^ b)) - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * (b ^^^  ~~~(a ||| c)) - 11 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 5 *  ~~~(a &&& c) + 2 * (a ||| c) - 6 * (b |||  ~~~(a |||  ~~~c)) - 11 * (a ^^^ (b ||| c)) + 4 * (c &&& (a ^^^ b)) - 5 * (c ||| (a &&&  ~~~b)) - 2 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 24 *  ~~~(a ||| (b ||| c)) - 23 *  ~~~(a ||| ( ~~~b ||| c)) + 22 *  ~~~( ~~~a ||| (b ||| c)) - 20 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 4 * ( ~~~a &&& ( ~~~b &&& c)) - 4 * ( ~~~a &&& (b &&& c)) - 1 * (a &&& (b &&& c)) = 35 * (a &&& ( ~~~b &&& c))

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

theorem not_add_proof : not_add_before ⊑ not_add_after

theorem test12_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 (zeroExtend 128 x_1 >>> (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 >>> zeroExtend 64 (x &&& 31#32)

theorem no_shift_no_xor_multiuse_or_proof : no_shift_no_xor_multiuse_or_before ⊑ no_shift_no_xor_multiuse_or_after

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

@[simp, grind=] lemma val_start_appendInr (r : DeleteRange ⟨ts⟩) :
    (r.appendInr (Γ := Γ)).start.val = r.start.val

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

theorem slt_or_not_max_commute_proof : slt_or_not_max_commute_before ⊑ slt_or_not_max_commute_after

theorem and_or1_commuted_proof : and_or1_commuted_before ⊑ and_or1_commuted_after

theorem icmp_eq_zext_eq_one_thm (e : IntW 32) :
  icmp IntPred.eq (zext 32 (icmp IntPred.eq e (const? 32 1))) e ⊑
    icmp IntPred.ult e (const? 32 2)

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

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

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

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

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

theorem test3_proof : test3_before ⊑ test3_after

theorem sext_multi_uses_thm (e : IntW 64) (e_1 : IntW 1) (e_2 : IntW 64) :
  add (mul e_2 (sext 64 e_1)) (sub (LLVM.xor e (sext 64 e_1)) (sext 64 e_1)) ⊑
    select e_1 (sub (const? 64 0) (add e_2 e)) e

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

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

theorem e_307 :
     - 6 * y - 1 *  ~~~(x &&& y) + 11 * (x ||| y) + 4 *  ~~~y - 4 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) - 3 * (x &&& y) = 2 * (x |||  ~~~y) + 1 *  ~~~(x ||| y)

theorem scalar_i32_signbit_shl_and_eq_nonzero_proof : scalar_i32_signbit_shl_and_eq_nonzero_before ⊑ scalar_i32_signbit_shl_and_eq_nonzero_after

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

theorem srem2_ashr_mask_proof : srem2_ashr_mask_before ⊑ srem2_ashr_mask_after

theorem fold_add_udiv_urem_thm (e : IntW 32) :
  add (shl (LLVM.udiv e (const? 32 10)) (const? 32 4)) (urem e (const? 32 10)) ⊑
    add (mul (LLVM.udiv e (const? 32 10)) (const? 32 6) { «nsw» := false, «nuw» := true }) e

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

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

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

theorem lshr_C1_add_A_C2_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 → x &&& 65535#32 ≥ ↑32 → False

theorem test_ule_xor_proof : test_ule_xor_before ⊑ test_ule_xor_after

theorem badimm1_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 9#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 9#16)) = 1#1 →
      7#8 ≥ ↑8 ∨
          9#16 ≥ ↑16 ∨
            True ∧ signExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 ∨
              True ∧ zeroExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 →
        False

@[simp]
lemma proj_accepts (M : NFA (BitVec m) σ) (f : Fin n → Fin m) :
    (M.proj f).accepts = BitVecs'.transport f '' M.accepts

theorem basic_preserve_nuw_nsw_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 ^^^ -1#8).saddOverflow x = true ∨ True ∧ (x_1 ^^^ -1#8).uaddOverflow x = true) →
    ¬(True ∧ x_1.ssubOverflow x = true ∨ True ∧ x_1.usubOverflow x = true) → (x_1 ^^^ -1#8) + x ^^^ -1#8 = x_1 - x

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

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬zeroExtend 32 x ≥ ↑32 →
    ¬(True ∧ x.msb = true ∨ zeroExtend 32 x ≥ ↑32) →
      x_1.sshiftRight' (zeroExtend 32 x) &&& 1#32 = x_1 >>> zeroExtend 32 x &&& 1#32

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

theorem icmp_eq_select_proof : icmp_eq_select_before ⊑ icmp_eq_select_after

theorem t20_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬x ≥ ↑16 → x_1 - truncate 8 (BitVec.ofInt 16 (-42) <<< x) = x_1 + truncate 8 (42#16 <<< x)

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

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

theorem bor_land_left1_proof : bor_land_left1_before ⊑ bor_land_left1_after

theorem logical_or_bitwise_or_icmps_comm1_thm (e e_1 e_2 : IntW 8) :
  select (icmp IntPred.eq (LLVM.and e_2 (shl (const? 8 1) e_1)) (const? 8 0)) (const? 1 1)
      (LLVM.or (icmp IntPred.eq e (const? 8 42)) (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 0))) ⊑
    select (icmp IntPred.eq (LLVM.and e_2 (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true })) (const? 8 0))
      (const? 1 1)
      (LLVM.or (icmp IntPred.eq e (const? 8 42))
        (icmp IntPred.eq (LLVM.and e_2 (const? 8 1)) (const? 8 0)))

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

theorem sdiv_mul_shl_nsw_proof : sdiv_mul_shl_nsw_before ⊑ sdiv_mul_shl_nsw_after

theorem or_and2_commuted_proof : or_and2_commuted_before ⊑ or_and2_commuted_after

theorem substitute_constant_and_eq_ugt_swap_logical_proof : substitute_constant_and_eq_ugt_swap_logical_before ⊑ substitute_constant_and_eq_ugt_swap_logical_after

theorem and_xor_or6_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_2 = 0 ∨ x_1 = 0 ∨ x = 0) →
    ¬(x_2 = 0 ∨ x = 0) → 42#64 / x_2 ||

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

theorem positive_biggershl_shlnuwnsw_ashrexact_proof : positive_biggershl_shlnuwnsw_ashrexact_before ⊑ positive_biggershl_shlnuwnsw_ashrexact_after

theorem demo (x y : BitVec 8) : (0#8 - x ||| y) + y = (y ||| 0#8 - x) + y

theorem not_xor_to_or_not4_proof : not_xor_to_or_not4_before ⊑ not_xor_to_or_not4_after

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

theorem negate_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  x_1 - zeroExtend 8 x = x_1 + signExtend 8 x

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

lemma dec_enc_w (bvs : BitVecs n) : (dec (enc bvs)).w = bvs.w

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

theorem sub_from_constant_of_add_with_constant_thm.extracted_1._1 : ∀ (x : BitVec 8),
  11#8 - (x + 42#8) = BitVec.ofInt 8 (-31) - x

theorem pow2_or_zero_is_negative_commute_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (0#8 - 42#8 * x &&& 42#8 * x <ₛ 0#8) = ofBool (x * 42#8 == BitVec.ofInt 8 (-128))

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

theorem icmp_shl_eq_1_thm (e : IntW 8) :
  icmp IntPred.eq (shl e (const? 8 1)) e ⊑ icmp IntPred.eq e (const? 8 0)

theorem ashrsgt_02_05_exact_proof : ashrsgt_02_05_exact_before ⊑ ashrsgt_02_05_exact_after

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

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

theorem fold_sext_to_and_wrong10_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-256) != 1#32) = 1#1

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

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

theorem a_thm (e : IntW 32) :
  LLVM.and (LLVM.srem e (const? 32 8)) (const? 32 1) ⊑ LLVM.and e (const? 32 1)

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

theorem slt_smin4_proof : slt_smin4_before ⊑ slt_smin4_after

theorem icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_proof : icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_before ⊑ icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail_after

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

theorem e_1799 :
    5 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) - 7 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 11 * (b ^^^ (a ||| ( ~~~b &&& c))) + 3 * (a &&& ( ~~~b ||| c)) - 1 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 6 *  ~~~(a &&&  ~~~b) + 2 * (b |||  ~~~(a |||  ~~~c)) + 1 * (b ^^^  ~~~(a &&&  ~~~c)) - 2 * (c ||| (a &&& b)) - 3 * (b ^^^ (a &&& ( ~~~b ||| c))) - 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 * (a ^^^ ( ~~~b &&& c)) + 3 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 *  ~~~(a ^^^ c) - 11 *  ~~~(a &&& b) + 7 *  ~~~( ~~~a ||| (b &&& c)) - 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 4 * (a ^^^ (b ||| c)) + 2 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 2 * (a &&& c) - 7 * (b ^^^ (a &&&  ~~~c)) - 5 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 2 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 3 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 5 * (c ^^^ ( ~~~a ||| (b ||| c))) + 24 *  ~~~(a ||| (b ||| c)) + 53 *  ~~~(a ||| ( ~~~b ||| c)) + 26 *  ~~~( ~~~a ||| (b ||| c)) + 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 40 * ( ~~~a &&& ( ~~~b &&& c)) + 46 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 39 * (a &&& (b &&& c)) =  - 5 *  ~~~(b ||| c) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c)))

theorem select_icmp_eq_and_1_0_or_2_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1#32 == 0#32) = 1#1 → ¬1#32 ≥ ↑32 → x ||

theorem trunc_sandwich_small_shift1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(19#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) →
    ¬(20#32 ≥ ↑32 ∨ True ∧ zeroExtend 32 (truncate 12 (x >>> 20#32)) ≠ x >>> 20#32) →
      truncate 12 (x >>> 19#32) >>> 1#12 = truncate 12 (x >>> 20#32) &&& 2047#12

theorem evalWith_eq_outputWith_carryWith_of_eq
    {p : FSM arity} {carryState : p.α → Bool} {n : Nat}
    (env : arity → BitStream)
    (outEnv : arity → Bool)
    (henv : (fun a => env a n) = outEnv) :
    p.evalWith carryState env n =
    p.outputWith (p.carryWith carryState env n) outEnv

theorem shift_mul:
    [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    %c1 = llvm.mlir.constant(1)
    %poty = llvm.shl %c1, %Y
    %r = llvm.mul %poty, %X
    llvm.return %r
  }] ⊑  [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    %r = llvm.shl %X, %Y
    llvm.return %r
  }]

theorem select_bittest_to_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 == 0#32) = 1#1 →
    True ∧ (x &&& 1#32).saddOverflow 3#32 = true ∨ True ∧ (x &&& 1#32).uaddOverflow 3#32 = true → False

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

theorem icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_proof : icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_before ⊑ icmp_power2_and_icmp_shifted_mask_2147483648_2147483647_after

theorem masked_and_notallzeroes_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 39)) (const? 32 0)) (const? 1 0) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0)

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

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

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

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

@[simp]
lemma product_accept {M : NFA α σ} {N : NFA α ς} :
    (q1, q2) ∈ (M.product accept? N).accept ↔ accept? (q1 ∈ M.accept) (q2 ∈ N.accept)

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

theorem slt_zero_ne_ne_b_proof : slt_zero_ne_ne_b_before ⊑ slt_zero_ne_ne_b_after

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

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

theorem test_sle_xor_proof : test_sle_xor_before ⊑ test_sle_xor_after

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

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

theorem uge_swap_and_max_logical_proof : uge_swap_and_max_logical_before ⊑ uge_swap_and_max_logical_after

theorem sub_shl_same_amount_proof : sub_shl_same_amount_before ⊑ sub_shl_same_amount_after

theorem lshr_or_and_proof : lshr_or_and_before ⊑ lshr_or_and_after

theorem icmp_ne_sext_slt_otherwise_nofold_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x <ₛ 2#32)) != x) = ofBool (x != signExtend 32 (ofBool (x <ₛ 2#32)))

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

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

theorem trunc_shl_ashr_infloop_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(3#64 ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬1#64 ≥ ↑64 → truncate 32 (x.sshiftRight' 3#64 <<< 2#64) = truncate 32 (x >>> 1#64) &&& BitVec.ofInt 32 (-4)

theorem trunc_shl_nuw_31_i32_i64_proof : trunc_shl_nuw_31_i32_i64_before ⊑ trunc_shl_nuw_31_i32_i64_after

theorem e_1927 :
     - 11 *  ~~~(a &&& (b &&& c)) - 7 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 4 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 11 * (c ^^^  ~~~(a |||  ~~~b)) + 2 * (b ^^^ c) + 3 *  ~~~(b &&& c) - 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 1 *  ~~~(a ||| b) - 2 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 *  ~~~(a ^^^ (b ^^^ c)) - 7 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 11 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 5 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 1 *  ~~~(b ^^^ c) + 11 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * (a &&& ( ~~~b ||| c)) - 5 *  ~~~(a &&& b) + 4 * (a ||| (b &&& c)) - 5 *  ~~~c - 2 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 2 * (b &&& (a |||  ~~~c)) + 7 * ( ~~~a ||| ( ~~~b ||| c)) + 1 * (b ||| c) + 11 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 1 *  ~~~(b &&&  ~~~c) - 2 *  ~~~a + 2 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 11 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 6 * ( ~~~b ||| (a ^^^ c)) - 6 * (b &&&  ~~~c) - 1 * (c ^^^ ( ~~~a ||| (b &&& c))) + 11 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ||| (a &&&  ~~~c)) + 1 * (b &&&  ~~~(a &&&  ~~~c)) - 11 * ( ~~~a ||| (b ||| c)) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 1 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) + 7 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~(a ||| ( ~~~b &&& c)) - 7 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 1 *  ~~~(a ^^^ ( ~~~b &&& c)) + 1 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| ( ~~~b ||| c))) + 12 *  ~~~(a ||| (b ||| c)) - 4 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 23 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 11 * (a &&& ( ~~~b &&& c)) - 31 * (a &&& (b &&& c)) =  - 35 *  ~~~( ~~~a ||| ( ~~~b ||| c))

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

theorem lshr_ne_both_equal_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 127) e) (const? 8 127) ⊑ icmp IntPred.ne e (const? 8 0)

theorem lshrugt_03_10_exact_proof : lshrugt_03_10_exact_before ⊑ lshrugt_03_10_exact_after

theorem lshrugt_01_03_proof : lshrugt_01_03_before ⊑ lshrugt_01_03_after

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

theorem e_1562 :
     - 1 * (b ||| (a ^^^ c)) + 4 *  ~~~( ~~~a ||| (b &&& c)) - 2 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 * (b ^^^ ( ~~~a ||| (b ||| c))) - 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 6 * ( ~~~b ||| (a ^^^ c)) - 7 * ((a &&& b) ^^^ (b |||  ~~~c)) + 7 *  ~~~(b ^^^ c) + 22 *  ~~~(a ||| (b ||| c)) + 8 *  ~~~( ~~~a ||| (b ||| c)) + 13 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 21 * ( ~~~a &&& ( ~~~b &&& c)) + 10 * ( ~~~a &&& (b &&& c)) + 18 * (a &&& ( ~~~b &&& c)) + 2 * (a &&& (b &&& c)) = 3 * ( ~~~a ||| (b ||| c)) - 11 *  ~~~(a ||| ( ~~~b ||| c))

theorem invert_both_cmp_operands_add_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (0#32 <ₛ x_1 + (x ^^^ -1#32)) = ofBool (x - x_1 <ₛ -1#32)

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

theorem udiv_i80_thm.extracted_1._1 : ∀ (x : BitVec 80), ¬(2#80 ≥ ↑80 ∨ 100#80 = 0) → 400#80 = 0 → False

theorem add_shl_same_amount_nuw_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨
        x_1 ≥ ↑64 ∨ True ∧ x <<< x_1 >>> x_1 ≠ x ∨ x_1 ≥ ↑64 ∨ True ∧ (x_2 <<< x_1).uaddOverflow (x <<< x_1) = true) →
    ¬(True ∧ x_2.uaddOverflow x = true ∨ True ∧ (x_2 + x) <<< x_1 >>> x_1 ≠ x_2 + x ∨ x_1 ≥ ↑64) →
      x_2 <<< x_1 + x <<< x_1 = (x_2 + x) <<< x_1

theorem shl_nsw_nuw_add_nsw_nuw_proof : shl_nsw_nuw_add_nsw_nuw_before ⊑ shl_nsw_nuw_add_nsw_nuw_after

theorem e_2498 :
    1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 5 *  ~~~(d |||  ~~~e) - 1 *  ~~~(e &&& f) + 3 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) + 1 *  ~~~(d &&&  ~~~d) - 11 * (e ^^^ (d ||| (e &&& f))) - 5 * (e ||| (d &&& f)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * (f ^^^  ~~~(d ||| (e &&& f))) + 7 * (f ^^^ (d &&& e)) - 5 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * (e |||  ~~~(d |||  ~~~f)) - 7 * ( ~~~d &&& (e ||| f)) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * d + 11 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f))) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 4 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * ( ~~~e &&&  ~~~(d ^^^ f)) + 7 * (e |||  ~~~(d ^^^ f)) + 4 * (e ||| f) + 7 *  ~~~(d &&& f) + 3 *  ~~~(d ^^^ (e ^^^ f)) - 6 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~d &&& (e ^^^ f)) - 2 * ((e &&& f) ||| (d &&& (e ||| f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ( ~~~d ||| ( ~~~e &&& f)) + 5 * ((d &&& f) ^^^ (e ||| f)) - 6 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 7 * (e ^^^  ~~~(d &&& (e ||| f))) - 11 * ( ~~~e ||| (d ^^^ f)) - 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 *  ~~~( ~~~d ||| (e &&& f)) - 2 *  ~~~f + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 5 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 2 * (d ||| (e &&& f)) + 2 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 11 *  ~~~( ~~~d &&& (e ^^^ f)) + 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f ^^^ (d &&& (e ||| f))) + 2 * (d ^^^ (e ^^^ f)) + 5 * ( ~~~e &&& (d ^^^ f)) - 7 * (d |||  ~~~e) + 11 * (f ^^^ (d ||| ( ~~~e ||| f))) - 2 * ((d &&& e) |||  ~~~(e ^^^ f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 * ( ~~~d ||| (e ^^^ f)) + 2 * (f &&& (d ^^^ e)) - 1 * (f ||| (d ^^^ e)) - 1 * (d ^^^ e) - 5 * ((d &&& e) ^^^ (e ||| f)) - 2 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d ||| (e ^^^ f)) - 6 * (e &&& (d ^^^ f)) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 *  ~~~(d ^^^ (e ||| f)) - 1 * (f ||| (d &&&  ~~~e)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 3 * (e ^^^ (d &&& (e ||| f))) + 3 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 20 *  ~~~(d ||| (e ||| f)) + 9 *  ~~~(d ||| ( ~~~e ||| f)) - 18 *  ~~~( ~~~d ||| (e ||| f)) - 38 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 22 * ( ~~~d &&& ( ~~~e &&& f)) + 13 * ( ~~~d &&& (e &&& f)) + 42 * (d &&& ( ~~~e &&& f)) - 5 * (d &&& (e &&& f)) = 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 5 * f

theorem reassoc_add_nuw_proof : reassoc_add_nuw_before ⊑ reassoc_add_nuw_after

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

theorem eq_umin3_proof : eq_umin3_before ⊑ eq_umin3_after

theorem xor_nosignbit_ashr_thm (e : IntW 32) :
  ashr (LLVM.xor e (const? 32 2147418112)) (const? 32 8) ⊑ LLVM.xor (ashr e (const? 32 8)) (const? 32 8388352)

theorem sge_or_max_proof : sge_or_max_before ⊑ sge_or_max_after

theorem xor_or_xor_common_op_commute4_proof : xor_or_xor_common_op_commute4_before ⊑ xor_or_xor_common_op_commute4_after

theorem demorgan_and_zext_proof : demorgan_and_zext_before ⊑ demorgan_and_zext_after

@[simp] theorem HVector.vars_nil :
    (HVector.nil : HVector (Var Γ) ([] : List d.Ty)).vars = ∅

theorem test_sext4_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → x ^^^ 1#1 = 1#1 → -1#32 = signExtend 32 1#1

theorem ashrsgt_02_05_exact_proof : ashrsgt_02_05_exact_before ⊑ ashrsgt_02_05_exact_after

theorem test_shl_nuw_nsw__none_are_safe_thm.extracted_1._4 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2) == 0#32) = 1#1 →
    ¬(True ∧ ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& BitVec.ofInt 32 (-2) ∨
          True ∧ (x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32 >>> 2#32 ≠ x_1 &&& BitVec.ofInt 32 (-2) ∨
            2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32) ≥ ↑64) →
      ¬(2#32 ≥ ↑32 ∨
            True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
              zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64) →
        x.sshiftRight' (zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2)) <<< 2#32)) =
          x.sshiftRight' (zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)))

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

theorem shl_nsw_add_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 1#32 = true ∨
        True ∧ ((-1#32) <<< (x + 1#32)).sshiftRight' (x + 1#32) ≠ -1#32 ∨ x + 1#32 ≥ ↑32) →
    True ∧ (BitVec.ofInt 32 (-2) <<< x).sshiftRight' x ≠ BitVec.ofInt 32 (-2) ∨ x ≥ ↑32 → False

theorem test11_proof : test11_before ⊑ test11_after

theorem and_ranges_overlap_single_proof : and_ranges_overlap_single_before ⊑ and_ranges_overlap_single_after
</all_available_lemmas>

<local_ctx>
import LeanMLIR.Framework.Basic

import LeanMLIR.Transforms.Rewrite.Match

open Ctxt (Valuation Var Hom)

variable (d : Dialect) [DialectSignature d]

structure Zipper (Γ_in : Ctxt d.Ty) (eff : EffectKind) (tys : List d.Ty) where
   
  {Γ_mid : Ctxt d.Ty}
   
  top : Lets d Γ_in eff Γ_mid
   
  bot : Com d Γ_mid eff tys

namespace Zipper

variable {d}

section Denote

variable [TyDenote d.Ty] [DialectDenote d] [Monad d.m]

def denote (zip : Zipper d Γ_in eff tys) (V_in : Valuation Γ_in) :
    eff.toMonad d.m (HVector toType tys) :=
  (zip.top.denote V_in) >>= zip.bot.denote

end Denote

section ToCom

variable {Γ_mid}

variable [TyDenote d.Ty] [DialectDenote d] [Monad d.m]

end ToCom

section InsertCom

variable [DecidableEq d.Ty]

def insertCom (zip : Zipper d Γ_in eff ty)
    (vs : HVector zip.Γ_mid.Var newTy) (newCom : Com d zip.Γ_mid eff newTy) :
    Zipper d Γ_in eff ty :=
  let top := zip.top.addComToEnd newCom
  
  let bot := zip.bot.changeVars <| newCom.outContextHom.with vs newCom.returnVars
  
  
  { top, bot }

def insertPureCom (zip : Zipper d Γ_in eff ty)
    (vs : HVector zip.Γ_mid.Var newTy)
    (newCom : Com d zip.Γ_mid .pure newTy) : Zipper d Γ_in eff ty :=
  zip.insertCom vs (newCom.castPureToEff eff)

section Lemmas

variable [TyDenote d.Ty] [DialectDenote d] [Monad d.m]
</local_ctx>

<target_theorem>
theorem denote_insertPureCom_eq_of [LawfulMonad d.m]
    {zip : Zipper d Γ_in eff tys} {vs}
    {newCom : Com d zip.Γ_mid .pure newTys} {V_in : Valuation Γ_in}
    (h : ∀ V : zip.top.ValidDenotation,
        newCom.denote V.val = vs.map V.val) :
    (zip.insertPureCom vs newCom).denote V_in = zip.denote V_in :=
</target_theorem>

