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
PUnit in Init.Prelude
Id in Init.Control.Id
List.map in Init.Prelude
Pure in Init.Prelude
Fin in Init.Prelude
Inhabited in Init.Prelude
BitVec in Init.Prelude
LawfulMonad in Init.Control.Lawful.Basic
id 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 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 map (f : Ty₁ → Ty₂) : Ctxt Ty₁ → Ctxt Ty₂ :=
  ofList ∘ (List.map f) ∘ toList

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

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

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

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

@[match_pattern] abbrev Ty.bitvec (w : Nat) : SLLVM.Ty := .arith (.bitvec w)

def test7_before := [llvm|
{
^0(%arg2 : i1024):
  %0 = llvm.mlir.constant(1 : i1024) : i1024
  %1 = llvm.mlir.constant(1023 : i1024) : i1024
  %2 = llvm.shl %0, %1 : i1024
  %3 = llvm.xor %arg2, %2 : i1024
  %4 = llvm.add %3, %2 : i1024
  "llvm.return"(%4) : (i1024) -> ()
}
]

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

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

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

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

def test_add_nuw_nsw__nsw_is_safe_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(-2147483648 : 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.or %arg39, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.add %4, %2 overflow<nsw,nuw> : i32
  %7 = "llvm.select"(%5, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def bool_zext_after := [llvm|
{
^0(%arg172 : i1):
  %0 = llvm.zext %arg172 : i1 to i16
  "llvm.return"(%0) : (i16) -> ()
}
]

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

def and_ranges_signed_pred_after := [llvm|
{
^0(%arg253 : i64):
  %0 = llvm.mlir.constant(-9223372036854775681) : i64
  %1 = llvm.mlir.constant(-9223372036854775553) : i64
  %2 = llvm.add %arg253, %0 : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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 llvm_shl_lower_riscv_nsw_16: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16)] where
  lhs := shl_llvm_nsw_16
  rhs := shl_riscv_16

def mkUnsatImpliesCircuit (lhs rhs : Circuit α) : Circuit α :=
  
  
  
  
  
  
  ~~~ lhs &&& rhs

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

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

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

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

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

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

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

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)

private def constantExprsEnumerationFromCache
    (previousLevelCache allLhsVars : EnumerativeSearchCache)
    (lhsSymVars rhsSymVars : Std.HashMap Nat FpExprWrapper)
    (ops: List (FpExpr w → FpExpr w → FpExpr w))
    : GeneralizerStateM ParsedFpExpr FpPredicate (ExpressionSynthesisResult × EnumerativeSearchCache) := do
  return ({}, {})

Lean.registerSimplePersistentEnvExtension in Lean.EnvExtension

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

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

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

Lean.withImportModules in Lean.Environment

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

def ule_or_not_min_before := [llvm|
{
^0(%arg272 : i427, %arg273 : i427):
  %0 = llvm.mlir.constant(0 : i427) : i427
  %1 = llvm.icmp "ule" %arg272, %arg273 : i427
  %2 = llvm.icmp "ne" %arg272, %0 : i427
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def add_multiuse_const_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64) ] where
  lhs := add_multiuse_const_llvm_i64
  rhs := add_multiuse_const_riscv_i64

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

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

def sub_ule_sext_after := [llvm|
{
^0(%arg121 : i1, %arg122 : i8, %arg123 : i8):
  %0 = llvm.icmp "eq" %arg122, %arg123 : i8
  %1 = llvm.or %0, %arg121 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def llvm_ashr_lower_riscv_no_flag_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := ashr_llvm_no_flag_32
  rhs := ashr_riscv_32

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

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

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

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

def negative_not_next_power_of_two_after := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(192 : i32) : i32
  %1 = llvm.icmp "ult" %arg5, %0 : i32
  "llvm.return"(%1) : (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 zext_add_after := [llvm|
{
^0(%arg15 : i8):
  %0 = llvm.mlir.constant(44 : i8) : i8
  %1 = llvm.add %arg15, %0 : i8
  %2 = llvm.and %1, %arg15 : i8
  %3 = llvm.zext %2 : i8 to i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

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

def select_of_symmetric_selects_negative1_after := [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, %0, %arg29) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

instance : HydrableGetGenPredSize GenBVPred where
  getGenPredSize e := e.size

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

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

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

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

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

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

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

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

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

def shl_trunc_bigger_ashr_after := [llvm|
{
^0(%arg42 : i32):
  %0 = llvm.mlir.constant(9 : i32) : i32
  %1 = llvm.mlir.constant(-8 : i24) : i24
  %2 = llvm.ashr %arg42, %0 : i32
  %3 = llvm.trunc %2 overflow<nsw> : i32 to i24
  %4 = llvm.and %3, %1 : i24
  "llvm.return"(%4) : (i24) -> ()
}
]

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

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

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

def n3_before := [llvm|
{
^0(%arg1 : i8, %arg2 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg2 : i8
  %2 = llvm.xor %1, %0 : i8
  %3 = llvm.icmp "ule" %2, %arg1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def select_xor_icmp_bad_6_before := [llvm|
{
^0(%arg169 : i32, %arg170 : i32, %arg171 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "ne" %arg169, %0 : i32
  %2 = llvm.xor %arg169, %arg171 : i32
  %3 = "llvm.select"(%1, %arg170, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

Lean.withoutModifyingState in Lean.Util.MonadBacktrack

def Com.letPure (e : Expr d Γ .pure t) (body : Com d (e.outContext) eff u) : Com d Γ eff u :=
  body.var (e.castPureToEff eff)

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

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

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

def mkDecideTy : SolverM Expr := do
  let ty ← mkEq (mkNatLit 1) (mkNatLit 1)
  debugCheck ty
  return ty

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

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

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

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

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

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

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

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

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 sextbool_add_commute_before := [llvm|
{
^0(%arg10 : i1, %arg11 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.urem %arg11, %0 : i32
  %2 = llvm.sext %arg10 : i1 to i32
  %3 = llvm.add %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def foo_after := [llvm|
{
^0(%arg8 : i16):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.and %arg8, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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 c : DCOp.ValueStream (BitVec 1) := ofList [some 1, none, some 0, some 1, some 0]

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

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

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

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

Eq.mp in Init.Core

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

def positive_different_trunc_both_after := [llvm|
{
^0(%arg37 : i32):
  %0 = llvm.mlir.constant(16384 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(128 : i16) : i16
  %3 = llvm.mlir.constant(256 : i16) : i16
  %4 = llvm.and %arg37, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.trunc %arg37 : i32 to i16
  %7 = llvm.add %6, %2 : i16
  %8 = llvm.icmp "ult" %7, %3 : i16
  %9 = llvm.and %5, %8 : i1
  "llvm.return"(%9) : (i1) -> ()
}
]

def flipAccept (M : NFA α σ) : NFA α σ where
  start := M.start
  accept := M.accept.compl
  step := M.step

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

def tryFactorization_add_mul_nuw_mul_var_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32):
  %0 = llvm.mul %arg0, %arg1 overflow<nuw> : i32
  %1 = llvm.mul %arg0, %arg2 overflow<nuw> : i32
  %2 = llvm.add %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

def masked_bit_clear_commute_after := [llvm|
{
^0(%arg77 : i32, %arg78 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.srem %0, %arg77 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.lshr %4, %arg78 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def 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 shl_lshr_eq_amt_multi_use_before := [llvm|
{
^0(%arg7 : i44):
  %0 = llvm.mlir.constant(33 : i44) : i44
  %1 = llvm.shl %arg7, %0 : i44
  %2 = llvm.lshr %1, %0 : i44
  %3 = llvm.add %1, %2 : i44
  "llvm.return"(%3) : (i44) -> ()
}
]

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

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

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 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 t0_after := [llvm|
{
^0(%arg22 : i32, %arg23 : i32):
  %0 = llvm.sub %arg23, %arg22 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

def add_mask_ashr27_i32_before := [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 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def t2_after := [llvm|
{
^0(%arg237 : i64, %arg238 : i32):
  %0 = llvm.zext nneg %arg238 : i32 to i64
  %1 = llvm.lshr %arg237, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

Lean.findSysroot in Lean.Util.Path

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

def inputSource : DCOp.TokenStream := ofList [some (), none, some (), some (), none]

def timeElapsedMs (x : IO α) : IO (α × Int) := do
    let tStart ← IO.monoMsNow
    let b ← x
    let tEnd ← IO.monoMsNow
    return (b, tEnd - tStart)

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

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

def 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 lor_band_right1_before := [llvm|
{
^0(%arg22 : i1, %arg23 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = "llvm.select"(%arg22, %0, %arg23) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %2 = llvm.and %arg22, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

def Term.Ctx.Env.get {tcard : Nat}
  {wcard : Nat} {wenv : Fin wcard → Nat}
  {tctx : Term.Ctx wcard tcard}
  (tenv : tctx.Env wenv) (i : Nat) (hi : i < tcard) :
  BitVec ((tctx ⟨i, hi⟩).toNat wenv) :=
  tenv ⟨i, hi⟩

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

def src_is_mask_const_sle_before := [llvm|
{
^0(%arg46 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(31 : i8) : i8
  %2 = llvm.xor %arg46, %0 : i8
  %3 = llvm.and %2, %1 : i8
  %4 = llvm.icmp "sle" %3, %2 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

def mul {w : Nat} (l : List (BitVec w)) : BitVec w :=
  List.foldr BitVec.mul (1#w) l

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

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

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

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

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

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

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

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

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

def add_shl_rhs_constant_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64),Ty.llvm (.bitvec 64) ] where
  lhs := add_shl_rhs_constant_llvm
  rhs := add_shl_rhs_constant_riscv

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

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

def t10_shift_by_one_before := [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 %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 land_land_left1_after := [llvm|
{
^0(%arg102 : i1, %arg103 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = "llvm.select"(%arg102, %arg103, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%1) : (i1) -> ()
}
]

def negation_of_increment_via_or_with_no_common_bits_set_before := [llvm|
{
^0(%arg71 : i8, %arg72 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %arg72, %0 : i8
  %2 = llvm.or %1, %0 : i8
  %3 = llvm.sub %arg71, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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 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 test51_before := [llvm|
{
^0(%arg133 : i64, %arg134 : i1):
  %0 = llvm.mlir.constant(-2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.trunc %arg133 : i64 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = llvm.or %2, %1 : i32
  %5 = "llvm.select"(%arg134, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = llvm.sext %5 : i32 to i64
  "llvm.return"(%6) : (i64) -> ()
}
]

instance : Lean.ToExpr RegIndex := inherit

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

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

def 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 shift_xor_multiuse_cmp_xor_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32, %arg35 : 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 %arg32, %0 : i32
  %4 = llvm.icmp "ne" %1, %3 : i32
  %5 = llvm.xor %arg33, %2 : i32
  %6 = "llvm.select"(%4, %arg33, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg34, %arg35) <{"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 test_mul_nsw__nsw_is_safe_after := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.or %arg5, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def fold_select_trunc_nuw_false_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.trunc %arg8 overflow<nuw> : i8 to i1
  %2 = "llvm.select"(%1, %arg9, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

noncomputable def toArgResult
    (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInl mapIn) :
    let args := mapOut.getPureExpr_eq_some.choose
    MatchArgResult lets matchLets args matchExpr.args mapIn :=
  ⟨mapOut.1, by admit /- proof elided -/
  ⟩

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

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

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

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

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

def PostLegalizerCombiner_RISCV: List (Σ Γ,RISCVPeepholeRewrite  Γ) :=
    RISCV_identity_combines ++
    commute_int_constant_to_rhs ++
    simplify_neg ++
    mulh_to_lshr

Lean.mkIdent in Init.Meta.Defs

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

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

def demorgan_nor_use2bc_after := [llvm|
{
^0(%arg20 : i8, %arg21 : i8):
  %0 = llvm.mlir.constant(23 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mul %arg21, %0 : i8
  %3 = llvm.xor %arg20, %1 : i8
  %4 = llvm.or %arg21, %3 : i8
  %5 = llvm.mul %4, %0 : i8
  %6 = llvm.xor %4, %1 : i8
  %7 = llvm.sdiv %6, %5 : i8
  %8 = llvm.sdiv %7, %2 : i8
  "llvm.return"(%8) : (i8) -> ()
}
]

def logical_or_logical_or_icmps_comm1_after := [llvm|
{
^0(%arg157 : i8, %arg158 : i8, %arg159 : 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" %arg158, %0 : i8
  %5 = llvm.and %arg157, %1 : i8
  %6 = llvm.shl %1, %arg159 overflow<nuw> : i8
  %7 = llvm.and %arg157, %6 : i8
  %8 = llvm.icmp "eq" %5, %2 : i8
  %9 = llvm.icmp "eq" %7, %2 : i8
  %10 = "llvm.select"(%9, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = "llvm.select"(%10, %3, %8) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%11) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def intro_example_rhs := [LV| {
  ^entry (%arg: i64, %amount: i64):
    llvm.return %arg : i64
  }]

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

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

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

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

def test15_before := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(-1431655767 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg40, %0 : i32
  %3 = llvm.xor %2, %0 : i32
  %4 = llvm.add %arg41, %1 : i32
  %5 = llvm.add %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def union' (M : NFA α σ) (N : NFA α ς) : NFA α (σ × ς) := product Or M N

def rewrite_e : PeepholeRewrite DCPlus [.tokenstream, .valuestream 1] [.tokenstream] :=
  { lhs := [DCPlus_com| {
      ^entry(%c : !ValueStream_1, %d : !TokenStream):
        %forkc = "DCPlus.forkVal" (%c) : (!ValueStream_1) -> (!ValueStream2_1)
        %forkc' = "DCPlus.forkVal" (%c) : (!ValueStream_1) -> (!ValueStream2_1)
        %fstc = "DCPlus.fstValPure" (%forkc) : (!ValueStream2_1) -> (!ValueStream_1)
        %sndc = "DCPlus.sndValPure" (%forkc) : (!ValueStream2_1) -> (!ValueStream_1)
        %trdc = "DCPlus.fstValPure" (%forkc') : (!ValueStream2_1) -> (!ValueStream_1)
        %forkd = "DCPlus.fork" (%d) : (!TokenStream) -> (!TokenStream2)
        %fstd = "DCPlus.fst" (%forkd) : (!TokenStream2) -> (!TokenStream)
        %sndd = "DCPlus.snd" (%forkd) : (!TokenStream2) -> (!TokenStream)
        %supp1 = "DCPlus.supp" (%fstc, %fstd) : (!ValueStream_1, !TokenStream) -> (!TokenStream)
        %not = "DCPlus.not" (%sndc) : (!ValueStream_1) -> (!ValueStream2_1)
        %supp2 = "DCPlus.supp" (%not, %sndd) : (!ValueStream_1, !TokenStream) -> (!TokenStream)
        %mux = "DCPlus.mux" (%supp1, %supp2, %trdc) : (!TokenStream, !TokenStream, !ValueStream_1) -> (!TokenStream)
        "return" (%mux) : (!TokenStream) -> ()
      }],
    rhs := [DCPlus_com| {
      ^entry(%c : !ValueStream_1, %d : !TokenStream):
        "return" (%d) : (!TokenStream) -> ()
      }],
    correct :=
    by admit /- proof elided -/

def select_icmp_ne_0_and_4096_xor_32_after := [llvm|
{
^0(%arg207 : i32, %arg208 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.lshr %arg207, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %arg208 : i32
  %5 = llvm.xor %4, %1 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

List.filter in Init.Data.List.Basic

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

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

def llvm_const_lower_riscv_li_36 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_36, rhs:= liRiscv_36,
   correct := by admit /- proof elided -/

def add_nsw_mul_nsw_before := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.add %arg33, %arg33 overflow<nsw> : i16
  %1 = llvm.add %0, %arg33 overflow<nsw> : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

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

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

def lshrult_01_15_after := [llvm|
{
^0(%arg352 : i4):
  %0 = llvm.mlir.constant(true) : 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 isSuccess : DecideIfZerosOutput → Bool
  | .safetyFailure _ => false
  | .exhaustedIterations _ => false
  | .provenByKIndCycleBreaking .. => true

def sub_shl_same_amount_before := [llvm|
{
^0(%arg29 : i6, %arg30 : i6, %arg31 : i6):
  %0 = llvm.shl %arg29, %arg31 : i6
  %1 = llvm.shl %arg30, %arg31 : i6
  %2 = llvm.sub %0, %1 : i6
  "llvm.return"(%2) : (i6) -> ()
}
]

def main12_after := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(32896 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mlir.constant(2 : i32) : i32
  %4 = llvm.and %arg20, %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 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) -> ()
}
]

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

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

def 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 Expr.mkToFSM (self : Expr) : MetaM Expr :=
  mkAppM ``FSMPredicateSolution.toFSM #[self]

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

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

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

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

def invert_both_cmp_operands_sub_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(-43 : i32) : i32
  %1 = llvm.add %arg36, %arg37 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

Int.natAbs in Init.Data.Int.Basic

def uge_or_max_before := [llvm|
{
^0(%arg174 : i8, %arg175 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "uge" %arg174, %arg175 : i8
  %2 = llvm.icmp "eq" %arg174, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (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 ashrsgt_01_13_after := [llvm|
{
^0(%arg304 : i4):
  %0 = llvm.mlir.constant(-5 : i4) : i4
  %1 = llvm.icmp "sgt" %arg304, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

def 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 llvm_const_lower_riscv_li_10 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_10, rhs:= liRiscv_10,
   correct := by admit /- proof elided -/

instance : Zero Term := ⟨zero⟩

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

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

def XorZextXor_before := [llvm|
{
^0(%arg6 : i3):
  %0 = llvm.mlir.constant(3 : i3) : i3
  %1 = llvm.mlir.constant(12 : i5) : i5
  %2 = llvm.xor %arg6, %0 : i3
  %3 = llvm.zext %2 : i3 to i5
  %4 = llvm.xor %3, %1 : i5
  "llvm.return"(%4) : (i5) -> ()
}
]

def test7_after := [llvm|
{
^0(%arg0 : i47):
  %0 = llvm.mlir.constant(-70368744177664 : i47) : i47
  %1 = llvm.mlir.constant(70368040490200 : i47) : i47
  %2 = llvm.and %arg0, %0 : i47
  %3 = llvm.or disjoint %2, %1 : i47
  "llvm.return"(%3) : (i47) -> ()
}
]

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

RV64.add in RISCV.Instructions

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

def test_sdiv_canonicalize_op0_exact_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.sdiv exact %arg13, %arg14 : i32
  %2 = llvm.sub %0, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

def xor_andn_commute2_before := [llvm|
{
^0(%arg70 : i33, %arg71 : i33):
  %0 = llvm.mlir.constant(42 : i33) : i33
  %1 = llvm.mlir.constant(-1 : i33) : i33
  %2 = llvm.udiv %0, %arg71 : i33
  %3 = llvm.xor %arg70, %1 : i33
  %4 = llvm.and %2, %3 : i33
  %5 = llvm.xor %4, %arg70 : i33
  "llvm.return"(%5) : (i33) -> ()
}
]

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

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

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

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

def swapLastTwo (x : Fin (n + 2)) : Fin (n + 2) :=
  if x = Fin.last (n + 1) then n else if x = n then Fin.last (n + 1) else x

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

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

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

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

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

def sink (x : Stream α) : Stream (BitVec 1) :=
  Stream.corec (β := Stream α) (x) fun (x) => (none, x.tail)

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

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

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

def test70_after := [llvm|
{
^0(%arg150 : i8, %arg151 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.lshr %arg150, %0 : i8
  %3 = llvm.and %2, %1 : i8
  %4 = llvm.or %arg151, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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 bools2_logical_commute1_and2_after := [llvm|
{
^0(%arg46 : i1, %arg47 : i1, %arg48 : i1):
  %0 = "llvm.select"(%arg48, %arg46, %arg47) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

def Lets.getPureExprAux {Γ₁ Γ₂ : Ctxt d.Ty} {t} : Lets d Γ₁ eff Γ₂ → (v : Var Γ₂ t) →
    Option (Σ ts, (Var ⟨ts⟩ t) × Expr d (Γ₂.dropUntil v) .pure ts)
  | .nil, _ => none
  | .var (Γ_out := Γ_out) (t := t) lets e, v => by admit /- proof elided -/
    | right v =>
        apply cast ?_ <| Lets.getPureExprAux lets v
        simp
    | left v =>
        have h : (Ctxt.dropUntil t v) ++ Γ_out = e.outContext.dropUntil v.appendInl := by admit /- proof elided -/

def sdiv_shl_pair1_before := [llvm|
{
^0(%arg43 : i32, %arg44 : i32, %arg45 : i32):
  %0 = llvm.shl %arg43, %arg44 overflow<nsw> : i32
  %1 = llvm.shl %arg43, %arg45 overflow<nsw,nuw> : i32
  %2 = llvm.sdiv %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

def test5_before := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(30000 : i32) : i32
  %1 = llvm.urem %arg32, %0 : i32
  %2 = llvm.sext %1 : i32 to i64
  "llvm.return"(%2) : (i64) -> ()
}
]

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 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 uge_swap_or_max_after := [llvm|
{
^0(%arg166 : i8, %arg167 : i8):
  %0 = llvm.icmp "ule" %arg167, %arg166 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def p_commutative0_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg34, %arg32 : i32
  %2 = llvm.xor %arg34, %0 : i32
  %3 = llvm.and %arg33, %2 : i32
  %4 = llvm.or disjoint %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def t8_lshr_exact_flag_preservation_before := [llvm|
{
^0(%arg27 : i32, %arg28 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.sub %0, %arg28 : i32
  %3 = llvm.lshr exact %arg27, %2 : i32
  %4 = llvm.add %arg28, %1 : i32
  %5 = llvm.lshr exact %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def Lets.addComToEnd {Γ_out} {eff} (lets : Lets d Γ_in eff Γ_out) :
      (com : Com d Γ_out eff ty) → Lets d Γ_in eff com.outContext
  | Com.rets _       => lets
  | Com.var e body => addComToEnd (Lets.var lets e) body

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

def logic_and_logic_or_2_before := [llvm|
{
^0(%arg174 : i1, %arg175 : i1, %arg176 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg175, %arg174, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg174, %arg176, %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) -> ()
}
]

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

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

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

def lshr_eq_opposite_msb_before := [llvm|
{
^0(%arg163 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.lshr %0, %arg163 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (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 test_after := [llvm|
{
^0(%arg0 : i26):
  "llvm.return"(%arg0) : (i26) -> ()
}
]

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

@[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 test15f_after := [llvm|
{
^0(%arg22 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(256 : i32) : i32
  %2 = llvm.shl %arg22, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def not_ashr_not_bitwidth_mask_before := [llvm|
{
^0(%arg97 : i8, %arg98 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg97, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.and %3, %arg98 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

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

def t10_constants_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i64):
  %0 = llvm.mlir.constant(26 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.trunc %arg15 : i64 to i32
  %3 = llvm.lshr %arg14, %0 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def mkInitCarryAssignCircuitAux {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (s : p.α):
  Circuit (Vars p.α arity 0) :=
    Circuit.xor
      (Circuit.ofBool (p.initCarry s))
      (Circuit.var true <| Vars.stateN s 0)

def t0_before := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(32 : i8) : i8
  %1 = llvm.sdiv exact %arg22, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

@[simp_denote]
def add_b31_llvm_i64 := [LV| {
    ^entry (%x: i64):
    %0 = llvm.mlir.constant (2147483648) : i64
    %1 = llvm.add %x, %0 : i64
    llvm.return %1 : i64
  }]

def lt_unsigned_to_small_negative_before := [llvm|
{
^0(%arg42 : i8):
  %0 = llvm.mlir.constant(-17 : i32) : i32
  %1 = llvm.zext %arg42 : i8 to i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

def test1_before := [llvm|
{
^0(%arg19 : i32, %arg20 : i8):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.zext %arg20 : i8 to i32
  %2 = llvm.ashr %arg19, %1 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

Int.instAdd in Init.Data.Int.Basic

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

def mul_constant_eq_nsw_after := [llvm|
{
^0(%arg130 : i32, %arg131 : i32):
  %0 = llvm.icmp "eq" %arg130, %arg131 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

def reduce_xor_common_op_commute1_after := [llvm|
{
^0(%arg7 : i4, %arg8 : i4, %arg9 : i4):
  %0 = llvm.xor %arg8, %arg9 : i4
  %1 = llvm.or %0, %arg7 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

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

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

def mul_unkV_evenC_ne_after := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(4611686018427387903) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.and %arg12, %0 : i64
  %3 = llvm.icmp "ne" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

bne in Init.Core

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

def lshrugt_03_05_exact_after := [llvm|
{
^0(%arg184 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 llvm_const_lower_riscv_li_33 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_33, rhs:= liRiscv_33,
   correct := by admit /- proof elided -/

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

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

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

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 srem_constant_dividend_select_of_constants_divisor_before := [llvm|
{
^0(%arg37 : i1):
  %0 = llvm.mlir.constant(12 : i32) : i32
  %1 = llvm.mlir.constant(-3 : i32) : i32
  %2 = llvm.mlir.constant(42 : i32) : i32
  %3 = "llvm.select"(%arg37, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.srem %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

def llvm_const_lower_riscv_li17 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM17, rhs:= liRiscv17,
   correct := by admit /- proof elided -/

instance : AST.TransformReturn (MetaLLVM φ) φ := { mkReturn }

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 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.add %1, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def alive_AndOrXor_1683_2_src :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.icmp.uge %a, %b : i64
  %v2 = llvm.icmp.ne %a, %b : i64
  %v3 = llvm.or %v1, %v2 : i1
  llvm.return %v3 : i1
}]

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

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

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 logical_or_not_cond_reuse_after := [llvm|
{
^0(%arg252 : i1, %arg253 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg252, %0 : i1
  %3 = "llvm.select"(%2, %arg253, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def sshr (a : BitVec n) (s : Nat) := BitVec.sshiftRight a s

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

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

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

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

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

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

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

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 carry (initCarry : Bool) (x y : BitStream) : BitStream :=
  fun n => (addAux' initCarry x y n).2

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 test_shl_nuw_nsw__none_are_safe_after := [llvm|
{
^0(%arg70 : i32, %arg71 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(-8 : i32) : i32
  %2 = llvm.shl %arg70, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg71, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

private def opRgnAttr0 : Op φ := [mlir_op|
 "module"() ({
  ^entry:
   "func"() ({
     ^bb0(%arg0:i32, %arg1:i32):
      %zero = "std.addi"(%arg0 , %arg1) : (i32, i16) -> (i64)
      "std.return"(%zero) : (i32) -> ()
    }){sym_name = "add"} : () -> ()
   "module_terminator"() : () -> ()
 }) : () -> ()
]

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

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

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

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

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

def trunc_sandwich_small_shift1_after := [llvm|
{
^0(%arg67 : i32):
  %0 = llvm.mlir.constant(20 : i32) : i32
  %1 = llvm.mlir.constant(2047 : i12) : i12
  %2 = llvm.lshr %arg67, %0 : i32
  %3 = llvm.trunc %2 overflow<nuw> : i32 to i12
  %4 = llvm.and %3, %1 : i12
  "llvm.return"(%4) : (i12) -> ()
}
]

def xor_ashr_not_fail_invalid_xor_constant_before := [llvm|
{
^0(%arg15 : i8, %arg16 : i8, %arg17 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.ashr %arg15, %arg17 : i8
  %2 = llvm.ashr %arg16, %arg17 : i8
  %3 = llvm.xor %2, %0 : i8
  %4 = llvm.xor %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

instance [ToMessageData α] : ToMessageData (ReflectResult α) where
  toMessageData result := m!"{result.e} {result.exprToIx}"



 
#guard_msgs in set_option pp.explicit true in

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

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

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

def test0_after := [llvm|
{
^0(%arg210 : i1):
  "llvm.return"(%arg210) : (i1) -> ()
}
]

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

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

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

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

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

def samesign_inverted_commute2_after := [llvm|
{
^0(%arg99 : i32, %arg100 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.xor %arg99, %arg100 : i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

def exactly_one_set_signbit_wrong_pred_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.and %arg29, %arg28 : i8
  %2 = llvm.icmp "slt" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def not {w : Nat} (x : IntW w) : IntW w := do
  let x' ← x
  not? x'

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

def t1_flags_nuw_only_after := [llvm|
{
^0(%arg45 : i8, %arg46 : i8, %arg47 : i8):
  %0 = llvm.add %arg46, %arg47 overflow<nuw> : i8
  %1 = llvm.sub %arg45, %0 overflow<nuw> : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

instance : One Term := ⟨one⟩

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

LT.lt in Init.Prelude

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

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

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 mul_of_bool_no_lz_other_op_before := [llvm|
{
^0(%arg85 : i32, %arg86 : i8):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.and %arg85, %0 : i32
  %3 = llvm.sext %arg86 : i8 to i32
  %4 = llvm.mul %2, %3 overflow<nsw,nuw> : i32
  %5 = llvm.icmp "sgt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

def ashr_known_pos_exact_before := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.and %arg35, %0 : i8
  %2 = llvm.ashr exact %1, %arg36 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def 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 autMsb_equiv : CNFA.autMsbSet.m.states ≃ NFA'.autMsbSet.σ where
  toFun := fun ⟨s, hs⟩ =>
    match s with
    | 0 => .i
    | 1 => .f
    | _ => .i
  invFun q :=
    match q with
    | .i => ⟨0, by admit /- proof elided -/
    ⟩
    | .f => ⟨1, by admit /- proof elided -/
    ⟩
  left_inv := by admit /- proof elided -/

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

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

def alive_AndOrXor_1705_src :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant 0 : i64
  %v2 = llvm.icmp.eq %B, %v1 : i64
  %v3 = llvm.icmp.ugt %B, %A : i64
  %v4 = llvm.or %v2, %v3 : i1
  llvm.return %v4 : 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) -> ()
}
]

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 n2_after := [llvm|
{
^0(%arg1 : i8, %arg2 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg2 overflow<nuw> : i8
  %2 = llvm.icmp "ult" %1, %arg1 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

dite in Init.Prelude

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

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

def simpHide (e : Expr) : Meta.SimpM Meta.Simp.Step := do
  let ctx ← Simp.getContext
  if let some parent := ctx.parent? then
    if parent.isAppOf ``hide then
      trace[LeanMLIR.Elab] "{Lean.crossEmoji}: parent ({parent}) is an application of `hide`"
      return .continue

  let expr ← Meta.mkAppM ``hide #[e]
  let proof ← Meta.mkAppOptM ``eq_hide #[none, e]
  return .done {
    expr := expr
    proof? := some proof
  }

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

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

def and_sext_to_sel_after := [llvm|
{
^0(%arg41 : i32, %arg42 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = "llvm.select"(%arg42, %arg41, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%1) : (i32) -> ()
}
]

macro "[llvm| " reg:mlir_region "]" : term => `([llvm()| $reg])

def xw : WidthExpr 1 := WidthExpr.var ⟨0, by admit /- proof elided -/
⟩

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

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

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

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

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

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

def lowmask_sub_zext_commute_before := [llvm|
{
^0(%arg223 : i5, %arg224 : i17):
  %0 = llvm.mlir.constant(31 : i17) : i17
  %1 = llvm.zext %arg223 : i5 to i17
  %2 = llvm.sub %arg224, %1 : i17
  %3 = llvm.and %2, %0 : i17
  "llvm.return"(%3) : (i17) -> ()
}
]

Lean.registerBuiltinAttribute in Lean.Attributes

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

def t20_after := [llvm|
{
^0(%arg145 : i8, %arg146 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.shl %0, %arg146 : i16
  %2 = llvm.trunc %1 : i16 to i8
  %3 = llvm.add %arg145, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

BitVec.signExtend in Init.Data.BitVec.Basic

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

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

Lean.Meta.getIntValue? in Lean.Meta.LitValues

def slti_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := slti_llvm_i32
  rhs := slti_riscv_i32

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

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

private def pretty_select (w : Nat) :=
  [llvm(w)| {
    ^bb0(%arg0: i1, %arg1 : _):
      %0 = llvm.select %arg0, %arg1, %arg1
      llvm.return %0
  }]

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

inductive FpPredicate where
 
| bin (lhs : FpExpr e) (op : FpBinaryPredKind) (rhs : FpExpr e)
deriving Hashable, DecidableEq, Repr, BEq

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

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

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

@[simp]
def envBitstream_set_self_eq_self (x : arity → BitStream) (n : Nat) :
    (envBitstream_set x n (fun a => x a n)) = x :=

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

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

Std.Sat.AIG in Std.Sat.AIG.Basic

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

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

instance : TyDenote Ty2 where
toType := fun
|  Ty2.bitvec w => BitVec w

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

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

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

def llvm_const_lower_riscv_li4 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM4, rhs:= liRiscv4,
   correct := by admit /- proof elided -/

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

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

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

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

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

def test11_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg84 : i32 to i64
  %2 = llvm.and %arg85, %0 : i32
  %3 = llvm.zext nneg %2 : i32 to i64
  %4 = llvm.shl %1, %3 overflow<nsw,nuw> : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

class Refinement (α : Type) where
  IsRefinedBy : α → α → Prop

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

def or_and_not_not_wrong_b_before := [llvm|
{
^0(%arg378 : i32, %arg379 : i32, %arg380 : i32, %arg381 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.or %arg381, %arg378 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %arg378, %arg380 : i32
  %4 = llvm.xor %3, %0 : i32
  %5 = llvm.and %4, %arg379 : i32
  %6 = llvm.or %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

@[match_pattern]
def last (Γ : Ctxt Ty) (t : Ty) : Ctxt.Var (Ctxt.cons t Γ) t :=
  ⟨0, by admit /- proof elided -/
  ⟩

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

def exampleMerge := [HSxComb_com| {
  ^entry(%0: !Stream_BitVec_8, %1: !Stream_BitVec_8):
    %src = "HSxComb.merge" (%0, %1) : (!Stream_BitVec_8, !Stream_BitVec_8) -> (!Stream_BitVec_8)
    "return" (%src) : (!Stream_BitVec_8) -> ()
  }]

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 icmp_ne_mul_nsw_nonequal_after := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ne" %arg29, %0 : i8
  "llvm.return"(%1) : (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 or_signbit_select_shl_after := [llvm|
{
^0(%arg42 : i32, %arg43 : i1):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-16777216 : i32) : i32
  %2 = llvm.shl %arg42, %0 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = "llvm.select"(%arg43, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

def test19_before := [llvm|
{
^0(%arg4 : i39, %arg5 : i39):
  %0 = llvm.sub %arg4, %arg5 : i39
  %1 = llvm.add %0, %arg5 : i39
  "llvm.return"(%1) : (i39) -> ()
}
]

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

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

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

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

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

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

def squared_nsw_sgt0_after := [llvm|
{
^0(%arg178 : i5):
  %0 = llvm.mlir.constant(0 : i5) : i5
  %1 = llvm.icmp "ne" %arg178, %0 : i5
  "llvm.return"(%1) : (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) -> ()
}
]

Lean.Elab.Tactic.BVDecide.Frontend.LratCert in Lean.Elab.Tactic.BVDecide.Frontend.LRAT

@[simp_denote]
def and_llvm_32 := [LV| {
  ^entry (%lhs: i32, %rhs: i32):
  %1 = llvm.and %lhs, %rhs : i32
  llvm.return %1 : i32
  }]

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

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

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

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

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

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

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

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 sgt_and_min_commute_before := [llvm|
{
^0(%arg348 : i8, %arg349 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "sgt" %arg348, %arg349 : i8
  %2 = llvm.icmp "eq" %arg348, %0 : i8
  %3 = llvm.and %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def zext_negate_after := [llvm|
{
^0(%arg37 : i1):
  %0 = llvm.sext %arg37 : i1 to i64
  "llvm.return"(%0) : (i64) -> ()
}
]

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

def factorize5_after := [llvm|
{
^0(%arg1 : i32, %arg2 : i32):
  %0 = llvm.mul %arg2, %arg1 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

def p4 : PeepholeRewrite ExOp [.nat, .nat] .nat:=
  { lhs := r3, rhs := m, correct :=
    by admit /- proof elided -/

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 sext_zext_apint2_after := [llvm|
{
^0(%arg85 : i11):
  %0 = llvm.zext %arg85 : i11 to i47
  "llvm.return"(%0) : (i47) -> ()
}
]

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

def t4_commutative_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8):
  %0 = llvm.add %arg34, %arg35 : i8
  %1 = llvm.icmp "ule" %arg35, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def and_xor_or6_after := [llvm|
{
^0(%arg658 : i64, %arg659 : i64, %arg660 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg659 : i64
  %2 = llvm.udiv %0, %arg660 : i64
  %3 = llvm.or %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

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

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

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

def State.cseExpr
 {Γstart Γ : Ctxt d.Ty}
 {lets : Lets d Γstart .pure Γ}
 (s : State d lets)
 (e : Expr d Γ .pure α) :
 {e' : Expr d Γ .pure α //
  ∀ (V : Γstart.Valuation), e'.denote (lets.denote V) =
    e.denote (lets.denote V) }
    × Option ({ v' : HVector Γ.Var α // ∀ (V : Γstart.Valuation),
      v'.map (lets.denote V) = e.denoteOp (lets.denote V) }) :=
  match E : e with
  | .mk op ty_eq eff_le args regArgs =>
      let ⟨args', hargs'⟩ := s.cseArgList args
      let regArgs' := s.cseRegionArgList regArgs
      let ⟨regArgs', hregArgs'⟩ := regArgs'
      let e' : Expr d Γ .pure α  := .mk op ty_eq eff_le args' regArgs'
      ⟨⟨e', by admit /- proof elided -/
      ⟩,
        match s.expr2cache _ e with
        | .some ⟨v', hv'⟩ =>
          .some ⟨v', by admit /- proof elided -/
          ⟩
        | .none => .none
      ⟩

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

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

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

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

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

def ne_3210_after := [llvm|
{
^0(%arg74 : i32, %arg75 : i32):
  %0 = llvm.icmp "ne" %arg74, %arg75 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def t7_after := [llvm|
{
^0(%arg197 : i8, %arg198 : i1, %arg199 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg199 overflow<nsw> : i8
  %3 = "llvm.select"(%arg198, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.add %3, %arg197 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

RV64.andi in RISCV.Instructions

Lean.importModules in Lean.Environment
</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 [*])

@[simp] theorem getValue_value [Inhabited α] : (value a).getValue = a

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

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

theorem test12_logical_proof : test12_logical_before ⊑ test12_logical_after

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

theorem PR38021_proof : PR38021_before ⊑ PR38021_after

theorem e_1151 :
    4 *  ~~~(z ^^^ t) - 7 * z + 11 *  ~~~z - 5 *  ~~~(z &&& t) - 1 *  ~~~(z &&&  ~~~z) - 9 *  ~~~(z ||| t) + 14 * (z &&&  ~~~t) + 5 * (z &&& t) = 1 * (z ||| t) + 4 *  ~~~(z |||  ~~~t)

@[simp_denote] lemma toType_bitvec : TyDenote.toType (Ty.bitvec w) = LLVM.IntW w

theorem not_and_and_or_no_or_commute2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_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 → False

theorem multiuse3_proof : multiuse3_before ⊑ multiuse3_after

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

theorem no_masks_with_logical_or_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 != 0#32) = 1#1 → ofBool (x_2 ||| x != 0#32) = 1#1 → ofBool (x_1 != 63#32) ||

theorem lshrult_03_07_proof : lshrult_03_07_before ⊑ lshrult_03_07_after

theorem alive_AndOrXor_2243__B__C__A__B___B__A__C  (w : Nat)   : alive_AndOrXor_2243__B__C__A__B___B__A__C_src w  ⊑ alive_AndOrXor_2243__B__C__A__B___B__A__C_tgt w

theorem shl_and_add_thm (e e_1 : IntW 8) :
  add (shl e_1 (const? 8 1)) (LLVM.and (shl e (const? 8 1)) (const? 8 119)) ⊑
    shl (add e_1 (LLVM.and e (const? 8 59))) (const? 8 1)

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

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

theorem add_shl_same_amount_partial_nuw1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨ x_1 ≥ ↑6 ∨ True ∧ x <<< x_1 >>> x_1 ≠ x ∨ x_1 ≥ ↑6) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 + x <<< x_1 = (x_2 + x) <<< x_1

theorem abs_diff_signed_slt_swap_wrong_pred1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == x) = 1#1 →
    ¬(True ∧ x.ssubOverflow x_1 = true) → ¬(True ∧ x_1.ssubOverflow x = true) → x - x_1 = x_1 - x

theorem e_1755 :
     - 2 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) - 7 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 11 *  ~~~(b ||| c) + 1 * (c ^^^ (a ||| ( ~~~b &&& c))) - 11 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 11 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ||| c) + 3 * (a &&& (b ||| c)) - 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 11 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 7 *  ~~~(a &&& (b ||| c)) + 11 * (b &&&  ~~~c) - 3 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 11 * (b ^^^ (a &&& (b ||| c))) - 2 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 3 * (b ||| (a &&&  ~~~c)) + 7 *  ~~~(a &&& c) - 1 * (c ^^^ ( ~~~a &&& (b ||| c))) - 7 * ( ~~~c &&& (a ^^^ b)) + 11 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 2 * (b &&&  ~~~(a &&& c)) - 1 *  ~~~(a &&& (b ^^^ c)) + 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 5 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 20 *  ~~~(a ||| (b ||| c)) - 20 *  ~~~(a ||| ( ~~~b ||| c)) - 2 *  ~~~( ~~~a ||| (b ||| c)) - 4 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 14 * ( ~~~a &&& (b &&& c)) - 22 * (a &&& ( ~~~b &&& c)) + 44 * (a &&& (b &&& c)) =  - 1 *  ~~~(a &&& (b &&& c)) + 7 *  ~~~(a ||| b)

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

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

theorem uadd_sat_flipped_wrong_bounds_proof : uadd_sat_flipped_wrong_bounds_before ⊑ uadd_sat_flipped_wrong_bounds_after

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

theorem corec₂_corec1 (s : Stream γ) (f : Stream γ -> Option α × Option β × Stream γ) :
  (corec₂ s f).1 = corec s (fun s' => let ⟨ a, _, b ⟩ := f s'; (a, b) )

theorem src_is_notmask_neg_p2_fail_not_invertable_proof : src_is_notmask_neg_p2_fail_not_invertable_before ⊑ src_is_notmask_neg_p2_fail_not_invertable_after

theorem lshr_and_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 48#8 >>> x &&& 64#8 >>> (x + 1#8) = 32#8 >>> x

theorem ashr_lshr_shift_wrong_pred2_proof : ashr_lshr_shift_wrong_pred2_before ⊑ ashr_lshr_shift_wrong_pred2_after

theorem test46_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬8#32 ≥ ↑32 →
    ¬(8#32 ≥ ↑32 ∨ True ∧ (truncate 32 x <<< 8#32 &&& 10752#32).msb = true) →
      zeroExtend 64 ((truncate 32 x &&& 42#32) <<< 8#32) = zeroExtend 64 (truncate 32 x <<< 8#32 &&& 10752#32)

theorem eval_eq_false_of_mkIndHypCycleBreaking_eval_eq_false_of_mkSafetyCircuit_eval_eq_false
    (circs : KInductionCircuits fsm K)
    (hCircs : circs.IsLawful)
    (hSafety : ∀ (env : _), (mkSafetyCircuit circs).eval env = false)
    (hIndHyp : ∀ (env : _), (mkIndHypCycleBreaking circs).eval env = false) :
    (∀ (envBitstream : _), fsm.eval envBitstream i = false)

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

theorem e_2409 :
    3 * (e |||  ~~~(d ^^^ f)) + 3 *  ~~~(d ||| f) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) + 4 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 2 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 7 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 5 * (e ||| (d ^^^ f)) + 5 *  ~~~( ~~~d ||| (e &&& f)) - 1 *  ~~~(d &&& f) + 2 *  ~~~(d ||| (e &&& f)) + 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 *  ~~~(e &&& f) - 5 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * (e ^^^ (d &&& ( ~~~e ||| f))) - 5 * ( ~~~d ||| (e ||| f)) - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 11 * (f ^^^  ~~~(d &&& (e ||| f))) - 7 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * (d |||  ~~~f) - 6 * (f ^^^ ( ~~~d &&& (e ||| f))) - 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 2 * ( ~~~f &&&  ~~~(d ^^^ e)) + 11 * (e ^^^ ( ~~~d ||| (e &&& f))) + 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 3 * (d ||| ( ~~~e &&& f)) + 4 * (e |||  ~~~(d |||  ~~~f)) + 5 * (e ||| f) + 11 *  ~~~( ~~~d &&& (e ||| f)) - 3 * ( ~~~d ||| ( ~~~e ||| f)) - 2 *  ~~~(d &&& ( ~~~e ||| f)) - 1 * e - 6 *  ~~~(d ^^^ (e &&& f)) - 6 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 11 * ( ~~~d ||| (e &&& f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 3 * (f ^^^ ( ~~~d ||| (e ||| f))) - 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 4 * (d &&&  ~~~f) + 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 2 * (d ^^^ f) + 1 * (e ^^^ (d &&&  ~~~f)) + 2 *  ~~~( ~~~d &&& (e &&& f)) + 3 * ((e &&& f) ||| (d &&& (e ||| f))) - 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (f &&& (d |||  ~~~e)) - 5 * (f ||| (d &&&  ~~~e)) - 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 * (d |||  ~~~e) - 6 *  ~~~(d |||  ~~~f) - 1 * (f ^^^ (d ||| (e &&& f))) - 1 * (e ^^^ (d ||| f)) - 1 * (d ||| (e ^^^ f)) - 6 * ((d &&& e) ||| (e ^^^ f)) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * ( ~~~d &&& (e ||| f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 * ( ~~~f &&& (d ^^^ e)) + 1 * (e ^^^ (d ||| (e ^^^ f))) + 13 *  ~~~(d ||| (e ||| f)) - 26 *  ~~~( ~~~d ||| (e ||| f)) - 21 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 36 * ( ~~~d &&& ( ~~~e &&& f)) - 5 * ( ~~~d &&& (e &&& f)) - 16 * (d &&& ( ~~~e &&& f)) + 34 * (d &&& (e &&& f)) =  - 19 *  ~~~(d ||| ( ~~~e ||| f)) + 1 * (f |||  ~~~(d ||| e))

theorem n5_proof : n5_before ⊑ n5_after

theorem select_icmp_eq_and_1_0_or_2_proof : select_icmp_eq_and_1_0_or_2_before ⊑ select_icmp_eq_and_1_0_or_2_after

theorem test_ne_0_and_15_add_3_proof : test_ne_0_and_15_add_3_before ⊑ test_ne_0_and_15_add_3_after

theorem ashrslt_03_12_exact_proof : ashrslt_03_12_exact_before ⊑ ashrslt_03_12_exact_after

@[simp] theorem isPoison_value : isPoison (value a) = false

theorem narrow_sext_mul_proof : narrow_sext_mul_before ⊑ narrow_sext_mul_after

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

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

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

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

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

theorem mul_of_udiv_proof : mul_of_udiv_before ⊑ mul_of_udiv_after

theorem e_1723 :
    7 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 * ( ~~~b |||  ~~~(a ^^^ c)) - 1 * (a ||| (b ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 *  ~~~b + 1 * ( ~~~c |||  ~~~(a ^^^ b)) - 1 * (a |||  ~~~c) + 5 * ( ~~~b &&& (a ^^^ c)) - 5 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) - 2 * (b &&& (a ||| c)) - 2 * ( ~~~a ||| (b &&& c)) - 2 * (c ^^^ (a |||  ~~~b)) + 2 * (a &&& ( ~~~b ||| c)) - 11 * ( ~~~a ||| (b ||| c)) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 7 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 * (b ^^^ ( ~~~a ||| (b ||| c))) - 1 * (c ||| (a &&& b)) - 1 *  ~~~(a ^^^ c) - 7 * ( ~~~a &&& (b ||| c)) - 11 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 12 *  ~~~(a ||| (b ||| c)) + 50 *  ~~~(a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a ||| (b ||| c)) + 17 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 11 * ( ~~~a &&& ( ~~~b &&& c)) + 23 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) + 38 * (a &&& (b &&& c)) = 1 * ((a &&& c) ^^^ (b ||| c))

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

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

theorem and_or_not_not_commute7_proof : and_or_not_not_commute7_before ⊑ and_or_not_not_commute7_after

theorem mul_select_zext_proof : mul_select_zext_before ⊑ mul_select_zext_after

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

theorem e_1691 :
     - 2 * (a ||| (b ^^^ c)) + 2 * (a ^^^ b) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 2 * (b ^^^ (a |||  ~~~c)) - 11 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * (b ||| (a &&& c)) - 6 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 4 * (b &&& (a |||  ~~~c)) - 2 *  ~~~(a &&& b) - 1 * (a &&& (b ||| c)) + 4 * (c &&& (a ^^^ b)) + 1 *  ~~~(a ||| b) - 5 * (b ^^^ (a &&& (b ^^^ c))) - 6 * (a ||| (b &&& c)) - 1 * c + 2 *  ~~~(a |||  ~~~b) - 2 *  ~~~(a ^^^ b) - 7 * (c ^^^  ~~~(a &&& (b ||| c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 1 * (b &&&  ~~~c) - 6 * (c ^^^ (a ||| ( ~~~b ||| c))) + 1 * ( ~~~a ||| (b ^^^ c)) + 28 *  ~~~(a ||| (b ||| c)) + 32 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 10 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 33 * (a &&& ( ~~~b &&& c)) + 27 * (a &&& (b &&& c)) =  - 11 *  ~~~(a ||| ( ~~~b ||| c)) - 39 *  ~~~( ~~~a ||| (b ||| c))

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

theorem test1_proof : test1_before ⊑ test1_after

theorem test_sdiv_canonicalize_op0_proof : test_sdiv_canonicalize_op0_before ⊑ test_sdiv_canonicalize_op0_after

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

theorem e_2281 :
    4 * (e ^^^  ~~~(d ||| f)) - 7 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * (f ^^^  ~~~(d |||  ~~~e)) + 5 * (f &&& (d ^^^ e)) - 6 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 11 * (e ^^^ f) + 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 *  ~~~(d ||| (e ^^^ f)) - 2 *  ~~~f + 3 * (f &&&  ~~~(d ^^^ e)) + 1 * (d ^^^ f) - 11 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 2 *  ~~~(d &&& e) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 *  ~~~(d &&& f) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 7 * (f ^^^ ( ~~~d ||| (e &&& f))) - 3 * (f ||| (d ^^^ e)) + 1 * ((d &&& e) ||| (e ^^^ f)) - 1 *  ~~~(d &&&  ~~~f) + 5 * (f ^^^ (d &&& ( ~~~e ||| f))) - 1 * (e &&& f) - 1 * (f |||  ~~~(d ^^^ e)) + 7 * ( ~~~d ||| ( ~~~e ||| f)) - 11 *  ~~~(d &&& ( ~~~e &&& f)) - 1 *  ~~~d + 7 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * (f ^^^ (d ||| (e ||| f))) + 2 * ( ~~~f ||| (d ^^^ e)) - 7 * (e |||  ~~~(d ^^^ f)) - 7 *  ~~~( ~~~d &&& (e &&& f)) + 2 * (e ||| (d &&&  ~~~f)) + 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * (f ^^^  ~~~(d ||| e)) + 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 5 *  ~~~(e &&&  ~~~f) - 1 *  ~~~(d ||| f) - 11 * ( ~~~d ||| (e ||| f)) + 3 * (d |||  ~~~e) - 6 * (f ^^^ (d |||  ~~~e)) + 5 * (f &&& (d |||  ~~~e)) - 3 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 7 *  ~~~( ~~~d ||| (e ^^^ f)) - 6 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 7 * (e ^^^ (d ||| f)) + 1 * (d ^^^ (e ^^^ f)) + 20 *  ~~~(d ||| (e ||| f)) - 22 *  ~~~(d ||| ( ~~~e ||| f)) + 6 *  ~~~( ~~~d ||| (e ||| f)) + 9 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 16 * ( ~~~d &&& ( ~~~e &&& f)) + 19 * ( ~~~d &&& (e &&& f)) - 25 * (d &&& ( ~~~e &&& f)) + 8 * (d &&& (e &&& f)) =  - 1 *  ~~~(d &&& (e ^^^ f))

theorem add_five (x : BitVec w) : (x + x) + (x + x) + x = x + x + x + x + x

theorem zext_nneg_signbit_extract_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.msb = true ∨ 31#64 ≥ ↑64) → zeroExtend 64 x >>> 31#64 = 0#64

theorem and_or_not_not_commute1_proof : and_or_not_not_commute1_before ⊑ and_or_not_not_commute1_after

theorem test68_proof : test68_before ⊑ test68_after

theorem shrink_xor_thm.extracted_1._1 : ∀ (x : BitVec 64), truncate 32 (x ^^^ 1#64) = truncate 32 x ^^^ 1#32

theorem scalar_i8_shl_and_negC_eq_proof : scalar_i8_shl_and_negC_eq_before ⊑ scalar_i8_shl_and_negC_eq_after

theorem a_true_implies_b_true2_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬ofBool (10#8 <ᵤ x_1) = 1#1 → ¬ofBool (20#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) &&& x = 0#1

theorem twoway_clamp_lt_proof : twoway_clamp_lt_before ⊑ twoway_clamp_lt_after

theorem sext_sub_const_thm (e : IntW 1) : sub (const? 64 42) (sext 64 e) ⊑ select e (const? 64 43) (const? 64 42)

theorem lshrugt_03_07_exact_proof : lshrugt_03_07_exact_before ⊑ lshrugt_03_07_exact_after

theorem lshr_and_sub_proof : lshr_and_sub_before ⊑ lshr_and_sub_after

theorem shl_lshr_pow2_not_const_case2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 3#16 ≥ ↑16) → ofBool (x == 2#16) = 1#1 → 16#16 <<< x >>> 3#16 &&& 8#16 ^^^ 8#16 = 0#16

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

theorem and_xor_or7_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x = 0 ∨ x_2 = 0) →
    ¬(x_2 = 0 ∨ x_1 = 0) → 42#64 / x_2 ||

theorem gt_unsigned_to_large_unsigned_proof : gt_unsigned_to_large_unsigned_before ⊑ gt_unsigned_to_large_unsigned_after

theorem main4c_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 != 7#32) ||

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

theorem modulo32_proof : modulo32_before ⊑ modulo32_after

theorem test40_thm (e : IntW 16) :
  trunc 16 (LLVM.or (lshr (zext 32 e) (const? 32 9)) (shl (zext 32 e) (const? 32 8))) ⊑
    LLVM.or (lshr e (const? 16 9)) (shl e (const? 16 8)) { «disjoint» := true }

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

theorem lshr_32_add_zext_basic_proof : lshr_32_add_zext_basic_before ⊑ lshr_32_add_zext_basic_after

theorem signExtend_succ (i : Nat) (x : BitVec w) :
    x.signExtend (i+1) = cons (if i < w then x.getLsbD i else x.msb) (x.signExtend i)

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

theorem ashrslt_02_11_proof : ashrslt_02_11_before ⊑ ashrslt_02_11_after

theorem not_zext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#999 = zeroExtend 999 (x ^^^ 1#1)

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

theorem sle_smax4_proof : sle_smax4_before ⊑ sle_smax4_after

theorem scanAnd_false_iff (s : BitStream) (n : Nat)
    : s.scanAnd n = false ↔ ∃ (i : Nat), (i ≤ n) ∧ s i = false

theorem icmp_eq_mul_nsw_nonequal_commuted_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (mul e_1 e { «nsw» := true, «nuw» := false })
      (mul e (add e_1 (const? 8 1)) { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.eq e (const? 8 0)

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

theorem test_shl_nsw__all_are_safe_proof : test_shl_nsw__all_are_safe_before ⊑ test_shl_nsw__all_are_safe_after

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

theorem src_srem_shl_demand_min_signbit_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((1073741823#32 == 0 || 32 != 1 && x == intMin 32 && 1073741823#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    (1073741823#32 == 0 || 32 != 1 && x == intMin 32 && 1073741823#32 == -1) = true → False

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

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 0#32) &&& ofBool (x <ᵤ 14#32) = ofBool (x + -1#32 <ᵤ 13#32)

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

theorem test4_proof : test4_before ⊑ test4_after

theorem sdiv6_proof : sdiv6_before ⊑ sdiv6_after

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

theorem not_ashr_not_bitwidth_mask_proof : not_ashr_not_bitwidth_mask_before ⊑ not_ashr_not_bitwidth_mask_after

theorem test_or3_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sle (LLVM.and e_1 (const? 32 2147483647)) e) (const? 1 1)
      (icmp IntPred.slt e (const? 32 0)) ⊑
    icmp IntPred.uge e (LLVM.and e_1 (const? 32 2147483647))

theorem lt_unsigned_to_small_signed_proof : lt_unsigned_to_small_signed_before ⊑ lt_unsigned_to_small_signed_after

theorem sge_or_not_max_commute_proof : sge_or_not_max_commute_before ⊑ sge_or_not_max_commute_after

theorem and_nosignbit_lshr_thm (e : IntW 32) :
  lshr (LLVM.and e (const? 32 2147418112)) (const? 32 8) ⊑ LLVM.and (lshr e (const? 32 8)) (const? 32 8388352)

theorem eval_mkSuccCarryAndOutAssignPrecond_eq_false_iff₁
  {circs : KInductionCircuits fsm n}
  (hCircs : circs.IsLawful) :
  ∀ (env : Vars fsm.α arity (n + 2) → Bool),
  (mkSuccCarryAndOutsAssignPrecond circs).eval env = false ↔
  (∀ (s : fsm.α) (i : Nat) (hi : i < n + 2),
    env (Vars.stateN s (i + 1)) =
      ((mkCarryAssignCircuitNAux fsm s i).map
        (fun v => v.castLe (by omega))).eval env) ∧
  (∀ (i : Nat) (hi : i < n + 2),
    (fsm.outputCirc).eval
      (fun x => match x with
        | .inl s => env (Vars.stateN s i)
        | .inr j => env (Vars.inputN j i)) =
    env (Vars.outputs ⟨i, by omega⟩))

theorem ule_and_min_commute_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.eq e_1 (const? 8 0)) (icmp IntPred.ule e_1 e) (const? 1 0) ⊑
    icmp IntPred.eq e_1 (const? 8 0)

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

theorem lshrugt_01_09_exact_proof : lshrugt_01_09_exact_before ⊑ lshrugt_01_09_exact_after

theorem or_eq_with_diff_one_proof : or_eq_with_diff_one_before ⊑ or_eq_with_diff_one_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_3_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 0)) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 15)) (const? 32 8)

theorem test5_proof : test5_before ⊑ test5_after

theorem src_is_mask_zext_fail_not_mask_thm (e : IntW 8) (e_1 : IntW 16) :
  icmp IntPred.eq (LLVM.and (LLVM.xor e_1 (const? 16 123)) (zext 16 (lshr (const? 8 (-2)) e)))
      (LLVM.xor e_1 (const? 16 123)) ⊑
    icmp IntPred.eq (LLVM.or (LLVM.xor e_1 (const? 16 (-124))) (zext 16 (lshr (const? 8 (-2)) e)))
      (const? 16 (-1))

theorem demorgan_nor_use2ac_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(((x_1 ^^^ -1#8 ||| x) * 23#8 == 0 ||
            8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && (x_1 ^^^ -1#8 ||| x) * 23#8 == -1) =
          true ∨
        ((x_1 ^^^ -1#8) * 17#8 == 0 ||
            8 != 1 && ((x_1 ^^^ -1#8 ||| x) ^^^ -1#8).sdiv ((x_1 ^^^ -1#8 ||| x) * 23#8) == intMin 8 &&
              (x_1 ^^^ -1#8) * 17#8 == -1) =
          true) →
    ¬(((x ||| x_1 ^^^ -1#8) * 23#8 == 0 ||
              8 != 1 && (x ||| x_1 ^^^ -1#8) ^^^ -1#8 == intMin 8 && (x ||| x_1 ^^^ -1#8) * 23#8 == -1) =
            true ∨
          ((x_1 ^^^ -1#8) * 17#8 == 0 ||
              8 != 1 && ((x ||| x_1 ^^^ -1#8) ^^^ -1#8).sdiv ((x ||| x_1 ^^^ -1#8) * 23#8) == intMin 8 &&
                (x_1 ^^^ -1#8) * 17#8 == -1) =
            true) →
      (((x_1 ^^^ -1#8 ||| x) ^^^ -1#8).sdiv ((x_1 ^^^ -1#8 ||| x) * 23#8)).sdiv ((x_1 ^^^ -1#8) * 17#8) =
        (((x ||| x_1 ^^^ -1#8) ^^^ -1#8).sdiv ((x ||| x_1 ^^^ -1#8) * 23#8)).sdiv ((x_1 ^^^ -1#8) * 17#8)

theorem same_source_shifted_signbit_proof : same_source_shifted_signbit_before ⊑ same_source_shifted_signbit_after

theorem srem_common_dividend_defined_cond_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (LLVM.srem e_2 e_1) (LLVM.srem e_2 e) ⊑ LLVM.srem e_2 (select e_3 e_1 e)

theorem t1_sshr_thm (e e_1 : IntW 32) :
  ashr (LLVM.and (shl (const? 32 (-1)) e_1) e) e_1 { «exact» := true } ⊑
    ashr (LLVM.and (shl (const? 32 (-1)) e_1 { «nsw» := true, «nuw» := false }) e) e_1 { «exact» := true }

theorem or_signbit_select_ashr_proof : or_signbit_select_ashr_before ⊑ or_signbit_select_ashr_after

theorem main2_proof : main2_before ⊑ main2_after

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

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

theorem lshrugt_03_03_proof : lshrugt_03_03_before ⊑ lshrugt_03_03_after

theorem sext_thm (e : IntW 16) :
  add (LLVM.xor (zext 32 e) (const? 32 32768)) (const? 32 (-32768)) ⊑ sext 32 e

theorem test_or2_logical_proof : test_or2_logical_before ⊑ test_or2_logical_after

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

theorem ne_nuw_rem_nz_proof : ne_nuw_rem_nz_before ⊑ ne_nuw_rem_nz_after

theorem icmp_slt_0_and_icmp_ne_neg2_i32_fail_proof : icmp_slt_0_and_icmp_ne_neg2_i32_fail_before ⊑ icmp_slt_0_and_icmp_ne_neg2_i32_fail_after

theorem invert_both_cmp_operands_complex_proof : invert_both_cmp_operands_complex_before ⊑ invert_both_cmp_operands_complex_after

@[simp]
lemma proj_eval (M : NFA (BitVec m) σ) (f : Fin n → Fin m) :
    (M.proj f).eval w =
      ⋃ w' ∈ BitVecs'.transport f ⁻¹' {w}, M.eval w'

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

theorem icmp_equality_test_swift_optional_pointers_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ofBool (x_1 == 0#64) = 1#1 → ¬True → ofBool (x == 0#64) = ofBool (x_1 == x)

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

theorem ashr_eq_msb_low_second_zero_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((127#8).sshiftRight' x == 0#8) = ofBool (6#8 <ᵤ x)

theorem add_const_const_sub_proof : add_const_const_sub_before ⊑ add_const_const_sub_after

theorem select_icmp_and_8_eq_0_xor_8_proof : select_icmp_and_8_eq_0_xor_8_before ⊑ select_icmp_and_8_eq_0_xor_8_after

theorem test15f_thm.extracted_1._4 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 128#32 != 0#32) = 1#1 → ¬1#32 ≥ ↑32 → 256#32 = x <<< 1#32 &&& 256#32 ^^^ 256#32

theorem sgt_swap_or_not_min_proof : sgt_swap_or_not_min_before ⊑ sgt_swap_or_not_min_after

theorem lsb_mask_sign_zext_commuted_proof : lsb_mask_sign_zext_commuted_before ⊑ lsb_mask_sign_zext_commuted_after

theorem and_add_bool_to_select_thm (e : IntW 32) (e_1 : IntW 1) :
  LLVM.and (add (const? 32 (-1)) (zext 32 e_1)) e ⊑ select e_1 (const? 32 0) e

theorem ashrsgt_03_11_exact_proof : ashrsgt_03_11_exact_before ⊑ ashrsgt_03_11_exact_after

theorem test_invalid_simplify_sub2_proof : test_invalid_simplify_sub2_before ⊑ test_invalid_simplify_sub2_after

theorem HVector.map_eq_of_eq_on_vars {A : d.Ty → Type*}
    {T : HVector (Var Γ) l}
    {s₁ s₂ : ∀ (t), Var Γ t → A t}
    (h : ∀ v, v ∈ T.vars → s₁ _ v.2 = s₂ _ v.2) :
    T.map s₁ = T.map s₂

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

theorem main5e_like_logical_proof : main5e_like_logical_before ⊑ main5e_like_logical_after

theorem and_nosignbit_select_ashr_proof : and_nosignbit_select_ashr_before ⊑ and_nosignbit_select_ashr_after

include hinj in
lemma product.prodArray'_spec_full {aᵢ : Array γ} (hnd: aᵢ.toList.Nodup) (hnin : ∀ s₁ s₂, f s₁ s₂ ∉ aᵢ) :
    (product.prodArray' f hm₁ hm₂ aᵢ).toList.Nodup ∧
    (∃ r, (product.prodArray' f hm₁ hm₂ aᵢ).toList = aᵢ.toList ++ r ∧ (∀ z ∈ r, ∃ s₁ s₂, z = f s₁ s₂)) ∧
    ∀ s₁ s₂, f s₁ s₂ ∈ product.prodArray' f hm₁ hm₂ aᵢ ↔ (s₁.val ∈ m₁ ∧ s₂.val ∈ m₂)

theorem test3_thm (e : IntW 1) (e_1 : IntW 59) :
  LLVM.udiv e_1 (select e (const? 59 1024) (const? 59 4096)) ⊑
    lshr e_1 (select e (const? 59 10) (const? 59 12))

theorem logical_and_bitwise_and_icmps_comm2_proof : logical_and_bitwise_and_icmps_comm2_before ⊑ logical_and_bitwise_and_icmps_comm2_after

theorem src_is_notmask_x_xor_neg_x_inv_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ofBool ((x_1 ^^^ 0#8 - x_1) &&& (x ^^^ 123#8) == 0#8) = ofBool (x ^^^ 123#8 ≤ᵤ x_1 ^^^ x_1 + -1#8)

theorem e_617 :
     - 5 *  ~~~(x &&& y) - 5 * y - 1 *  ~~~y + 2 *  ~~~(x &&&  ~~~x) - 2 * (x ^^^ y) - 5 * x + 2 *  ~~~(x ||| y) + 9 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) + 5 * (x &&& y) =  - 1 * (x ||| y) - 2 * (x |||  ~~~y)

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

theorem src_x_and_nmask_ult_proof : src_x_and_nmask_ult_before ⊑ src_x_and_nmask_ult_after

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

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

theorem cmpeq_xor_cst3_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (LLVM.xor e_1 (const? 32 10)) (LLVM.xor e (const? 32 10)) ⊑ icmp IntPred.eq e_1 e

theorem and_xor_or3_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(x_2 = 0 ∨ x_1 = 0 ∨ x = 0 ∨ x = 0) →
    ¬(x_2 = 0 ∨ x = 0) → 42#64 / x_2 ^^^ 42#64 / x_1 &&& 42#64 / x ||

theorem lshrugt_01_12_exact_proof : lshrugt_01_12_exact_before ⊑ lshrugt_01_12_exact_after

theorem Factor.denote_eq_toNat_reflectFin {w : Nat} (xs : Env w) (f : Factor) :
    f.denote xs = (f.reflectFin (EnvFin.ofEnv xs _)).toNat

theorem test8_thm (e : IntW 999) : LLVM.and e (const? 999 0) ⊑ const? 999 0

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

theorem e_1383 :
    11 * (z |||  ~~~t) + 3 * (z ||| t) + 3 *  ~~~(z &&&  ~~~t) + 4 * z - 6 *  ~~~t + 1 * t + 14 *  ~~~(z ||| t) + 15 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 22 * (z &&& t) = 11 *  ~~~z + 11 *  ~~~(z &&& t)

theorem alive_AndOrXor_1288_A__B__B__C__A___A__B__C  (w : Nat)   : alive_AndOrXor_1288_A__B__B__C__A___A__B__C_src w  ⊑ alive_AndOrXor_1288_A__B__B__C__A___A__B__C_tgt w

theorem tryFactorization_xor_lshr_ashr_proof : tryFactorization_xor_lshr_ashr_before ⊑ tryFactorization_xor_lshr_ashr_after

theorem test68_xor_proof : test68_xor_before ⊑ test68_xor_after

theorem badimm4_thm.extracted_1._3 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬15#16 ≥ ↑16 → ofBool (127#16 <ₛ x) = 1#1 → truncate 8 (x.sshiftRight' 15#16) ^^^ 126#8 = 126#8

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

theorem e_2370 :
    7 * (f |||  ~~~(d ||| e)) - 11 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 11 * (e ||| (d ^^^ f)) - 1 * (d ||| f) + 3 * (e ^^^ (d ||| ( ~~~e ||| f))) - 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 * ((d &&& f) ^^^ (e ||| f)) + 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (e ^^^ f) - 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 11 * (f ^^^ (d &&& e)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (d &&& (e ||| f)) + 1 * (d &&& e) - 5 * (f |||  ~~~(d |||  ~~~e)) + 4 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 5 *  ~~~(d ||| (e ^^^ f)) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 1 * (d ^^^ ( ~~~e ||| f)) - 2 *  ~~~(d ||| (e &&& f)) + 11 * (f ||| (d ^^^ e)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * ( ~~~d &&& (e ^^^ f)) + 4 * (e ||| (d &&& f)) + 1 * (d &&& (e ^^^ f)) - 1 * ( ~~~f ||| (d ^^^ e)) - 1 *  ~~~(e &&&  ~~~f) - 7 *  ~~~(d &&& (e ^^^ f)) - 3 *  ~~~(d ||| ( ~~~e &&& f)) + 11 * ((d |||  ~~~e) &&& (e ^^^ f)) + 3 * (d ^^^ f) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * (d ||| (e ^^^ f)) - 11 * (e |||  ~~~(d ||| f)) + 5 *  ~~~e + 2 * (e &&& (d |||  ~~~f)) - 2 * ((d ||| e) &&& (e ^^^ f)) + 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * (f ^^^ (d &&& (e ||| f))) - 1 * (f ^^^  ~~~(d |||  ~~~e)) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * ((d &&& e) ^^^ (e ||| f)) + 7 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 6 * ((d &&& e) |||  ~~~(e ||| f)) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * (e ^^^ (d &&& (e ||| f))) + 3 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ^^^ ( ~~~d &&& (e ||| f))) - 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 2 * (f &&& (d ^^^ e)) - 10 *  ~~~(d ||| (e ||| f)) - 23 *  ~~~(d ||| ( ~~~e ||| f)) - 4 *  ~~~( ~~~d ||| (e ||| f)) - 65 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 74 * ( ~~~d &&& ( ~~~e &&& f)) - 52 * ( ~~~d &&& (e &&& f)) - 76 * (d &&& ( ~~~e &&& f)) - 1 * (d &&& (e &&& f)) =  - 2 * (d &&& f) - 5 * (e |||  ~~~(d |||  ~~~f))

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

theorem uge_umin1_proof : uge_umin1_before ⊑ uge_umin1_after

theorem n12_thm (e e_1 : IntW 32) :
  add (add (LLVM.xor e_1 (const? 32 (-1))) e) (const? 32 2) ⊑
    add (add e (LLVM.xor e_1 (const? 32 (-1)))) (const? 32 2)

theorem ashr_ult_15_proof : ashr_ult_15_before ⊑ ashr_ult_15_after

theorem e_1563 :
    2 * ( ~~~b |||  ~~~(a ^^^ c)) - 1 * (c &&& (a ^^^ b)) - 3 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (a ||| (b ||| c)) + 4 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 5 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) + 9 *  ~~~( ~~~a ||| (b ||| c)) + 1 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 6 * ( ~~~a &&& (b &&& c)) + 3 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) = 1 * (a |||  ~~~b)

theorem sdiv_shl_shl_nsw2_nuw_thm (e e_1 e_2 : IntW 8) :
  LLVM.sdiv (shl e_2 e_1 { «nsw» := true, «nuw» := false }) (shl e e_1 { «nsw» := true, «nuw» := true }) ⊑
    LLVM.sdiv e_2 e

@[grind =, simp, aesop 50% unsafe]
lemma states_empty :
    RawCNFA.empty (A := A).states = ∅

theorem ashrslt_03_00_exact_proof : ashrslt_03_00_exact_before ⊑ ashrslt_03_00_exact_after

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

theorem or_and_not_not_commute2_proof : or_and_not_not_commute2_before ⊑ or_and_not_not_commute2_after

theorem e_1033 :
     - 1 * t + 11 *  ~~~(z &&&  ~~~z) + 2 *  ~~~(z ^^^ t) + 3 * (z |||  ~~~t) - 1 *  ~~~t - 15 *  ~~~(z ||| t) - 10 *  ~~~(z |||  ~~~t) = 15 * (z &&& t) + 13 * (z &&&  ~~~t)

theorem testtrunclowhigh_thm (e e_1 : IntW 16) (e_2 : IntW 32) :
  select (icmp IntPred.ult (add e_2 (const? 32 128)) (const? 32 256)) (trunc 16 e_2)
      (select (icmp IntPred.sgt e_2 (const? 32 (-1))) e_1 e) ⊑
    select (icmp IntPred.ult (add e_2 (const? 32 128)) (const? 32 256)) (trunc 16 e_2)
      (select (icmp IntPred.slt e_2 (const? 32 0)) e e_1)

theorem e_2250 :
    11 * (f ^^^ (d &&& ( ~~~e ||| f))) - 2 * ( ~~~e ||| (d ^^^ f)) - 6 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 3 * (f &&& (d |||  ~~~e)) - 11 * (e ^^^ (d |||  ~~~f)) - 2 * (e |||  ~~~(d ||| f)) + 2 * (f ^^^ (d &&& e)) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * ( ~~~d &&& ( ~~~e ||| f)) - 5 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 7 * (d ^^^ ( ~~~e &&& f)) + 1 *  ~~~(e ||| f) + 3 * (e &&&  ~~~(d &&& f)) + 1 *  ~~~(d &&&  ~~~d) - 2 * (d ^^^ f) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 *  ~~~(d &&& (e &&& f)) + 7 * (e ^^^ (d ||| (e ||| f))) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 1 *  ~~~(d |||  ~~~f) - 6 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 *  ~~~(d &&& e) + 3 * (f &&&  ~~~(d &&& e)) - 5 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 * (e &&& (d ||| f)) + 1 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 6 * (e |||  ~~~(d ^^^ f)) + 5 * (d &&& (e ^^^ f)) + 3 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * (f ^^^ (d |||  ~~~e)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 5 *  ~~~(d &&& (e ||| f)) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 * (d ^^^ (e &&& f)) - 1 * ( ~~~e &&& (d ^^^ f)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 *  ~~~(d ^^^ ( ~~~e &&& f)) - 1 * ((d ||| e) &&& (e ^^^ f)) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (f &&& (d ||| e)) - 5 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ e) + 2 *  ~~~(e |||  ~~~f) + 7 * e - 1 *  ~~~(d ||| f) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 37 *  ~~~(d ||| (e ||| f)) + 10 *  ~~~(d ||| ( ~~~e ||| f)) + 19 *  ~~~( ~~~d ||| (e ||| f)) + 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) + 20 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) =  - 28 * (d &&& (e &&& f))

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

theorem test_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (lshr (const? 32 3968) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (shl (const? 32 1) e { «nsw» := false, «nuw» := true }) (const? 32 3968))
      (const? 32 0)

theorem alive_152 : alive_152_src ⊑ alive_152_tgt

theorem p0_proof : p0_before ⊑ p0_after

theorem sgt_swap_or_not_min_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.slt e_1 e) (icmp IntPred.ne e (const? 8 (-128))) ⊑
    icmp IntPred.ne e (const? 8 (-128))

theorem test_shl_nuw_nsw__nuw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    ¬(True ∧ ((x_1 &&& 1073741822#32) <<< 2#32).sshiftRight' 2#32 ≠ x_1 &&& 1073741822#32 ∨
          True ∧ (x_1 &&& 1073741822#32) <<< 2#32 >>> 2#32 ≠ x_1 &&& 1073741822#32 ∨
            2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& 1073741822#32) <<< 2#32) ≥ ↑64) →
      2#32 ≥ ↑32 ∨
          True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
            zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64 →
        False

theorem not_mul_of_pow2_proof : not_mul_of_pow2_before ⊑ not_mul_of_pow2_after

theorem logic_or_logic_and_5_proof : logic_or_logic_and_5_before ⊑ logic_or_logic_and_5_after

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

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 or_and1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1), (x_2 ^^^ 1#1) &&& x_1 = 1#1 → x_2 = 1#1 → x = 1#1

theorem foo_proof : foo_before ⊑ foo_after

theorem prove_exact_with_high_mask_limit_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-32) == 0 || 8 != 1 && x &&& BitVec.ofInt 8 (-32) == intMin 8 && BitVec.ofInt 8 (-32) == -1) =
        true →
    5#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 5#8) = true → False

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

theorem lshr_2_add_zext_basic_proof : lshr_2_add_zext_basic_before ⊑ lshr_2_add_zext_basic_after

theorem sub_zext_trunc_lshr_proof : sub_zext_trunc_lshr_before ⊑ sub_zext_trunc_lshr_after

theorem neg_sgt_42_proof : neg_sgt_42_before ⊑ neg_sgt_42_after

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

theorem PR60818_sgt_proof : PR60818_sgt_before ⊑ PR60818_sgt_after

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

theorem test1_proof : test1_before ⊑ test1_after

theorem or_simplify_ugt_proof : or_simplify_ugt_before ⊑ or_simplify_ugt_after

theorem canonicalize_logic_first_and0_nswnuw_proof : canonicalize_logic_first_and0_nswnuw_before ⊑ canonicalize_logic_first_and0_nswnuw_after

theorem test9_proof : test9_before ⊑ test9_after

theorem positive_samevar_lshrexact_proof : positive_samevar_lshrexact_before ⊑ positive_samevar_lshrexact_after

theorem zext_shl_proof : zext_shl_before ⊑ zext_shl_after

theorem test_thm.extracted_1._2 : ∀ (x : BitVec 31),
  ¬15#32 ≥ ↑32 →
    ¬(True ∧ (zeroExtend 32 x).uaddOverflow 16384#32 = true ∨ 15#32 ≥ ↑32) →
      truncate 16 ((signExtend 32 x + 16384#32) >>> 15#32) = truncate 16 ((zeroExtend 32 x + 16384#32) >>> 15#32)

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

theorem lor_bor_right2_thm (e e_1 : IntW 1) : LLVM.or e_1 (select e (const? 1 1) e_1) ⊑ select e (const? 1 1) e_1

theorem lshr_shl_demand4_thm (e : IntW 8) :
  LLVM.or (shl (lshr (const? 8 60) e) (const? 8 3)) (const? 8 7) ⊑
    LLVM.or (shl (lshr (const? 8 60) e) (const? 8 3)) (const? 8 7) { «disjoint» := true }

theorem cmpeq_bitwise_thm (e e_1 e_2 e_3 : IntW 8) :
  icmp IntPred.eq (LLVM.or (LLVM.xor e_3 e_2) (LLVM.xor e_1 e)) (const? 8 0) ⊑
    LLVM.and (icmp IntPred.eq e_3 e_2) (icmp IntPred.eq e_1 e)

theorem lshr_31_i32_add_zext_basic_proof : lshr_31_i32_add_zext_basic_before ⊑ lshr_31_i32_add_zext_basic_after

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(zeroExtend 32 (32#16 - x) ≥ ↑32 ∨ x + -1#16 ≥ ↑16) →
    31#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 16 (x_1.sshiftRight' 31#32)) ≠ x_1.sshiftRight' 31#32 → False

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

theorem splat_mul_known_lz_proof : splat_mul_known_lz_before ⊑ splat_mul_known_lz_after

theorem add_umin_simplify2_thm (e : IntW 32) :
  select (icmp IntPred.ult (add e (const? 32 43) { «nsw» := false, «nuw» := true }) (const? 32 42))
      (add e (const? 32 43) { «nsw» := false, «nuw» := true }) (const? 32 42) ⊑
    const? 32 42

theorem xor_icmp_to_ne_proof : xor_icmp_to_ne_before ⊑ xor_icmp_to_ne_after

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

theorem foo_proof : foo_before ⊑ foo_after

theorem ashr_lshr_wrong_operands_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 ≤ₛ x_1) = 1#1 → ¬x ≥ ↑32 → ¬ofBool (x_1 <ₛ 0#32) = 1#1 → x_1 >>> x = x_1.sshiftRight' x

theorem test21_proof : test21_before ⊑ test21_after

theorem demorgan_plus_and_to_xor_proof : demorgan_plus_and_to_xor_before ⊑ demorgan_plus_and_to_xor_after

theorem trunc_sandwich_big_sum_shift1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(21#32 ≥ ↑32 ∨ 11#12 ≥ ↑12) → truncate 12 (x >>> 21#32) >>> 11#12 = 0#12

theorem 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 main11_logical_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 == 0#32) = 1#1 →
    ofBool (x &&& 192#32 == 192#32) = 1#1 → ofBool (0#8 ≤ₛ truncate 8 x) = 1#1 → 2#32 = 1#32

theorem sgt_and_min_logical_thm (e e_1 : IntW 9) :
  select (icmp IntPred.sgt e_1 e) (icmp IntPred.eq e_1 (const? 9 (-256))) (const? 1 0) ⊑ const? 1 0

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

theorem sub_self (a : ZMod q) : a - a = 0

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

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

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

theorem match_unsigned_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(299#64 = 0 ∨ 299#64 = 0 ∨ 64#64 = 0) → ¬19136#64 = 0 → x % 299#64 + x / 299#64 % 64#64 * 299#64 = x % 19136#64

theorem and_ne_with_one_bit_diff_constants1_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 51)) (icmp IntPred.ne e (const? 32 50)) (const? 1 0) ⊑
    icmp IntPred.ult (add e (const? 32 (-52))) (const? 32 (-2))

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

theorem icmp_select_var_pred_uge_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 0#8) = 1#1 →
    ¬(True ∧ x.uaddOverflow 2#8 = true) → ¬ofBool (x_1 != 0#8) = 1#1 → ofBool (x + 2#8 ≤ᵤ x) = 0#1

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

theorem dec_mask_commute_neg_i32_thm (e : IntW 32) :
  add (LLVM.and (LLVM.sdiv (const? 32 42) e) (sub (const? 32 0) (LLVM.sdiv (const? 32 42) e))) (const? 32 (-1)) ⊑
    LLVM.and (add (LLVM.sdiv (const? 32 42) e) (const? 32 (-1)) { «nsw» := true, «nuw» := false })
      (LLVM.xor (LLVM.sdiv (const? 32 42) e) (const? 32 (-1)))

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

theorem or_def {α : Type _} (c d : Circuit α) :
  (c ||| d) = Circuit.simplifyOr c d

lemma eval_scanAnd_eq_decide (x : Unit → BitStream) (n : Nat) : scanAnd.eval x n =
  decide (∀ (i : Nat), (hi : i ≤ n) → x () i = true)

theorem add_signbit_shl_proof : add_signbit_shl_before ⊑ add_signbit_shl_after

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

theorem n2_proof : n2_before ⊑ n2_after

theorem pr4917_3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (4294967295#64 <ᵤ zeroExtend 64 x_1 * zeroExtend 64 x) = 1#1 →
    True ∧ (zeroExtend 64 x_1).umulOverflow (zeroExtend 64 x) = true → False

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

theorem sle_smin2_thm (e e_1 : IntW 32) :
  icmp IntPred.sle (select (icmp IntPred.slt e_1 e) e_1 e) e ⊑ const? 1 1

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

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

theorem trunc_sandwich_min_shift1_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(20#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) →
    ¬(21#32 ≥ ↑32 ∨
          True ∧ signExtend 32 (truncate 12 (x >>> 21#32)) ≠ x >>> 21#32 ∨
            True ∧ zeroExtend 32 (truncate 12 (x >>> 21#32)) ≠ x >>> 21#32) →
      truncate 12 (x >>> 20#32) >>> 1#12 = truncate 12 (x >>> 21#32)

theorem shl_or_with_or_disjoint_instead_of_add_proof : shl_or_with_or_disjoint_instead_of_add_before ⊑ shl_or_with_or_disjoint_instead_of_add_after

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

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

theorem neg_or_ashr_i32_proof : neg_or_ashr_i32_before ⊑ neg_or_ashr_i32_after

theorem e_1930 :
     - 1 * (c ^^^ ( ~~~a ||| (b ||| c))) - 7 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 1 * (b &&& c) + 7 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 11 * (c ||| (a ^^^ b)) - 2 * (a ^^^ ( ~~~b ||| c)) - 1 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 3 * (c ^^^  ~~~(a &&& b)) - 3 * (b ^^^  ~~~(a &&& c)) + 1 * (c &&&  ~~~(a ^^^ b)) + 7 * ((a &&& c) |||  ~~~(b ||| c)) - 7 * (b ^^^ ( ~~~a ||| (b ||| c))) + 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 5 *  ~~~(a ^^^ (b ^^^ c)) - 1 * (c ^^^ (a ||| (b &&& c))) - 6 * (c ^^^  ~~~(a ||| b)) - 5 * (a ^^^ (b &&& c)) + 2 * ((a ||| b) &&& (b ^^^ c)) + 1 * c + 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 * (c ^^^  ~~~(a |||  ~~~b)) + 4 * (a ||| (b ^^^ c)) - 6 *  ~~~(a &&& (b ||| c)) - 11 * (c ^^^ ( ~~~a ||| (b &&& c))) - 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 3 * (b ^^^ (a &&& (b ^^^ c))) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) + 1 * (c ^^^ (a &&& b)) - 7 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 3 * (a ^^^ b) - 7 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 1 * (b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a &&& (b ||| c))) - 2 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 1 *  ~~~(a ^^^ c) + 2 * (b ||| (a ^^^ c)) + 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 11 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 7 * (a ||| b) + 1 * ( ~~~a &&& (b ^^^ c)) + 4 *  ~~~(a |||  ~~~b) + 5 *  ~~~( ~~~a &&& (b &&& c)) + 38 *  ~~~(a ||| (b ||| c)) + 9 *  ~~~(a ||| ( ~~~b ||| c)) - 10 *  ~~~( ~~~a ||| (b ||| c)) - 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 9 * ( ~~~a &&& ( ~~~b &&& c)) + 3 * ( ~~~a &&& (b &&& c)) - 7 * (a &&& ( ~~~b &&& c)) - 5 * (a &&& (b &&& c)) =  - 1 * (b ^^^  ~~~(a &&&  ~~~c))

theorem e_601 :
     - 1 *  ~~~(x ^^^ y) - 1 *  ~~~x + 4 * y + 5 * x - 5 * (x |||  ~~~y) - 11 *  ~~~(x &&&  ~~~x) + 25 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 17 * (x &&&  ~~~y) + 8 * (x &&& y) = 7 *  ~~~y - 1 * (x ^^^ y)

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

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

theorem ashrslt_02_05_exact_proof : ashrslt_02_05_exact_before ⊑ ashrslt_02_05_exact_after

theorem select_constants_and_icmp_eq0_zero_fval_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x = 1#1 → ofBool (0#8 &&& 0#8 == 0#8) = 0#1 ^^^ 1#1

theorem bor_lor_right2_proof : bor_lor_right2_before ⊑ bor_lor_right2_after

theorem lshr_not_nneg2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 →
    ¬(1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8 &&& BitVec.ofInt 8 (-128) != 0) = true) →
      (x ^^^ -1#8) >>> 1#8 ^^^ -1#8 = x >>> 1#8 ||

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

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

theorem lshrult_03_15_proof : lshrult_03_15_before ⊑ lshrult_03_15_after

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

theorem and_sel_op0_thm (e : IntW 1) : LLVM.and (select e (const? 32 25) (const? 32 0)) (const? 32 1) ⊑ zext 32 e

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

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

theorem PR2539_B_proof : PR2539_B_before ⊑ PR2539_B_after

theorem or_xor_common_op_commute6_proof : or_xor_common_op_commute6_before ⊑ or_xor_common_op_commute6_after

@[simp]
theorem envBitstream_set_eq_self_of_ne {x : arity → BitStream}
    {n k : Nat} {v : arity → Bool} {a : arity} (hneq : k ≠ n) :
  (envBitstream_set x n v) a k = x a k

theorem src_srem_shl_demand_max_mask_hit_demand_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬((4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    (4#32 == 0 || 32 != 1 && x == intMin 32 && 4#32 == -1) = true ∨
        True ∧ (x.srem 4#32 <<< 1#32).sshiftRight' 1#32 ≠ x.srem 4#32 ∨ 1#32 ≥ ↑32 →
      False

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

theorem fold_add_sdiv_srem_proof : fold_add_sdiv_srem_before ⊑ fold_add_sdiv_srem_after

theorem test10_logical_proof : test10_logical_before ⊑ test10_logical_after

theorem no_shift_xor_multiuse_cmp_or_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (0#32 != x_2 &&& 4096#32) = 1#1 → ofBool (x_2 &&& 4096#32 == 0#32) = 1#1 → False

theorem zext_or_eq_ult_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32) ||| ofBool (x == 5#32)) =
    zeroExtend 32 (ofBool (x + BitVec.ofInt 32 (-3) <ᵤ 3#32))

theorem multiuse_add_thm (e : IntW 1) :
  add (add (select e (const? 64 64) (const? 64 1)) (zext 64 e)) (const? 64 1) ⊑
    select e (const? 64 66) (const? 64 2)

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 xor_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ^^^ signExtend 16 x = signExtend 16 (x_1 ^^^ signExtend 8 x)

theorem positive_sameconst_shlnsw_lshrexact_proof : positive_sameconst_shlnsw_lshrexact_before ⊑ positive_sameconst_shlnsw_lshrexact_after

theorem ashrslt_01_08_proof : ashrslt_01_08_before ⊑ ashrslt_01_08_after

theorem or_eq_with_one_bit_diff_constants2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 97#32) ||

theorem logic_and_logic_or_3_proof : logic_and_logic_or_3_before ⊑ logic_and_logic_or_3_after

theorem test_ult_xor_proof : test_ult_xor_before ⊑ test_ult_xor_after

theorem narrow_zext_ashr_keep_trunc_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (signExtend 32 x_1).saddOverflow (signExtend 32 x) = true ∨ 1#32 ≥ ↑32) →
    ¬(True ∧ (signExtend 16 x_1).saddOverflow (signExtend 16 x) = true ∨ 1#16 ≥ ↑16) →
      truncate 8 ((signExtend 32 x_1 + signExtend 32 x).sshiftRight' 1#32) =
        truncate 8 ((signExtend 16 x_1 + signExtend 16 x) >>> 1#16)

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& 3#8 != x) = ofBool (3#8 <ᵤ x)

theorem alive_AddSub_1309  (w : Nat)   : alive_AddSub_1309_src w  ⊑ alive_AddSub_1309_tgt w

theorem lshrult_02_12_exact_proof : lshrult_02_12_exact_before ⊑ lshrult_02_12_exact_after

theorem icmp_sle6_proof : icmp_sle6_before ⊑ icmp_sle6_after

theorem test46_proof : test46_before ⊑ test46_after

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

@[simp]
theorem eval_bigAnd_eq_false_iff
    (cs : List (Circuit α)) (env : α → Bool):
    (Circuit.bigAnd cs).eval env = false ↔
    (∃ (c : Circuit α), c ∈ cs ∧ c.eval env = false)

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

theorem lshrugt_01_09_proof : lshrugt_01_09_before ⊑ lshrugt_01_09_after

theorem t1_sub_of_falseval_proof : t1_sub_of_falseval_before ⊑ t1_sub_of_falseval_after

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

theorem sdiv_i1_is_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬(x == 0 || 1 != 1 && x_1 == intMin 1 && x == -1) = true → x_1.sdiv x = x_1

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

@[simp] theorem Lets.vars_var {lets : Lets d Γ_in eff Γ_out}
    {t} {e : Expr d Γ_out eff t} {w : Γ_out.Var u} :
    Lets.vars (Lets.var lets e) w.appendInr
    = Lets.vars lets w

theorem e_2163 :
     - 5 * ((d ^^^ e) &&& (d ^^^ f)) + 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 5 * ( ~~~f &&&  ~~~(d ^^^ e)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) - 7 * (e ^^^ f) - 1 * ((e &&& f) ||| (d &&& (e ||| f))) + 11 * (f ^^^  ~~~(d |||  ~~~e)) - 6 * (f ^^^ (d ||| (e &&& f))) + 2 * ( ~~~d ||| (e ^^^ f)) - 6 * ( ~~~e &&& (d ^^^ f)) + 7 * (e &&&  ~~~f) - 11 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 3 *  ~~~(d ||| (e ^^^ f)) + 11 * (d ^^^ (e &&& f)) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e &&& (d |||  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d &&& f)) - 7 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 2 * ( ~~~d &&& (e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 7 *  ~~~(d ^^^ (e ^^^ f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 2 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) - 2 *  ~~~(d ^^^ (e ||| f)) + 5 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * (f ^^^  ~~~(d &&& (e &&& f))) - 7 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (e |||  ~~~f) - 5 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 3 * (e |||  ~~~(d |||  ~~~f)) - 1 * (f &&&  ~~~(d ^^^ e)) - 5 *  ~~~(d ||| (e ||| f)) - 2 *  ~~~(d ||| ( ~~~e ||| f)) + 13 *  ~~~( ~~~d ||| (e ||| f)) - 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 9 * ( ~~~d &&& ( ~~~e &&& f)) + 2 * ( ~~~d &&& (e &&& f)) - 25 * (d &&& ( ~~~e &&& f)) + 4 * (d &&& (e &&& f)) =  - 7 *  ~~~( ~~~d &&& (e &&& f))

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

theorem test_add_nuw_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    ¬(True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true ∨
          True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).uaddOverflow 1#32 = true) →
      True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true → False

@[simp] theorem Com.returnVars_var :
    returnVars (var (d:=d) (eff:=eff) e body) = body.returnVars

theorem ripple_nsw5_thm (e e_1 : IntW 16) :
  add (LLVM.or e_1 (const? 16 (-21845))) (LLVM.or e (const? 16 (-10923))) ⊑
    add (LLVM.or e_1 (const? 16 (-21845))) (LLVM.or e (const? 16 (-10923))) { «nsw» := true, «nuw» := false }

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

theorem and_add_bool_to_select_multi_use_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → (-1#32 + zeroExtend 32 x_1 &&& x) + (-1#32 + zeroExtend 32 x_1) = 0#32

theorem icmp_sgt9_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 7#8).sshiftRight' 7#8 ≠ x ∨ 7#8 ≥ ↑8) →
    ofBool (BitVec.ofInt 8 (-128) <ₛ x <<< 7#8) = ofBool (x == 0#8)

theorem test7_proof : test7_before ⊑ test7_after

theorem ugt_and_not_min_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) &&& ofBool (x_1 != 0#8) = ofBool (x <ᵤ x_1)

theorem shl_nsw_nuw_proof : shl_nsw_nuw_before ⊑ shl_nsw_nuw_after

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

theorem test3_proof : test3_before ⊑ test3_after

theorem select_lshr_icmp_const_reordered_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 32#32) = 1#1 → 5#32 ≥ ↑32 → False

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

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

theorem icmp_eq_x_invertable_y2_proof : icmp_eq_x_invertable_y2_before ⊑ icmp_eq_x_invertable_y2_after

theorem e_1679 :
    1 * (a ||| (b ||| c)) + 11 * (b &&&  ~~~(a ^^^ c)) - 11 * (a &&&  ~~~b) + 5 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 7 * ( ~~~c &&& (a ^^^ b)) - 1 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * (a ^^^ (b ^^^ c)) + 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 11 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 4 * ((a &&& b) ||| (b ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 2 * (b ^^^ (a ||| (b ||| c))) - 11 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 7 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * ((a &&& b) ^^^ (b ||| c)) - 1 * (c |||  ~~~(a |||  ~~~b)) + 1 * (c ^^^ ( ~~~a ||| (b ||| c))) + 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 11 *  ~~~(a ||| (b ||| c)) - 26 *  ~~~(a ||| ( ~~~b ||| c)) + 10 *  ~~~( ~~~a ||| (b ||| c)) - 29 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) - 31 * (a &&& ( ~~~b &&& c)) - 11 * (a &&& (b &&& c)) =  - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 *  ~~~( ~~~a ||| ( ~~~b ||| c))

theorem test_or_eq_different_operands_proof : test_or_eq_different_operands_before ⊑ test_or_eq_different_operands_after

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

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

theorem test5_thm (e e_1 e_2 : IntW 19) : sub e_2 (sub e_1 e) ⊑ add (sub e e_1) e_2

theorem sge_smin1_proof : sge_smin1_before ⊑ sge_smin1_after

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

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

theorem not_select_bool_const1_proof : not_select_bool_const1_before ⊑ not_select_bool_const1_after

theorem positive_biggershl_thm (e : IntW 8) :
  shl (lshr e (const? 8 3)) (const? 8 6) ⊑ LLVM.and (shl e (const? 8 3)) (const? 8 (-64))

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

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (BitVec.ofInt 8 (-127) ≤ₛ x) = ofBool (x != BitVec.ofInt 8 (-128))

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

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

theorem p0_proof : p0_before ⊑ p0_after

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

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

theorem icmp_power2_and_icmp_shifted_mask_swapped_2147483648_1610612736_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1610612736#32 != 1610612736#32) &&& ofBool (x <ᵤ BitVec.ofInt 32 (-2147483648)) =
    ofBool (x <ᵤ 1610612736#32)

theorem gt_signed_to_small_unsigned_proof : gt_signed_to_small_unsigned_before ⊑ gt_signed_to_small_unsigned_after

theorem test94_thm.extracted_1._1 : ∀ (x : BitVec 32),
  signExtend 64 (signExtend 8 (ofBool (x == BitVec.ofInt 32 (-2))) ^^^ -1#8) =
    signExtend 64 (ofBool (x != BitVec.ofInt 32 (-2)))

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

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

theorem carry_incr (x : Unit → BitStream) : ∀ (n : ℕ),
    incr.carry x (n+1) = fun _ => (BitStream.incrAux (x ()) n).2

theorem lsb_mask_sign_zext_wrong_cst2_proof : lsb_mask_sign_zext_wrong_cst2_before ⊑ lsb_mask_sign_zext_wrong_cst2_after

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

theorem select_or_icmp_bad_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == 3#32) = 1#1 → x_1 ||

theorem substitute_constant_or_ne_uge_commute_logical_proof : substitute_constant_or_ne_uge_commute_logical_before ⊑ substitute_constant_or_ne_uge_commute_logical_after

@[aesop 80% unsafe]
theorem Std.HashMap.mem_keys_insert_old [BEq K] [LawfulBEq K] [Hashable K] [LawfulHashable K] (m : Std.HashMap K V) (k k' : K) :
    k ∈ m → k ∈ m.insert k' v

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

theorem masked_bit_set_nonzero_cmp_proof : masked_bit_set_nonzero_cmp_before ⊑ masked_bit_set_nonzero_cmp_after

theorem or_logic_or_logic_and_1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 ||

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

theorem sgt_and_not_min_proof : sgt_and_not_min_before ⊑ sgt_and_not_min_after

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

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

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

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

theorem test_mul_nuw_nsw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 268435457#32 == 268435456#32) = 1#1 → True ∧ (x &&& 268435457#32).umulOverflow 9#32 = true → False

theorem cmpeq_xor_cst1_commuted_proof : cmpeq_xor_cst1_commuted_before ⊑ cmpeq_xor_cst1_commuted_after

@[simp] theorem toCom_var {lets : Lets d Γ_in eff Γ_mid} :
    toCom ⟨Lets.var lets e, com⟩ = toCom ⟨lets, Com.var e com⟩

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

theorem e_267 :
     - 1 *  ~~~(x ^^^ y) - 3 *  ~~~(x &&&  ~~~y) - 6 * y - 11 *  ~~~(x &&&  ~~~x) + 15 *  ~~~(x ||| y) + 20 *  ~~~(x |||  ~~~y) + 4 * (x &&&  ~~~y) =  - 14 * (x &&& y) - 7 * x

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

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

lemma worklistRun'_wf :
    (worklistRun' A S final inits hinits f).WF

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_7_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 7)) (const? 32 0)) (const? 1 0) ⊑
    const? 1 0

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

theorem test16_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬1#32 ≥ ↑32 →
    ¬(1#32 ≥ ↑32 ∨ True ∧ (BitVec.ofInt 32 (-2)).usubOverflow (x >>> 1#32) = true) →
      4294967294#64 - zeroExtend 64 (x >>> 1#32) = zeroExtend 64 (BitVec.ofInt 32 (-2) - x >>> 1#32)

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

theorem corec₂_corec2 (s : Stream γ) (f : Stream γ -> Option α × Option β × Stream γ) :
  (corec₂ s f).2 = corec s (fun s' => let ⟨ _, a, b ⟩ := f s'; (a, b) )

theorem add_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → (x_1 ^^^ -1#8) + x ^^^ -1#8 = x_1 - x

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

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 shl1_trunc_sgt0_thm (e : IntW 9) :
  icmp IntPred.sgt (trunc 6 (shl (const? 9 1) e)) (const? 6 0) ⊑
    icmp IntPred.sgt (trunc 6 (shl (const? 9 1) e { «nsw» := false, «nuw» := true })) (const? 6 0)

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

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

theorem not_sext_proof : not_sext_before ⊑ not_sext_after

theorem lshrult_02_07_exact_proof : lshrult_02_07_exact_before ⊑ lshrult_02_07_exact_after

theorem slt_zero_eq_i1_fail_signed_proof : slt_zero_eq_i1_fail_signed_before ⊑ slt_zero_eq_i1_fail_signed_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_5_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 15)) (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 ashrslt_03_14_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬3#4 ≥ ↑4 → ofBool (x.sshiftRight' 3#4 <ₛ BitVec.ofInt 4 (-2)) = 0#1

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

theorem n13_overshift_thm (e : IntW 64) (e_1 e_2 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (lshr e_2 (sub (const? 32 32) e_1)) (trunc 32 (shl e (zext 64 (add e_1 (const? 32 32))))))
      (const? 32 0) ⊑
    icmp IntPred.ne
      (LLVM.and (lshr e_2 (sub (const? 32 32) e_1))
        (trunc 32 (shl e (zext 64 (add e_1 (const? 32 32)) { «nneg» := true }))))
      (const? 32 0)

theorem e_1741 :
    1 * c + 1 * (a &&& ( ~~~b ||| c)) + 2 * b + 3 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 1 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 3 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 11 * (b ^^^  ~~~(a &&&  ~~~c)) - 2 * (a ^^^ (b ||| c)) + 4 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 3 * (c ^^^ (a ||| (b &&& c))) - 3 * (a &&& (b ||| c)) + 1 * (b ^^^  ~~~(a &&& (b ||| c))) + 2 * (c ^^^  ~~~(a &&& b)) - 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 2 * (c ^^^ (a &&& b)) - 1 *  ~~~b - 6 * (c &&& (a ||| b)) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 2 * ( ~~~a ||| ( ~~~b &&& c)) - 5 * (a ||| ( ~~~b &&& c)) + 1 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 5 * (b ||| (a &&&  ~~~c)) - 5 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 1 * (b &&& (a ||| c)) + 6 *  ~~~(a ||| (b ||| c)) - 4 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) + 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& (b &&& c)) + 23 * (a &&& ( ~~~b &&& c)) + 9 * (a &&& (b &&& c)) =  - 5 * (c ^^^ (a ||| b)) - 1 * ( ~~~a &&& ( ~~~b &&& c))

theorem not_and_and_or_no_or_commute1_proof : not_and_and_or_no_or_commute1_before ⊑ not_and_and_or_no_or_commute1_after

theorem lshr_and_sub_proof : lshr_and_sub_before ⊑ lshr_and_sub_after

theorem PR42691_5_logical_proof : PR42691_5_logical_before ⊑ PR42691_5_logical_after

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

theorem vars_simplifyXor [DecidableEq α] (c₁ c₂ : Circuit α) :
    (vars (simplifyXor c₁ c₂)) ⊆ (vars c₁ ++ vars c₂).dedup

theorem main8_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 64#32 != 0#32) ||

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

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

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

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

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

theorem or_eq_with_diff_one_signed_proof : or_eq_with_diff_one_signed_before ⊑ or_eq_with_diff_one_signed_after

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

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

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

theorem trunc_lshr_sext_exact_proof : trunc_lshr_sext_exact_before ⊑ trunc_lshr_sext_exact_after

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

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

theorem icmp_sle6_proof : icmp_sle6_before ⊑ icmp_sle6_after

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  zeroExtend 32 (ofBool (x_1 <ₛ 0#32) ^^^ ofBool (-1#32 <ₛ x)) = zeroExtend 32 (ofBool (-1#32 <ₛ x_1 ^^^ x))

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

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

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

theorem add_const_sub_const_thm (e : IntW 32) : sub (add e (const? 32 8)) (const? 32 2) ⊑ add e (const? 32 6)

theorem alive_AddSub_1156 : alive_AddSub_1156_src ⊑ alive_AddSub_1156_tgt

theorem test36_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ (x + 7#32 &&& 240#32).msb = true) →
    zeroExtend 64 x + 7#64 &&& 240#64 = zeroExtend 64 (x + 7#32 &&& 240#32)

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

theorem icmp_sgt11_proof : icmp_sgt11_before ⊑ icmp_sgt11_after

theorem demo3 (x y : BitVec 8) :
    (x ^^^ -1#8 ||| 7#8) ^^^ 12#8 = x &&& BitVec.ofInt 8 (-8) ^^^ BitVec.ofInt 8 (-13)

theorem AndZextAnd_thm.extracted_1._2 : ∀ (x : BitVec 3),
  ¬(True ∧ (x &&& 2#3).msb = true) → zeroExtend 5 (x &&& 3#3) &&& 14#5 = zeroExtend 5 (x &&& 2#3)

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

theorem masked_bit_set_nonzero_cmp_proof : masked_bit_set_nonzero_cmp_before ⊑ masked_bit_set_nonzero_cmp_after

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

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

theorem multiuse1_proof : multiuse1_before ⊑ multiuse1_after

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

theorem t4_proof : t4_before ⊑ t4_after

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

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

theorem sextinreg2_thm (e : IntW 32) :
  add (LLVM.xor (LLVM.and e (const? 32 255)) (const? 32 128)) (const? 32 (-128)) ⊑
    ashr (shl e (const? 32 24)) (const? 32 24) { «exact» := true }

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

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

theorem negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_proof : negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_before ⊑ negtest_near_pow2_cmpval_ashr_wrong_cmp_pred_after

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

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

theorem ashr_and_icmp_sge_neg1_i64_proof : ashr_and_icmp_sge_neg1_i64_before ⊑ ashr_and_icmp_sge_neg1_i64_after

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

theorem land_lor_right2_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 1#1 = x

theorem test67_proof : test67_before ⊑ test67_after

theorem mul_zero (a : ZMod q) : a * 0 = 0

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

theorem bools2_logical_commute2_thm.extracted_1._10 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬x = 1#1 → x_1 = 1#1 → 1#1 = x_1

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

theorem sext_zext_slt_known_nonneg_proof : sext_zext_slt_known_nonneg_before ⊑ sext_zext_slt_known_nonneg_after

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

theorem f2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ₛ 0#32) = 1#1 →
    ¬x ≥ ↑32 → zeroExtend 32 (ofBool ((7#32).sshiftRight' x <ₛ x_1)) = zeroExtend 32 (ofBool (7#32 >>> x <ₛ x_1))

theorem p_commutative0_proof : p_commutative0_before ⊑ p_commutative0_after

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

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

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

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

theorem icmp_and_ashr_multiuse_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and (ashr e (const? 32 4)) (const? 32 15)) (const? 32 14))
      (icmp IntPred.ne (LLVM.and (ashr e (const? 32 4)) (const? 32 31)) (const? 32 27)) ⊑
    LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 240)) (const? 32 224))
      (icmp IntPred.ne (LLVM.and e (const? 32 496)) (const? 32 432))

theorem ashrsgt_01_00_exact_proof : ashrsgt_01_00_exact_before ⊑ ashrsgt_01_00_exact_after

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

theorem mul_add_to_mul_1_proof : mul_add_to_mul_1_before ⊑ mul_add_to_mul_1_after

omit [Fintype S] [DecidableEq S] in
lemma processOneElem_trans_preserve (st : worklist.St A S) (final : S → Bool) (a b : A) (sa : S) (s s1 s2 : State) :
    s2 ∈ st.m.tr s1 b →
    s2 ∈ (processOneElem A S final s st (a, sa)).m.tr s1 b

theorem udiv_icmp1_proof : udiv_icmp1_before ⊑ udiv_icmp1_after

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

theorem test_invalid_simplify_other_proof : test_invalid_simplify_other_before ⊑ test_invalid_simplify_other_after

theorem bitwise_and_logical_and_masked_icmp_allzeros_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 8#32 == 0#32) = 1#1 →
    ¬ofBool (x_1 &&& 15#32 == 0#32) = 1#1 → 0#1 &&& ofBool (x_1 &&& 7#32 == 0#32) = 0#1

theorem C0zero_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 + 10#8 <ᵤ 0#8) = 1#1 → ofBool (x_1 <ₛ BitVec.ofInt 8 (-10)) = 1#1 → x_1 = x

theorem test12_proof : test12_before ⊑ test12_after

theorem sdiv_mul_shl_nsw_exact_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 5),
  ¬(True ∧ x_2.smulOverflow x_1 = true ∨
        True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨
          x ≥ ↑5 ∨
            True ∧ (x_2 * x_1).smod (x_1 <<< x) ≠ 0 ∨
              (x_1 <<< x == 0 || 5 != 1 && x_2 * x_1 == intMin 5 && x_1 <<< x == -1) = true) →
    True ∧ 1#5 <<< x >>> x ≠ 1#5 ∨
        x ≥ ↑5 ∨
          True ∧ x_2.smod (1#5 <<< x) ≠ 0 ∨ (1#5 <<< x == 0 || 5 != 1 && x_2 == intMin 5 && 1#5 <<< x == -1) = true →
      False

theorem test20_thm (e : IntW 13) : icmp IntPred.eq (ashr e (const? 13 12)) (const? 13 123) ⊑ const? 1 0

theorem lshrult_02_14_exact_proof : lshrult_02_14_exact_before ⊑ lshrult_02_14_exact_after

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

@[simp, simp_sllvm]
theorem pure_eq (x : α) (s) : (pure x : EffectM _) s = .value (x, s)

theorem udiv_shl_pair_const_thm (e : IntW 32) :
  LLVM.udiv (shl e (const? 32 2) { «nsw» := false, «nuw» := true })
      (shl e (const? 32 1) { «nsw» := false, «nuw» := true }) ⊑
    const? 32 2

theorem trunc_nsw_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ signExtend 8 (truncate 1 (x_1 ^^^ x)) ≠ x_1 ^^^ x) → truncate 1 (x_1 ^^^ x) = ofBool (x_1 != x)

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

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

theorem tryFactorization_xor_ashr_ashr_proof : tryFactorization_xor_ashr_ashr_before ⊑ tryFactorization_xor_ashr_ashr_after

theorem test14_proof : test14_before ⊑ test14_after

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

theorem scalar_i32_shl_and_signbit_eq_X_is_constant2_proof : scalar_i32_shl_and_signbit_eq_X_is_constant2_before ⊑ scalar_i32_shl_and_signbit_eq_X_is_constant2_after

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

theorem p0_thm (e : IntW 8) :
  icmp IntPred.ne (ashr (shl e (const? 8 5)) (const? 8 5) { «exact» := true }) e ⊑
    icmp IntPred.ult (add e (const? 8 (-4))) (const? 8 (-8))

theorem e_2484 :
    11 *  ~~~(e ||| f) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * (e &&& (d ^^^ f)) + 11 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) + 2 *  ~~~(d &&&  ~~~d) + 5 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 11 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 3 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 11 * (d |||  ~~~f) - 7 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * ( ~~~d ||| (e ^^^ f)) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 3 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (f ^^^ (d ||| (e &&& f))) - 3 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 5 * (d ^^^ f) + 4 * (f ^^^ (d ||| e)) - 7 * (f ^^^ (d &&& e)) + 3 * (d &&&  ~~~f) + 11 * (d &&& (e ||| f)) + 7 * (e |||  ~~~(d |||  ~~~f)) - 5 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 3 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 4 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 2 * (f |||  ~~~(d ^^^ e)) - 5 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 *  ~~~(d &&& ( ~~~e &&& f)) - 6 * (e ||| (d ^^^ f)) + 5 * (d &&& ( ~~~e ||| f)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 11 *  ~~~(d |||  ~~~e) + 5 * (e ||| f) + 2 * (d ||| (e &&& f)) + 4 * (e ||| (d &&&  ~~~f)) - 2 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (e ^^^ (d ||| f)) + 1 *  ~~~( ~~~d ||| (e &&& f)) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (d ^^^ ( ~~~e &&& f)) - 7 * (e ^^^ (d &&&  ~~~f)) + 7 *  ~~~(d ^^^ (e ||| f)) - 2 * (f ^^^ (d ||| (e ||| f))) - 5 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 6 *  ~~~(d &&& f) - 1 * (f ^^^  ~~~(d ||| e)) + 3 * (e &&&  ~~~f) - 3 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 4 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~f ||| (d ^^^ e)) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * (e ^^^ (d ||| (e ^^^ f))) - 7 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (e ^^^ (d ||| (e &&& f))) - 1 * ((d &&& f) ^^^ (e ||| f)) - 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 6 *  ~~~( ~~~d &&& (e ||| f)) + 5 * (e ^^^ (d |||  ~~~f)) + 4 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * e - 5 * ( ~~~e ||| (d ^^^ f)) + 1 * d - 2 * (d ||| ( ~~~e ||| f)) - 7 * (d &&&  ~~~e) + 1 * (d ^^^ e) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 17 *  ~~~(d ||| (e ||| f)) + 19 *  ~~~(d ||| ( ~~~e ||| f)) - 12 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 32 * ( ~~~d &&& ( ~~~e &&& f)) + 36 * ( ~~~d &&& (e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) - 17 * (d &&& (e &&& f)) =  - 2 * (e &&&  ~~~(d &&&  ~~~f))

theorem icmp_slt_0_and_icmp_sgt_neg1_i64_proof : icmp_slt_0_and_icmp_sgt_neg1_i64_before ⊑ icmp_slt_0_and_icmp_sgt_neg1_i64_after

theorem lshr_shl_demand4_proof : lshr_shl_demand4_before ⊑ lshr_shl_demand4_after

theorem gt_signed_to_small_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (BitVec.ofInt 32 (-17) <ₛ signExtend 32 x) = ofBool (BitVec.ofInt 8 (-17) <ₛ x)

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

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

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

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 zext_masked_bit_zero_to_smaller_bitwidth_thm (e e_1 : IntW 32) :
  zext 16 (icmp IntPred.eq (LLVM.and (shl (const? 32 1) e_1) e) (const? 32 0)) ⊑
    LLVM.and (trunc 16 (lshr (LLVM.xor e (const? 32 (-1))) e_1)) (const? 16 1)

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem xor_or_xor_common_op_commute3_proof : xor_or_xor_common_op_commute3_before ⊑ xor_or_xor_common_op_commute3_after

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

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

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

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 test2_thm.extracted_1._2 : ∀ (x : BitVec 499),
  ¬(197#499 ≥ ↑499 ∨ 4096#499 <<< 197#499 = 0) → ¬209#499 ≥ ↑499 → x / 4096#499 <<< 197#499 = x >>> 209#499

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 not_and_and_or_not_or_or_commute1_and_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  (x_2 ^^^ -1#32) &&& x_1 &&& x ||

theorem signbit_splat_mask_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬7#8 ≥ ↑8 → ¬ofBool (x_1 <ₛ 0#8) = 1#1 → signExtend 16 (x_1.sshiftRight' 7#8) &&& x = 0#16

theorem scalar_i8_shl_ugt_const_proof : scalar_i8_shl_ugt_const_before ⊑ scalar_i8_shl_ugt_const_after

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

theorem ule_and_min_commute_proof : ule_and_min_commute_before ⊑ ule_and_min_commute_after

theorem icmp_select_implied_cond_proof : icmp_select_implied_cond_before ⊑ icmp_select_implied_cond_after

theorem src_is_mask_sext_proof : src_is_mask_sext_before ⊑ src_is_mask_sext_after

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

theorem xor_or_xor_common_op_commute2_proof : xor_or_xor_common_op_commute2_before ⊑ xor_or_xor_common_op_commute2_after

theorem ult_swap_and_max_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ugt e_1 e) (icmp IntPred.eq e (const? 8 (-1))) ⊑ const? 1 0

theorem test_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.slt e_1 e) (const? 1 1) (icmp IntPred.eq e_1 e) ⊑ icmp IntPred.sle e_1 e

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

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

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

theorem test_add__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == -1#32) = 1#1 →
    True ∧ (x ||| BitVec.ofInt 32 (-2147483648)).saddOverflow 1#32 = true → False

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

theorem addhshlhsdivhnegative0_proof : addhshlhsdivhnegative0_before ⊑ addhshlhsdivhnegative0_after

theorem test7_proof : test7_before ⊑ test7_after

theorem e_2307 :
    1 * (e &&&  ~~~f) - 2 *  ~~~(d &&&  ~~~e) + 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 * (e ^^^ (d &&&  ~~~f)) + 2 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 5 * (f ^^^ (d &&& (e ||| f))) + 3 * (d ||| (e &&& f)) + 7 *  ~~~(d &&&  ~~~f) + 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (d |||  ~~~f) - 1 *  ~~~(e ^^^ f) - 2 *  ~~~(d ^^^ (e ^^^ f)) + 1 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * (f &&& (d |||  ~~~e)) - 6 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 * (d ^^^ f) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 4 *  ~~~(d &&& (e &&& f)) + 11 *  ~~~e + 1 * (f ||| (d &&&  ~~~e)) - 11 * ( ~~~e &&& (d ^^^ f)) - 11 *  ~~~(d |||  ~~~f) - 6 *  ~~~(d &&& (e ^^^ f)) - 3 *  ~~~(d &&&  ~~~d) + 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 11 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 2 *  ~~~(e ||| f) - 6 * (d &&&  ~~~f) - 1 * (f &&& (d ^^^ e)) - 6 * ((d &&& e) ^^^ (e |||  ~~~f)) + 11 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 *  ~~~(d &&& (e ||| f)) + 2 * (f ^^^ (d &&& e)) + 5 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 11 * (f &&& (d ||| e)) - 1 *  ~~~(d ^^^ f) + 1 * ( ~~~f &&&  ~~~(d ^^^ e)) - 3 * (e ^^^ (d ||| f)) - 5 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 4 *  ~~~d + 3 * (f ^^^  ~~~(d |||  ~~~e)) - 5 * ( ~~~d ||| ( ~~~e ||| f)) + 4 *  ~~~(d ||| f) + 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * (f ^^^  ~~~(d &&& e)) + 1 * ( ~~~e ||| (d ^^^ f)) - 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 5 * (f ^^^ (d &&&  ~~~e)) + 4 * (d ^^^ e) - 12 *  ~~~(d ||| (e ||| f)) + 12 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) - 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 17 * ( ~~~d &&& ( ~~~e &&& f)) - 14 * ( ~~~d &&& (e &&& f)) - 24 * (d &&& ( ~~~e &&& f)) - 26 * (d &&& (e &&& f)) = 7 * (d &&& ( ~~~e ||| f))

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

@[simp, aesop 50% unsafe]
theorem stepSet_mono (M : NFA α σ) (S₁ S₂ : Set σ) (a : α) (h : S₁ ⊆ S₂) :
    M.stepSet S₁ a ⊆ M.stepSet S₂ a

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

theorem select2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → truncate 8 (zeroExtend 32 x_1) = x_1

theorem lshr_not_nneg2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → 1#8 ≥ ↑8 ∨ True ∧ (x >>> 1#8 &&& BitVec.ofInt 8 (-128) != 0) = true → False

theorem xor_and_or_proof : xor_and_or_before ⊑ xor_and_or_after

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

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

theorem or_not_and_commute9_proof : or_not_and_commute9_before ⊑ or_not_and_commute9_after

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

theorem and_ne_with_diff_one_proof : and_ne_with_diff_one_before ⊑ and_ne_with_diff_one_after

theorem no_shift_no_xor_multiuse_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 4096#32 == 0#32) = 1#1 → x * (x ^^^ 4096#32) = (x ^^^ x_1 &&& 4096#32) * (x ^^^ 4096#32)

@[simp] theorem not_value_isRefinedBy_poison : ¬value a ⊑ (@poison β)

theorem e_456 :
     - 6 * (x ||| y) + 4 *  ~~~x + 4 * (x |||  ~~~y) + 7 *  ~~~(x &&& y) - 2 *  ~~~(x &&&  ~~~y) - 7 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 10 * (x &&& y) = 6 *  ~~~(x &&&  ~~~x)

theorem udiv2_thm (e e_1 : IntW 32) :
  LLVM.udiv e_1 (shl (const? 32 1) e) { «exact» := true } ⊑ lshr e_1 e { «exact» := true }

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

theorem gt_signed_to_small_unsigned_proof : gt_signed_to_small_unsigned_before ⊑ gt_signed_to_small_unsigned_after

theorem select_exact_lshr_icmp_const_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (31#32 <ᵤ x) = 1#1 → 5#32 ≥ ↑32 → False

theorem src_is_notmask_x_xor_neg_x_inv_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (BitVec.ofInt 8 (-8) &&& (x ^^^ 123#8) == 0#8) = ofBool (x ^^^ 123#8 ≤ᵤ 7#8)

theorem head_isNone_of_bisim_stuck {α : Type} (x : Stream α) : x ~ stuck α → x.head = none

theorem ashr_sle_noexact_proof : ashr_sle_noexact_before ⊑ ashr_sle_noexact_after

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

theorem trunc_sandwich_max_sum_shift2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(30#32 ≥ ↑32 ∨ 1#12 ≥ ↑12) →
    ¬(31#32 ≥ ↑32 ∨
          True ∧ signExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32 ∨
            True ∧ zeroExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32) →
      truncate 12 (x >>> 30#32) >>> 1#12 = truncate 12 (x >>> 31#32)

theorem reassoc_mul_nuw_proof : reassoc_mul_nuw_before ⊑ reassoc_mul_nuw_after

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

theorem test9_proof : test9_before ⊑ test9_after

@[grind ., simp] lemma RawCNFA.empty_mem_initials {s : State} : s ∉ empty (A := A).initials

theorem or_xor_or_proof : or_xor_or_before ⊑ or_xor_or_after

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

theorem shl_ashr_pow2_const_case1_proof : shl_ashr_pow2_const_case1_before ⊑ shl_ashr_pow2_const_case1_after

theorem e_976 :
    2 * t - 6 * (z |||  ~~~t) - 7 * z + 5 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) + 13 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 1 *  ~~~(z &&&  ~~~t)

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

theorem lshrugt_01_08_proof : lshrugt_01_08_before ⊑ lshrugt_01_08_after

theorem e_524 :
     - 1 *  ~~~x + 1 * x - 7 *  ~~~(x &&& y) - 1 *  ~~~(x &&&  ~~~y) - 1 * y + 31 *  ~~~(x ||| y) + 21 *  ~~~(x |||  ~~~y) + 17 * (x &&&  ~~~y) + 23 * (x &&& y) = 11 *  ~~~(x &&&  ~~~x) + 11 *  ~~~(x ^^^ y)

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

theorem exact_lshr_eq_exactdiv_proof : exact_lshr_eq_exactdiv_before ⊑ exact_lshr_eq_exactdiv_after

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

theorem e_1161 :
    5 *  ~~~(z &&&  ~~~t) - 6 *  ~~~z - 1 *  ~~~(z &&&  ~~~z) - 1 *  ~~~t - 7 * (z ||| t) + 3 *  ~~~(z ||| t) + 15 *  ~~~(z |||  ~~~t) + 9 * (z &&& t) =  - 9 * (z &&&  ~~~t) + 6 * t

theorem lshr_16_add_zext_basic_proof : lshr_16_add_zext_basic_before ⊑ lshr_16_add_zext_basic_after

theorem e_98 :
     - 2 * (x ||| y) - 5 * (x |||  ~~~y) - 3 *  ~~~(x ^^^ y) + 8 *  ~~~(x ||| y) + 2 *  ~~~(x |||  ~~~y) + 10 * (x &&& y) =  - 7 * (x &&&  ~~~y)

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

theorem e_1557 :
     - 7 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 5 * (c ^^^ (a &&& b)) + 5 * (c ^^^  ~~~(a &&& (b ||| c))) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) - 5 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * (b ||| (a ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 7 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) + 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 12 * ( ~~~a &&& ( ~~~b &&& c)) + 15 * ( ~~~a &&& (b &&& c)) + 6 * (a &&& ( ~~~b &&& c)) = 1 *  ~~~(a &&& ( ~~~b ||| c)) - 5 * (a &&& (b &&& c))

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

theorem test28_sub_proof : test28_sub_before ⊑ test28_sub_after

theorem shl_xor_xor_no_const_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ¬(x_2 ≥ ↑8 ∨ x_2 ≥ ↑8) → ¬x_2 ≥ ↑8 → x_3 <<< x_2 ^^^ (x_1 <<< x_2 ^^^ x) = (x_1 ^^^ x_3) <<< x_2 ^^^ x

theorem src_fv_ne_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  icmp IntPred.ne (LLVM.or (select e_2 (add e_1 (const? 8 1) { «nsw» := false, «nuw» := true }) (const? 8 0)) e)
      (const? 8 0) ⊑
    LLVM.or (icmp IntPred.ne e (const? 8 0)) e_2

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

theorem zext_nneg_i1_proof : zext_nneg_i1_before ⊑ zext_nneg_i1_after

theorem src_is_mask_select_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ofBool (15#8 &&& (x ^^^ 123#8) != x ^^^ 123#8) = ofBool (15#8 <ᵤ x ^^^ 123#8)

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

theorem max_of_min_swap_proof : max_of_min_swap_before ⊑ max_of_min_swap_after

theorem trunc_shl_31_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬31#64 ≥ ↑64 → ¬31#32 ≥ ↑32 → truncate 32 (x <<< 31#64) = truncate 32 x <<< 31#32

theorem test36_proof : test36_before ⊑ test36_after

theorem eq_umin3_proof : eq_umin3_before ⊑ eq_umin3_after

theorem n9_wrong_x0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 &&& 15#8 == 0#8) = 1#1 → x_1 + 16#8 &&& BitVec.ofInt 8 (-16) = (x_1 &&& BitVec.ofInt 8 (-16)) + 16#8

theorem test94_proof : test94_before ⊑ test94_after

theorem ashrsgt_02_12_proof : ashrsgt_02_12_before ⊑ ashrsgt_02_12_after

theorem udiv_common_divisor_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (LLVM.udiv e_2 e_1) (LLVM.udiv e e_1) ⊑ LLVM.udiv (select e_3 e_2 e) e_1

theorem mul_of_pow2_commute_proof : mul_of_pow2_commute_before ⊑ mul_of_pow2_commute_after

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

@[grind =, simp]
lemma RawCNFA.same_stateMax (m : RawCNFA A) x y (z : Std.HashMap (State × A) (Std.HashSet State)) :
    (RawCNFA.mk m.stateMax x y z).states = m.states

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

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

theorem zext_sext_add_icmp_sgt_1_proof : zext_sext_add_icmp_sgt_1_before ⊑ zext_sext_add_icmp_sgt_1_after

theorem test9_proof : test9_before ⊑ test9_after

theorem icmp_sgt2_proof : icmp_sgt2_before ⊑ icmp_sgt2_after

theorem prove_exact_with_high_mask_proof : prove_exact_with_high_mask_before ⊑ prove_exact_with_high_mask_after

theorem shl_nsw_nuw_add_nsw_proof : shl_nsw_nuw_add_nsw_before ⊑ shl_nsw_nuw_add_nsw_after

theorem mult_assoc_1 (hq : q >= t) (hu : u >= t) :
  (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 sub_ule_sext_thm (e : IntW 1) (e_1 e_2 : IntW 8) :
  icmp IntPred.ule (sub e_2 e_1) (sext 8 e) ⊑ LLVM.or (icmp IntPred.eq e_2 e_1) e

theorem e_2022 :
     - 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 5 * (d &&& f) + 1 * ((e &&& f) ||| (d &&& (e ||| f))) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 *  ~~~(d &&& (e &&& f)) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 11 * ((d ^^^ e) ||| (d ^^^ f)) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 3 *  ~~~(d ^^^ (e &&& f)) - 1 * (f ^^^ ( ~~~d ||| (e &&& f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 4 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * f - 2 *  ~~~( ~~~d ||| (e &&& f)) - 6 * (e ^^^ (d ||| f)) - 7 * ( ~~~f &&& (d ^^^ e)) + 4 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 7 * (e &&&  ~~~f) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 5 *  ~~~( ~~~d &&& (e ||| f)) + 1 * ( ~~~d ||| (e ||| f)) + 11 * (d &&& ( ~~~e ||| f)) + 2 * ( ~~~d &&& (e ||| f)) + 1 * ((d ^^^ e) &&& (d ^^^ f)) - 9 *  ~~~(d ||| (e ||| f)) - 3 *  ~~~(d ||| ( ~~~e ||| f)) - 24 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 9 * ( ~~~d &&& ( ~~~e &&& f)) - 15 * ( ~~~d &&& (e &&& f)) - 29 * (d &&& ( ~~~e &&& f)) - 26 * (d &&& (e &&& f)) = 12 *  ~~~( ~~~d ||| (e ||| f))

theorem n14_wrong_comparison_constant_proof : n14_wrong_comparison_constant_before ⊑ n14_wrong_comparison_constant_after

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

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

theorem icmp_slt_0_or_icmp_sge_neg1_i32_proof : icmp_slt_0_or_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_or_icmp_sge_neg1_i32_after

theorem test11_thm (e : IntW 23) :
  shl (lshr (mul e (const? 23 3)) (const? 23 11)) (const? 23 12) ⊑
    LLVM.and (mul e (const? 23 6)) (const? 23 (-4096))

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

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

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

theorem const_index_fn_iterate (δ : Int)
    (i : Int) (vstart : α) (f : LoopBody α) (f' : α → α) (hf : f = fun _ a => f' a) (k : ℕ) :
    (f.counterDecorator δ)^[k] (i, vstart) = (i + k * δ, f'^[k] vstart)

theorem trunc_lshr_sext_proof : trunc_lshr_sext_before ⊑ trunc_lshr_sext_after

theorem xor_i8_to_i64_shl_save_and_ne_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 8),
  ¬ofBool (x_1 &&& 1#8 != 0#8) = 1#1 → 63#64 ≥ ↑64 → False

theorem t1_flags_nuw_nsw_first_proof : t1_flags_nuw_nsw_first_before ⊑ t1_flags_nuw_nsw_first_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_7b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_7b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_7b_logical_after

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

theorem test13_thm (e e_1 : IntW 32) :
  trunc 64 (ashr (sext 128 e_1) (LLVM.and (zext 128 e) (const? 128 31))) ⊑
    ashr (sext 64 e_1) (zext 64 (LLVM.and e (const? 32 31)) { «nneg» := true })

theorem t0_sub_from_trueval_proof : t0_sub_from_trueval_before ⊑ t0_sub_from_trueval_after

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

theorem lshr_lshr_proof : lshr_lshr_before ⊑ lshr_lshr_after

theorem test_mul_nsw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 268435457#32 == 268435456#32) = 1#1 → True ∧ (x &&& 268435457#32).umulOverflow 9#32 = true → False

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

theorem rem_euclid_wrong_operands_select_proof : rem_euclid_wrong_operands_select_before ⊑ rem_euclid_wrong_operands_select_after

theorem test7_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& 7#32 &&& (x &&& 128#32) != 0) = true → False

@[simp]
theorem if_then_poison_isRefinedBy_iff  :
    (if c then poison else a? : no_index _) ⊑ b? ↔ ¬c → a? ⊑ b?

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

theorem trunc_sandwich_max_sum_shift_thm (e : IntW 32) :
  lshr (trunc 12 (lshr e (const? 32 20))) (const? 12 11) ⊑
    trunc 12 (lshr e (const? 32 31)) { «nsw» := true, «nuw» := true }

theorem test_simplify_decrement_invalid_ne_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x != 0#8) = 1#1 → x - 1#8 = signExtend 8 (ofBool (x == 0#8))

theorem e_2353 :
     - 5 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~f &&& (d ^^^ e)) + 7 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 6 *  ~~~(d ^^^ e) - 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 4 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * (d ^^^ ( ~~~e &&& f)) - 1 * (e ^^^ f) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 11 * (e |||  ~~~(d |||  ~~~f)) + 1 * (e ^^^ (d ||| (e ||| f))) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 3 * (e |||  ~~~f) + 11 *  ~~~d + 5 *  ~~~( ~~~d &&& (e ^^^ f)) + 5 * (e ^^^ ( ~~~d &&& (e ||| f))) + 5 * (d &&& e) + 1 * ((d &&& f) ^^^ (e ||| f)) - 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 4 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * ( ~~~e ||| (d ^^^ f)) - 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 7 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~(d &&& (e ||| f)) - 3 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * (f &&& (d |||  ~~~e)) - 6 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 5 * (f ^^^  ~~~(d &&& (e ||| f))) - 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (e ^^^ (d &&&  ~~~f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 7 * (f ||| (d &&& e)) + 11 * ( ~~~d &&& (e ^^^ f)) + 5 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (d &&& f) - 6 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 2 *  ~~~(e ^^^ f) + 2 * (f ^^^ (d ||| e)) - 6 *  ~~~(d &&& (e ^^^ f)) - 1 * e - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~(d &&& f) + 7 * (f |||  ~~~(d ||| e)) - 7 *  ~~~(d ||| f) - 3 * (f ^^^ (d |||  ~~~e)) + 4 * (f ^^^ (d &&& ( ~~~e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 6 * ((d &&& f) ||| (e &&&  ~~~f)) + 2 * (d &&&  ~~~e) - 10 *  ~~~(d ||| (e ||| f)) - 6 *  ~~~(d ||| ( ~~~e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 28 * ( ~~~d &&& ( ~~~e &&& f)) - 44 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) =  - 2 * (f ^^^ (d ||| (e ||| f))) + 14 *  ~~~( ~~~d ||| (e ||| f))

theorem test_or4_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& 2147483647#32 <ₛ x) = 1#1 → 1#1 = ofBool (x_1 &&& 2147483647#32 <ᵤ x)

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

theorem different_size_zext_zext_slt_proof : different_size_zext_zext_slt_before ⊑ different_size_zext_zext_slt_after

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

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_after

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

theorem and_zext_zext_proof : and_zext_zext_before ⊑ and_zext_zext_after

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

theorem alive_AndOrXor_2063__X__C1__C2____X__C2__C1__C2  (w : Nat)   : alive_AndOrXor_2063__X__C1__C2____X__C2__C1__C2_src w  ⊑ alive_AndOrXor_2063__X__C1__C2____X__C2__C1__C2_tgt w

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

theorem test11_thm.extracted_1._1 : ∀ (x : BitVec 737),
  ofBool (x &&& BitVec.ofInt 737 (-2147483648) != 0#737) = ofBool (2147483647#737 <ᵤ x)

theorem p15_commutativity2_proof : p15_commutativity2_before ⊑ p15_commutativity2_after

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

theorem test17_thm.extracted_1._1 : ∀ (x : BitVec 1), 0#32 - signExtend 32 x = zeroExtend 32 x

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

theorem lshrugt_02_11_proof : lshrugt_02_11_before ⊑ lshrugt_02_11_after

theorem select_constants_and_icmp_ne0_zero_tval_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → x = 1#1 → ofBool (12#8 &&& 0#8 != 0#8) = x ^^^ 1#1

theorem n10_thm (e : IntW 64) :
  sub (const? 32 1) (trunc 32 (lshr e (const? 64 63))) ⊑
    add (trunc 32 (ashr e (const? 64 63)) { «nsw» := true, «nuw» := false }) (const? 32 1)
      { «nsw» := true, «nuw» := false }

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

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

@[simp, grind=] lemma val_num_appendInl (r : DeleteRange Γ) :
    (r.appendInl (ts := ts)).num.val = r.num.val

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

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

theorem rem_euclid_non_const_pow2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && x_1 == intMin 8 && 1#8 <<< x == -1) = true) →
    ¬ofBool (x_1.srem (1#8 <<< x) <ₛ 0#8) = 1#1 → True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

theorem main4d_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 7#32 != 7#32) ||

theorem src_is_mask_shl_lshr_fail_not_allones_proof : src_is_mask_shl_lshr_fail_not_allones_before ⊑ src_is_mask_shl_lshr_fail_not_allones_after

theorem ashrslt_03_03_proof : ashrslt_03_03_before ⊑ ashrslt_03_03_after

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

theorem not_proof : not_before ⊑ not_after

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

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

theorem main4f_like_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x != x) = 1#1 → ofBool (x_1 &&& x == x) = 1#1 → ¬True → False

theorem t2_ult_sgt_128_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult (add e_2 (const? 32 16)) (const? 32 144)) e_2
      (select (icmp IntPred.sgt e_2 (const? 32 127)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 127)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 (-16))) e e_2)

theorem e_2023 :
     - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (e ^^^ (d &&& ( ~~~e ||| f))) - 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 3 * (e &&&  ~~~(d ^^^ f)) - 2 * ((d &&& f) ^^^ (e ||| f)) - 7 * ((d ||| e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 7 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 11 *  ~~~(d ||| e) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (d ||| ( ~~~e ||| f)) + 2 *  ~~~f + 2 * ( ~~~d &&& (e ||| f)) - 1 * ( ~~~d ||| (e &&& f)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 3 * (d ^^^ f) - 7 * (d &&& (e ||| f)) - 1 * (d ||| (e ||| f)) - 1 * (e ^^^ (d ||| (e ||| f))) + 3 * (e ^^^ ( ~~~d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) + 4 * (e ^^^ ( ~~~d ||| (e ||| f))) - 9 *  ~~~(d ||| (e ||| f)) + 13 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) + 36 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 25 * ( ~~~d &&& (e &&& f)) + 29 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) = 1 * ( ~~~d ||| (e ||| f))

theorem test_and_ne_a_b_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  select (LLVM.and e_2 (icmp IntPred.ne e_1 e)) e_1 e ⊑ select e_2 e_1 e

theorem zext_sext_add_icmp_slt_minus1_proof : zext_sext_add_icmp_slt_minus1_before ⊑ zext_sext_add_icmp_slt_minus1_after

theorem width5 (w : Nat) (a b : BitVec w) : (a + b = a - a) → a = - b

theorem mul_of_udiv_fail_bad_remainder_thm (e : IntW 8) :
  mul (LLVM.udiv e (const? 8 11) { «exact» := true }) (const? 8 6) ⊑
    mul (LLVM.udiv e (const? 8 11) { «exact» := true }) (const? 8 6) { «nsw» := false, «nuw» := true }

theorem and_min_7_8_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x <ᵤ BitVec.ofInt 8 (-8)) = 1#1 → BitVec.ofInt 8 (-8) &&& BitVec.ofInt 8 (-8) = x &&& BitVec.ofInt 8 (-8)

theorem slt_smin1_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (select (icmp IntPred.slt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.slt e e_1

theorem lshrugt_03_14_proof : lshrugt_03_14_before ⊑ lshrugt_03_14_after

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

theorem icmp_select_var_commuted_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_2 = 0 → ofBool (x_1 == 0#8) = 1#1 → ofBool (42#8 / x_2 == 42#8 / x_2) = 1#1

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

theorem test_ne_0_and_15_add_1_proof : test_ne_0_and_15_add_1_before ⊑ test_ne_0_and_15_add_1_after

theorem 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 t9_nocse_thm (e : IntW 8) :
  LLVM.or (add (shl (const? 8 1) e) (const? 8 (-1))) (shl (const? 8 1) e) ⊑
    LLVM.or (shl (const? 8 1) e { «nsw» := false, «nuw» := true })
      (LLVM.xor (shl (const? 8 (-1)) e { «nsw» := true, «nuw» := false }) (const? 8 (-1)))

theorem not_or_or_and_no_and_proof : not_or_or_and_no_and_before ⊑ not_or_or_and_no_and_after

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

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

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

theorem fold_mask_cmps_to_false_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq e (const? 32 2147483647))
      (icmp IntPred.eq (LLVM.and e (const? 32 2147483647)) (const? 32 0)) ⊑
    const? 1 0

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

theorem not_invert_signbit_splat_mask2_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬6#8 ≥ ↑8 →
    signExtend 16 (x_1.sshiftRight' 6#8 ^^^ -1#8) &&& x = x &&& signExtend 16 (x_1.sshiftRight' 6#8 ^^^ -1#8)

theorem PR96857_xor_without_noundef_proof : PR96857_xor_without_noundef_before ⊑ PR96857_xor_without_noundef_after

theorem ule_umax2_thm (e e_1 : IntW 32) :
  icmp IntPred.ule (select (icmp IntPred.ugt e_1 e) e_1 e) e ⊑ icmp IntPred.ule e_1 e

theorem negate_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬7#8 ≥ ↑8 → x_1 - x >>> 7#8 = x.sshiftRight' 7#8 + x_1

theorem test8_proof : test8_before ⊑ test8_after

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

theorem lshrugt_01_12_proof : lshrugt_01_12_before ⊑ lshrugt_01_12_after

theorem n10_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 →
    ¬(63#64 ≥ ↑64 ∨
          True ∧ signExtend 64 (truncate 32 (x.sshiftRight' 63#64)) ≠ x.sshiftRight' 63#64 ∨
            True ∧ (truncate 32 (x.sshiftRight' 63#64)).saddOverflow 1#32 = true) →
      1#32 - truncate 32 (x >>> 63#64) = truncate 32 (x.sshiftRight' 63#64) + 1#32

theorem test11c_proof : test11c_before ⊑ test11c_after

theorem t6_no_extrause_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 + x <ᵤ x) = ofBool (x ^^^ -1#8 <ᵤ x_1)

theorem lshrugt_01_03_proof : lshrugt_01_03_before ⊑ lshrugt_01_03_after

theorem n2_proof : n2_before ⊑ n2_after

theorem e_1850 :
    11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 * (b ^^^ (a ||| ( ~~~b &&& c))) - 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 11 * ( ~~~a &&& (b ||| c)) + 5 * ((a &&& b) |||  ~~~(b ^^^ c)) + 7 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 1 * ( ~~~a ||| ( ~~~b ||| c)) - 11 * ((a ||| b) &&& (b ^^^ c)) + 5 * ((a &&& b) ^^^ (b ||| c)) + 5 * ( ~~~b &&& (a ^^^ c)) + 1 *  ~~~(a |||  ~~~c) + 2 * (a ||| (b &&& c)) - 2 *  ~~~(a ||| ( ~~~b &&& c)) - 6 * (b ^^^  ~~~(a ||| c)) + 4 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 5 * (c ^^^  ~~~(a &&& (b ||| c))) - 6 * (b &&&  ~~~c) - 6 *  ~~~(a &&& ( ~~~b &&& c)) - 2 *  ~~~(a |||  ~~~b) + 5 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 11 * ((a ^^^ b) ||| (a ^^^ c)) - 1 *  ~~~( ~~~a &&& (b ||| c)) - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 3 *  ~~~( ~~~a ||| (b ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) - 1 * (b ^^^ (a ||| c)) - 7 *  ~~~(a ^^^ ( ~~~b &&& c)) - 1 * (c ||| (a &&&  ~~~b)) + 1 * (b ||| c) - 2 * (a &&&  ~~~c) + 11 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 5 *  ~~~c - 7 * (a ^^^ b) + 4 * (b ||| (a &&&  ~~~c)) - 5 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 2 * (a ^^^ c) + 7 *  ~~~(a ||| (b ||| c)) + 22 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) + 9 * (a &&& ( ~~~b &&& c)) - 6 * (a &&& (b &&& c)) =  - 42 *  ~~~(a ||| ( ~~~b ||| c)) - 1 * (b ^^^ ( ~~~a &&& (b ^^^ c)))

theorem sub_ashr_or_i16_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 15#16 ≥ ↑16) →
    ofBool (x_1 <ₛ x) = 1#1 → (x_1 - x).sshiftRight' 15#16 ||

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

theorem select1_thm (e e_1 e_2 : IntW 32) (e_3 : IntW 1) :
  zext 32 (select e_3 (trunc 8 e_2) (add (trunc 8 e_1) (trunc 8 e))) ⊑
    LLVM.and (select e_3 e_2 (add e_1 e)) (const? 32 255)

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

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

theorem ugt_zext_proof : ugt_zext_before ⊑ ugt_zext_after

theorem t7_ugt_sgt_neg1_thm.extracted_1._12 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (143#32 <ᵤ x_2 + 16#32) = 1#1 →
    ¬ofBool (BitVec.ofInt 32 (-17) <ₛ x_2) = 1#1 → ofBool (127#32 <ₛ x_2) = 1#1 → x = x_1

theorem select_1_thm.extracted_1._20 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1) (x_3 x_4 : BitVec 8) (x_5 : BitVec 1),
  ¬x_5 = 1#1 → ¬x_2 = 1#1 → x ^^^ 123#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-124)

@[bv_mba_preprocess]
theorem BitVec.ofNat_eq_ofInt (n w : Nat) :
    BitVec.ofNat w n = BitVec.ofInt w n

theorem ne_3210_proof : ne_3210_before ⊑ ne_3210_after

theorem or_not_and_wrong_b_proof : or_not_and_wrong_b_before ⊑ or_not_and_wrong_b_after

theorem select_icmp_ne_0_and_8_xor_1073741824_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 8),
  ofBool (0#8 != x_1 &&& 8#8) = 1#1 → ofBool (x_1 &&& 8#8 == 0#8) = 1#1 → x = x ^^^ 1073741824#32

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

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

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

theorem test_mul_nsw__nsw_is_safe_proof : test_mul_nsw__nsw_is_safe_before ⊑ test_mul_nsw__nsw_is_safe_after

lemma eval_eq_up_to :
    (∀ ar k, k ≤ n → x ar k = y ar k) →
    p.eval x n = p.eval y n

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

omit [Fintype S] [DecidableEq S] [LawfulBEq A] in
lemma processOneElem_preserves_mem (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s : State) :
    let st' := processOneElem _ _  final s st (a, sa')
    sa ∈ st.map →
    sa ∈ st'.map

theorem test_add_nuw__all_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 1073741823)) (const? 32 3)) (const? 32 4)
      (add (LLVM.and e (const? 32 1073741823)) (const? 32 1) { «nsw» := false, «nuw» := true }) ⊑
    add (LLVM.and e (const? 32 1073741823)) (const? 32 1) { «nsw» := true, «nuw» := true }

theorem sle_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 ≤ₛ x) = 1#1 → 0#1 = ofBool (x_1 == BitVec.ofInt 8 (-128))

theorem AvoidCollision_signExtend_or {x y : BitVec w} :
    (x ||| y).signExtend v = (x.signExtend v) ||

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

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

theorem udiv_exact_eq_1_proof : udiv_exact_eq_1_before ⊑ udiv_exact_eq_1_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_4_after

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

theorem sgt_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 9),
  ofBool (x <ₛ x_1) = 1#1 → ofBool (x_1 == BitVec.ofInt 9 (-256)) = 0#1

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

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

theorem test18_proof : test18_before ⊑ test18_after

theorem uge_or_not_max_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.uge e_1 e) (icmp IntPred.ne e_1 (const? 8 (-1))) ⊑ const? 1 1

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

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 8 x_1 + x ^^^ signExtend 8 x_1 = 0#8 - x

theorem xor_or_xor_common_op_commute2_proof : xor_or_xor_common_op_commute2_before ⊑ xor_or_xor_common_op_commute2_after

theorem src_is_mask_sext_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(x_1 ≥ ↑8 ∨ True ∧ (31#8 >>> x_1).msb = true) →
      ofBool ((signExtend 16 (31#8 >>> x_1) ^^^ -1#16) &&& (x ^^^ 123#16) == 0#16) =
        ofBool (x ^^^ 123#16 ≤ᵤ zeroExtend 16 (31#8 >>> x_1))

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

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

theorem test56_proof : test56_before ⊑ test56_after

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

theorem select_icmp_x_and_2147483648_ne_0_or_2147483648_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 (-2147483648))) (const? 32 0))
      (LLVM.or e (const? 32 (-2147483648))) e ⊑
    LLVM.or e (const? 32 (-2147483648))

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 src_fv_ne_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ofBool (0#8 ||| x != 0#8) = ofBool (x != 0#8) ||

@[simp]
lemma swapLastTwo_eq1 : swapLastTwo (n := n) (Fin.natAdd n 1) = n

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

theorem no_masks_with_logical_or2_proof : no_masks_with_logical_or2_before ⊑ no_masks_with_logical_or2_after

theorem sub_select_not_zext_thm (e : IntW 64) (e_1 : IntW 1) :
  sub (select e_1 e (const? 64 64)) (zext 64 (LLVM.xor e_1 (const? 1 1))) ⊑ select e_1 e (const? 64 63)

theorem test_mul_nuw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 255#32 == 17#32) = 1#1 →
    True ∧ (x &&& 255#32).smulOverflow 9#32 = true ∨ True ∧ (x &&& 255#32).umulOverflow 9#32 = true → False

theorem eq_umin4_proof : eq_umin4_before ⊑ eq_umin4_after

theorem land_bor_left2_proof : land_bor_left2_before ⊑ land_bor_left2_after

theorem different_size_sext_sext_eq_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (signExtend 25 x_1 == signExtend 25 x) = ofBool (x_1 == signExtend 7 x)

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

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 and_zext_eq_zero_proof : and_zext_eq_zero_before ⊑ and_zext_eq_zero_after

theorem fold_sext_to_and_wrong5_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x &&& BitVec.ofInt 32 (-256) == 1#32) = 0#1
</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 {zip : Zipper d Γ_in eff t₁} [LawfulMonad d.m]
    {newCom : Com d zip.Γ_mid .pure newTys} {vs : HVector zip.Γ_mid.Var newTys} :
    (zip.insertPureCom vs newCom).denote = (fun (V_in : Valuation Γ_in) => do
      let V_mid ← zip.top.denote V_in
      zip.bot.denote
        ((Com.denoteLets newCom V_mid).comap <| newCom.outContextHom.with vs newCom.returnVars)
      ) :=
</target_theorem>

