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>
DecidableEq in Init.Prelude
Lean.ToExpr in Lean.ToExpr
List in Init.Prelude
Repr in Init.Data.Repr
Nat in Init.Prelude
AList in Mathlib.Data.List.AList
Option in Init.Prelude
StateT in Init.Control.State
Unit in Init.Prelude
String in Init.Prelude
BEq in Init.Prelude
ite 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
AList.insert in Mathlib.Data.List.AList
Valuation.map in Mathlib.RingTheory.Valuation.Basic
PUnit in Init.Prelude
Finset in Mathlib.Data.Finset.Defs
Sigma in Init.Core
Sigma.mk in Init.Core
liftM in Init.Prelude
Iff in Init.Core
IsEmpty in Mathlib.Logic.IsEmpty
StateT.bind in Init.Control.State
Set in Mathlib.Data.Set.Defs
Set.Subset in Mathlib.Data.Set.Defs
List.Subset in Init.Data.List.Basic
reduceCtorEq in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Core

abbrev Mapping (Γ Δ : Ctxt Ty) : Type :=
  @AList (Σ t, Var Γ t) (fun x => Var Δ x.1)

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

def Var (Γ : Ctxt Ty) (t : Ty) : Type :=
  { i : Nat // Γ[i]? = some 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 }

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

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

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

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

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

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

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

def Com.vars (com : Com d Γ eff ts) : VarSet Γ :=
  com.toLets.varsOfVec com.returnVars

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

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

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 β

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

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

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

def Lets.varsOfVec (lets : Lets d Γ_in eff Γ_out) (vs : HVector Γ_out.Var ts) :
    VarSet Γ_in :=
  (vs.vars).biUnion (fun v => lets.vars v.2)

def HVector.vars {l : List d.Ty} (T : HVector (Var Γ) l) : VarSet Γ :=
  T.foldl (fun _ s a => insert ⟨_, a⟩ s) ∅

abbrev VarSet (Γ : Ctxt Ty) : Type :=
  Finset (Σ t, Γ.Var t)

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

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

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

def sig          := Signature.sig ∘ 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

@[simp]
def ofVar {Γ : Ctxt Ty} (v : Γ.Var t) : VarSet Γ :=
  {⟨_, v⟩}

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

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

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

def andn_or_cmp_2_logical_before := [llvm|
{
^0(%arg167 : i16, %arg168 : i16, %arg169 : i16):
  %0 = llvm.mlir.constant(42 : i16) : i16
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sge" %arg167, %arg168 : i16
  %4 = llvm.icmp "slt" %arg167, %arg168 : i16
  %5 = llvm.icmp "ugt" %arg169, %0 : i16
  %6 = "llvm.select"(%5, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = "llvm.select"(%6, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def test43_after := [llvm|
{
^0(%arg205 : i32, %arg206 : i32, %arg207 : i32):
  %0 = llvm.mul %arg206, %arg207 : i32
  %1 = llvm.and %0, %arg205 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

def bigOr (constraints : List (BoolExpr α)) : BoolExpr α :=
  foldConstraints (BoolExpr.const false) constraints Gate.or

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 mulh_to_lshr_8 : RISCVPeepholeRewrite [Ty.riscv (.bv)] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (8) : !riscv.reg
      %0 = mulh %c, %x : !riscv.reg
      ret %0 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      %c = li (61) : !riscv.reg
      %0 = sra %x, %c : !riscv.reg
      ret %0 : !riscv.reg
  }]

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

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

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

def ult_rem_zero_nsw_before := [llvm|
{
^0(%arg173 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(21 : i8) : i8
  %2 = llvm.mul %arg173, %0 overflow<nsw,nuw> : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (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 constLLVM_38 : Com LLVMPlusRiscV ⟨[]⟩ .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry ():
    %1 = llvm.mlir.constant (-38) : i64
    llvm.return %1 : i64
  }]

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

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

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

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

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

Std.HashMap in Std.Data.HashMap.Basic

RV64.mulhsu in RISCV.Instructions

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

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

def ule_or_not_min_after := [llvm|
{
^0(%arg272 : i427, %arg273 : i427):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

def t1_flags_nuw_first_after := [llvm|
{
^0(%arg39 : i8, %arg40 : i8, %arg41 : i8):
  %0 = llvm.add %arg40, %arg41 : i8
  %1 = llvm.sub %arg39, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

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

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

Neg in Init.Prelude

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

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

elab "[llvm(" mvars:term,* ")| " reg:mlir_region "]" : term => do
  withTraceNode `LeanMLIR.Elab (pure m!"{exceptEmoji ·} elaborate LLVM program") <| do

  let φ : Nat := mvars.getElems.size
  let ⟨_, _, _, mcom⟩ ← SSA.elabIntoComObj reg (MetaLLVM φ)

  let res ← mcom.metaMap <| MetaLLVM.instantiate <| ←do
    let mvars : Vector _ φ := ⟨mvars.getElems, rfl⟩
    mvars.mapM fun (stx : Term) =>
      elabTermEnsuringType stx (mkConst ``Nat)

  trace[LeanMLIR.Elab] "elaborated expression: {res}"
  return res

structure Item where
 name : String
 tac : Syntax

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

@[simp_denote]
def add_shl_sext_llvm := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (3) : i32
    %1 = llvm.add %a, %0 : i32
    %2 = llvm.shl %1, %a : i32
    %3 = llvm.sext %2 : i32 to i64
    llvm.return %3 : i64
  }]

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

def llvm_ashr_lower_riscv_flag_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := ashr_llvm_exact_flag_64
  rhs := ashr_riscv_64

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

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

inductive ConsumeFrom
  | left
  | right

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

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

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

def multiuse1_before := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.mlir.constant(6 : i32) : i32
  %3 = llvm.mlir.constant(1 : i32) : i32
  %4 = llvm.and %arg11, %0 : i32
  %5 = llvm.and %arg11, %1 : i32
  %6 = llvm.shl %4, %2 overflow<nsw,nuw> : i32
  %7 = llvm.lshr exact %4, %3 : i32
  %8 = llvm.shl %5, %2 overflow<nsw,nuw> : i32
  %9 = llvm.lshr exact %5, %3 : i32
  %10 = llvm.or %6, %8 : i32
  %11 = llvm.or %7, %9 : i32
  %12 = llvm.or %11, %10 : i32
  "llvm.return"(%12) : (i32) -> ()
}
]

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

EIO.toIO' in Init.System.IO

Lean.Meta.getNatValue? in Lean.Meta.LitValues

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

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

def narrow_zext_and_before := [llvm|
{
^0(%arg54 : i16, %arg55 : i32):
  %0 = llvm.zext %arg54 : i16 to i32
  %1 = llvm.and %0, %arg55 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

def test14_after := [llvm|
{
^0(%arg176 : i32, %arg177 : i32):
  %0 = llvm.xor %arg176, %arg177 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

structure _root_.SetRel.set_eq (R : SetRel α β) (A : Set α) (B : Set β) where
  fwd : a ∈ A → ∃ b ∈ B, a ~[R] b
  bwd : b ∈ B → ∃ a ∈ A, a ~[R] b

Std.Format.nest in Init.Data.Format.Basic

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

def exactly_one_set_signbit_signed_before := [llvm|
{
^0(%arg26 : i8, %arg27 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg26, %0 : i8
  %3 = llvm.icmp "sgt" %arg27, %1 : i8
  %4 = llvm.sext %3 : i1 to i8
  %5 = llvm.icmp "eq" %2, %4 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

def substitute  (pred : FpPredicate) (assignment: Std.HashMap Nat (SubstitutionValue FpExpr)) :
          FpPredicate :=
  match pred with
  | (FpPredicate.bin lhs op rhs) =>
    (FpPredicate.bin (substituteBVExpr lhs assignment) op (substituteBVExpr rhs assignment))

def lhsSketchEnumeration  (lhsSketch: GenBVExpr w) (inputVars: List Nat) (lhsSymVars rhsSymVars : Std.HashMap Nat BVExpr.PackedBitVec) : ExpressionSynthesisResult := Id.run do
  let zero := wrap (GenBVExpr.const (BitVec.ofNat w 0))
  let one := wrap (GenBVExpr.const (BitVec.ofNat w 1 ))
  let minusOne := wrap (GenBVExpr.const (BitVec.ofInt w (-1)))

  
  let specialConstants := [zero, one, minusOne]
  let inputCombinations := productsList (List.replicate inputVars.length specialConstants)

  let lhsSymVarsAsBVExprs : List (BVExprWrapper):= lhsSymVars.toList.map (λ (id, pbv) => {bvExpr := GenBVExpr.var id, width := pbv.w})
  let lhsSymVarsPermutation := productsList (List.replicate lhsSymVarsAsBVExprs.length lhsSymVarsAsBVExprs)

  let inputsAndSymVars := List.product inputCombinations lhsSymVarsPermutation

  let mut rhsVarByValue : Std.HashMap (BitVec w) Nat := Std.HashMap.emptyWithCapacity
  for (var, value) in rhsSymVars.toArray do
    let h : value.w = w := sorry
    rhsVarByValue := rhsVarByValue.insert (h ▸ value.bv) var

  let mut res : ExpressionSynthesisResult := Std.HashMap.emptyWithCapacity
  for combo in inputsAndSymVars do
    let inputsSubstitutions := bvExprToSubstitutionValue (Std.HashMap.ofList (List.zip inputVars combo.fst))
    let symVarsSubstitutions := bvExprToSubstitutionValue (Std.HashMap.ofList (List.zip lhsSymVars.keys combo.snd))

    let substitutedExpr := substituteBVExpr lhsSketch (Std.HashMap.union inputsSubstitutions symVarsSubstitutions)
    let evalRes : BitVec w := evalBVExpr lhsSymVars substitutedExpr

    if rhsVarByValue.contains evalRes then
      let existingVar := rhsVarByValue[evalRes]!
      let existingVarRes := res.getD existingVar []

      res := res.insert existingVar (wrap substitutedExpr :: existingVarRes)

  pure res

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

def n2_after := [llvm|
{
^0(%arg19 : i1, %arg20 : i8, %arg21 : i8, %arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "eq" %arg20, %arg21 : i8
  %2 = llvm.xor %arg19, %0 : i1
  %3 = llvm.and %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def no_shift_xor_multiuse_cmp_with_and_after := [llvm|
{
^0(%arg88 : i32, %arg89 : i32, %arg90 : i32, %arg91 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-4097 : i32) : i32
  %3 = llvm.and %arg88, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.and %arg89, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg89) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg91, %arg90) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

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

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

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

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

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

def test15_before := [llvm|
{
^0(%arg24 : i1):
  %0 = llvm.mlir.constant(3 : i45) : i45
  %1 = llvm.mlir.constant(1 : i45) : i45
  %2 = llvm.mlir.constant(2 : i45) : i45
  %3 = "llvm.select"(%arg24, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i45, i45) -> i45
  %4 = llvm.shl %3, %2 : i45
  "llvm.return"(%4) : (i45) -> ()
}
]

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

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

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

@[match_pattern] abbrev icmp (c : IntPred)   : Nat → LLVM.Op  := MOp.icmp c ∘ .concrete

def icmp_eq_and_pow2_shl_pow2_negative3_before := [llvm|
{
^0(%arg59 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.shl %0, %arg59 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  %6 = llvm.zext %5 : i1 to i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def ule_or_not_min_logical_after := [llvm|
{
^0(%arg270 : i427, %arg271 : i427):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def shl_or_disjoint_lshr_comm_before := [llvm|
{
^0(%arg103 : i32, %arg104 : i32, %arg105 : i32):
  %0 = llvm.shl %arg103, %arg104 overflow<nuw> : i32
  %1 = llvm.or disjoint %arg105, %0 : i32
  %2 = llvm.lshr %1, %arg104 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def PR39793_bswap_u32_as_u16_trunc_before := [llvm|
{
^0(%arg24 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(65280 : i32) : i32
  %3 = llvm.lshr %arg24, %0 : i32
  %4 = llvm.and %3, %1 : i32
  %5 = llvm.shl %arg24, %0 : i32
  %6 = llvm.and %5, %2 : i32
  %7 = llvm.or %4, %6 : i32
  %8 = llvm.trunc %7 : i32 to i8
  "llvm.return"(%8) : (i8) -> ()
}
]

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

def 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 IsBisim' (R' : Stream α → Stream α → Prop) : Prop :=
  ∀ a b, R' a b → ∃ n m,
    R' (a.drop (n+1)) (b.drop (m+1))
    ∧ a.get n = b.get m
    ∧ (∀ i < n, a.get i = none)
    ∧ (∀ j < m, b.get j = none)

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

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

def attr0Str : AttrEntry 0 := [mlir_attr_entry| sym_name = "add"]

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

def addhshlhsdivhnegative0_after := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.sdiv %arg8, %0 : i8
  %3 = llvm.shl %2, %1 overflow<nsw> : i8
  %4 = llvm.add %3, %arg8 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def uge_swap_and_max_after := [llvm|
{
^0(%arg230 : i8, %arg231 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "eq" %arg230, %0 : i8
  "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 lsb_mask_sign_zext_after := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.icmp "eq" %arg11, %0 : i32
  %2 = llvm.zext %1 : i1 to i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def rewrite_c_A : PeepholeRewrite DCPlus [.tokenstream, .valuestream 1] [.valuestream 1] :=
  { lhs := [DCPlus_com| {
      ^entry(%c : !ValueStream_1, %d : !TokenStream):
        %forkc = "DCPlus.forkVal" (%c) : (!ValueStream_1) -> (!ValueStream2_1)
        %fstc = "DCPlus.fstValPure" (%forkc) : (!ValueStream2_1) -> (!ValueStream_1)
        %sndc = "DCPlus.sndValPure" (%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)
        %cmerge = "DCPlus.cMerge" (%supp1, %supp2) : (!TokenStream, !TokenStream) -> (!ValueTokenStream_1)
        %fstmerge = "DCPlus.fstVal" (%cmerge) : (!ValueTokenStream_1) -> (!ValueStream_1)
        "return" (%fstmerge) : (!ValueStream_1) -> ()
      }],
    rhs := [DCPlus_com| {
      ^entry(%c : !ValueStream_1, %d : !TokenStream):
        "return" (%c) : (!ValueStream_1) -> ()
      }],
    correct :=
    by admit /- proof elided -/

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

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

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

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

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

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

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

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

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

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

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

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

instance : Min EffectKind where
  min := inf

def different_size_zext_zext_sgt_after := [llvm|
{
^0(%arg16 : i7, %arg17 : i4):
  %0 = llvm.zext %arg17 : i4 to i7
  %1 = llvm.icmp "ugt" %arg16, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

instance [ToString w] : ToString (Stream w) where
  toString s := toString (Stream.toList 10 s)

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

instance [CommSemiring α] : CommSemiring (Holor α ds) :=

def icmp_mul_nsw_sle_after := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.icmp "sle" %arg17, %arg18 : i8
  "llvm.return"(%0) : (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 slt_zero_ult_i1_before := [llvm|
{
^0(%arg10 : i32, %arg11 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg11 : i1 to i32
  %2 = llvm.lshr %arg10, %0 : i32
  %3 = llvm.icmp "ult" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

Lean.Meta.reduce in Lean.Meta.Reduce

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

def solve
[H : HydrableSolve parsedExpr genPred genExpr]
  (bvExpr : BoolExpr genPred) : GeneralizerStateM parsedExpr genPred (Option (Std.HashMap Nat BVExpr.PackedBitVec)) := do
    let state ← get
    let allVars := Std.HashMap.union state.parsedLogicalExpr.state.inputVarIdToVariable state.parsedLogicalExpr.state.symVarIdToVariable

    let bitVecType (w : Nat) :=  mkApp (mkConst ``BitVec) (mkNatLit w)

    let nameTypeCombo : List (Name × Expr) := allVars.values.map (λ n => (n.name, bitVecType n.width))

    let res ←
      withLocalDeclsDND nameTypeCombo.toArray fun _ => do
        let mVar ← withTraceNode `Generalize (fun _ => return m!"Converted bvExpr to expr (size : {getGenLogicalExprSize bvExpr})") do
          let mut expr : Expr ←
            genLogicalExprToExpr (state.parsedLogicalExpr : ParsedLogicalExpr parsedExpr genPred) (bvExpr : BoolExpr genPred)
          Lean.Meta.check expr

          expr ← mkEq expr (mkConst ``Bool.false) 
          Lean.Meta.check expr

          mkFreshExprMVar expr

        let cfg: BVDecideConfig := {timeout := 60, embeddedConstraintSubst := false}

        IO.FS.withTempFile fun _ lratFile => do
          let ctx ← (BVDecide.Frontend.TacticContext.new lratFile cfg)
          let res ← BVDecide.Frontend.bvDecide' mVar.mvarId! ctx

          match res with
          | .ok _ => pure none
          | .error counterExample =>
            let nameToId : Std.HashMap Name Nat := Std.HashMap.ofList (allVars.toList.map (λ (id, var) => (var.name, id)))
            let mut assignment : Std.HashMap Nat BVExpr.PackedBitVec := Std.HashMap.emptyWithCapacity
            for (var, val) in counterExample.equations do
              let name := ((← getLCtx).get! var.fvarId!).userName
              assignment := assignment.insert nameToId[name]! val
            pure (some assignment)
    return res

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

def eq_3210_before := [llvm|
{
^0(%arg126 : i32, %arg127 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.mlir.constant(24 : i32) : i32
  %3 = llvm.trunc %arg126 : i32 to i8
  %4 = llvm.lshr %arg126, %0 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg126, %1 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg126, %2 : i32
  %9 = llvm.trunc %8 : i32 to i8
  %10 = llvm.trunc %arg127 : i32 to i8
  %11 = llvm.lshr %arg127, %0 : i32
  %12 = llvm.trunc %11 : i32 to i8
  %13 = llvm.lshr %arg127, %1 : i32
  %14 = llvm.trunc %13 : i32 to i8
  %15 = llvm.lshr %arg127, %2 : i32
  %16 = llvm.trunc %15 : i32 to i8
  %17 = llvm.icmp "eq" %3, %10 : i8
  %18 = llvm.icmp "eq" %5, %12 : i8
  %19 = llvm.icmp "eq" %7, %14 : i8
  %20 = llvm.icmp "eq" %9, %16 : i8
  %21 = llvm.and %17, %18 : i1
  %22 = llvm.and %19, %21 : i1
  %23 = llvm.and %20, %22 : i1
  "llvm.return"(%23) : (i1) -> ()
}
]

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

def or_signbit_ashr_before := [llvm|
{
^0(%arg5 : i32):
  %0 = llvm.mlir.constant(-65536 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.or %arg5, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def List.product (l₁ : List α) (l₂ : List β) : List (α × β) := l₁.flatMap fun a => l₂.map (Prod.mk a)

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

def c : DCOp.ValueStream Bool := ofList [true, true, none, none, false]

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

structure KInductionCircuits {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity] (fsm : FSM arity) (n : Nat) where
  
  cInitCarryAssignCirc : Circuit (Vars fsm.α arity 0)
  
  cSuccCarryAssignCirc : Circuit (Vars fsm.α arity (n+2))
  
  cOutAssignCirc : Circuit (Vars fsm.α arity (n + 2))
  
  cStatesUniqueCirc : Circuit (Vars fsm.α arity n)

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

def State.get? (e : Expr) : GenM (Option Expr) := do
  let s ← get
  match ← s.mapping.getMatch e with
  | #[x] => return x
  | #[] => return none
  | _ => unreachable!

def ule_or_not_min_commute_before := [llvm|
{
^0(%arg268 : i8, %arg269 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "ule" %arg268, %arg269 : i8
  %2 = llvm.icmp "ne" %arg268, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def test29_after := [llvm|
{
^0(%arg166 : i32, %arg167 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.or %arg167, %arg166 : i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

def zext_or_masked_bit_test_after := [llvm|
{
^0(%arg54 : i32, %arg55 : i32, %arg56 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg55 overflow<nuw> : i32
  %3 = llvm.and %2, %arg54 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.icmp "eq" %arg56, %arg55 : i32
  %6 = llvm.or %4, %5 : i1
  %7 = llvm.zext %6 : i1 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

def test3_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.add %arg2, %arg3 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

def foo_before := [llvm|
{
^0(%arg0 : i1):
  %0 = llvm.zext %arg0 : i1 to i8
  "llvm.return"(%arg0) : (i1) -> ()
}
]

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

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

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

structure DisjointFlag where
  disjoint : Bool := false
  deriving Repr, DecidableEq, Lean.ToExpr

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

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

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

def FpBinaryPredKind.toString : FpBinaryPredKind → String
  | FpBinaryPredKind.eq => "="

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

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

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

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

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

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

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

def sub_2_after := [llvm|
{
^0(%arg109 : i8, %arg110 : i1, %arg111 : i8, %arg112 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.xor %arg112, %0 : i8
  %3 = "llvm.select"(%arg110, %arg111, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.add %3, %arg109 : i8
  %5 = llvm.sub %1, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

private abbrev ReaderM := MLIR.AST.ReaderM SLLVM

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

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

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

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

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

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

instance : Hashable (FpExpr e) where
  hash expr := expr.hashCode

def and_two_ranges_to_mask_and_range_no_add_on_one_range_after := [llvm|
{
^0(%arg249 : i16):
  %0 = llvm.mlir.constant(-20 : i16) : i16
  %1 = llvm.mlir.constant(11 : i16) : i16
  %2 = llvm.and %arg249, %0 : i16
  %3 = llvm.icmp "ugt" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def t1_flags_nuw_nsw_first_after := [llvm|
{
^0(%arg33 : i8, %arg34 : i8, %arg35 : i8):
  %0 = llvm.add %arg34, %arg35 : i8
  %1 = llvm.sub %arg33, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

abbrev tctx : Term.Ctx (wcard := 1) (tcard := 1) := (Term.Ctx.empty (wcard := 1))
  
  |>.cons (WidthExpr.var ⟨0, by admit /- proof elided -/
  ⟩)

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

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

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 alive_AndOrXor_1683_1_tgt :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.icmp.ugt %a, %b : i64
  %v2 = llvm.icmp.eq %a, %b : i64
  %v3 = llvm.icmp.uge %a, %b : i64
  llvm.return %v3 : i1
}]

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

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

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

def 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 -/
  ⟩

instance : ToString SSAVal where
  toString := SSAValToString

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

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

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

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

private def test_slli := [RV64_com| {
 ^bb0(%e1 : !i64, %e2 : !i64 ):
 %1 = slli %e1, 42 : !i64
 ret %1 : !i64
}]

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

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

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

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

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

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

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

inductive Ty
| int : Ty
| ix : Ty
| tensor2d : Ty
deriving DecidableEq, Inhabited

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

partial def ctxtNf (as : Expr) : MetaM Expr := do
  let as ← whnf as
  match_expr as with
    | Ctxt.cons _ a as =>
        let as ← ctxtNf as
        mkAppM ``Ctxt.cons #[a, as]
    | List.cons _ a as =>
        let as ← ctxtNf as
        mkAppM ``Ctxt.cons #[a, as]
    | _ => return as

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 trunc_unsigned_nsw_after := [llvm|
{
^0(%arg58 : i16, %arg59 : i16):
  %0 = llvm.icmp "ult" %arg58, %arg59 : i16
  "llvm.return"(%0) : (i1) -> ()
}
]

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

Std.Tactic.BVDecide.BVUnOp.rotateLeft in Std.Tactic.BVDecide.Bitblast.BVExpr.Basic

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

private def bb1NoArgs : Region φ :=
  [mlir_region| {
     ^entry:
     "foo"(%x, %y) : (i32, i32) -> ()
      %z = "bar"(%x) : (i32) -> (i32)
      "std.return"(%x0) : (i42) -> ()
  }]

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

def const_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  constantLowering1bit)
  ++
  (List.map (fun ⟨_,y⟩ => mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND y))
  constantLowering64bit)

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

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

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

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

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

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

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

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

def and_not_or_commute9_after := [llvm|
{
^0(%arg454 : i32, %arg455 : i32, %arg456 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg454 : i32
  %3 = llvm.sdiv %0, %arg455 : i32
  %4 = llvm.sdiv %0, %arg456 : i32
  %5 = llvm.xor %3, %4 : i32
  %6 = llvm.and %5, %2 : i32
  %7 = llvm.xor %6, %1 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def bw (w : Nat) (x : BitVec v) : BitVec w := x.zeroExtend w

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

def irc_constants_AMinusC1MinusC2_2_1 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64):
      %c1 = llvm.mlir.constant (2) : i64
      %c2 = llvm.mlir.constant (1) : i64
      %0 = llvm.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 ashr_overshift_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(17 : i32) : i32
  %2 = llvm.ashr %arg6, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def sext_zext_apint2_before := [llvm|
{
^0(%arg85 : i11):
  %0 = llvm.zext %arg85 : i11 to i39
  %1 = llvm.sext %0 : i39 to i47
  "llvm.return"(%1) : (i47) -> ()
}
]

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

Dvd in Init.Prelude

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

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

def test_add_zero_lhs_RHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    return %x : !R
}]

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

def pr51551_2_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32):
  %0 = llvm.mlir.constant(-7 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg7, %0 : i32
  %4 = llvm.or %3, %1 : i32
  %5 = llvm.mul %4, %arg6 overflow<nsw> : i32
  %6 = llvm.and %5, %1 : i32
  %7 = llvm.icmp "eq" %6, %2 : i32
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def HVector.replicateToList {α : Type} {f : α → Type} {a : α} :
    {n : Nat} → HVector f (List.replicate n a) → List (f a)
  | 0, _ => []
  | n+1, HVector.cons x xs => x :: replicateToList xs

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

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

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

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

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

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

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_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 test28_sub_before := [llvm|
{
^0(%arg175 : i32):
  %0 = llvm.mlir.constant(-2147483647 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.sub %0, %arg175 : i32
  %3 = llvm.xor %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def lshr_31_i32_add_zext_basic_after := [llvm|
{
^0(%arg21 : i32, %arg22 : i32):
  %0 = llvm.mlir.constant(31) : i64
  %1 = llvm.zext %arg21 : i32 to i64
  %2 = llvm.zext %arg22 : i32 to i64
  %3 = llvm.add %1, %2 overflow<nsw,nuw> : i64
  %4 = llvm.lshr %3, %0 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

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

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

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

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

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

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

abbrev ofTerm (t : Term) : FSM (Fin t.arity) := termEvalEqFSM t |>.toFSM

def visitSUB_APlusBNegB : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%a: i64, %b: i64):
      %0 = llvm.add %a, %b : i64
      %1 = llvm.sub %0, %b : i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%a: i64, %b: i64):
      llvm.return %a : 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 ashr_ugt_8_after := [llvm|
{
^0(%arg106 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  %1 = llvm.icmp "slt" %arg106, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

def VarRemapVar
  (w': HVector Γ'.Var β) :
  {w : HVector Γ.Var β //
    ∀ (Vstart : Ctxt.Valuation Γstart),
      w.map (lets.denote Vstart)
      = w'.map ((lets.denote Vstart).comap hom)  } :=
    if TY : β = α then
      if H : TY ▸ w' = vnew then
        ⟨TY ▸ vold, by admit /- proof elided -/
          ⟩
      else ⟨w'.map hom, by admit /- proof elided -/
      ⟩
    else ⟨w'.map hom, by admit /- proof elided -/
    ⟩

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

def argNames : List SSAVal :=
  op.args.map Prod.fst

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

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

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

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

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

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

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

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

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

def not_mul_of_bool_before := [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 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

Lean.Elab.Tactic.run in Lean.Elab.Tactic.Basic

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

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

def 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 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 positive_sameconst_shlnsw_before := [llvm|
{
^0(%arg51 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.ashr %arg51, %0 : i8
  %2 = llvm.shl %1, %0 overflow<nsw> : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def icmp_ule_riscv_eq_icmp_ule_llvm_32 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] :=
  {lhs:= icmp_ule_llvm_32, rhs:= icmp_ule_riscv_32}

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

instance : Monad PoisonOr where
  pure := value
  bind := fun a f => match a with
    | poison  => poison
    | value a => f a

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

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

def and_orn_cmp_1_before := [llvm|
{
^0(%arg194 : i32, %arg195 : i32, %arg196 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.icmp "sgt" %arg194, %arg195 : i32
  %2 = llvm.icmp "sle" %arg194, %arg195 : i32
  %3 = llvm.icmp "ugt" %arg196, %0 : i32
  %4 = llvm.or %3, %2 : i1
  %5 = llvm.and %1, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def j : Stream (BitVec 8) := ofList [none, 3#8, none]

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

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

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

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

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

def mul_constant_mismatch_wrap_eq_before := [llvm|
{
^0(%arg102 : i32, %arg103 : i32):
  %0 = llvm.mlir.constant(54 : i32) : i32
  %1 = llvm.mul %arg102, %0 overflow<nsw> : i32
  %2 = llvm.mul %arg103, %0 overflow<nuw> : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

BitVec.smulOverflow in Init.Data.BitVec.Basic

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

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

def main6c_logical_before := [llvm|
{
^0(%arg89 : 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(true) : i1
  %5 = llvm.mlir.constant(0 : i32) : i32
  %6 = llvm.mlir.constant(1 : i32) : i32
  %7 = llvm.and %arg89, %0 : i32
  %8 = llvm.icmp "ne" %7, %1 : i32
  %9 = llvm.and %arg89, %2 : i32
  %10 = llvm.icmp "ne" %9, %3 : i32
  %11 = "llvm.select"(%8, %4, %10) <{"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 ashrslt_02_07_exact_after := [llvm|
{
^0(%arg30 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def CNFA.toNFA' (m : CNFA n) : NFA' n := ⟨_, m.toNFA⟩

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

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

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 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 smear_set_bit_after := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.shl %arg6, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def alive_AddSub_1202_tgt :=
[sllvm| {
^bb0(%x : i64, %C : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %x, %v1 : i64
  %v3 = llvm.mlir.constant 1 : i64
  %v4 = llvm.sub %C, %v3 : i64
  %v5 = llvm.sub %v4, %x : i64
  llvm.return %v5 : i64
}]

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

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

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

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

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

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

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

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

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

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

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

ZMod.val in Mathlib.Data.ZMod.Basic

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

def not? {w : Nat} (x : BitVec w) : IntW w := do
  .value (~~~x)

def main7c_after := [llvm|
{
^0(%arg72 : i32, %arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg74, %0 : i32
  %2 = llvm.or %arg73, %1 : i32
  %3 = llvm.and %arg72, %2 : i32
  %4 = llvm.icmp "ne" %3, %2 : i32
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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 "ugt" %2, %arg1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def and_ranges_overlap_single_before := [llvm|
{
^0(%arg255 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.mlir.constant(20 : i8) : i8
  %3 = llvm.icmp "uge" %arg255, %0 : i8
  %4 = llvm.icmp "ule" %arg255, %1 : i8
  %5 = llvm.and %3, %4 : i1
  %6 = llvm.icmp "uge" %arg255, %1 : i8
  %7 = llvm.icmp "ule" %arg255, %2 : i8
  %8 = llvm.and %6, %7 : i1
  %9 = llvm.and %5, %8 : i1
  "llvm.return"(%9) : (i1) -> ()
}
]

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

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

def xor_to_xor3_after := [llvm|
{
^0(%arg81 : i32, %arg82 : i32):
  %0 = llvm.xor %arg81, %arg82 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def alive_Select_1100_tgt :=
[sllvm| {
^bb0(%Y : i64, %X : i64):
  %v1 = llvm.copy %X : i64
  llvm.return %v1 : i64
}]

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

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

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

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 main6c_logical_before := [llvm|
{
^0(%arg89 : 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(true) : i1
  %5 = llvm.mlir.constant(0 : i32) : i32
  %6 = llvm.mlir.constant(1 : i32) : i32
  %7 = llvm.and %arg89, %0 : i32
  %8 = llvm.icmp "ne" %7, %1 : i32
  %9 = llvm.and %arg89, %2 : i32
  %10 = llvm.icmp "ne" %9, %3 : i32
  %11 = "llvm.select"(%8, %4, %10) <{"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 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_with_icmp_logical_before := [llvm|
{
^0(%arg57 : i32):
  %0 = llvm.mlir.constant(512 : i32) : i32
  %1 = llvm.mlir.constant(128 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.icmp "ult" %arg57, %0 : i32
  %5 = llvm.add %arg57, %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 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 shl_or_after := [llvm|
{
^0(%arg25 : i8):
  %0 = llvm.mlir.constant(22 : i8) : i8
  %1 = llvm.shl %0, %arg25 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

def pr89516_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "slt" %arg1, %0 : i8
  %3 = llvm.shl %1, %arg0 overflow<nuw> : i8
  %4 = llvm.srem %1, %3 : i8
  %5 = "llvm.select"(%2, %3, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.add %4, %5 overflow<nuw> : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

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

def add_multiuse_riscv_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_multiuse_llvm_i64
  rhs :=  add_multiuse_riscv_i64

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

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

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

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

private def attrVal4Symbol : AttrVal := [mlir_attr_val| @"foo" ]

def select_or_icmp_bad_after := [llvm|
{
^0(%arg149 : i32, %arg150 : i32, %arg151 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.icmp "eq" %arg149, %0 : i32
  %2 = llvm.or %arg151, %0 : i32
  %3 = "llvm.select"(%1, %2, %arg150) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

IO.FS.FileType.file in Init.System.IO

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

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

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

def binop_right_to_zero: List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, binop_right_to_zero_mul⟩]

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

def ashrslt_03_08_after := [llvm|
{
^0(%arg229 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 test3_before := [llvm|
{
^0(%arg207 : i32):
  %0 = llvm.xor %arg207, %arg207 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def langBinop (op : Binop) (l1 l2 : Set (BitVecs n)) : Set (BitVecs n) :=
  match op with
  | .and => l1 ∩ l2
  | .or => l1 ∪ l2
  | .impl => l1ᶜ ∪ l2
  | .equiv => (l1ᶜ ∪ l2) ∩ (l2ᶜ ∪ l1)

def add_nsw_or_and_after := [llvm|
{
^0(%arg11 : i32, %arg12 : i32):
  %0 = llvm.add %arg11, %arg12 overflow<nsw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

Lean.MacroM in Init.Prelude

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

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

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

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

def 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 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 negative_trunc_not_arg_logical_after := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(256 : i32) : i32
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.and %arg20, %0 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.add %arg21, %0 : 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 ashrsgt_01_10_exact_before := [llvm|
{
^0(%arg91 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-6 : i4) : i4
  %2 = llvm.ashr exact %arg91, %0 : i4
  %3 = llvm.icmp "sgt" %2, %1 : i4
  "llvm.return"(%3) : (i1) -> ()
}
]

def src_is_notmask_x_xor_neg_x_inv_after := [llvm|
{
^0(%arg66 : i8, %arg67 : i8, %arg68 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.xor %arg66, %0 : i8
  %4 = llvm.add %arg67, %1 : i8
  %5 = llvm.xor %arg67, %4 : i8
  %6 = "llvm.select"(%arg68, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.icmp "ule" %3, %6 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

def src_is_mask_or_before := [llvm|
{
^0(%arg117 : i8, %arg118 : i8):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.xor %arg117, %0 : i8
  %4 = llvm.lshr %1, %arg118 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.and %5, %3 : i8
  %7 = llvm.icmp "eq" %3, %6 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

def llvm02:=
  [LV|{
  ^bb0(%X : i64, %Y : i64 ):
    %1 = llvm.mlir.constant 9 : i64
    %2 = llvm.sub %X, %X : i64
    llvm.return %1 : i64
  }]

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

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

@[simp_denote] def add_nat (e₁ e₂ : Var Γ .nat) : Expr ScfArith Γ .pure .nat :=
  Expr.mk
    (op := .coe <| .add_nat)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons e₁ <| .cons e₂ .nil)
    (regArgs := .nil)

def llvm_sext_lower_riscv_i8_to_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 8)] :=
  {lhs:= sext_llvm_i8_to_32, rhs:= sext_riscv_i8_to_32}

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

def sub_ule_sext_before := [llvm|
{
^0(%arg121 : i1, %arg122 : i8, %arg123 : i8):
  %0 = llvm.sext %arg121 : i1 to i8
  %1 = llvm.sub %arg122, %arg123 : i8
  %2 = llvm.icmp "ule" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

def test34_after := [llvm|
{
^0(%arg160 : i16):
  %0 = llvm.mlir.constant(8 : i16) : i16
  %1 = llvm.lshr %arg160, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

partial def visit (t : Expr) : GenM Expr := do
  let t ← instantiateMVars t
  match t with
  | .app _ _ =>
    let f := t.getAppFn
    let args := t.getAppArgs
    let table ←
      if let some (f, _) := f.const? then do
        let out ← genTable.getGenTable f args
        pure out
      else
        pure none
    let bv? (n : Nat) :=
      match table with
      | .some xs => xs.getD n false
      | .none => false
    args.zipIdx.foldlM (init := f) fun res (arg, i) => do
      let arg ← if bv? i then State.add? arg else visit arg
      pure <| .app res arg
  | .forallE n e₁ e₂ info =>
    pure <| .forallE n (← visit e₁) (← visit e₂) info
  | e =>
    pure e

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

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

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

def test2_before := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(3 : i32) : i32
  %2 = llvm.zext %arg18 : i8 to i32
  %3 = llvm.add %2, %0 : i32
  %4 = llvm.ashr %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

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 -/
  ⟩

inductive DecideIfZerosOutput
 
| safetyFailure (iter : Nat)
 
| exhaustedIterations (numIters : Nat)
 
| provenByKIndCycleBreaking (numIters : Nat) (safetyCert : BVDecide.Frontend.LratCert) (indCertCycleBreaking : BVDecide.Frontend.LratCert)

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

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

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

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

def test_lshr_exact__exact_is_safe_after := [llvm|
{
^0(%arg62 : i32, %arg63 : i64):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.lshr %arg62, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.zext nneg %3 : i32 to i64
  %5 = llvm.ashr %arg63, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

def trunc_unsigned_both_after := [llvm|
{
^0(%arg56 : i16, %arg57 : i16):
  %0 = llvm.icmp "ult" %arg56, %arg57 : i16
  "llvm.return"(%0) : (i1) -> ()
}
]

def and_zext_before := [llvm|
{
^0(%arg40 : i32, %arg41 : i1):
  %0 = llvm.zext %arg41 : i1 to i32
  %1 = llvm.and %arg40, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

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

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

Sum.inl in Init.Core

def substBvEqualitiesTac : TacticM Unit := do
  liftMetaTactic1 substBvEqualities

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

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

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

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

@[simp_denote]
def add_multiuse_riscv_i64 :=
  [LV| {
    ^entry (%x: i64):
    %0 = "li"() {imm = -1 : !i64} : (!i64) -> (!i64)
    %1 = slli %0, 40 : !i64
    %2 = addi %1, 1 : !i64
    %a0  = "builtin.unrealized_conversion_cast" (%x) : (i64) -> (!i64)
    %3 = add %a0, %2 : !i64
    %4 = and %3, %2 : !i64
    %5 = "builtin.unrealized_conversion_cast" (%4) : (!i64) -> (i64)
    llvm.return %5 : i64
  }]

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

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

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

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

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

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

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

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

Lean.Elab.Tactic.State in Lean.Elab.Term.TermElabM

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

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

def src_is_notmask_x_xor_neg_x_inv_after := [llvm|
{
^0(%arg66 : i8, %arg67 : i8, %arg68 : i1):
  %0 = llvm.mlir.constant(123 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.xor %arg66, %0 : i8
  %4 = llvm.add %arg67, %1 : i8
  %5 = llvm.xor %arg67, %4 : i8
  %6 = "llvm.select"(%arg68, %5, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %7 = llvm.icmp "ule" %3, %6 : i8
  "llvm.return"(%7) : (i1) -> ()
}
]

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

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

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

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

def or_and_or_pat3_before := [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.and %arg30, %arg31 : i8
  %3 = llvm.and %arg31, %arg33 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

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

def shl_nsw_nuw_after := [llvm|
{
^0(%arg4 : i1, %arg5 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(56 : i8) : i8
  %2 = llvm.shl %0, %arg5 overflow<nsw,nuw> : i8
  %3 = "llvm.select"(%arg4, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

def t1_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.sext %arg11 : i8 to i32
  %2 = llvm.and %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def Expr.mkVerifyCircuit (c cert : Expr) : MetaM Expr :=
  mkAppM ``Circuit.verifyCircuit #[c, cert]

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

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

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

def test18_after := [llvm|
{
^0(%arg179 : i8):
  %0 = llvm.sext %arg179 : i8 to i16
  "llvm.return"(%0) : (i16) -> ()
}
]

def zext_sext_ule_known_nonneg_op0_wide_after := [llvm|
{
^0(%arg16 : i9, %arg17 : i8):
  %0 = llvm.mlir.constant(254 : i9) : i9
  %1 = llvm.urem %arg16, %0 : i9
  %2 = llvm.sext %arg17 : i8 to i9
  %3 = llvm.icmp "ule" %1, %2 : i9
  "llvm.return"(%3) : (i1) -> ()
}
]

def mul {Γ : Ctxt (Ty q)} (x y : Var Γ .modLike)
    : Expr (ModArith q) Γ .pure .modLike :=
  Expr.mk
    (op      := .mul)
    (ty_eq   := rfl)
    (eff_le  := by admit /- proof elided -/
    )
    (args    := .cons x (.cons y .nil))
    (regArgs := .nil)

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

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

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

def reprWithoutFlags (op : MOp.BinaryOp) (prec : Nat) : Format :=
  let op  : String := match op with
    | .and                => "and"
    | .or   ⟨false⟩        => "or"
    | .or   ⟨true⟩         => "or disjoint"
    | .xor                => "xor"
    | .shl  ⟨false, false⟩ => "shl"
    | .shl  ⟨nsw, nuw⟩     => toString f!"shl {nsw} {nuw}"
    | .lshr ⟨false⟩        => "lshr"
    | .lshr ⟨true⟩         => "lshr exact"
    | .ashr ⟨false⟩        => "ashr"
    | .ashr ⟨true⟩         => "ashr exact"
    | .urem               => "urem"
    | .srem               => "srem"
    | .add  ⟨false, false⟩ => "add"
    | .add  ⟨nsw, nuw⟩     => toString f!"add {nsw} {nuw}"
    | .mul  ⟨false, false⟩ => "mul"
    | .mul  ⟨nsw, nuw⟩     => toString f!"mul {nsw} {nuw}"
    | .sub  ⟨false, false⟩ => "sub"
    | .sub  ⟨nsw, nuw⟩     => toString f!"sub {nsw} {nuw}"
    | .sdiv ⟨false⟩        => "sdiv"
    | .sdiv ⟨true⟩         => "sdiv exact"
    | .udiv ⟨false⟩        => "udiv"
    | .udiv ⟨true⟩         => "udiv exact"
  Repr.addAppParen (Format.group (Format.nest
    (if prec >= max_prec then 1 else 2) f!"InstCombine.MOp.BinaryOp.{op}"))
    prec

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

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

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

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

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

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

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

def neg_nsw_slt_0_before := [llvm|
{
^0(%arg20 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg20 overflow<nsw> : i8
  %2 = llvm.icmp "slt" %1, %0 : 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 sle_swap_or_not_min_after := [llvm|
{
^0(%arg280 : i8, %arg281 : i8):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def xor_and_before := [llvm|
{
^0(%arg146 : i1, %arg147 : i32, %arg148 : i32):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "ult" %arg147, %arg148 : i32
  %3 = "llvm.select"(%arg146, %2, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = llvm.xor %3, %1 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

Matrix.of in Mathlib.LinearAlgebra.Matrix.Defs

instance : Coe (Γ.Var t) ((Γ ++ ts).Var t) where coe := appendInl

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

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

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

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

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

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

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

def main7c_before := [llvm|
{
^0(%arg72 : i32, %arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.mul %arg74, %0 : i32
  %4 = llvm.and %arg73, %arg72 : i32
  %5 = llvm.icmp "eq" %arg73, %4 : i32
  %6 = llvm.and %3, %arg72 : i32
  %7 = llvm.icmp "eq" %3, %6 : i32
  %8 = llvm.and %5, %7 : i1
  %9 = "llvm.select"(%8, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%9) : (i32) -> ()
}
]

def Com.changeVars : Com d Γ eff ty →
    (varsMap : Γ.Hom Γ') →
    Com d Γ' eff ty
  |  .rets e => fun varsMap => .rets (e.map varsMap)
  |  .var e body => fun varsMap => .var (e.changeVars varsMap)
      (body.changeVars (fun _ v => varsMap.append v))

def udiv_ne_big_after := [llvm|
{
^0(%arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "ne" %arg36, %0 : i8
  %3 = llvm.icmp "ne" %arg37, %1 : i8
  %4 = llvm.or %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def pruneConstantExprsSynthesisResults(exprSynthesisResults : ExpressionSynthesisResult)
                            : GeneralizerStateM ParsedBVExpr GenBVPred ExpressionSynthesisResult := do
      withTraceNode `Generalize (fun _ => return "Pruned expressions synthesis results") do
          let state ← get
          let mut tempResults : Std.HashMap Nat (List (BVExprWrapper)) := Std.HashMap.emptyWithCapacity

          for (var, expressions) in exprSynthesisResults.toList do
              let width := state.parsedLogicalExpr.state.symVarIdToVariable[var]!.width
              let mut bvExprs : List (GenBVExpr width) := []

              for expr in expressions do
                let h : width = expr.width := sorry
                bvExprs := h ▸ expr.bvExpr :: bvExprs

              let mut prunedExprs ← pruneEquivalentBVExprs bvExprs.reverse 
              tempResults := tempResults.insert var (prunedExprs.map (λ expr => wrap expr))

          pure tempResults

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

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

def not_match_inconsistent_values_before := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(299) : i64
  %1 = llvm.mlir.constant(29) : i64
  %2 = llvm.mlir.constant(64) : i64
  %3 = llvm.urem %arg12, %0 : i64
  %4 = llvm.udiv %arg12, %1 : i64
  %5 = llvm.urem %4, %2 : i64
  %6 = llvm.mul %5, %0 : i64
  %7 = llvm.add %3, %6 : i64
  "llvm.return"(%7) : (i64) -> ()
}
]

RV64.bexti in RISCV.Instructions

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

def sltu_i32_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := sltu_llvm_i64
  rhs := sltu_riscv_i64

instance : DialectSignature Ex where
  signature
    | .add    => ⟨[.nat, .nat], [], [.nat], .pure⟩
    | .beq    => ⟨[.nat, .nat], [], [.bool], .pure⟩
    | .cst _  => ⟨[], [], [.nat], .pure⟩

def trunc_signed_nsw_sext_after := [llvm|
{
^0(%arg28 : i32, %arg29 : i8):
  %0 = llvm.sext %arg29 : i8 to i32
  %1 = llvm.icmp "slt" %arg28, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def shl_and_lshr_after := [llvm|
{
^0(%arg94 : i32, %arg95 : i32, %arg96 : i32):
  %0 = llvm.lshr %arg96, %arg95 : i32
  %1 = llvm.and %0, %arg94 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

def mkReturn (Γ : Ctxt HSxComb.Ty) (opStx : MLIR.AST.Op 0) :
   MLIR.AST.ReaderM HSxComb (Σ eff ty, Com HSxComb Γ eff ty) := do
  if opStx.name ≠ "return" then
    throw <| .generic s!"Tried to build return out of non-return statement {opStx.name}"
  else
    let args ← (← opStx.parseArgs Γ).assumeArity 1
    let ⟨ty, v⟩ := args[0]
    return ⟨.pure, ty, Com.ret v⟩

def or_test2_after := [llvm|
{
^0(%arg0 : i7, %arg1 : i7):
  %0 = llvm.mlir.constant(-64 : i7) : i7
  "llvm.return"(%0) : (i7) -> ()
}
]

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

def zext_lshr_before := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(4 : i16) : i16
  %1 = llvm.zext %arg12 : i8 to i16
  %2 = llvm.lshr %1, %0 : i16
  %3 = llvm.and %2, %1 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

RV64.sh2add in RISCV.Instructions

def negate_add_with_single_negatible_operand_depth2_after := [llvm|
{
^0(%arg35 : i8, %arg36 : i8):
  %0 = llvm.mlir.constant(-21 : i8) : i8
  %1 = llvm.sub %0, %arg35 : i8
  %2 = llvm.mul %1, %arg36 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def CNFA.proj_spec (m : CNFA n2) (f : Fin n1 → Fin n2) {M : NFA' n2} :
    m.Sim M → (m.proj f |>.Sim (M.proj f)) :=

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

def test6_after := [llvm|
{
^0(%arg1 : i7):
  "llvm.return"(%arg1) : (i7) -> ()
}
]

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

instance instReprTy : Repr (Dialect.Ty d) where reprPrec t _ := printTy t

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

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

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

abbrev Width φ := ConcreteOrMVar Nat φ

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 Vars.stateN (s : σ) (i : Nat) {n : Nat} (hin : i ≤ n := by admit /- proof elided -/
) : Vars σ ι n :=
  .state (Inputs.mk ⟨i, by admit /- proof elided -/
  ⟩ s)

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

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

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

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

def not_and_and_or_not_or_or_commute2_or_after := [llvm|
{
^0(%arg247 : i32, %arg248 : i32, %arg249 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg249, %arg248 : i32
  %2 = llvm.or %1, %arg247 : i32
  %3 = llvm.xor %2, %0 : i32
  "llvm.return"(%3) : (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 select_bittest_to_sub_before := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(4 : i32) : i32
  %3 = llvm.mlir.constant(3 : i32) : i32
  %4 = llvm.and %arg4, %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 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 shift_no_xor_multiuse_cmp_before := [llvm|
{
^0(%arg120 : i32, %arg121 : i32, %arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2 : i32) : i32
  %3 = llvm.and %arg120, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.or %arg121, %2 : i32
  %6 = "llvm.select"(%4, %arg121, %5) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg122, %arg123) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %8 = llvm.mul %6, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

def t7_after := [llvm|
{
^0(%arg6 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.icmp "slt" %arg6, %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 not_or_or_and_no_and_commute2_or_after := [llvm|
{
^0(%arg115 : i32, %arg116 : i32, %arg117 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg115, %0 : i32
  %2 = llvm.xor %arg116, %0 : i32
  %3 = llvm.and %arg117, %2 : i32
  %4 = llvm.or %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

Subsingleton in Init.Core

def llvm_sub_lower_riscv_no_flag_self: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := llvm_sub_self_ex
  rhs := sub_riscv_self_ex
  correct := by admit /- proof elided -/

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

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

abbrev WidthToExprMap := Std.HashMap Expr Expr

def and_to_xor2_after := [llvm|
{
^0(%arg117 : i32, %arg118 : i32):
  %0 = llvm.xor %arg117, %arg118 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

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

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

def bools_logical_commute0_and1_and2_after := [llvm|
{
^0(%arg99 : i1, %arg100 : i1, %arg101 : i1):
  %0 = "llvm.select"(%arg101, %arg100, %arg99) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

def verifyCircuit {α : Type} [DecidableEq α] [Fintype α] [Hashable α]
    (c : Circuit α) (cert : String) : Bool :=
  verifyAIG (α := α) c.toAIG cert

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

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

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

def CollectState.mkTctxExpr (reader : CollectState) : SolverM Expr := do
  let mut ctx ← mkTermCtxEmptyExpr reader
  
  for (_bv, wexpr) in reader.bvToIx.toArrayAsc.reverse do
    ctx ← mkTermCtxConsExpr reader ctx wexpr
  debugCheck ctx
  return ctx

def test_sle_xor_before := [llvm|
{
^0(%arg42 : i32, %arg43 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg43, %0 : i32
  %2 = llvm.xor %1, %arg42 : i32
  %3 = llvm.icmp "sle" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

abbrev Term.Ctx (wcard : Nat) (tcard : Nat) : Type :=
  Fin tcard → WidthExpr wcard

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

def neg_or_ashr_i32_commute_before := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(31 : i32) : i32
  %3 = llvm.sdiv %0, %arg27 : i32
  %4 = llvm.sub %1, %3 : i32
  %5 = llvm.or %3, %4 : i32
  %6 = llvm.ashr %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def State.envToExpr (w : WidthExpr) (s : State) : MetaM Expr := do
  let mut ix2e : Std.HashMap Nat Expr := {}
  for (e, ix) in s.e2ix do
    ix2e := ix2e.insert ix e
  let bvTy := w.toBitVecType
  let mut env :=  mkApp (mkConst ``List.nil [Level.zero]) bvTy
  for i in [0:ix2e.size] do
    let i := ix2e.size - 1 - i
    env := mkApp3 (mkConst ``List.cons [Level.zero]) bvTy  ix2e[i]! env
  return env

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

def opName (op : RISCV64.Op) : String :=
  let op  : String := match op with
  | .li _ => "li"
  | .mulh => "mulh"
  | .mulhu => "mulhu"
  | .mulhsu => "mulhsu"
  | .divu => "divu"
  | .remuw => "remuw"
  | .remu => "remu"
  | .addiw _ => "addiw"
  | .lui _ => "lui"
  | .auipc _ => "auipc"
  | .slliw _ => "slliw"
  | .srliw _ => "srliw"
  | .sraiw _ => "sraiw"
  | .slli _ => "slli"
  | .srli _ => "srli"
  | .srai _ => "srai"
  | .addw => "addw"
  | .subw => "subw"
  | .sllw => "sllw"
  | .srlw => "srlw"
  | .sraw => "sraw"
  | .add => "add"
  | .slt => "slt"
  | .sltu => "sltu"
  | .and => "and"
  | .or => "or"
  | .xor => "xor"
  | .sll => "sll"
  | .srl => "srl"
  | .sub => "sub"
  | .sra => "sra"
  | .remw  => "remw"
  | .rem => "rem"
  | .mul => "mul"
  | .mulw => "mulw"
  | .div => "div"
  | .divw => "divw"
  | .divuw => "divuw"
  | .addi _ => "addi"
  | .slti _ => "slti"
  | .sltiu _ => "sltiu"
  | .andi _ => "andi"
  | .ori _ => "ori"
  | .xori _ => "xori"
  | .bclr => "bclr"
  | .bext => "bext"
  | .binv => "binv"
  | .bset => "bset"
  | .bclri _ => "bclri"
  | .bexti _ => "bexti"
  | .binvi _ => "binvi"
  | .bseti _ => "bseti"
  | .adduw => "add.uw"
  | .sh1adduw => "sh1add.uw"
  | .sh2adduw => "sh2add.uw"
  | .sh3adduw => "sh3add.uw"
  | .sh1add => "sh1add"
  | .sh2add => "sh2add"
  | .sh3add => "sh3add"
  | .slliuw _ => "slli.uw"
  | .andn => "andn"
  | .orn => "orn"
  | .xnor => "xnor"
  | .clz => "clz"
  | .clzw => "clzw"
  | .ctz => "ctz"
  | .ctzw => "ctzw"
  | .max => "max"
  | .maxu => "maxu"
  | .min  => "min"
  | .minu  => "minu"
  | .sextb => "sext.b"
  | .sexth => "sext.h"
  | .zexth => "zext.h"
  | .rol => "rol"
  | .rolw => "rolw"
  | .ror => "ror"
  | .rori _ => "rori"
  | .roriw _ => "roriw"
  | .rorw => "rorw"
  | .pack => "pack"
  | .packh => "packh"
  | .packw => "packw"
  
  | .mv => "mv"
  | .not => "not"
  | .neg => "neg"
  | .negw => "negw"
  | .sextw => "sext.w"
  | .zextb => "zext.b"
  | .zextw => "zext.w"
  | .seqz => "seqz"
  | .snez => "snez"
  | .sltz => "sltz"
  | .sgtz => "sgtz"
  op

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

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

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

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

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

def canonicalize_icmp_sge_neg5 : 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 getIntWidth {Γ : Ctxt SLLVM.Ty} : (Σ t, Γ.Var t) → ReaderM Nat
  | ⟨Ty.bitvec w, _⟩ => return w
  | ⟨t, _⟩ => throw <| .generic s!"Expected type `bitvec _`, but found: {t}"

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

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

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

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

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

def not_ashr_not_after := [llvm|
{
^0(%arg139 : i32, %arg140 : i32):
  %0 = llvm.ashr %arg139, %arg140 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def fsmMsbAux : FSM Bool where
  
  α := Unit
  initCarry := fun () => false
  outputCirc :=
    let s : Circuit (Unit ⊕ (Bool)) := Circuit.var (positive := true) (.inl ())
    let x : Circuit (Unit ⊕ (Bool)) := Circuit.var (positive := true) (.inr false)
    let w : Circuit (Unit ⊕ (Bool))  := Circuit.var (positive := true) (.inr true)
    Circuit.ite w 
    x 
    s 
  nextStateCirc := fun () =>
    let s : Circuit (Unit ⊕ (Bool)) := Circuit.var (positive := true) (.inl ())
    let x : Circuit (Unit ⊕ (Bool)) := Circuit.var (positive := true) (.inr false)
    let w : Circuit (Unit ⊕ (Bool)) := Circuit.var (positive := true) (.inr true)
    
    Circuit.ite w 
      x 
      s  

def invert_icmp_after := [llvm|
{
^0(%arg151 : i32, %arg152 : i32):
  %0 = llvm.icmp "sgt" %arg151, %arg152 : i32
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

def foo1_or_commuted_after := [llvm|
{
^0(%arg145 : i32, %arg146 : i32, %arg147 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mul %arg145, %arg145 : i32
  %2 = llvm.shl %0, %arg146 overflow<nuw> : i32
  %3 = llvm.shl %0, %arg147 overflow<nuw> : i32
  %4 = llvm.or %2, %3 : i32
  %5 = llvm.and %1, %4 : i32
  %6 = llvm.icmp "eq" %5, %4 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

Stream'.iterate in Mathlib.Data.Stream.Defs

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

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

inductive FpBinOp
| add
deriving Hashable, DecidableEq, Repr

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

def test1_before := [llvm|
{
^0(%arg9 : i32, %arg10 : i32, %arg11 : i32):
  %0 = llvm.and %arg11, %arg9 : i32
  %1 = llvm.and %arg11, %arg10 : i32
  %2 = llvm.xor %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

instance : Lean.ToExpr RegIndex := inherit

Trans in Init.Prelude
</all_available_defs>

<all_available_lemmas>
Bool.false_eq_true in Init.Data.Bool
IsEmpty.exists_iff in Mathlib.Logic.IsEmpty
Option.isSome_none in Init.Data.Option.Basic
iff_false in Init.SimpLemmas
AList.lookup_isSome in Mathlib.Data.List.AList
Finset.mem_singleton in Mathlib.Data.Finset.Insert
Option.mem_def in Init.Data.Option.Instances
Sigma.mk.inj_iff in Mathlib.Data.Sigma.Basic
and_imp in Init.SimpLemmas
Option.bind_eq_some_iff in Init.Data.Option.Lemmas
AList.entries_insert_of_notMem in Mathlib.Data.List.AList
AList.lookup_eq_none in Mathlib.Data.List.AList
List.subset_cons_of_subset in Init.Data.List.Sublist
IsEmpty.forall_iff in Mathlib.Logic.IsEmpty
forall_eq' in Init.PropLemmas
iff_true in Init.SimpLemmas
implies_true in Init.SimpLemmas
AList.keys_subset_keys_of_entries_subset_entries in Mathlib.Data.List.AList
Finset.biUnion_insert in Mathlib.Data.Finset.Union
Finset.mem_biUnion in Mathlib.Data.Finset.Union
Finset.mem_union in Mathlib.Data.Finset.Lattice.Basic

@[simp] theorem appendCases_appendInr (v : Γ.Var t) :
    appendCases (motive := motive) left right v.appendInr = (right v)

@[simp] theorem appendCases_appendInl (v : Γ.Var t) :
    appendCases (motive := motive) left right v.appendInl = (left v)

@[simp] theorem HVector.vars_cons {t  : d.Ty} {l : List d.Ty}
    (v : Var Γ t) (T : HVector (Var Γ) l) :
    (HVector.cons v T).vars = insert ⟨_, v⟩ T.vars

theorem test16_proof : test16_before ⊑ test16_after

theorem neg_mask1_lshr_proof : neg_mask1_lshr_before ⊑ neg_mask1_lshr_after

theorem test5_proof : test5_before ⊑ test5_after

theorem icmp_and_ashr_multiuse_logical_proof : icmp_and_ashr_multiuse_logical_before ⊑ icmp_and_ashr_multiuse_logical_after

theorem masked_and_notallzeroes_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0))
      (icmp IntPred.ne (LLVM.and e (const? 32 39)) (const? 32 0)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 7)) (const? 32 0)

theorem test_ne_thm (e : IntW 32) :
  select (icmp IntPred.ne (LLVM.and e (const? 32 1073741823)) (const? 32 0)) (shl e (const? 32 2)) (const? 32 0) ⊑
    shl e (const? 32 2)

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

theorem no_shift_xor_multiuse_cmp_and_proof : no_shift_xor_multiuse_cmp_and_before ⊑ no_shift_xor_multiuse_cmp_and_after

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

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

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

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

theorem trunc_equality_nsw_zext_proof : trunc_equality_nsw_zext_before ⊑ trunc_equality_nsw_zext_after

theorem cast_test_2002h08h02_proof : cast_test_2002h08h02_before ⊑ cast_test_2002h08h02_after

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

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

@[simp] theorem ofBitVec_and {w : Nat} {x y : BitVec w} : ofBitVecSext (x &&& y) = (ofBitVecSext x) &&& (ofBitVecSext y)

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

theorem icmp_power2_and_icmp_shifted_mask_8_7_proof : icmp_power2_and_icmp_shifted_mask_8_7_before ⊑ icmp_power2_and_icmp_shifted_mask_8_7_after

lemma bisimul_eval_one (hsim : Bisimul R M₁ M₂) :
    R.set_eq Q₁ Q₂ → R.set_eq (M₁.stepSet Q₁ a) (M₂.stepSet Q₂ a)

theorem test8_proof : test8_before ⊑ test8_after

theorem eq_rem_zero_nonuw_proof : eq_rem_zero_nonuw_before ⊑ eq_rem_zero_nonuw_after

theorem and_sgt_to_mask_proof : and_sgt_to_mask_before ⊑ and_sgt_to_mask_after

theorem shl_add_nsw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x ≥ ↑32 ∨ True ∧ (1#32 <<< x).saddOverflow (-1#32) = true) →
    ¬(True ∧ ((-1#32) <<< x).sshiftRight' x ≠ -1#32 ∨ x ≥ ↑32) → 1#32 <<< x + -1#32 = (-1#32) <<< x ^^^ -1#32

@[simp] theorem Com.outContext_var {eff} (e : Expr d Γ eff t) (body : Com d e.outContext eff u) :
    (Com.var e body).outContext = body.outContext

theorem trunc_lshr_sext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (signExtend 32 x >>> 6#32) = x.sshiftRight' 6#8

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

theorem lowmask_or_zext_commute_proof : lowmask_or_zext_commute_before ⊑ lowmask_or_zext_commute_after

theorem and_or_not_not_commute3_proof : and_or_not_not_commute3_before ⊑ and_or_not_not_commute3_after

theorem e_2267 :
    3 * (f &&&  ~~~(d &&& e)) + 4 * ((d &&& f) ^^^ (e ||| f)) + 4 * (d ^^^ e) - 11 *  ~~~( ~~~d &&& (e &&& f)) + 1 *  ~~~(d ||| f) - 2 *  ~~~(d ^^^ e) - 3 * (f ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * ( ~~~d &&& (e ||| f)) + 2 *  ~~~(d ||| e) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 3 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 * (f ^^^  ~~~(d &&& e)) - 5 *  ~~~(d &&& e) + 5 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~(d |||  ~~~f)) + 5 *  ~~~(d ||| ( ~~~e &&& f)) + 1 * (d &&&  ~~~f) + 1 * (f |||  ~~~(d ^^^ e)) + 1 * (f &&& (d |||  ~~~e)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e &&& (d |||  ~~~f)) - 11 * (f &&&  ~~~(d &&&  ~~~e)) - 11 *  ~~~(d &&& (e ^^^ f)) + 3 *  ~~~(e ||| f) - 5 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 4 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 11 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 3 * (e &&&  ~~~(d &&& f)) + 3 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (e ^^^ (d ||| (e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e &&& f))) + 3 *  ~~~(d |||  ~~~f) - 1 * (d &&& (e ||| f)) + 2 * (e ^^^  ~~~(d ||| f)) - 7 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 6 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 3 * (f ^^^ (d &&& e)) + 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 7 * (d ||| e) - 11 *  ~~~(d &&& ( ~~~e &&& f)) - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~(e &&&  ~~~f) - 6 * (e |||  ~~~f) + 30 *  ~~~(d ||| (e ||| f)) + 16 *  ~~~(d ||| ( ~~~e ||| f)) + 46 *  ~~~( ~~~d ||| (e ||| f)) + 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 27 * ( ~~~d &&& ( ~~~e &&& f)) + 21 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) + 54 * (d &&& (e &&& f)) =  - 7 *  ~~~(d &&& ( ~~~e ||| f))

theorem ugt_umax2_proof : ugt_umax2_before ⊑ ugt_umax2_after

theorem demorgan_and_apint1_proof : demorgan_and_apint1_before ⊑ demorgan_and_apint1_after

theorem positive_biggerlshr_shlnsw_proof : positive_biggerlshr_shlnsw_before ⊑ positive_biggerlshr_shlnsw_after

theorem icmp_select_var_pred_uge_proof : icmp_select_var_pred_uge_before ⊑ icmp_select_var_pred_uge_after

theorem stream_pair_1 (s : Stream α) (f : Stream α → Option α × Option α × Stream α):
    (corec₂ s f).1 = corec s (fun x => let ⟨f1, _, f2⟩ := f x; (f1, f2))

theorem splat_mul_known_lz_proof : splat_mul_known_lz_before ⊑ splat_mul_known_lz_after

theorem uadd_sat_flipped_wrong_bounds6_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x ≤ᵤ BitVec.ofInt 32 (-12)) = 1#1 → ¬ofBool (x <ᵤ BitVec.ofInt 32 (-11)) = 1#1 → x + 9#32 = -1#32

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

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

theorem and_logic_and_logic_or_7_proof : and_logic_and_logic_or_7_before ⊑ and_logic_and_logic_or_7_after

theorem icmp_sle3_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 (-16)) = ofBool (x <ₛ BitVec.ofInt 8 (-7))

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

theorem ashrslt_02_05_proof : ashrslt_02_05_before ⊑ ashrslt_02_05_after

theorem foo1_and_signbit_lshr_without_shifting_signbit_both_sides_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32) →
    ofBool (-1#32 <ₛ x_2 <<< x_1) ||

theorem ashrslt_03_13_exact_proof : ashrslt_03_13_exact_before ⊑ ashrslt_03_13_exact_after

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

theorem test2_proof : test2_before ⊑ test2_after

theorem PR60818_eq_commuted_thm (e : IntW 32) :
  icmp IntPred.eq (mul e (const? 32 43)) (sub (const? 32 0) (mul e (const? 32 43))) ⊑
    icmp IntPred.eq (LLVM.and (mul e (const? 32 43)) (const? 32 2147483647)) (const? 32 0)

theorem e_2227 :
     - 3 * (e ^^^  ~~~(d ||| (e &&& f))) - 6 *  ~~~(e ^^^ f) - 3 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 *  ~~~(d ^^^ (e ||| f)) - 2 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 3 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * ( ~~~d ||| ( ~~~e ||| f)) - 6 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (f ||| (d &&& e)) - 2 * ((d &&& e) ^^^ (e ||| f)) - 1 *  ~~~(d &&& f) - 2 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) - 3 * ((d ||| e) &&& (e ^^^ f)) - 7 * (f ^^^ (d &&& (e ||| f))) - 1 *  ~~~( ~~~d ||| (e &&& f)) - 2 * (e ^^^ (d ||| ( ~~~e ||| f))) + 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 1 * (e ^^^ (d &&& (e ||| f))) + 11 *  ~~~(e &&&  ~~~f) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (d &&& f) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 3 *  ~~~(d &&& e) - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 5 * (d ||| (e ||| f)) + 7 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 7 * ( ~~~d ||| ( ~~~e &&& f)) + 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 6 *  ~~~(d ^^^ ( ~~~e &&& f)) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * ( ~~~e &&& (d ^^^ f)) - 5 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 2 * (f ^^^ (d ||| (e ||| f))) - 5 * (d ^^^ (e ^^^ f)) + 7 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * (e ||| (d &&&  ~~~f)) - 5 * f + 3 * (d ||| ( ~~~e &&& f)) + 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f |||  ~~~(d ^^^ e)) - 1 *  ~~~(d ||| (e ||| f)) - 27 *  ~~~(d ||| ( ~~~e ||| f)) - 20 *  ~~~( ~~~d ||| (e ||| f)) - 14 * ( ~~~d &&& ( ~~~e &&& f)) - 16 * ( ~~~d &&& (e &&& f)) - 17 * (d &&& ( ~~~e &&& f)) - 27 * (d &&& (e &&& f)) =  - 2 * (f ^^^  ~~~(d &&& e)) + 1 *  ~~~( ~~~d ||| ( ~~~e ||| f))

theorem ne_basic_equal_minus_7_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-7)) &&& ofBool (x_1 + 7#8 ≤ᵤ x) = ofBool (x_1 + 6#8 <ᵤ x)

@[simp] lemma swapLastTwoBlock_n {n : Nat} : swapLastTwoBlock (n := n) n = n + 1

theorem icmp_slt_0_and_icmp_sge_neg2_i64_proof : icmp_slt_0_and_icmp_sge_neg2_i64_before ⊑ icmp_slt_0_and_icmp_sge_neg2_i64_after

theorem icmp_equality_test_swift_optional_pointers_proof : icmp_equality_test_swift_optional_pointers_before ⊑ icmp_equality_test_swift_optional_pointers_after

theorem icmp_ne_sext_slt_allones_nofold_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x <ₛ -1#32)) != x) = ofBool (x != signExtend 32 (ofBool (x <ₛ -1#32)))

theorem ashrsgt_03_06_proof : ashrsgt_03_06_before ⊑ ashrsgt_03_06_after

theorem neg_not_signbit3_thm (e : IntW 8) :
  sub (const? 32 0) (zext 32 (ashr e (const? 8 7))) ⊑
    sub (const? 32 0) (zext 32 (ashr e (const? 8 7))) { «nsw» := true, «nuw» := false }

theorem xor_nosignbit_select_shl_proof : xor_nosignbit_select_shl_before ⊑ xor_nosignbit_select_shl_after

theorem src_tv_eq_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ofBool (0#8 ||| x == 0#8) = ofBool (x == 0#8) &&& x_2

theorem t0_basic_thm (e e_1 : IntW 8) : icmp IntPred.ule (sub e_1 e) e_1 ⊑ icmp IntPred.ule e e_1

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

theorem test14_thm.extracted_1._1 : ∀ (x : BitVec 35),
  ¬(4#35 ≥ ↑35 ∨ 4#35 ≥ ↑35) → True ∧ (x &&& BitVec.ofInt 35 (-19760) &&& 19744#35 != 0) = true → False

theorem test_sext3_thm.extracted_1._3 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → x_1 ^^^ 1#1 = 1#1 → 0#32 = signExtend 32 x

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

theorem test23_thm (e : IntW 44) : trunc 11 (ashr (shl e (const? 44 33)) (const? 44 33)) ⊑ trunc 11 e

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

theorem test1_thm.extracted_1._2 : ∀ (x : BitVec 33), ¬4096#33 = 0 → ¬12#33 ≥ ↑33 → x / 4096#33 = x >>> 12#33

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

theorem n2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-128) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-128) == -1) = true →
    x.sdiv (BitVec.ofInt 8 (-128)) = zeroExtend 8 (ofBool (x == BitVec.ofInt 8 (-128)))

theorem lshrugt_01_11_proof : lshrugt_01_11_before ⊑ lshrugt_01_11_after

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

theorem lsb_mask_sign_zext_commuted_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ((x ^^^ -1#32) &&& x + -1#32) >>> 31#32 = zeroExtend 32 (ofBool (x == 0#32))

theorem and_not_or_commute9_proof : and_not_or_commute9_before ⊑ and_not_or_commute9_after

theorem wrongimm_thm (e : IntW 16) :
  LLVM.xor (trunc 8 (ashr e (const? 16 14))) (const? 8 27) ⊑
    LLVM.xor (trunc 8 (ashr e (const? 16 14)) { «nsw» := true, «nuw» := false }) (const? 8 27)

theorem neg_slt_1_proof : neg_slt_1_before ⊑ neg_slt_1_after

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

theorem icmp_eq_or_z_or_pow2orz_fail_nonzero_const_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == 1#8) ||

theorem select_or_disjoint_or_proof : select_or_disjoint_or_before ⊑ select_or_disjoint_or_after

theorem test22_proof : test22_before ⊑ test22_after

theorem sgt_3_impliesF_eq_2_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ofBool (3#8 <ₛ x) = 1#1 → ¬ofBool (x <ₛ 4#8) = 1#1 → ofBool (2#8 == x) = 0#1

theorem n0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x ≤ᵤ x &&& 4#8) = ofBool (x &&& BitVec.ofInt 8 (-5) == 0#8)

theorem ashrslt_01_00_proof : ashrslt_01_00_before ⊑ ashrslt_01_00_after

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

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

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

theorem sgt_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 n8_wrong_pred3_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (sub e_1 e) e_1 ⊑ icmp IntPred.ne e (const? 8 0)

theorem pr51551_neg2_thm (e e_1 : IntW 32) :
  icmp IntPred.eq
      (LLVM.and (mul (LLVM.and e_1 (const? 32 (-7))) e { «nsw» := true, «nuw» := false }) (const? 32 7)) (const? 32 0) ⊑
    select (LLVM.xor (trunc 1 e_1) (const? 1 1)) (const? 1 1)
      (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 0))

theorem e_1219 :
    2 *  ~~~(z ^^^ t) + 1 * (z ^^^ t) + 5 * (z ||| t) + 1 * z + 2 * (z |||  ~~~t) - 15 *  ~~~(z ||| t) - 17 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) - 21 * (z &&& t) =  - 11 *  ~~~(z &&&  ~~~t)

theorem e_509 :
    11 * x - 5 * y - 6 *  ~~~x - 6 *  ~~~y + 7 * (x ||| y) + 11 *  ~~~(x &&&  ~~~y) - 11 *  ~~~(x &&& y) - 1 * (x &&&  ~~~y) - 24 * (x &&& y) =  - 12 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y)

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

theorem shl_lshr_pow2_const_case1_proof : shl_lshr_pow2_const_case1_before ⊑ shl_lshr_pow2_const_case1_after

theorem slt_zero_eq_i1_signed_proof : slt_zero_eq_i1_signed_before ⊑ slt_zero_eq_i1_signed_after

omit [Fintype S] [LawfulBEq A] in
lemma addOrCreate_preserves_map (st : worklist.St A S) (final? : Bool) (sa sa' : S) :
    let (_, st') := st.addOrCreateState _ _  final? sa'
    st.map[sa]? = some s →
    st'.map[sa]? = some s

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

theorem test_logical_proof : test_logical_before ⊑ test_logical_after

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

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

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

theorem missed_const_prop_2002h12h05_proof : missed_const_prop_2002h12h05_before ⊑ missed_const_prop_2002h12h05_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 and_zext_proof : and_zext_before ⊑ and_zext_after

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

theorem n3_constmask_samemask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  (x_1 ||| BitVec.ofInt 32 (-65281)) &&& (x ||| BitVec.ofInt 32 (-65281)) = x_1 &&& x ||

theorem and_xor_common_op_commute1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 = 0 ∨ x = 0 ∨ x_1 = 0) →
    ¬(x_1 = 0 ∨ x = 0) → 42#32 / x_1 &&& (43#32 / x ^^^ 42#32 / x_1) = 42#32 / x_1 &&& (43#32 / x ^^^ -1#32)

theorem xor_nosignbit_select_shl_proof : xor_nosignbit_select_shl_before ⊑ xor_nosignbit_select_shl_after

@[simp] lemma mem_vars_iff_mem_sumVarsLeft [DecidableEq α] [DecidableEq β] :
    ∀ {c : Circuit (α ⊕ β)} {x : α},
    (x ∈ c.sumVarsLeft) ↔ Sum.inl x ∈ c.vars

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

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

theorem test4_logical_proof : test4_logical_before ⊑ test4_logical_after

theorem fold_zext_xor_sandwich_thm (e : IntW 1) :
  LLVM.xor (zext 32 (LLVM.xor e (const? 1 1))) (const? 32 2) ⊑ LLVM.xor (zext 32 e) (const? 32 3)

theorem n2_badmask_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  x_3 &&& x_2 ||

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

theorem sle_and_min_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.sle e_1 e) (icmp IntPred.eq e_1 (const? 8 (-128))) ⊑
    icmp IntPred.eq e_1 (const? 8 (-128))

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

theorem and_to_xor4_proof : and_to_xor4_before ⊑ and_to_xor4_after

theorem test_not_const_shr_and_1_ne_0_proof : test_not_const_shr_and_1_ne_0_before ⊑ test_not_const_shr_and_1_ne_0_after

theorem udiv2_proof : udiv2_before ⊑ udiv2_after

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

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

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

theorem t1_proof : t1_before ⊑ t1_after

theorem shl_nsw_nuw_uge_Csle0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ (x_1 <<< x).sshiftRight' x ≠ x_1 ∨ True ∧ x_1 <<< x >>> x ≠ x_1 ∨ x ≥ ↑8) →
    ofBool (BitVec.ofInt 8 (-120) ≤ᵤ x_1 <<< x) = ofBool (BitVec.ofInt 8 (-121) <ᵤ x_1)

theorem ashr_ugt_13_thm (e : IntW 4) :
  icmp IntPred.ugt (ashr e (const? 4 1)) (const? 4 (-3)) ⊑ icmp IntPred.ugt e (const? 4 (-5))

theorem e_266 :
     - 7 *  ~~~(x ^^^ y) - 7 *  ~~~y - 7 * x + 3 *  ~~~(x &&&  ~~~y) - 3 *  ~~~(x |||  ~~~y) + 14 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 11 *  ~~~(x ||| y)

theorem fold_icmp_shl_nuw_c2_precondition2_proof : fold_icmp_shl_nuw_c2_precondition2_before ⊑ fold_icmp_shl_nuw_c2_precondition2_after

theorem slt_zero_eq_ne_0_fail1_proof : slt_zero_eq_ne_0_fail1_before ⊑ slt_zero_eq_ne_0_fail1_after

theorem PR45977_f1_proof : PR45977_f1_before ⊑ PR45977_f1_after

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

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

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

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

theorem eq_21_comm_eq2_proof : eq_21_comm_eq2_before ⊑ eq_21_comm_eq2_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 t1_proof : t1_before ⊑ t1_after

theorem lshrugt_01_13_exact_proof : lshrugt_01_13_exact_before ⊑ lshrugt_01_13_exact_after

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

theorem add_nosignbit_select_shl_proof : add_nosignbit_select_shl_before ⊑ add_nosignbit_select_shl_after

theorem tail_iterate'' {α} {n} {s : Stream' α} : Stream'.iterate Stream'.tail s n m = s (n + m)

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

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

@[simp] theorem RegionList.WellTyped.iff
    (regions : List (UnTyped.Region Op VarName)) (regionTypes : List (RegionType Ty)) :
    RegionList.WellTyped regions regionTypes
    ↔ regions.length = regionTypes.length
      ∧ ∀ r ∈ regions.zip regionTypes, Region.WellTyped r.fst r.snd

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

theorem e_47 :
     - 11 *  ~~~(x &&&  ~~~y) + 11 * (x |||  ~~~y) + 10 *  ~~~(x |||  ~~~y) - 11 * (x &&&  ~~~y) - 1 * (x &&& y) =  - 1 * y

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

theorem lshr_or_and_thm (e e_1 : IntW 8) :
  LLVM.and (LLVM.or (lshr e_1 (const? 8 5)) (const? 8 (-58))) (lshr e (const? 8 5)) ⊑
    lshr (LLVM.and e (LLVM.or e_1 (const? 8 (-64)))) (const? 8 5)

private theorem if_else_if_then_poison_eq {α : Type} (c₁ c₂ : Prop) [Decidable c₁] [Decidable c₂]
      (x y : PoisonOr α):
    (if c₁ then x else (if c₂ then poison else y)) =
    (if ¬c₁ ∧ c₂ then poison else (if c₁ then x else y))

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

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

theorem test_sub__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 1073741824#32) = 1#1 →
    True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x &&& 2147483647#32) = true → False

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

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

theorem test14_proof : test14_before ⊑ test14_after

theorem shl_shl_constants_div_thm (e e_1 : IntW 32) :
  LLVM.udiv e_1 (shl (shl (const? 32 1) e) (const? 32 2)) ⊑ lshr e_1 (add e (const? 32 2))

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 33), ¬4096#33 = 0 → x % 4096#33 = x &&& 4095#33

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

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

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

theorem test33_proof : test33_before ⊑ test33_after

theorem select_icmp_ne_0_and_32_xor_4096_proof : select_icmp_ne_0_and_32_xor_4096_before ⊑ select_icmp_ne_0_and_32_xor_4096_after

theorem ashrslt_03_04_proof : ashrslt_03_04_before ⊑ ashrslt_03_04_after

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

theorem src_x_or_mask_ne_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ofBool (0#8 ||| x ^^^ -1#8 != -1#8) = ofBool (0#8 <ᵤ x)

@[simp, simp_denote, simp_sllvm] theorem not_ptr_isRefinedBy_bitvec :
    ¬(@Ty.IsRefinedBy ptr (bitvec w) x y)

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

theorem lshr_xor_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x + 1#8 ≥ ↑8) → ¬x ≥ ↑8 → 16#8 >>> x ^^^ 3#8 >>> (x + 1#8) = 17#8 >>> x

theorem lshr_C1_add_A_C2_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 →
    ¬x &&& 65535#32 ≥ ↑32 → 6#32 <<< ((x &&& 65535#32) + 5#32) = 192#32 <<< (x &&& 65535#32)

theorem n2_thm (e e_1 : IntW 8) (e_2 : IntW 1) :
  LLVM.and (LLVM.xor e_2 (const? 1 1)) (icmp IntPred.eq e_1 e) ⊑
    LLVM.and (icmp IntPred.eq e_1 e) (LLVM.xor e_2 (const? 1 1))

theorem lshr_pow2_ugt_proof : lshr_pow2_ugt_before ⊑ lshr_pow2_ugt_after

theorem t1_flags_nuw_nsw_first_thm (e e_1 e_2 : IntW 8) :
  sub (sub e_2 e_1 { «nsw» := true, «nuw» := true }) e ⊑ sub e_2 (add e_1 e)

theorem sub_dec_proof : sub_dec_before ⊑ sub_dec_after

theorem ashrslt_01_07_exact_proof : ashrslt_01_07_exact_before ⊑ ashrslt_01_07_exact_after

theorem e_142 :
    2 * y - 7 *  ~~~(x &&&  ~~~y) + 7 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) - 11 * (x &&&  ~~~y) + 5 * (x &&& y) =  - 11 * (x ^^^ y)

theorem mul_add_to_mul_6_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.smulOverflow x = true ∨
        True ∧ x_1.smulOverflow x = true ∨
          True ∧ (x_1 * x).smulOverflow 5#32 = true ∨ True ∧ (x_1 * x).saddOverflow (x_1 * x * 5#32) = true) →
    True ∧ x_1.smulOverflow x = true ∨ True ∧ (x_1 * x).smulOverflow 6#32 = true → False

theorem sext_thm (e : IntW 4) :
  add (zext 7 (LLVM.xor e (const? 4 (-8)))) (const? 7 (-8)) { «nsw» := true, «nuw» := false } ⊑ sext 7 e

theorem same_source_shifted_signbit_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬24#32 ≥ ↑32 → signExtend 32 (truncate 8 (x >>> 24#32)) = x.sshiftRight' 24#32

theorem sgt_swap_and_min_proof : sgt_swap_and_min_before ⊑ sgt_swap_and_min_after

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 in_constant_varx_mone_invmask_thm.extracted_1._1 : ∀ (x x_1 : BitVec 4),
  (x_1 ^^^ -1#4) &&& (x ^^^ -1#4) ^^^ -1#4 = x_1 ||

theorem canonicalize_logic_first_or0_thm (e : IntW 32) :
  LLVM.or (add e (const? 32 112)) (const? 32 15) ⊑ add (LLVM.or e (const? 32 15)) (const? 32 112)

theorem masked_icmps_mask_notallzeros_bmask_mixed_1_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_1_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_1_logical_after

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

theorem test54_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ (truncate 16 x &&& 7224#16 &&& BitVec.ofInt 16 (-32574) != 0) = true) →
    signExtend 32 ((truncate 16 x ||| BitVec.ofInt 16 (-32574)) &&& BitVec.ofInt 16 (-25350)) =
      signExtend 32 (truncate 16 x &&& 7224#16 ||| BitVec.ofInt 16 (-32574))

theorem test_proof : test_before ⊑ test_after

theorem ashrslt_03_10_exact_proof : ashrslt_03_10_exact_before ⊑ ashrslt_03_10_exact_after

lemma CNFA.autSignedCmp_spec {cmp} : (CNFA.autSignedCmp cmp).Sim (NFA'.autSignedCmp cmp)

theorem not_sub_eq_sub_sub_one :
    ~~~ (x - y) = y - x - 1

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

theorem and_nosignbit_shl_proof : and_nosignbit_shl_before ⊑ and_nosignbit_shl_after

theorem bitwise_or_logical_or_icmps_comm1_proof : bitwise_or_logical_or_icmps_comm1_before ⊑ bitwise_or_logical_or_icmps_comm1_after

theorem sgt_positive_multip_rem_nz_thm (e : IntW 8) :
  icmp IntPred.sgt (mul e (const? 8 5) { «nsw» := true, «nuw» := false }) (const? 8 21) ⊑
    icmp IntPred.sgt e (const? 8 4)

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

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

theorem t0_ult_slt_65536_proof : t0_ult_slt_65536_before ⊑ t0_ult_slt_65536_after

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

theorem test_sub_0_Y_eq_0_proof : test_sub_0_Y_eq_0_before ⊑ test_sub_0_Y_eq_0_after

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

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

theorem t7_thm (e : IntW 32) :
  LLVM.sdiv (shl e (const? 32 2) { «nsw» := true, «nuw» := false }) e ⊑ const? 32 4

theorem negative2_proof : negative2_before ⊑ negative2_after

theorem add_select_sext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (sext 64 e) ⊑ select e (const? 64 63) (const? 64 1)

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

theorem icmp_slt_0_or_icmp_sgt_0_i32_proof : icmp_slt_0_or_icmp_sgt_0_i32_before ⊑ icmp_slt_0_or_icmp_sgt_0_i32_after

@[simp] theorem Com.denote_var [LawfulMonad d.m] {e : Expr d Γ eff α} :
    (Com.var e body).denote =
    fun Γv => (e.denote Γv) >>= body.denote

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

theorem e_2140 :
    1 * (f ^^^  ~~~(d ||| (e &&& f))) + 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 5 * (d ||| ( ~~~e &&& f)) + 1 * (e ||| (d &&&  ~~~f)) - 7 * (d &&& (e ||| f)) - 1 * ((d &&& e) ||| (e ^^^ f)) - 7 *  ~~~(d &&& (e ||| f)) + 7 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 5 *  ~~~(d ||| e) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ||| f) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 *  ~~~(d &&&  ~~~f) - 5 * ( ~~~d &&& (e ||| f)) - 2 * ( ~~~f |||  ~~~(d ^^^ e)) + 2 * (e ^^^ ( ~~~d &&& (e ||| f))) + 2 * (f ^^^ (d ||| e)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 11 * (f &&&  ~~~(d &&&  ~~~e)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 11 * (d &&& (e ^^^ f)) + 11 * (e &&&  ~~~(d &&& f)) - 5 * (e &&& (d ||| f)) + 7 *  ~~~( ~~~d ||| (e &&& f)) + 3 *  ~~~f + 11 * (e ||| (d ^^^ f)) + 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 *  ~~~(d &&& e) + 3 *  ~~~(d ||| f) - 1 * (f &&& (d ||| e)) - 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 3 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) - 2 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 1 * ((d &&& f) ^^^ (e ||| f)) + 11 * (f &&&  ~~~(d &&& e)) + 18 *  ~~~(d ||| (e ||| f)) - 19 *  ~~~(d ||| ( ~~~e ||| f)) - 16 *  ~~~( ~~~d ||| (e ||| f)) - 29 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 2 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) - 23 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) = 7 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f)))

theorem 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 and_logic_and_logic_or_1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 &&& x = 1#1 → ¬x_1 = 1#1 → 1#1 = 0#1

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

theorem test2_proof : test2_before ⊑ test2_after

theorem test_logical_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (255#32 <ᵤ x) = 1#1 → 1#1 = ofBool (255#32 <ᵤ x)

theorem test11_proof : test11_before ⊑ test11_after

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

theorem test10_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬4#64 = 0 → truncate 32 (signExtend 64 (zeroExtend 32 x * 4#32) % 4#64) = 0#32

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

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 e_2102 :
     - 2 * (f ^^^ (d ||| (e ||| f))) - 5 * (f ^^^  ~~~(d &&&  ~~~e)) + 2 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 3 * (e &&& (d ||| f)) + 11 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 4 * ((e &&& f) ||| (d &&& (e ||| f))) - 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * (e &&&  ~~~f) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 1 * (e &&&  ~~~(d &&& f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^ f) + 11 * (e ^^^ ( ~~~d ||| (e ||| f))) + 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * (d ||| e) + 4 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 5 * (f ^^^  ~~~(d ||| e)) - 5 * (e ^^^ (d &&&  ~~~f)) - 1 * (e ^^^  ~~~(d |||  ~~~f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 * (e ^^^  ~~~(d &&&  ~~~f)) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (f ||| (d &&&  ~~~e)) + 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 4 * (f |||  ~~~(d |||  ~~~e)) + 1 *  ~~~(e ||| f) + 1 *  ~~~(d &&& (e ||| f)) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 2 * (f |||  ~~~(d ||| e)) - 11 * (f &&& (d ^^^ e)) + 11 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 4 * (e ^^^  ~~~(d ||| (e &&& f))) - 40 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~(d ||| ( ~~~e ||| f)) + 2 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 41 * ( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~d &&& (e &&& f)) - 30 * (d &&& (e &&& f)) = 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f)))

theorem e_1098 :
    7 *  ~~~t + 5 *  ~~~(z &&& t) - 3 *  ~~~z + 11 * z - 3 *  ~~~(z ||| t) + 4 *  ~~~(z |||  ~~~t) - 23 * (z &&&  ~~~t) - 5 * (z &&& t) = 6 *  ~~~(z &&&  ~~~t)

theorem test_thm (e : IntW 64) : zext 64 (trunc 32 e) ⊑ LLVM.and e (const? 64 4294967295)

theorem test1_logical_proof : test1_logical_before ⊑ test1_logical_after

theorem icmp_ne_and_pow2_shl1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (1#32 <<< x &&& 16#32 != 0#32)) = zeroExtend 32 (ofBool (x == 4#32))

theorem test48_proof : test48_before ⊑ test48_after

theorem squared_nsw_eq0_thm (e : IntW 5) :
  icmp IntPred.eq (mul e e { «nsw» := true, «nuw» := false }) (const? 5 0) ⊑
    icmp IntPred.eq e (const? 5 0)

theorem OrZextOr_proof : OrZextOr_before ⊑ OrZextOr_after

theorem udiv_c_i32_proof : udiv_c_i32_before ⊑ udiv_c_i32_after

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 andn_or_cmp_4_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == x) = 1#1 → ofBool (x_1 != x) = 1#1 → ¬True → False

theorem e_1730 :
     - 1 * (c ^^^  ~~~(a &&&  ~~~b)) - 5 * ((a ^^^ b) &&& (a ^^^ c)) + 11 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 *  ~~~(a &&& (b &&& c)) - 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 11 * (b &&& c) - 11 * (b ^^^  ~~~(a ||| c)) - 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) + 7 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 3 * (a ^^^ ( ~~~b ||| c)) - 3 * ((a &&& b) |||  ~~~(b ^^^ c)) + 7 * (c ^^^ (a ||| (b &&& c))) + 1 * (c ^^^ ( ~~~a ||| (b &&& c))) - 7 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * (b &&&  ~~~(a &&& c)) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) - 7 * (c ^^^  ~~~(a &&& (b &&& c))) + 2 * (a ||| c) - 1 * ( ~~~c &&& (a ^^^ b)) + 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 11 * (b ^^^ (a ||| (b &&& c))) + 2 * ( ~~~a ||| ( ~~~b ||| c)) - 2 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 15 *  ~~~(a ||| ( ~~~b ||| c)) + 21 *  ~~~( ~~~a ||| (b ||| c)) + 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 6 * ( ~~~a &&& ( ~~~b &&& c)) + 25 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) + 30 * (a &&& (b &&& c)) =  - 3 *  ~~~(a ||| (b ||| c))

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

theorem test14_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x &&& BitVec.ofInt 8 (-128) != 0#8) = ofBool (x <ₛ 0#8)

theorem sub_ashr_and_i64_thm (e e_1 : IntW 64) :
  LLVM.and (ashr (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 64 63)) e ⊑
    select (icmp IntPred.slt e_1 e) e (const? 64 0)

theorem t6_shl_thm (e e_1 : IntW 32) :
  shl (shl e_1 (sub (const? 32 32) e) { «nsw» := false, «nuw» := true }) (add e (const? 32 (-2)))
      { «nsw» := true, «nuw» := false } ⊑
    shl e_1 (const? 32 30)

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

theorem add_or_sub_comb_i8_negative_y_sub_proof : add_or_sub_comb_i8_negative_y_sub_before ⊑ add_or_sub_comb_i8_negative_y_sub_after

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

theorem t3_ult_sgt_neg1_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 <ᵤ 65536#32) = 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 shl_xor_xor_good_mask_thm (e e_1 : IntW 8) :
  LLVM.xor (shl e_1 (const? 8 1)) (LLVM.xor (shl e (const? 8 1)) (const? 8 88)) ⊑
    LLVM.xor (shl (LLVM.xor e e_1) (const? 8 1)) (const? 8 88)

theorem bools_proof : bools_before ⊑ bools_after

theorem different_size_zext_zext_eq_thm.extracted_1._1 : ∀ (x : BitVec 7) (x_1 : BitVec 4),
  ofBool (zeroExtend 25 x_1 == zeroExtend 25 x) = ofBool (x == zeroExtend 7 x_1)

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

theorem e_586 :
     - 1 *  ~~~y + 11 * (x ^^^ y) - 5 *  ~~~(x ^^^ y) + 3 *  ~~~(x &&& y) + 1 * y + 1 * (x |||  ~~~y) - 17 *  ~~~(x |||  ~~~y) - 16 * (x &&&  ~~~y) + 1 * (x &&& y) =  - 2 *  ~~~(x &&&  ~~~x)

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

theorem zext_nneg_sext_sgt_proof : zext_nneg_sext_sgt_before ⊑ zext_nneg_sext_sgt_after

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

theorem logic_and_logic_or_2_proof : logic_and_logic_or_2_before ⊑ logic_and_logic_or_2_after

theorem both_sides_fold_eq_proof : both_sides_fold_eq_before ⊑ both_sides_fold_eq_after

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

theorem slt_zero_ne_ne_0_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (zeroExtend 32 (ofBool (x != 0#32)) != x >>> 31#32) = ofBool (0#32 <ₛ x)

theorem sub_from_constant_of_add_with_constant_thm (e : IntW 8) : sub (const? 8 11) (add e (const? 8 42)) ⊑ sub (const? 8 (-31)) e

theorem test25_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.srem e (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 2147483647)) (const? 32 0)

theorem shl_nsw_add_negative_proof : shl_nsw_add_negative_before ⊑ shl_nsw_add_negative_after

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

theorem lshr_ne_msb_low_last_zero_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 127) e) (const? 8 0) ⊑ icmp IntPred.ult e (const? 8 7)

theorem t3_proof : t3_before ⊑ t3_after

@[simp]
theorem eval_bigAnd_eq_true_iff
    (cs : List (Circuit α)) (env : α → Bool):
    (Circuit.bigAnd cs).eval env = true ↔
    (∀ (c : Circuit α), c ∈ cs → c.eval env = true)

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

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

theorem and_xor_common_op_proof : and_xor_common_op_before ⊑ and_xor_common_op_after

theorem eval_eq_carry (x : arity → BitStream) (n : ℕ) :
    p.eval x n = (p.nextBit (p.carry x n) (fun i => x i n)).2

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

theorem and_or2_commuted_proof : and_or2_commuted_before ⊑ and_or2_commuted_after

theorem test_ashr__exact_is_unsafe_proof : test_ashr__exact_is_unsafe_before ⊑ test_ashr__exact_is_unsafe_after

theorem ashr_2_add_zext_basic_proof : ashr_2_add_zext_basic_before ⊑ ashr_2_add_zext_basic_after

@[simp]
lemma BitVec.cons_ugt_iff {w} {bv1 bv2 : BitVec w} :
    ((BitVec.cons b2 bv2).ult (BitVec.cons b1 bv1)) ↔ (if b1 = b2 then bv2.ult bv1 else b1)

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

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

theorem positive_samevar_shlnuw_proof : positive_samevar_shlnuw_before ⊑ positive_samevar_shlnuw_after

theorem alive_820   : alive_820_src ⊑ alive_820_tgt

theorem test4_proof : test4_before ⊑ test4_after

theorem alive_InstCombineShift__582 : alive_InstCombineShift__582_src ⊑ alive_InstCombineShift__582_tgt

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

@[simp] theorem scanAnd_zero (s : BitStream) : scanAnd s 0 = s 0

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

theorem narrow_sext_and_proof : narrow_sext_and_before ⊑ narrow_sext_and_after

theorem and_or2_wrong_operand_proof : and_or2_wrong_operand_before ⊑ and_or2_wrong_operand_after

theorem ashr_ult_10_proof : ashr_ult_10_before ⊑ ashr_ult_10_after

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

theorem uadd_sat_via_add_nonstrict_proof : uadd_sat_via_add_nonstrict_before ⊑ uadd_sat_via_add_nonstrict_after

theorem or_test1_thm.extracted_1._1 : ∀ (x : BitVec 231), x &&& 1#231 ||

theorem tryFactorization_add_mul_nuw_proof : tryFactorization_add_mul_nuw_before ⊑ tryFactorization_add_mul_nuw_after

theorem test15h_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 8#32 != 0#32) = 1#1 → -1#32 = x &&& 8#32 ^^^ -1#32

theorem uge_to_sgt_proof : uge_to_sgt_before ⊑ uge_to_sgt_after

theorem xor_of_icmps_to_eq_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x <ₛ BitVec.ofInt 8 (-128)) ^^^ ofBool (126#8 <ₛ x) = ofBool (x == 127#8)

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

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

theorem sub_mask1_lshr_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬1#8 ≥ ↑8 → 6#8 ≥ ↑8 ∨ 7#8 ≥ ↑8 ∨ True ∧ ((x <<< 6#8).sshiftRight' 7#8).saddOverflow 10#8 = true → False

theorem dec_mask_commute_neg_i32_proof : dec_mask_commute_neg_i32_before ⊑ dec_mask_commute_neg_i32_after

theorem trunc_lshr_zext_exact_proof : trunc_lshr_zext_exact_before ⊑ trunc_lshr_zext_exact_after

theorem ashr_ugt_5_proof : ashr_ugt_5_before ⊑ ashr_ugt_5_after

theorem select_1_thm.extracted_1._11 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 x_3 : BitVec 8) (x_4 : BitVec 1),
  x_4 = 1#1 → x_3 ^^^ (x_2 ^^^ 45#8) ^^^ -1#8 = x_2 ^^^ x_3 ^^^ BitVec.ofInt 8 (-46)

theorem e_1944 :
     - 7 * (b &&& (a |||  ~~~c)) + 7 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 1 * (a ^^^ c) - 11 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 1 * (b &&& c) - 5 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 3 *  ~~~(a ^^^ (b &&& c)) - 3 * (a &&& c) + 4 * ( ~~~b |||  ~~~(a ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 6 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 1 * ((a &&& b) |||  ~~~(b ^^^ c)) - 2 * (c &&& (a |||  ~~~b)) + 3 *  ~~~(a ^^^ (b ^^^ c)) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 3 * ( ~~~a &&& (b ||| c)) + 11 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 2 * (a ||| (b ^^^ c)) - 1 * (c |||  ~~~(a |||  ~~~b)) - 1 * (b &&&  ~~~c) - 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 *  ~~~(a &&& (b &&& c)) - 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 11 *  ~~~(a &&& (b ^^^ c)) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * (b ||| (a &&& c)) + 11 *  ~~~(a ^^^ b) - 7 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * (b ^^^ (a ||| (b ||| c))) + 5 * ((a &&& b) |||  ~~~(b ||| c)) - 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 5 * (a ^^^ ( ~~~b ||| c)) + 7 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 1 *  ~~~(a ||| c) + 11 * (c ^^^ (a |||  ~~~b)) - 1 * (a ||| ( ~~~b &&& c)) + 3 * ( ~~~a ||| ( ~~~b ||| c)) - 11 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * (c ^^^ (a ||| b)) - 11 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 10 *  ~~~(a ||| (b ||| c)) + 7 *  ~~~(a ||| ( ~~~b ||| c)) - 4 *  ~~~( ~~~a ||| (b ||| c)) + 14 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) + 24 * (a &&& ( ~~~b &&& c)) + 56 * (a &&& (b &&& c)) =  - 3 * (c &&&  ~~~(a &&& b)) + 2 * ( ~~~a ||| ( ~~~b &&& c))

theorem goo_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.or (LLVM.and (select (icmp IntPred.slt e_3 e_2) (const? 32 (-1)) (const? 32 0)) e_1)
      (LLVM.and (LLVM.xor (select (icmp IntPred.slt e_3 e_2) (const? 32 (-1)) (const? 32 0)) (const? 32 (-1))) e) ⊑
    select (icmp IntPred.slt e_3 e_2) e_1 e

theorem tryFactorization_add_mul_nuw_proof : tryFactorization_add_mul_nuw_before ⊑ tryFactorization_add_mul_nuw_after

theorem test13_proof : test13_before ⊑ test13_after

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

theorem not_masked_sub_i8_proof : not_masked_sub_i8_before ⊑ not_masked_sub_i8_after

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

theorem e_1726 :
     - 5 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 6 * c - 1 *  ~~~(a |||  ~~~c) - 1 * ((a &&& b) ^^^ (b |||  ~~~c)) - 5 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 4 * (c ^^^ (a ||| (b &&& c))) - 1 *  ~~~(a &&&  ~~~a) + 1 * (b ^^^ (a ||| c)) - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 5 * (b ^^^ (a &&&  ~~~c)) - 1 * ((a ^^^ b) &&& (a ^^^ c)) + 11 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 2 * (a ^^^ ( ~~~b &&& c)) - 11 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 1 *  ~~~(a ^^^ (b ||| c)) + 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 11 * (b ^^^  ~~~(a &&& (b ||| c))) + 11 * (c ^^^  ~~~(a &&&  ~~~b)) + 3 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 11 * (a &&&  ~~~b) + 8 *  ~~~(a ||| (b ||| c)) - 20 *  ~~~(a ||| ( ~~~b ||| c)) + 17 *  ~~~( ~~~a ||| (b ||| c)) - 6 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 34 * ( ~~~a &&& ( ~~~b &&& c)) + 18 * ( ~~~a &&& (b &&& c)) + 11 * (a &&& ( ~~~b &&& c)) + 29 * (a &&& (b &&& c)) = 11 *  ~~~(a ||| (b &&& c))

theorem test23_logical_proof : test23_logical_before ⊑ test23_logical_after

theorem abs_must_be_positive_proof : abs_must_be_positive_before ⊑ abs_must_be_positive_after

theorem PR42691_8_logical_proof : PR42691_8_logical_before ⊑ PR42691_8_logical_after

theorem test10_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.eq (LLVM.and e (const? 32 2)) (const? 32 0)) (icmp IntPred.ult e (const? 32 4)) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem add_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 + signExtend 64 x = 1#64

theorem positive_sameconst_shlnuwnsw_proof : positive_sameconst_shlnuwnsw_before ⊑ positive_sameconst_shlnuwnsw_after

theorem lt_signed_to_small_signed_thm (e : IntW 8) :
  icmp IntPred.slt (sext 32 e) (const? 32 17) ⊑ icmp IntPred.slt e (const? 8 17)

theorem PR38021_thm (e : IntW 8) :
  add (lshr e (const? 8 3)) (const? 8 (-63)) ⊑
    add (lshr e (const? 8 3)) (const? 8 (-63)) { «nsw» := true, «nuw» := true }

theorem n9_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬62#64 ≥ ↑64 →
    62#64 ≥ ↑64 ∨
        True ∧ signExtend 64 (truncate 32 (x >>> 62#64)) ≠ x >>> 62#64 ∨
          True ∧ zeroExtend 64 (truncate 32 (x >>> 62#64)) ≠ x >>> 62#64 ∨
            True ∧ (0#32).ssubOverflow (truncate 32 (x >>> 62#64)) = true →
      False

theorem sge_swap_or_max_proof : sge_swap_or_max_before ⊑ sge_swap_or_max_after

theorem sel_false_val_is_a_masked_shl_of_true_val1_proof : sel_false_val_is_a_masked_shl_of_true_val1_before ⊑ sel_false_val_is_a_masked_shl_of_true_val1_after

theorem scalar_i8_shl_and_negC_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (LLVM.and (shl e_1 e) (const? 8 (-4))) (const? 8 0) ⊑
    icmp IntPred.ult (shl e_1 e) (const? 8 4)

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

theorem ashrslt_03_05_exact_thm (e : IntW 4) :
  icmp IntPred.slt (ashr e (const? 4 3) { «exact» := true }) (const? 4 5) ⊑ const? 1 1

theorem bools_multi_uses2_proof : bools_multi_uses2_before ⊑ bools_multi_uses2_after

@[simp]
theorem ofNat_zero : ofNat 0 = FSM.zero

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

theorem test21 (x y : BitVec w) : (~~~(x - y)) = (~~~x + y)

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

theorem main3d_proof : main3d_before ⊑ main3d_after

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

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

theorem test_sub_nuw__all_are_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 255)) (const? 32 6)) (const? 32 (-260))
      (sub (const? 32 (-254)) (LLVM.and e (const? 32 255)) { «nsw» := false, «nuw» := true }) ⊑
    sub (const? 32 (-254)) (LLVM.and e (const? 32 255)) { «nsw» := true, «nuw» := true }

theorem ugt_swap_and_min_proof : ugt_swap_and_min_before ⊑ ugt_swap_and_min_after

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

theorem test8_thm (e : IntW 7) : shl (shl e (const? 7 4)) (const? 7 3) ⊑ const? 7 0

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

theorem or_eq_with_diff_one_signed_logical_proof : or_eq_with_diff_one_signed_logical_before ⊑ or_eq_with_diff_one_signed_logical_after

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

theorem test21_thm.extracted_1._1 : ∀ (x : BitVec 32), signExtend 32 (truncate 8 x) &&& 255#32 = x &&& 255#32

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

theorem and_ne_with_one_bit_diff_constants3_logical_proof : and_ne_with_one_bit_diff_constants3_logical_before ⊑ and_ne_with_one_bit_diff_constants3_logical_after

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

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

@[simp]
lemma dec_snoc_in_langRel2 :
    dec (w ++ [a]) ∈ langRel2 R ↔ R (.cons (a.getLsbD 0) ((dec w).bvs.get 0))
                                   (.cons (a.getLsbD 1) ((dec w).bvs.get 1))

theorem e_49 :
    11 * (x |||  ~~~y) + 2 * x - 12 *  ~~~(x ||| y) - 13 * (x &&&  ~~~y) - 14 * (x &&& y) =  - 1 *  ~~~(x ^^^ y)

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

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

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

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

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

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

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

theorem commutativity_constant_14_vary_proof : commutativity_constant_14_vary_before ⊑ commutativity_constant_14_vary_after

theorem ne_21_comm_or_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8))))
      (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16)))) ⊑
    icmp IntPred.ne (trunc 16 (lshr e_1 (const? 32 8))) (trunc 16 (lshr e (const? 32 8)))

theorem shl_lshr_eq_amt_multi_use_proof : shl_lshr_eq_amt_multi_use_before ⊑ shl_lshr_eq_amt_multi_use_after

theorem ashr_not_proof : ashr_not_before ⊑ ashr_not_after

theorem bor_lor_left1_proof : bor_lor_left1_before ⊑ bor_lor_left1_after

theorem not_cond_proof : not_cond_before ⊑ not_cond_after

theorem t2_proof : t2_before ⊑ t2_after

theorem test_shl_nuw__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 test_eq_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 0#32) = 1#1 → 2#32 ≥ ↑32 → False

theorem sub_from_constant_thm (e e_1 : IntW 5) : add (sub (const? 5 10) e_1) e ⊑ add (sub e e_1) (const? 5 10)

theorem band_lor_right2_proof : band_lor_right2_before ⊑ band_lor_right2_after

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

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

theorem p_proof : p_before ⊑ p_after

theorem test_sub_255_Y_eq_255_proof : test_sub_255_Y_eq_255_before ⊑ test_sub_255_Y_eq_255_after

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

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

theorem test17_proof : test17_before ⊑ test17_after

theorem shl_nuw_add_nuw_proof : shl_nuw_add_nuw_before ⊑ shl_nuw_add_nuw_after

theorem icmp_ne_zext_eq_non_boolean_thm (e : IntW 32) :
  icmp IntPred.ne (zext 32 (icmp IntPred.eq e (const? 32 2))) e ⊑
    icmp IntPred.ne e (const? 32 0)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_1b_logical_after

theorem udiv_i8_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

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

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

@[simp]
lemma BitVecs.transport_w {bvs : BitVecs n} : (BitVecs.transport f bvs).w = bvs.w

theorem test20_proof : test20_before ⊑ test20_after

theorem icmp_select_var_commuted_proof : icmp_select_var_commuted_before ⊑ icmp_select_var_commuted_after

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

theorem lshr_sext_i1_to_i16_proof : lshr_sext_i1_to_i16_before ⊑ lshr_sext_i1_to_i16_after

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

theorem shrink_select_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1), ¬x_1 = 1#1 → truncate 8 42#32 = 42#8

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

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

theorem positive_with_extra_and_logical_thm (e : IntW 1) (e_1 : IntW 32) :
  select (icmp IntPred.ult (add e_1 (const? 32 128)) (const? 32 256))
      (select (icmp IntPred.sgt e_1 (const? 32 (-1))) e (const? 1 0)) (const? 1 0) ⊑
    select (icmp IntPred.ult e_1 (const? 32 128)) e (const? 1 0)

theorem masked_icmps_mask_notallzeros_bmask_mixed_5_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_5_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_5_logical_after

theorem shl_add_lshr_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_1).uaddOverflow x = true ∨ x_1 ≥ ↑32) →
    x_1 ≥ ↑32 ∨ True ∧ (x >>> x_1).uaddOverflow x_2 = true → False

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

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

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

theorem scalar_i8_shl_ule_const_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬5#8 ≥ ↑8 → ofBool (x <<< 5#8 ≤ᵤ 63#8) = ofBool (x &&& 6#8 == 0#8)

theorem or_nontrivial_mask2_thm (e : IntW 16) :
  LLVM.or (icmp IntPred.ne (trunc 8 e) (const? 8 127))
      (icmp IntPred.ne (LLVM.and e (const? 16 (-4096))) (const? 16 20480)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 16 (-3841))) (const? 16 20607)

theorem e_2455 :
    2 *  ~~~(d ^^^ e) - 2 * (e ||| (d ^^^ f)) + 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 6 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 3 * (f ^^^ ( ~~~d ||| (e ||| f))) + 3 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 * (e &&&  ~~~(d ^^^ f)) - 3 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 11 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) + 5 * ((d &&& e) ^^^ (e |||  ~~~f)) - 1 * ( ~~~e &&& (d ^^^ f)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 11 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 1 *  ~~~( ~~~d &&& (e ||| f)) + 2 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * (f ^^^ (d |||  ~~~e)) - 1 *  ~~~(d &&& ( ~~~e ||| f)) + 2 *  ~~~(d &&& (e &&& f)) - 1 * (f ^^^  ~~~(d |||  ~~~e)) - 7 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 11 * (d |||  ~~~f) - 3 * (e &&&  ~~~(d &&& f)) - 11 * (f ^^^ (d ||| ( ~~~e &&& f))) - 1 * (f ^^^ (d &&&  ~~~e)) - 5 * ((d ^^^ e) &&& (d ^^^ f)) + 2 *  ~~~(d ^^^ f) + 7 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 11 * (f &&& (d ||| e)) + 4 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 2 *  ~~~(d &&& ( ~~~e &&& f)) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * (d ||| (e &&& f)) - 1 * ( ~~~e &&&  ~~~(d ^^^ f)) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 6 *  ~~~(d &&&  ~~~f) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * ( ~~~f &&&  ~~~(d ^^^ e)) + 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 11 * (d ^^^ (e ||| f)) - 1 * (e &&& (d ^^^ f)) - 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 4 * ( ~~~e ||| (d ^^^ f)) - 7 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 5 * (e ^^^ (d &&& (e ||| f))) - 2 * (e &&& (d ||| f)) - 5 * (e |||  ~~~(d ^^^ f)) - 1 * (d |||  ~~~e) + 4 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 *  ~~~(d ||| ( ~~~e &&& f)) + 11 * (d ^^^ (e ^^^ f)) - 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 7 * (e ^^^ (d ||| (e &&& f))) - 6 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 5 *  ~~~(d ||| (e ^^^ f)) + 5 * (e ^^^ (d &&&  ~~~f)) - 7 * (f ^^^  ~~~(d &&&  ~~~e)) + 1 * (f &&&  ~~~(d &&& e)) + 3 * (e ^^^ (d ||| (e ||| f))) + 5 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 11 * (f ^^^ (d ||| (e ||| f))) + 2 * (d &&& f) - 1 * ( ~~~f |||  ~~~(d ^^^ e)) + 4 *  ~~~(e &&&  ~~~f) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 3 * ( ~~~d &&& (e ||| f)) + 20 *  ~~~(d ||| (e ||| f)) - 11 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) + 17 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 37 * ( ~~~d &&& ( ~~~e &&& f)) + 40 * ( ~~~d &&& (e &&& f)) + 50 * (d &&& ( ~~~e &&& f)) + 21 * (d &&& (e &&& f)) =  - 3 * ((d &&& f) |||  ~~~(e ||| f))

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

theorem zext_masked_bit_zero_to_smaller_bitwidth_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x_1 ≥ ↑32 → zeroExtend 16 (ofBool (1#32 <<< x_1 &&& x == 0#32)) = truncate 16 ((x ^^^ -1#32) >>> x_1) &&& 1#16

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

theorem lshrult_01_14_proof : lshrult_01_14_before ⊑ lshrult_01_14_after

theorem lsb_mask_sign_sext_commuted_proof : lsb_mask_sign_sext_commuted_before ⊑ lsb_mask_sign_sext_commuted_after

theorem or_xor_tree_0100_proof : or_xor_tree_0100_before ⊑ or_xor_tree_0100_after

theorem neg_or_ashr_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → (0#32 - x ||| x).sshiftRight' 31#32 = signExtend 32 (ofBool (x != 0#32))

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

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

theorem and_xor_common_op_commute1_proof : and_xor_common_op_commute1_before ⊑ and_xor_common_op_commute1_after

@[simp_denote]
theorem valuation_var_cons_eq.lemma {Ty : Type} [TyDenote Ty] {Γ : Ctxt Ty} {t t' : Ty}
  {s : Γ.Valuation} {x : TyDenote.toType t} {v : Γ.Var t'} :
  (s.cons x) (Ctxt.Var.toCons v) = s v

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

theorem PR2330_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 <ᵤ 8#32) &&& ofBool (x <ᵤ 8#32) = ofBool (x_1 ||| x <ᵤ 8#32)

@[bv_automata_nnf] theorem cond_eq_ite (c : Bool) (a b : α) : cond c a b = ite c a b

theorem xor_sub :
    [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    %v1 = llvm.sub %X, %X
    %r = llvm.xor %v1, %Y
    llvm.return %r
  }] ⊑  [llvm(w)| {
  ^bb0(%X : _, %Y : _):
    llvm.return %Y
  }]

theorem t11_shl_nsw_flag_preservation_thm (e e_1 : IntW 32) :
  shl (shl e_1 (sub (const? 32 32) e) { «nsw» := true, «nuw» := false }) (add e (const? 32 (-2)))
      { «nsw» := true, «nuw» := true } ⊑
    shl e_1 (const? 32 30) { «nsw» := true, «nuw» := false }

theorem lshr_pow2_ugt1_proof : lshr_pow2_ugt1_before ⊑ lshr_pow2_ugt1_after

theorem wide_source_matching_signbits_proof : wide_source_matching_signbits_before ⊑ wide_source_matching_signbits_after

theorem substitute_constant_or_ne_swap_sle_proof : substitute_constant_or_ne_swap_sle_before ⊑ substitute_constant_or_ne_swap_sle_after

theorem udiv_i80_thm (e : IntW 80) :
  LLVM.udiv (lshr e (const? 80 2)) (const? 80 100) ⊑ LLVM.udiv e (const? 80 400)

private theorem falseAfterIncluding_false_iff (n i : Nat) {env : Fin 0 → BitStream} :
  (falseAfterIncluding n).eval env i = false ↔ i ≥ n

theorem icmp_ne_sext_ne_otherwise_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x != 2#32)) != x) = ofBool (x != -1#32)

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

theorem bitwise_and_logical_and_masked_icmp_allzeros_thm (e : IntW 1) (e_1 : IntW 32) :
  LLVM.and (select (icmp IntPred.eq (LLVM.and e_1 (const? 32 8)) (const? 32 0)) e (const? 1 0))
      (icmp IntPred.eq (LLVM.and e_1 (const? 32 7)) (const? 32 0)) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 15)) (const? 32 0)) e (const? 1 0)

theorem neg_nsw_sgt_0_proof : neg_nsw_sgt_0_before ⊑ neg_nsw_sgt_0_after

theorem test_add_nuw_nsw__all_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 == 3#32) = 1#1 →
    True ∧ (x &&& 1073741823#32).saddOverflow 1#32 = true ∨ True ∧ (x &&& 1073741823#32).uaddOverflow 1#32 = true →
      False

theorem test_sgt_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.sgt (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.slt (LLVM.xor e e_1) e_1

theorem logical_or_logical_or_icmps_comm3_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 8),
  ¬x_1 ≥ ↑8 →
    ¬(ofBool (x_2 &&& 1#8 <<< x_1 == 0#8) = 1#1 ∨ 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 == 42#8) = 1#1

theorem or_eq_with_diff_one_signed_proof : or_eq_with_diff_one_signed_before ⊑ or_eq_with_diff_one_signed_after

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

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

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

theorem icmp_ne_and_pow2_shl_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 16#32 != 0#32)) = zeroExtend 32 (ofBool (x == 3#32))

theorem icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1073741823#32 != 1073741823#32) &&& ofBool (x <ᵤ 1073741824#32) = ofBool (x <ᵤ 1073741823#32)

theorem zext_negate_proof : zext_negate_before ⊑ zext_negate_after

theorem icmp_ne_mul_nsw_nonequal_proof : icmp_ne_mul_nsw_nonequal_before ⊑ icmp_ne_mul_nsw_nonequal_after

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

theorem lshr_sub_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬((42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨ 3#8 ≥ ↑8 ∨ 3#8 ≥ ↑8) →
    (42#8 == 0 || 8 != 1 && x_1 == intMin 8 && 42#8 == -1) = true ∨
        3#8 ≥ ↑8 ∨ True ∧ (x_1.srem 42#8).ssubOverflow (x >>> 3#8) = true ∨ 3#8 ≥ ↑8 →
      False

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

theorem add_of_selects_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → BitVec.ofInt 32 (-2) + 2#32 = 0#32

theorem PR42691_10_logical_proof : PR42691_10_logical_before ⊑ PR42691_10_logical_after

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

theorem test69_xor_proof : test69_xor_before ⊑ test69_xor_after

theorem test_or3_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 test1_thm.extracted_1._1 : ∀ (x : BitVec 32), ofBool (x ^^^ 12345#32 <ₛ 0#32) = ofBool (x <ₛ 0#32)

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

theorem not_lshr_proof : not_lshr_before ⊑ not_lshr_after

@[simp] theorem map_cons {A B : α → Type u} {as : List α} {f : (a : α) → A a → B a}
    {x : A a} {xs : HVector A as} :
    map f (cons x xs) = cons (f _ x) (map f xs)

theorem foo1_or_signbit_lshr_without_shifting_signbit_both_sides_proof : foo1_or_signbit_lshr_without_shifting_signbit_both_sides_before ⊑ foo1_or_signbit_lshr_without_shifting_signbit_both_sides_after

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

theorem scalar_i32_signbit_shl_and_slt_proof : scalar_i32_signbit_shl_and_slt_before ⊑ scalar_i32_signbit_shl_and_slt_after

theorem ashr_exact_add_negative_shift_negative_proof : ashr_exact_add_negative_shift_negative_before ⊑ ashr_exact_add_negative_shift_negative_after

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

theorem fast_div_201_proof : fast_div_201_before ⊑ fast_div_201_after

theorem decideIfZeros_correct {arity : Type _} [DecidableEq arity]
    (p : FSM arity) : decideIfZeros p = true ↔ ∀ n x, p.simplify.eval x n = false

theorem test19_commutative1_proof : test19_commutative1_before ⊑ test19_commutative1_after

theorem scalar_i16_lshr_and_negC_eq_proof : scalar_i16_lshr_and_negC_eq_before ⊑ scalar_i16_lshr_and_negC_eq_after

theorem e_1603 :
    3 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) - 1 * (a ^^^ (b ^^^ c)) + 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 3 * (b &&&  ~~~(a &&& c)) + 11 *  ~~~(a ||| ( ~~~b &&& c)) - 3 *  ~~~(b &&&  ~~~c) - 11 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 6 *  ~~~(b |||  ~~~c) + 3 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 5 * (b &&&  ~~~c) + 7 * (c ||| (a &&&  ~~~b)) + 4 * ((a |||  ~~~b) &&& (b ^^^ c)) + 11 * (c ^^^ ( ~~~a ||| (b &&& c))) - 12 *  ~~~(a ||| (b ||| c)) - 19 *  ~~~(a ||| ( ~~~b ||| c)) - 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 4 * ( ~~~a &&& ( ~~~b &&& c)) - 25 * ( ~~~a &&& (b &&& c)) - 16 * (a &&& ( ~~~b &&& c)) =  - 5 *  ~~~( ~~~a ||| (b ||| c)) + 7 * (a &&& (b &&& c))

theorem alive_AddSub_1564  (w : Nat)   : alive_AddSub_1564_src w  ⊑ alive_AddSub_1564_tgt w

theorem t_2_192_proof : t_2_192_before ⊑ t_2_192_after

theorem t1_flags_nuw_first_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 8),
  ¬(True ∧ x_2.usubOverflow x_1 = true) → x_2 - x_1 - x = x_2 - (x_1 + x)

theorem test22_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬24#32 ≥ ↑32 → signExtend 32 (truncate 8 x) <<< 24#32 = x <<< 24#32

theorem neg_nsw_slt_n1_proof : neg_nsw_slt_n1_before ⊑ neg_nsw_slt_n1_after

theorem or_not_and_commute5_thm (e e_1 e_2 : IntW 32) :
  LLVM.or
      (LLVM.and (LLVM.sdiv (const? 32 42) e_2) (LLVM.xor (LLVM.or (LLVM.sdiv (const? 32 42) e_1) e) (const? 32 (-1))))
      (LLVM.and (LLVM.xor (LLVM.or (LLVM.sdiv (const? 32 42) 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 (LLVM.sdiv (const? 32 42) e_1) (const? 32 (-1)))

theorem masked_and_notA_proof : masked_and_notA_before ⊑ masked_and_notA_after

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

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

theorem R.surjective_fromPoly (q n : ℕ) : Function.Surjective (R.fromPoly (q := q) (n := n))

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

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

theorem t3_singlebit_proof : t3_singlebit_before ⊑ t3_singlebit_after

@[grind =, simp]
lemma RawCNFA.empty_stateMax : empty (A := A).stateMax = 0

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

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

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

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

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

theorem e_2293 :
     - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 3 * (d &&&  ~~~e) - 5 *  ~~~(e |||  ~~~f) + 2 * (f ^^^ (d ||| e)) + 2 * ((d |||  ~~~e) &&& (e ^^^ f)) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 6 * (f ^^^ ( ~~~d ||| (e &&& f))) - 3 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * (f ^^^ (d &&&  ~~~e)) - 3 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 7 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * (e ^^^  ~~~(d ||| f)) + 4 * ( ~~~d &&& (e ^^^ f)) - 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 *  ~~~(d ^^^ ( ~~~e ||| f)) + 7 * (e ||| (d ^^^ f)) - 1 *  ~~~(e &&& f) - 7 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 6 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * (e |||  ~~~f) + 5 *  ~~~(d ||| f) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * ( ~~~d ||| (e &&& f)) + 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 5 * (e ^^^  ~~~(d &&& (e ||| f))) + 4 * (e ||| (d &&&  ~~~f)) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d ||| e)) - 11 *  ~~~(d &&&  ~~~f) - 5 *  ~~~(d |||  ~~~e) - 2 * ( ~~~d &&& (e ||| f)) - 6 * (e ^^^ (d |||  ~~~f)) - 3 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 *  ~~~d - 5 * ( ~~~e ||| (d ^^^ f)) + 11 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 3 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * (e ^^^  ~~~(d ||| (e &&& f))) + 11 *  ~~~(d ^^^ ( ~~~e &&& f)) + 4 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * (e &&& f) + 11 * (d ^^^ (e ||| f)) - 1 *  ~~~(d &&&  ~~~e) + 1 * (f ^^^ ( ~~~d &&& (e ||| f))) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 5 *  ~~~(d ||| (e ||| f)) - 23 *  ~~~(d ||| ( ~~~e ||| f)) - 17 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 13 * ( ~~~d &&& ( ~~~e &&& f)) - 16 * ( ~~~d &&& (e &&& f)) + 3 * (d &&& ( ~~~e &&& f)) - 27 * (d &&& (e &&& f)) =  - 4 * (e ^^^ (d ||| ( ~~~e &&& f))) - 3 * (f &&& (d |||  ~~~e))

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

theorem add_or_sub_comb_i8_negative_y_add_proof : add_or_sub_comb_i8_negative_y_add_before ⊑ add_or_sub_comb_i8_negative_y_add_after

theorem positive_biggershl_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ 6#8 ≥ ↑8) → ¬3#8 ≥ ↑8 → x >>> 3#8 <<< 6#8 = x <<< 3#8 &&& BitVec.ofInt 8 (-64)

theorem e_2224 :
     - 7 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 *  ~~~(d ^^^ e) - 2 *  ~~~(d ^^^ ( ~~~e ||| f)) - 11 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (e ^^^  ~~~(d ||| f)) - 5 * (d ^^^ ( ~~~e &&& f)) + 7 *  ~~~(d ^^^ ( ~~~e &&& f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 5 * (d ^^^ f) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 5 * (f ^^^  ~~~(d &&&  ~~~e)) + 2 *  ~~~(d ^^^ (e ||| f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 6 * (f ^^^ ( ~~~d &&& (e ||| f))) + 7 * (d &&& ( ~~~e ||| f)) + 1 * (d &&&  ~~~f) + 1 *  ~~~(d |||  ~~~f) + 4 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 11 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 1 * (e &&&  ~~~(d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (d ^^^ (e &&& f)) + 11 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 7 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * (e ^^^ (d &&& (e ||| f))) + 2 * ((d &&& f) ^^^ (e ||| f)) + 4 * ((d &&& e) |||  ~~~(e ^^^ f)) - 1 * f + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 2 *  ~~~(d ||| f) - 1 * d - 1 *  ~~~(d &&& e) + 5 * ( ~~~e |||  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * e + 1 * (d ||| ( ~~~e &&& f)) - 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 5 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 6 * (e |||  ~~~(d ^^^ f)) + 7 * (e ^^^ (d &&& f)) - 1 * (d &&& e) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * (d ||| (e ^^^ f)) + 3 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 10 *  ~~~(d ||| (e ||| f)) - 11 *  ~~~(d ||| ( ~~~e ||| f)) + 8 *  ~~~( ~~~d ||| (e ||| f)) + 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 27 * ( ~~~d &&& ( ~~~e &&& f)) + 6 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) + 30 * (d &&& (e &&& f)) = 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 5 * (f ||| (d &&& e))

theorem test_shl_nuw__nsw_is_safe_thm (e : IntW 32) :
  mul
      (mul
        (select (icmp IntPred.eq (LLVM.or e (const? 32 (-83886080))) (const? 32 (-83886079)))
          (const? 32 (-335544316))
          (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := false, «nuw» := true }))
        (LLVM.or e (const? 32 (-83886080))))
      (shl (LLVM.or e (const? 32 (-83886080))) (const? 32 2) { «nsw» := false, «nuw» := true }) ⊑
    const? 32 0

theorem negative2_logical_proof : negative2_logical_before ⊑ negative2_logical_after

lemma toNat_neq_zero_of_neq_zero {x : BitVec w} (hx : x ≠ 0) : x.toNat ≠ 0

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

@[simp]
theorem BitVec.intCast_zero : ((0 : Int) : BitVec w) = 0#w

theorem test87_proof : test87_before ⊑ test87_after

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

theorem exact_lshr_ne_opposite_msb_thm (e : IntW 8) :
  icmp IntPred.ne (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.ne e (const? 8 7)

@[simp] lemma swapLastTwoBlock_SSn {n : Nat} : swapLastTwoBlock (Fin.last (n+2)) = n

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

theorem test7_proof : test7_before ⊑ test7_after

theorem test_nuw_and_unsigned_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).usubOverflow x = true) → ofBool (10#64 - x <ᵤ 3#64) = ofBool (7#64 <ᵤ x)

theorem main10_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e (const? 32 64)) (const? 32 0))
        (icmp IntPred.sge (trunc 8 e) (const? 8 0)) (const? 1 0))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 192)) (const? 32 0)) (const? 32 2) (const? 32 1)

@[simp]
theorem unifyVars_eq_some_iff :
    unifyVars w v mapIn = some ((), mapOut)
    ↔ ( mapIn.lookup ⟨t, w⟩ = none ∧ mapIn.insert ⟨t, w⟩ v = mapOut
        ∨ mapIn.lookup ⟨t, w⟩ = v ∧ mapIn = mapOut
      )

theorem urem_i8_proof : urem_i8_before ⊑ urem_i8_after

theorem and_or2_proof : and_or2_before ⊑ and_or2_after

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

theorem add_smin_simplify2_thm (e : IntW 32) :
  select (icmp IntPred.slt (add e (const? 32 (-3)) { «nsw» := true, «nuw» := false }) (const? 32 2147483645))
      (add e (const? 32 (-3)) { «nsw» := true, «nuw» := false }) (const? 32 2147483645) ⊑
    add e (const? 32 (-3)) { «nsw» := true, «nuw» := false }

theorem shl_or_proof : shl_or_before ⊑ shl_or_after

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

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

theorem sext_sext_add_mismatched_types_proof : sext_sext_add_mismatched_types_before ⊑ sext_sext_add_mismatched_types_after

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

theorem test_sext3_thm.extracted_1._5 : ∀ (x x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → signExtend 32 x = signExtend 32 0#1

theorem test1_proof : test1_before ⊑ test1_after

theorem shl_add_log_may_cause_poison_pr62175_with_nsw_proof : shl_add_log_may_cause_poison_pr62175_with_nsw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nsw_after

theorem fold_icmp_shl_nuw_c2_non_pow2_proof : fold_icmp_shl_nuw_c2_non_pow2_before ⊑ fold_icmp_shl_nuw_c2_non_pow2_after

theorem width2 {v w : Nat} (x : BitVec v) :
    x.signExtend (max v (min v w)) = x.zeroExtend (max v (min v w))

theorem add_select_sext_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → 64#64 + signExtend 64 x = 63#64

theorem add_or_sub_comb_i8_negative_y_or_proof : add_or_sub_comb_i8_negative_y_or_before ⊑ add_or_sub_comb_i8_negative_y_or_after

theorem e_708 :
    1 *  ~~~(x &&&  ~~~x) + 1 *  ~~~x - 11 * y - 1 * x - 2 *  ~~~(x ^^^ y) + 1 * (x ^^^ y) + 7 *  ~~~(x ||| y) + 15 *  ~~~(x |||  ~~~y) - 1 * (x &&&  ~~~y) + 20 * (x &&& y) = 7 *  ~~~(x &&&  ~~~y)

@[simp, grind=] theorem length_cons (Γ : Ctxt α) (x : α) : (Γ.cons x).length = Γ.length + 1

theorem zext_shl_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬3#16 ≥ ↑16 → ¬3#8 ≥ ↑8 → zeroExtend 16 x <<< 3#16 &&& zeroExtend 16 x = zeroExtend 16 (x <<< 3#8 &&& x)

theorem a_thm (e e_1 : IntW 1) :
  add (add (zext 32 e_1) (const? 32 1)) (sub (const? 32 0) (zext 32 e)) ⊑
    add (select e_1 (const? 32 2) (const? 32 1)) (sext 32 e) { «nsw» := true, «nuw» := false }

theorem sgt_positive_multip_rem_zero_proof : sgt_positive_multip_rem_zero_before ⊑ sgt_positive_multip_rem_zero_after

@[simp] theorem Hom.appendCodomain_apply (f : Γ.Hom Δ) (v : Γ.Var t) :
    (f.appendCodomain (ts := ts)) v = (f v).appendInr

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

theorem sext_zext_ne_known_nonneg_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (sext 32 e_1) (zext 32 (LLVM.udiv e (const? 8 6))) ⊑
    icmp IntPred.ne e_1 (LLVM.udiv e (const? 8 6))

theorem PR42691_7_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (BitVec.ofInt 32 (-2147483647) ≤ᵤ x) = 1#1 → 1#1 = ofBool (x + -1#32 <ₛ 0#32)

theorem select_icmp_ne_0_and_8_or_1073741824_proof : select_icmp_ne_0_and_8_or_1073741824_before ⊑ select_icmp_ne_0_and_8_or_1073741824_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 src_srem_shl_demand_min_signbit_proof : src_srem_shl_demand_min_signbit_before ⊑ src_srem_shl_demand_min_signbit_after

theorem mul_x_selectp2_thm (e : IntW 1) (e_1 : IntW 8) :
  mul (mul e_1 e_1) (select e (const? 8 8) (const? 8 1)) ⊑
    shl (mul e_1 e_1) (select e (const? 8 3) (const? 8 0))

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

theorem andn_or_cmp_1_logical_proof : andn_or_cmp_1_logical_before ⊑ andn_or_cmp_1_logical_after

theorem trunc_nuw_xor_proof : trunc_nuw_xor_before ⊑ trunc_nuw_xor_after

theorem drop_nuw_trunc_thm (e e_1 : IntW 16) :
  trunc 8 (LLVM.and (LLVM.and e_1 (const? 16 255)) e) { «nsw» := false, «nuw» := true } ⊑
    trunc 8 (LLVM.and e_1 e)

theorem PR1817_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 10#32) = 1#1 → 0#1 = ofBool (x <ᵤ 10#32)

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

theorem xor_signbit_select_lshr_thm (e : IntW 32) (e_1 : IntW 1) :
  lshr (select e_1 (LLVM.xor e (const? 32 (-65536))) e) (const? 32 8) ⊑
    select e_1 (LLVM.xor (lshr e (const? 32 8)) (const? 32 16776960)) (lshr e (const? 32 8))

theorem src_x_and_nmask_eq_proof : src_x_and_nmask_eq_before ⊑ src_x_and_nmask_eq_after

theorem e_1943 :
    5 * (b |||  ~~~(a ^^^ c)) - 11 * ((a &&& b) ^^^ (b ||| c)) - 2 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 4 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 1 *  ~~~(b &&&  ~~~c) + 1 *  ~~~(a ^^^ b) - 1 *  ~~~(a ||| (b &&& c)) + 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 2 *  ~~~(a &&&  ~~~b) - 7 *  ~~~(a &&& c) + 7 * (c ^^^ (a ||| b)) + 3 * (b ^^^ (a &&& c)) - 1 * (a |||  ~~~b) - 7 * (b ||| (a &&&  ~~~c)) + 5 * (b ^^^ (a ||| (b ||| c))) - 2 * (c ^^^  ~~~(a ||| (b &&& c))) + 1 * (a ^^^ (b ^^^ c)) + 11 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 4 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 6 * (c ^^^ ( ~~~a ||| (b ||| c))) + 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 7 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * ( ~~~c &&&  ~~~(a ^^^ b)) - 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * ( ~~~b &&&  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a &&& b)) + 1 *  ~~~a + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 4 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 7 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 7 *  ~~~(a &&& (b &&& c)) - 1 * (c &&& (a ^^^ b)) - 2 * (c ^^^  ~~~(a |||  ~~~b)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 2 * ((a &&& b) |||  ~~~(b ||| c)) - 1 *  ~~~(b &&& c) - 1 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 3 * (c ^^^ (a ||| (b &&& c))) + 1 * ( ~~~a ||| (b &&& c)) + 1 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 2 * (c ^^^ (a &&& b)) + 7 * ((a ^^^ b) ||| (a ^^^ c)) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 1 * ((a &&& b) ^^^ (b |||  ~~~c)) + 5 * (b ^^^ (a ||| c)) - 25 *  ~~~(a ||| (b ||| c)) - 21 *  ~~~(a ||| ( ~~~b ||| c)) - 23 *  ~~~( ~~~a ||| (b ||| c)) - 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 26 * ( ~~~a &&& ( ~~~b &&& c)) - 35 * (a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) =  - 4 *  ~~~(a ||| ( ~~~b &&& c)) + 9 * ( ~~~a &&& (b &&& c))

theorem icmp_eq_sext_ne_allones_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x != -1#32)) == x) = 0#1

theorem test1_trunc_proof : test1_trunc_before ⊑ test1_trunc_after

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

theorem test_with_5_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → 5#32 <<< x &&& 1#32 = zeroExtend 32 (ofBool (x == 0#32))

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

theorem test4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) &&& ofBool (-1#32 <ₛ x) = ofBool (-1#32 <ₛ x_1 ||| x)

theorem e_2067 :
     - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 11 * (e &&& (d |||  ~~~f)) - 11 * (f ^^^ (d &&& (e ||| f))) + 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (d |||  ~~~e) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * ( ~~~d ||| ( ~~~e ||| f)) + 2 * (e ^^^  ~~~(d ||| f)) - 5 * (d |||  ~~~f) - 2 * (e |||  ~~~(d ||| f)) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * (e |||  ~~~(d |||  ~~~f)) + 3 * ( ~~~d &&& (e ^^^ f)) + 1 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ||| (d ^^^ f)) + 11 * ( ~~~e ||| (d ^^^ f)) + 11 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 1 * (f ^^^  ~~~(d |||  ~~~e)) + 2 * (f &&& (d |||  ~~~e)) + 1 * (d ^^^ f) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 4 *  ~~~(d ||| (e ||| f)) + 33 *  ~~~(d ||| ( ~~~e ||| f)) - 2 *  ~~~( ~~~d ||| (e ||| f)) + 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 10 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) - 11 * (d &&& ( ~~~e &&& f)) + 19 * (d &&& (e &&& f)) =  - 3 *  ~~~( ~~~d &&& (e &&& f))

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

theorem test18_thm.extracted_1._1 : ∀ (x : BitVec 8), truncate 16 (signExtend 32 x) = signExtend 16 x

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

theorem udiv_shl_pair1_proof : udiv_shl_pair1_before ⊑ udiv_shl_pair1_after

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

@[simp]
theorem eval_sub (x : Bool → BitStream) : sub.eval x = (x true) - (x false)

theorem zext_ult_zext_proof : zext_ult_zext_before ⊑ zext_ult_zext_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 t9_thm (e : IntW 8) :
  icmp IntPred.ne (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e ⊑
    icmp IntPred.ne e (const? 8 0)

theorem test1_proof : test1_before ⊑ test1_after

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

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

theorem scalar_i8_shl_ult_const_1_proof : scalar_i8_shl_ult_const_1_before ⊑ scalar_i8_shl_ult_const_1_after

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

theorem shl_bad_sub_i64_thm (e : IntW 64) :
  shl (const? 64 1) (sub (const? 64 67) e) ⊑
    shl (const? 64 1) (sub (const? 64 67) e) { «nsw» := false, «nuw» := true }

theorem main4f_like_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 != x_1) ||

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 trunc_sel_equal_sext_thm.extracted_1._4 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 32 42#16 = 42#32

theorem logical_and_not_proof : logical_and_not_before ⊑ logical_and_not_after

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

theorem e_1351 :
    2 *  ~~~(z &&& t) - 6 *  ~~~t + 4 *  ~~~z - 2 * z - 6 * (z ^^^ t) - 7 * t - 1 *  ~~~(z ||| t) + 7 *  ~~~(z |||  ~~~t) + 12 * (z &&&  ~~~t) + 8 * (z &&& t) =  - 1 *  ~~~(z ^^^ t)

theorem or_sext_sext_thm (e : IntW 4) (e_1 : IntW 8) :
  LLVM.or (sext 16 e_1) (sext 16 e) ⊑ sext 16 (LLVM.or e_1 (sext 8 e))

theorem negate_select_of_op_vs_negated_op_nsw_thm (e : IntW 8) (e_1 : IntW 1) (e_2 : IntW 8) :
  sub e_2 (select e_1 (sub (const? 8 0) e { «nsw» := true, «nuw» := false }) e) ⊑
    add (select e_1 e (sub (const? 8 0) e)) e_2

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 ne_umax4_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 + 3#32 <ᵤ x) = 1#1 → ofBool (x_1 + 3#32 != x_1 + 3#32) = ofBool (x_1 + 3#32 <ᵤ x)

theorem logical_or_not_proof : logical_or_not_before ⊑ logical_or_not_after

theorem udiv_i8_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬zeroExtend 32 x = 0 → x = 0 → False

theorem PR56294_proof : PR56294_before ⊑ PR56294_after

theorem lowmask_xor_zext_commute_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  (x_1 * x_1 ^^^ zeroExtend 32 x) &&& 255#32 = zeroExtend 32 (x ^^^ truncate 8 (x_1 * x_1))

theorem shl_nsw_add_nsw_nuw_proof : shl_nsw_add_nsw_nuw_before ⊑ shl_nsw_add_nsw_nuw_after

theorem negate_add_with_single_negatible_operand_depth2_proof : negate_add_with_single_negatible_operand_depth2_before ⊑ negate_add_with_single_negatible_operand_depth2_after

theorem e_826 :
    7 * t + 2 *  ~~~(z &&& t) - 3 *  ~~~(z ||| t) - 10 *  ~~~(z |||  ~~~t) - 8 * (z &&& t) =  - 1 *  ~~~(z &&&  ~~~t) + 2 * (z &&&  ~~~t)

theorem ule_swap_or_not_min_logical_proof : ule_swap_or_not_min_logical_before ⊑ ule_swap_or_not_min_logical_after

theorem test_sub_127_Y_eq_127_proof : test_sub_127_Y_eq_127_before ⊑ test_sub_127_Y_eq_127_after

theorem t7_ashr_proof : t7_ashr_before ⊑ t7_ashr_after

theorem logical_and_logical_and_icmps_comm1_thm.extracted_1._7 : ∀ (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 ult_2_thm (e : IntW 32) :
  icmp IntPred.ult (trunc 8 e) (const? 8 2) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 254)) (const? 32 0)

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

theorem zext_sext_add_icmp_sgt_minus1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (-1#8 <ₛ zeroExtend 8 x_1 + signExtend 8 x) = x_1 ||

theorem sle_or_not_min_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 (-128))) (icmp IntPred.sle e_1 e) ⊑ const? 1 1

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

theorem select_replace_nested_no_simplify_proof : select_replace_nested_no_simplify_before ⊑ select_replace_nested_no_simplify_after

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

theorem test_or_eq_different_operands_thm (e e_1 e_2 : IntW 8) :
  select (LLVM.or (icmp IntPred.eq e_2 e_1) (icmp IntPred.eq e e_2)) e_2 e ⊑
    select (icmp IntPred.eq e_2 e_1) e_2 e

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

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

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

theorem test_with_3_proof : test_with_3_before ⊑ test_with_3_after

@[simp] theorem map_poison : f <$> poison = poison

theorem substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

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

@[simp]
theorem inter_accepts (M : NFA α σ) (N : NFA α ς) :
    (M.inter N).accepts = M.accepts ∩ N.accepts

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

theorem e_1082 :
     - 3 *  ~~~z - 3 *  ~~~(z &&&  ~~~t) + 11 * (z |||  ~~~t) + 7 *  ~~~(z &&&  ~~~z) + 2 * (z ||| t) - 15 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) - 23 * (z &&&  ~~~t) =  - 3 *  ~~~t + 17 * (z &&& t)

theorem test40_proof : test40_before ⊑ test40_after

omit [Fintype S] [LawfulBEq A] in
lemma processOneElem_preserves_map (st : worklist.St A S) (final : S → Bool) (a : A) (sa sa' : S) (s s' : State) :
    let st' := processOneElem _ _  final s st (a, sa')
    st.map[sa]? = some s' →
    st'.map[sa]? = some s'

theorem ule_swap_and_min_commute_proof : ule_swap_and_min_commute_before ⊑ ule_swap_and_min_commute_after

theorem e_373 :
     - 1 *  ~~~(x &&&  ~~~y) - 2 *  ~~~(x &&&  ~~~x) + 1 * (x |||  ~~~y) + 7 * y + 13 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y) + 1 * (x &&&  ~~~y) + 6 * (x &&& y) = 11 *  ~~~(x ^^^ y)

theorem test2_thm (e : IntW 15) : LLVM.xor e (const? 15 0) ⊑ e

theorem shift_xor_multiuse_cmp_xor_proof : shift_xor_multiuse_cmp_xor_before ⊑ shift_xor_multiuse_cmp_xor_after

theorem positive_biggershl_shlnuw_proof : positive_biggershl_shlnuw_before ⊑ positive_biggershl_shlnuw_after

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

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

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

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

theorem mul_constant_eq_nsw_proof : mul_constant_eq_nsw_before ⊑ mul_constant_eq_nsw_after

theorem max_sub_ugt_c32_thm (e : IntW 32) :
  select (icmp IntPred.ugt (const? 32 3) e) (add e (const? 32 (-2))) (const? 32 0) ⊑
    select (icmp IntPred.ult e (const? 32 3)) (add e (const? 32 (-2))) (const? 32 0)

theorem t3_no_extrause_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor e_1 (const? 8 (-1))) e ⊑
    icmp IntPred.ugt e (LLVM.xor e_1 (const? 8 (-1)))

theorem lshrult_03_02_exact_proof : lshrult_03_02_exact_before ⊑ lshrult_03_02_exact_after

theorem sdiv_ult_smin_proof : sdiv_ult_smin_before ⊑ sdiv_ult_smin_after

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

theorem ule_swap_or_min_commute_proof : ule_swap_or_min_commute_before ⊑ ule_swap_or_min_commute_after

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

theorem ashr_sub_nsw_proof : ashr_sub_nsw_before ⊑ ashr_sub_nsw_after

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

theorem test12_proof : test12_before ⊑ test12_after

theorem and_xor_not_common_op_proof : and_xor_not_common_op_before ⊑ and_xor_not_common_op_after

theorem t0_commutative_proof : t0_commutative_before ⊑ t0_commutative_after

theorem negative_trunc_not_arg_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt (trunc 8 e_1) (const? 8 (-1)))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) (const? 1 0) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 128)) (const? 32 0))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) (const? 1 0)

theorem src_srem_shl_demand_max_mask_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬((2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true ∨ 1#32 ≥ ↑32) →
    ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
      x.srem 2#32 <<< 1#32 &&& BitVec.ofInt 32 (-4) = x.srem 2#32 &&& BitVec.ofInt 32 (-4)

theorem orn_and_cmp_2_partial_logical_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 x_2 : BitVec 16),
  ofBool (x_1 ≤ₛ x_2) &&& x = 1#1 → 1#1 = x ||

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

theorem lshrult_03_07_exact_proof : lshrult_03_07_exact_before ⊑ lshrult_03_07_exact_after

theorem AvoidCollision_toNat_setWidth_of_le {w w' : Nat} {b : BitVec w} (h : w ≤ w') : (b.setWidth w').toNat = b.toNat

theorem no_shift_no_xor_multiuse_cmp_or_thm (e e_1 e_2 e_3 : IntW 32) :
  mul
      (mul
        (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_2 (LLVM.or e_2 (const? 32 4096)))
        (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_1 e))
      (LLVM.or e_2 (const? 32 4096)) ⊑
    mul
      (mul (LLVM.or e_2 (LLVM.and e_3 (const? 32 4096)))
        (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e_1 e))
      (LLVM.or e_2 (const? 32 4096))

lemma worklistRun'_go_wf :
    (st.m.WF ∧ (∀ (sa : S) s, st.map[sa]? = some s → s ∈ st.m.states)) →
    (worklistRun'.go A S final f st).WF

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

theorem ule_umax1_thm (e e_1 : IntW 32) :
  icmp IntPred.ule (select (icmp IntPred.ugt e_1 e) e_1 e) e_1 ⊑ icmp IntPred.ule e e_1

theorem sext_zext_ne_known_nonneg_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬6#8 = 0 → ofBool (signExtend 32 x_1 != zeroExtend 32 (x / 6#8)) = ofBool (x_1 != x / 6#8)

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

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

theorem positive_biggerlshr_shlnuwnsw_lshrexact_proof : positive_biggerlshr_shlnuwnsw_lshrexact_before ⊑ positive_biggerlshr_shlnuwnsw_lshrexact_after

theorem sext_sub_const_proof : sext_sub_const_before ⊑ sext_sub_const_after

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

theorem uge_sext_thm (e : IntW 8) (e_1 : IntW 1) :
  icmp IntPred.uge (sext 8 e_1) e ⊑ LLVM.or (icmp IntPred.eq e (const? 8 0)) e_1

theorem p15_commutativity2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 65536#32) = 1#1 → ¬ofBool (65535#32 <ᵤ x) = 1#1 → 65535#32 = 42#32

theorem ashrslt_01_15_exact_proof : ashrslt_01_15_exact_before ⊑ ashrslt_01_15_exact_after

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

theorem lshrugt_01_07_proof : lshrugt_01_07_before ⊑ lshrugt_01_07_after

theorem ne_umin4_proof : ne_umin4_before ⊑ ne_umin4_after

theorem test_imply_not2_proof : test_imply_not2_before ⊑ test_imply_not2_after

theorem test9_thm (e e_1 : IntW 32) : LLVM.xor (LLVM.and e_1 e) (LLVM.xor e_1 e) ⊑ LLVM.or e_1 e

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

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

theorem bitwise_or_bitwise_or_icmps_proof : bitwise_or_bitwise_or_icmps_before ⊑ bitwise_or_bitwise_or_icmps_after

theorem narrow_source_matching_signbits_proof : narrow_source_matching_signbits_before ⊑ narrow_source_matching_signbits_after

theorem and_zext_demanded_thm (e : IntW 16) (e_1 : IntW 32) :
  LLVM.and (LLVM.or e_1 (const? 32 255)) (zext 32 (lshr e (const? 16 8))) ⊑
    zext 32 (lshr e (const? 16 8)) { «nneg» := true }

theorem mul_add_to_mul_8_thm (e : IntW 16) :
  add (mul e (const? 16 16383) { «nsw» := true, «nuw» := false })
      (mul e (const? 16 16384) { «nsw» := true, «nuw» := false }) { «nsw» := true, «nuw» := false } ⊑
    mul e (const? 16 32767) { «nsw» := true, «nuw» := false }

theorem eq_smax2_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (select (icmp IntPred.sgt e_1 e) e_1 e) e ⊑ icmp IntPred.sge e e_1

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 exact_ashr_ne_proof : exact_ashr_ne_before ⊑ exact_ashr_ne_after

theorem select_zext_or_eq_ult_add_proof : select_zext_or_eq_ult_add_before ⊑ select_zext_or_eq_ult_add_after

theorem multiuse_shl_shl_thm.extracted_1._1 : ∀ (x : BitVec 42),
  ¬(8#42 ≥ ↑42 ∨ 8#42 ≥ ↑42 ∨ 9#42 ≥ ↑42) → 8#42 ≥ ↑42 ∨ 17#42 ≥ ↑42 → False

@[simp] theorem Expr.denote_changeVars {Γ Γ' : Ctxt d.Ty}
    (varsMap : Γ.Hom Γ')
    (e : Expr d Γ eff Δ)
    (V : Γ'.Valuation)
    (f : e.outContext.Valuation → eff.toMonad d.m α) :
    (Expr.changeVars varsMap e).denote V
      >>= (f <| Valuation.comap · varsMap.append)
    = e.denote (V.comap varsMap) >>= f

theorem not_mul_of_bool_proof : not_mul_of_bool_before ⊑ not_mul_of_bool_after

theorem pow2_or_zero_is_not_negative_commute_proof : pow2_or_zero_is_not_negative_commute_before ⊑ pow2_or_zero_is_not_negative_commute_after

theorem missed_const_prop_2002h12h05_thm (e : IntW 32) :
  add (sub (const? 32 0) e) (add e (add (sub (const? 32 0) (const? 32 1)) (const? 32 1))) ⊑ const? 32 0

theorem e_530 :
     - 6 *  ~~~(x &&&  ~~~x) - 6 *  ~~~(x ^^^ y) - 1 * (x ||| y) - 1 *  ~~~y - 1 *  ~~~(x &&&  ~~~y) + 12 *  ~~~(x ||| y) + 7 *  ~~~(x |||  ~~~y) + 5 * (x &&&  ~~~y) + 12 * (x &&& y) =  - 1 * (x ^^^ y) - 2 * (x |||  ~~~y)

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

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

theorem test13_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.ult e_1 e) (icmp IntPred.ugt e_1 e) ⊑ const? 1 0

theorem not_invert_signbit_splat_mask2_proof : not_invert_signbit_splat_mask2_before ⊑ not_invert_signbit_splat_mask2_after

theorem ashr_C1_add_A_C2_i32_proof : ashr_C1_add_A_C2_i32_before ⊑ ashr_C1_add_A_C2_i32_after

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

theorem e_874 :
    1 * (z ^^^ t) - 7 * (z |||  ~~~t) + 11 * z - 1 *  ~~~(z |||  ~~~t) - 12 * (z &&&  ~~~t) - 4 * (z &&& t) =  - 7 *  ~~~t

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

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

theorem icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_proof : icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_before ⊑ icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_after

theorem masked_bit_clear_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬((x_1 == 0 || 32 != 1 && 42#32 == intMin 32 && x_1 == -1) = true ∨ x ≥ ↑32) →
    zeroExtend 32 (ofBool ((42#32).srem x_1 &&& 1#32 <<< x == 0#32)) = ((42#32).srem x_1 ^^^ -1#32) >>> x &&& 1#32

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

theorem icmp_ne_and_pow2_minus1_shl1_proof : icmp_ne_and_pow2_minus1_shl1_before ⊑ icmp_ne_and_pow2_minus1_shl1_after

theorem lshrult_01_12_exact_proof : lshrult_01_12_exact_before ⊑ lshrult_01_12_exact_after

theorem and_and_proof : and_and_before ⊑ and_and_after

theorem or_and3_commuted_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1) (x_2 x_3 : BitVec 32),
  ofBool (x_3 == x_2) ||

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

theorem no_shift_xor_multiuse_and_proof : no_shift_xor_multiuse_and_before ⊑ no_shift_xor_multiuse_and_after

theorem test87_proof : test87_before ⊑ test87_after

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

theorem lshrugt_03_14_proof : lshrugt_03_14_before ⊑ lshrugt_03_14_after

@[simp]
theorem Term.toBV_band {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a b : Term bcard ncard icard pcard tctx (.bv w)) :
  Term.toBV benv nenv ienv penv tenv (.band a b) = a.toBV benv nenv ienv penv tenv &&& b.toBV benv nenv ienv penv tenv

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

theorem isMonotone_matchVar
    {lets : Lets d Γ_in eff Γ_out} {v : Var Γ_out t}
    {matchLets : Lets d Δ_in .pure Δ_out}
    {w : Var Δ_out t} :
    (matchVar lets v matchLets w).IsMonotone

theorem foo1_and_signbit_lshr_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 (lshr (const? 32 (-2147483648)) 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 })
          (lshr (const? 32 (-2147483648)) e { «exact» := true })))
      (LLVM.or (shl (const? 32 1) e_2 { «nsw» := false, «nuw» := true })
        (lshr (const? 32 (-2147483648)) e { «exact» := true }))

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

theorem test9a_proof : test9a_before ⊑ test9a_after

theorem xor_add_proof : xor_add_before ⊑ xor_add_after

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

theorem shl_bad_sub_i64_proof : shl_bad_sub_i64_before ⊑ shl_bad_sub_i64_after

theorem icmp_slt_0_or_icmp_sge_100_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → x >>> 31#32 ||

@[simp]
theorem ofBitVecSextMsb_eq_concat_ofBitVec (x : BitVec w) :
    ofBitVecSextMsb x = (ofBitVecSext x).concat false

theorem allOnes_sub_eq_xor (x :BitVec w) : (allOnes w) - x = x ^^^ (allOnes w)

theorem test69_and_proof : test69_and_before ⊑ test69_and_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 lt_signed_to_small_signed_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x <ₛ 17#32) = ofBool (x <ₛ 17#8)

theorem prove_exact_with_high_mask_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(BitVec.ofInt 8 (-4) == 0 || 8 != 1 && x &&& BitVec.ofInt 8 (-32) == intMin 8 && BitVec.ofInt 8 (-4) == -1) = true →
    ¬(2#8 ≥ ↑8 ∨ True ∧ (0#8).ssubOverflow (x.sshiftRight' 2#8 &&& BitVec.ofInt 8 (-8)) = true) →
      (x &&& BitVec.ofInt 8 (-32)).sdiv (BitVec.ofInt 8 (-4)) = 0#8 - (x.sshiftRight' 2#8 &&& BitVec.ofInt 8 (-8))

theorem sdiv_icmp4_proof : sdiv_icmp4_before ⊑ sdiv_icmp4_after

theorem n4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    32#32 - x ≥ ↑32 ∨
        True ∧ (x + BitVec.ofInt 32 (-16)).msb = true ∨
          zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64 ∨
            True ∧
                signExtend 64 (truncate 32 (262143#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16)))) ≠
                  262143#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ∨
              True ∧
                zeroExtend 64 (truncate 32 (262143#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16)))) ≠
                  262143#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16)) →
      False

theorem logical_or_implies_thm (e : IntW 32) :
  select (icmp IntPred.eq e (const? 32 0)) (const? 1 1) (icmp IntPred.eq e (const? 32 42)) ⊑
    LLVM.or (icmp IntPred.eq e (const? 32 0)) (icmp IntPred.eq e (const? 32 42))

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

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

theorem n3_constmask_samemask_thm (e e_1 : IntW 32) :
  LLVM.or (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) ⊑
    LLVM.and (LLVM.or e_1 e) (const? 32 65280)

theorem or_xor_tree_1110_proof : or_xor_tree_1110_before ⊑ or_xor_tree_1110_after

@[simp] theorem Com.denote_toFlatCom_lets [LawfulMonad d.m] (com : Com d Γ .pure t) :
    com.toFlatCom.lets.denote = com.denoteLets

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

theorem shl_add_log_may_cause_poison_pr62175_with_nsw_proof : shl_add_log_may_cause_poison_pr62175_with_nsw_before ⊑ shl_add_log_may_cause_poison_pr62175_with_nsw_after

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

theorem sext_sext_sge_op0_narrow_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 5),
  ofBool (signExtend 32 x ≤ₛ signExtend 32 x_1) = ofBool (x ≤ₛ signExtend 8 x_1)

theorem test23_proof : test23_before ⊑ test23_after

theorem src_is_notmask_lshr_shl_fail_mismatch_shifts_proof : src_is_notmask_lshr_shl_fail_mismatch_shifts_before ⊑ src_is_notmask_lshr_shl_fail_mismatch_shifts_after

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

theorem and_logic_and_logic_or_4_proof : and_logic_and_logic_or_4_before ⊑ and_logic_and_logic_or_4_after

theorem test3_proof : test3_before ⊑ test3_after

theorem eq_rem_zero_nonuw_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (x * 5#8 == 20#8) = ofBool (x == 4#8)

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

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

theorem or_logic_or_logic_and_2_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ||

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

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

theorem e_1836 :
    2 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 2 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 1 * (a &&&  ~~~b) + 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 5 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 11 * ((a |||  ~~~b) &&& (b ^^^ c)) - 6 * (c ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 4 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~a &&& (b ||| c)) - 5 *  ~~~(a ^^^ c) + 4 * ( ~~~(a ||| b) ||| (b ^^^ c)) - 1 * (a ||| (b &&& c)) + 3 *  ~~~(a &&& ( ~~~b &&& c)) + 7 * (b ^^^ (a ||| (b ||| c))) - 1 * (c ^^^  ~~~(a ||| b)) - 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 2 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 11 *  ~~~(a ||| (b &&& c)) + 1 * (c ^^^ (a &&& ( ~~~b ||| c))) + 4 * (c |||  ~~~(a ||| b)) - 6 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * (a &&& c) - 6 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) + 2 * (c ^^^ (a ||| ( ~~~b &&& c))) + 11 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 2 * ((a ^^^ b) &&& (a ^^^ c)) - 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 11 * ( ~~~b |||  ~~~(a ^^^ c)) + 11 * ( ~~~a ||| (b ^^^ c)) + 1 * (b ||| c) + 1 * (b &&& (a ^^^ c)) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 2 * (b ^^^ (a ||| (b ^^^ c))) + 3 * (a ^^^ (b ||| c)) - 2 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 37 *  ~~~(a ||| ( ~~~b ||| c)) - 29 *  ~~~( ~~~a ||| (b ||| c)) - 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 70 * ( ~~~a &&& ( ~~~b &&& c)) - 23 * ( ~~~a &&& (b &&& c)) - 36 * (a &&& ( ~~~b &&& c)) - 9 * (a &&& (b &&& c)) = 50 *  ~~~(a ||| (b ||| c)) - 4 * (b ^^^  ~~~(a &&& ( ~~~b &&& c)))

theorem sel_false_val_is_a_masked_lshr_of_true_val1_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 60#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 test87_thm (e : IntW 16) :
  trunc 16 (ashr (mul (sext 32 e) (const? 32 16) { «nsw» := true, «nuw» := false }) (const? 32 16)) ⊑
    ashr e (const? 16 12)

theorem test_sext2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), x_1 = 1#1 → -1#32 = signExtend 32 1#1

theorem test_shl_nuw_nsw__nuw_is_safe_proof : test_shl_nuw_nsw__nuw_is_safe_before ⊑ test_shl_nuw_nsw__nuw_is_safe_after

theorem test10_proof : test10_before ⊑ test10_after

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

theorem main4c_logical_thm.extracted_1._3 : ∀ (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 xor_or2_proof : xor_or2_before ⊑ xor_or2_after

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

theorem test5_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.udiv (const? 32 (-1)) e) (const? 32 0) ⊑ const? 1 1

theorem sle_smin3_proof : sle_smin3_before ⊑ sle_smin3_after

theorem or_test2_proof : or_test2_before ⊑ or_test2_after

theorem invert_signbit_splat_mask_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (sext 16 (LLVM.xor (ashr e_1 (const? 8 7)) (const? 8 (-1)))) e ⊑
    select (icmp IntPred.sgt e_1 (const? 8 (-1))) e (const? 16 0)

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

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

theorem fold_icmp_shl_nuw_c2_indivisible_proof : fold_icmp_shl_nuw_c2_indivisible_before ⊑ fold_icmp_shl_nuw_c2_indivisible_after

theorem xor_signbit_select_ashr_proof : xor_signbit_select_ashr_before ⊑ xor_signbit_select_ashr_after

theorem and_zext_demanded_thm.extracted_1._2 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬8#16 ≥ ↑16 →
    ¬(8#16 ≥ ↑16 ∨ True ∧ (x >>> 8#16).msb = true) →
      (x_1 ||| 255#32) &&& zeroExtend 32 (x >>> 8#16) = zeroExtend 32 (x >>> 8#16)

theorem fold_sext_to_and_wrong5_proof : fold_sext_to_and_wrong5_before ⊑ fold_sext_to_and_wrong5_after

theorem e_1911 :
     - 6 * (a &&& c) - 1 * (a ||| (b &&& c)) - 6 * (b ^^^ (a ||| c)) - 5 * ( ~~~a ||| ( ~~~b &&& c)) - 11 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) + 2 *  ~~~(a ||| b) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) - 6 * ((a &&& b) ^^^ (b ||| c)) + 1 * (b ^^^  ~~~(a &&& (b ||| c))) - 2 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) + 3 *  ~~~(a ^^^ b) - 2 * ( ~~~b &&& (a ^^^ c)) - 2 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 11 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 11 * (c ^^^ (a &&& b)) - 1 *  ~~~(a ||| ( ~~~b &&& c)) + 11 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 5 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 6 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) - 5 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 5 * (c ^^^ (a &&& ( ~~~b ||| c))) + 1 *  ~~~(a ^^^ (b ||| c)) - 3 * ((a &&& b) |||  ~~~(b ||| c)) - 7 * ( ~~~a ||| (b &&& c)) + 2 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * (b ^^^  ~~~(a |||  ~~~c)) + 2 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 5 * (b ^^^ c) - 2 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * (b ^^^ (a &&& c)) - 11 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 7 * (a ^^^ (b ||| c)) + 1 *  ~~~(a ||| (b ^^^ c)) + 3 *  ~~~(a |||  ~~~b) + 3 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 2 *  ~~~(b &&& c) + 5 *  ~~~(a ^^^ (b ^^^ c)) - 2 * (b ^^^  ~~~(a ||| (b &&& c))) + 2 * (c &&& (a ||| b)) + 9 *  ~~~(a ||| (b ||| c)) + 67 *  ~~~(a ||| ( ~~~b ||| c)) + 42 *  ~~~( ~~~a ||| (b ||| c)) + 24 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 70 * ( ~~~a &&& ( ~~~b &&& c)) + 71 * ( ~~~a &&& (b &&& c)) + 48 * (a &&& ( ~~~b &&& c)) =  - 40 * (a &&& (b &&& c))

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

theorem lor_band_right2_proof : lor_band_right2_before ⊑ lor_band_right2_after

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

theorem shl_bad_sub2_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬x - 31#32 ≥ ↑32 →
    ¬(True ∧ 1#32 <<< (x + BitVec.ofInt 32 (-31)) >>> (x + BitVec.ofInt 32 (-31)) ≠ 1#32 ∨
          x + BitVec.ofInt 32 (-31) ≥ ↑32) →
      1#32 <<< (x - 31#32) = 1#32 <<< (x + BitVec.ofInt 32 (-31))

theorem test_uge_xor_proof : test_uge_xor_before ⊑ test_uge_xor_after

theorem invert_both_cmp_operands_complex_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → ofBool (x_1 + (x ^^^ -1#32) ≤ₛ x_1 ^^^ -1#32) = ofBool (x_1 ≤ₛ x - x_1)

theorem icmp_eq_and_pow2_shl_pow2_negative2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 14#32 == 0#32)) = zeroExtend 32 (ofBool (2#32 <ᵤ x))

theorem lshr_mul_times_3_div_2_exact_2_proof : lshr_mul_times_3_div_2_exact_2_before ⊑ lshr_mul_times_3_div_2_exact_2_after

theorem reassoc_x2_mul_nuw_proof : reassoc_x2_mul_nuw_before ⊑ reassoc_x2_mul_nuw_after

theorem lshrult_03_06_exact_proof : lshrult_03_06_exact_before ⊑ lshrult_03_06_exact_after

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

theorem zext_sext_add_icmp_i128_proof : zext_sext_add_icmp_i128_before ⊑ zext_sext_add_icmp_i128_after

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

theorem icmp_eq_and_pow2_shl1_thm (e : IntW 32) :
  zext 32 (icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 16)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 4))

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

theorem test4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 9),
  True ∧ (zeroExtend 64 x_1).saddOverflow (zeroExtend 64 x) = true ∨
      True ∧ (zeroExtend 64 x_1).uaddOverflow (zeroExtend 64 x) = true →
    False

theorem mul_sel_op0_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬(True ∧ (42#32).umod x ≠ 0 ∨ x = 0) → 42#32 / x * x = 42#32

theorem ashrsgt_02_15_exact_proof : ashrsgt_02_15_exact_before ⊑ ashrsgt_02_15_exact_after

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

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

theorem R.trimTensor_toTensor'_eq_trimTensor_toTensor [Fact (q > 1)] (a : R q n) :
  trimTensor a.toTensor' = trimTensor a.toTensor

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

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

theorem e_931 :
     - 11 *  ~~~(z &&&  ~~~z) - 5 *  ~~~t + 7 *  ~~~z + 5 *  ~~~(z |||  ~~~t) + 16 * (z &&&  ~~~t) + 12 * (z &&& t) =  - 9 *  ~~~(z ||| t) + 1 * t

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

theorem AvoidCollision_setWidth_ushiftRight {x : BitVec w} {y : Nat} (hi : w ≤ i) :
    (x >>> y).setWidth i = x.setWidth i >>> y

theorem xor_or_xor_common_op_commute6_proof : xor_or_xor_common_op_commute6_before ⊑ xor_or_xor_common_op_commute6_after

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

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

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

theorem e_1009 :
     - 5 * (z ^^^ t) - 2 *  ~~~t - 1 * (z ||| t) - 1 * (z |||  ~~~t) + 13 *  ~~~(z |||  ~~~t) + 16 * (z &&&  ~~~t) + 9 * (z &&& t) =  - 10 *  ~~~(z ||| t) + 7 *  ~~~(z &&&  ~~~z)

theorem icmp_mul_nsw_slt_neg_proof : icmp_mul_nsw_slt_neg_before ⊑ icmp_mul_nsw_slt_neg_after

theorem sub_eq_and_not_sub_not_and :
    x - y = (x &&& ~~~ y) - (~~~ x &&& y)

theorem alive_275_2   : alive_275_2_src ⊑ alive_275_2_tgt

theorem eq_smax2_proof : eq_smax2_before ⊑ eq_smax2_after

theorem bv_AndOrXor_2486 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.xor (LLVM.add e e_1) (LLVM.const? w (-1)) ⊑ LLVM.sub (LLVM.sub (LLVM.const? w (-1)) e_1) e

theorem no_shift_xor_multiuse_or_proof : no_shift_xor_multiuse_or_before ⊑ no_shift_xor_multiuse_or_after

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

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

theorem or_not_xor_common_op_commute2_proof : or_not_xor_common_op_commute2_before ⊑ or_not_xor_common_op_commute2_after

theorem eq_commuted_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x == 0 || 8 != 1 && 43#8 == intMin 8 && x == -1) = true →
    ofBool (x_1 == 0#8) ||
</all_available_lemmas>

<local_ctx>
import LeanMLIR.Framework

import LeanMLIR.Transforms.Rewrite.Mapping

open Ctxt (Var VarSet Valuation Hom)

variable {d} [DialectSignature d] [DecidableEq d.Ty]

variable {Γ : Ctxt d.Ty} {ty : d.Ty}

abbrev MatchVarM (Δ Γ : Ctxt d.Ty) := (StateT (Mapping Δ Γ) Option)

abbrev MatchVar (Δ Γ : Ctxt d.Ty)  := MatchVarM Δ Γ Unit

def MatchVarM.unifyVars {Δ Γ : Ctxt d.Ty} (v : Δ.Var t) (w : Γ.Var t) : MatchVar Δ Γ :=
  fun ma =>
    match ma.lookup ⟨_, v⟩ with
    | some v =>
      if v = w then
        some ((), ma)
      else
        none
    | none =>
      some ((), AList.insert ⟨_, v⟩ w ma)

open MatchVarM

variable [DecidableEq d.Op]

def matchArg [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (matchLets : Lets d Δ_in .pure Δ_out) :
    {l : List d.Ty} → HVector (Var Γ_out) l → HVector (Var Δ_out) l →
    MatchVar Δ_in Γ_out
  | _, .nil, .nil => return
  | t::l, .cons vₗ vsₗ, .cons vᵣ vsᵣ => do
      matchVar (t := t) lets vₗ matchLets vᵣ
      matchArg lets matchLets vsₗ vsᵣ
  termination_by l => (sizeOf matchLets, l.length + 1)

def matchVar {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty} {t : d.Ty} [DecidableEq d.Op]
    (lets : Lets d Γ_in eff Γ_out) (v : Var Γ_out t) :
    (matchLets : Lets d Δ_in .pure Δ_out) →
    (w : Var Δ_out t) →
    MatchVar Δ_in Γ_out
   
  | @Lets.var _ _ _ _ Δ_out ts matchLets matchExpr, w => by admit /- proof elided -/
      | right w =>
        exact matchVar lets v matchLets w
      | left w => exact do
        let ⟨ts', w', ie⟩ ← lets.getPureExpr v
        if hs : ∃ h : ie.op = matchExpr.op, ie.regArgs = (h ▸ matchExpr.regArgs) then
          have hts : Ctxt.ofList ts' = ts := by admit /- proof elided -/

end

section MatchVar

variable [DecidableEq d.Op] {Γ_in Γ_out Δ_in Δ_out t te}
          {lets : Lets d Γ_in eff Γ_out} {v : Var Γ_out t}
          {matchLets : Lets d Δ_in .pure Δ_out}
          {matchExpr : Expr d Δ_out .pure te}

variable (lets v matchLets w) (mapIn : Mapping _ _) in

variable (lets matchLets) {tys} (vs ws : HVector _ tys) (mapIn : Mapping _ _) in

namespace MatchVarResult

variable [TyDenote d.Ty] [∀ (t : d.Ty), Inhabited ⟦t⟧] in

section Left

variable {w : Δ_out.Var t}

variable {mapIn} (mapOut : MatchVarResult lets v (.var matchLets matchExpr) w.appendInr mapIn)

end Left

variable {w : Var ⟨te⟩ _} {mapIn}

end MatchVarResult

end MatchVar

section SubsetEntries

def MatchVar.IsMonotone (f : MatchVar Δ Γ) : Prop :=
    ∀ mapIn, ∀ mapOut ∈ f mapIn,
      mapIn.entries ⊆ mapOut.2.entries

open MatchVar

section UnifyVars

variable {Δ Γ : Ctxt d.Ty} {t} (w : Δ.Var t) (v : Γ.Var t)

end UnifyVars

variable [DecidableEq d.Op]

end SubsetEntries

namespace MatchArgResult

variable [DecidableEq d.Op] {Γ_in Γ_out Δ_in Δ_out te}
          {lets : Lets d Γ_in eff Γ_out}
          {matchLets : Lets d Δ_in .pure Δ_out}
          {matchExpr : Expr d Δ_out .pure te}
          {u us}
          {v : Γ_out.Var u} {vs : HVector Γ_out.Var us}
          {w : Δ_out.Var u} {ws : HVector Δ_out.Var us}
          {mapIn : Mapping _ _}
          (mapOut : MatchArgResult lets matchLets (v ::ₕ vs) (w ::ₕ ws) mapIn)

end MatchArgResult

section DenoteLemmas

variable [TyDenote d.Ty] [DecidableEq d.Op]

variable [∀ (t : d.Ty), Inhabited ⟦t⟧]

variable [Monad d.m] [LawfulMonad d.m] [DialectDenote d]

section DenoteIntoSubtype

end DenoteIntoSubtype

variable {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty}
    {lets : Lets d Γ_in eff Γ_out}
    {matchLets : Lets d Δ_in .pure Δ_out}
</local_ctx>

<target_theorem>
theorem mem_matchVar {Δ_out}
    {varMap : Mapping Δ_in Γ_out} {ma : Mapping Δ_in Γ_out}
    {lets : Lets d Γ_in eff Γ_out} {v : Var Γ_out t} /- : -/
    {matchLets : Lets d Δ_in .pure Δ_out}  {w : Var Δ_out t}
    (hvarMap : ((), varMap) ∈ matchVar lets v matchLets w ma)
    {t': _ } {v' : _}
    (hMatchLets : ⟨t', v'⟩ ∈ matchLets.vars w) :
  ⟨t', v'⟩ ∈ varMap :=
</target_theorem>

