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
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
Id in Init.Control.Id
List.map in Init.Prelude
PUnit in Init.Prelude
Pure in Init.Prelude
And in Init.Prelude
Prod in Init.Prelude
Prod.mk in Init.Prelude

macro "simp_peephole" loc:(location)? : tactic =>
  `(tactic|(
      
      first
      | rw [funext_iff (α := Ctxt.Valuation _)] $[$loc]?
      | change ∀ (_ : Ctxt.Valuation _), _ $[$loc]?
      | skip

simp (config := {failIfUnchanged := false}) only
        [Expr.denote_castPureToEff, simp_denote] $[$loc]?
      
      
      
  ))

@[match_pattern]
def cons (hd : Ty) : Ctxt Ty → Ctxt Ty
| ⟨tl⟩ => ⟨hd :: tl⟩

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 }

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 }

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

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

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

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

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

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

def 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

def regSig       := Signature.regSig ∘ s.signature

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

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

def effectKind   := Signature.effectKind ∘ s.signature

def returnTypes  := Signature.returnTypes ∘ s.signature

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

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

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

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

inductive Ty
  | int
   
  | int2
  deriving DecidableEq, Lean.ToExpr

inductive Op
  | noop
  | mkPair
  | unPair
  deriving Lean.ToExpr

def Com.ret {Γ : Ctxt d.Ty} {ty : d.Ty} {eff : EffectKind} : Γ.Var ty → Com d Γ eff [ty] :=
  (Com.rets [·]ₕ)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

def test_negative_combined_sub_unsigned_overflow_before := [llvm|
{
^0(%arg51 : i64):
  %0 = llvm.mlir.constant(10) : i64
  %1 = llvm.mlir.constant(11) : i64
  %2 = llvm.sub %0, %arg51 overflow<nuw> : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def not_mul_of_pow2_before := [llvm|
{
^0(%arg77 : i32, %arg78 : i8):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(1530 : i32) : i32
  %2 = llvm.and %arg77, %0 : i32
  %3 = llvm.zext %arg78 : i8 to i32
  %4 = llvm.mul %2, %3 : i32
  %5 = llvm.icmp "ugt" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

@[simp_denote]
def add_positive_high_bound_reject_llvm := [LV| {
    ^entry (%a: i32):
    %0 = llvm.mlir.constant (4095) : i32
    %1 = llvm.add %0, %a : i32
    llvm.return %1 :i32
  }]

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

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

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

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

def MatchArgResult.toHom
    (map : MatchArgResult lets matchLets vs ws mapIn)
    (hvars : ∀ t (v : Var Δ_in t), ⟨t, v⟩ ∈ matchLets.varsOfVec ws) :
    Δ_in.Hom Γ_out :=
  map.val.toHom <| map.isTotal_of hvars

variable
  {Γ_in Γ_out Δ_in Δ_out : Ctxt d.Ty}
  {lets : Lets d Γ_in eff Γ_out}
  {matchTy}
  {v : Var Γ_out matchTy}
  {matchLets : Lets d Δ_in .pure Δ_out}
  {w : Var Δ_out matchTy}
in

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

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

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

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

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

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

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

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

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

def test6_before := [llvm|
{
^0(%arg3 : i65):
  %0 = llvm.mlir.constant(1 : i65) : i65
  %1 = llvm.mlir.constant(64 : i65) : i65
  %2 = llvm.shl %0, %1 : i65
  %3 = llvm.xor %arg3, %2 : i65
  %4 = llvm.add %3, %2 : i65
  "llvm.return"(%4) : (i65) -> ()
}
]

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

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

def product (final? : Bool → Bool → Bool) (m₁ m₂ : CNFA n) : CNFA n :=
  worklistRun (m₁.m.states × m₂.m.states) final (product.inits m₁ m₂)
    (by admit /- proof elided -/
    ) f
where final (ss : m₁.m.states × m₂.m.states) := final? (ss.1 ∈ m₁.m.finals) (ss.2 ∈ m₂.m.finals)
      f (ss : m₁.m.states × m₂.m.states) :=
        let (s1, s2) := ss
        (FinEnum.toList (α := BitVec n)).foldl (init := Array.empty) fun as a =>
          product.prodArray' (λ s₁ s₂ ↦ (a, (s₁, s₂)))
            (fun s' => m₁.wf.trans_tgt_lt (s := s1) (a := a)) (fun s' => m₂.wf.trans_tgt_lt (s := s2) (a := a)) as

def test_logical_or_eq_a_b_after := [llvm|
{
^0(%arg9 : i1, %arg10 : i8, %arg11 : i8):
  %0 = "llvm.select"(%arg9, %arg10, %arg11) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%0) : (i8) -> ()
}
]

local macro:50 x:term:50 " ={≤" w:term "} " y:term:51 : term =>
  `(EqualUpTo $w $x $y)

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

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

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

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

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

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

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

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

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

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

def stats {arity : Type _}
    [DecidableEq arity] [Fintype arity] [Hashable arity]
    {fsm : FSM arity} (circs : KInductionCircuits fsm n) : CircuitStats where
  iter := n
  size := circs.cSuccCarryAssignCirc.size +
    circs.cOutAssignCirc.size +
    circs.cInitCarryAssignCirc.size

def trunc_sandwich_before := [llvm|
{
^0(%arg70 : i32):
  %0 = llvm.mlir.constant(28 : i32) : i32
  %1 = llvm.mlir.constant(2 : i12) : i12
  %2 = llvm.lshr %arg70, %0 : i32
  %3 = llvm.trunc %2 : i32 to i12
  %4 = llvm.lshr %3, %1 : i12
  "llvm.return"(%4) : (i12) -> ()
}
]

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

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

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

def ule_or_min_after := [llvm|
{
^0(%arg142 : i8, %arg143 : i8):
  %0 = llvm.icmp "ule" %arg142, %arg143 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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 n1_after := [llvm|
{
^0(%arg2 : i8, %arg3 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg3 overflow<nuw> : i8
  %3 = llvm.and %arg2, %2 : i8
  %4 = llvm.icmp "ne" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def invert_both_cmp_operands_sub_before := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.xor %arg36, %0 : i32
  %3 = llvm.sub %2, %arg37 : i32
  %4 = llvm.icmp "ult" %3, %1 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def test13_after := [llvm|
{
^0(%arg10 : i79):
  %0 = llvm.mlir.constant(78 : i79) : i79
  %1 = llvm.ashr %arg10, %0 : i79
  "llvm.return"(%1) : (i79) -> ()
}
]

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

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

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

def and_slt_to_mask_before := [llvm|
{
^0(%arg5 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "slt" %arg5, %0 : i8
  %4 = llvm.and %arg5, %1 : i8
  %5 = llvm.icmp "eq" %4, %2 : i8
  %6 = llvm.and %3, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

def icmp_slt_0_or_icmp_sgt_0_i64_fail3_after := [llvm|
{
^0(%arg69 : i64):
  %0 = llvm.mlir.constant(62) : i64
  %1 = llvm.mlir.constant(63) : i64
  %2 = llvm.ashr %arg69, %0 : i64
  %3 = llvm.lshr %arg69, %1 : i64
  %4 = llvm.or %2, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

instance : MonadLiftT (eff.toMonad m) m                  := instMonadLiftOfLe (le_impure eff)

def shl_or_lshr_comm_before := [llvm|
{
^0(%arg106 : i32, %arg107 : i32, %arg108 : i32):
  %0 = llvm.shl %arg106, %arg107 overflow<nuw> : i32
  %1 = llvm.or %arg108, %0 : i32
  %2 = llvm.lshr %1, %arg107 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def llvm_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 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 negate_ashr_after := [llvm|
{
^0(%arg110 : i8, %arg111 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.lshr %arg111, %0 : i8
  %2 = llvm.add %1, %arg110 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

ReaderT.run in Init.Prelude

Fin.clamp in Batteries.Data.Fin.Basic

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

Lean.crossEmoji in Lean.Util.Trace

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

def three_inst_macro_proof (w : Nat) :
    three_inst_macro w ⊑ three_inst_macro w :=

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

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

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

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

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

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

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

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

@[simp_denote]
def sub_riscv_32 := [LV| {
  ^entry (%x: i32, %y: i32 ):
    %0 = "builtin.unrealized_conversion_cast"(%x) : (i32) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%y) : (i32) -> (!i64)
    %2 = sub %0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i32)
    llvm.return %3 : i32
  }]

instance (priority := low) : Monad (pure.toMonad m) :=

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

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 t6_shl_before := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-2 : i32) : i32
  %2 = llvm.sub %0, %arg32 : i32
  %3 = llvm.shl %arg31, %2 overflow<nuw> : i32
  %4 = llvm.add %arg32, %1 : i32
  %5 = llvm.shl %3, %4 overflow<nsw> : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

instance : AST.TransformExpr LLVM 0 := { mkExpr }

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

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

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

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

def nonexact_lshr_ne_noexactlog_before := [llvm|
{
^0(%arg135 : i8):
  %0 = llvm.mlir.constant(90 : i8) : i8
  %1 = llvm.mlir.constant(30 : i8) : i8
  %2 = llvm.lshr %0, %arg135 : i8
  %3 = llvm.icmp "ne" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def sext_non_bool_xor_sub_1_after := [llvm|
{
^0(%arg18 : i64, %arg19 : i8):
  %0 = llvm.sext %arg19 : i8 to i64
  %1 = llvm.xor %arg18, %0 : i64
  %2 = llvm.sub %1, %0 : i64
  "llvm.return"(%2) : (i64) -> ()
}
]

@[simp_denote]
def or_llvm_disjoint_64 := [LV| {
  ^entry (%x: i64, %y: i64 ):
    %1 = llvm.or disjoint %x, %y : i64
    llvm.return %1 : i64
  }]

def icmp? {w : Nat} (c : IntPred) (x y : BitVec w) : IntW 1 :=
  .value <| .ofBool (icmp' c x y) 

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

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

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

def logical_and_bitwise_and_icmps_before := [llvm|
{
^0(%arg220 : i8, %arg221 : i8, %arg222 : 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" %arg221, %0 : i8
  %5 = llvm.and %arg220, %1 : i8
  %6 = llvm.shl %1, %arg222 : i8
  %7 = llvm.and %arg220, %6 : i8
  %8 = llvm.icmp "ne" %5, %2 : i8
  %9 = llvm.icmp "ne" %7, %2 : i8
  %10 = llvm.and %4, %8 : i1
  %11 = "llvm.select"(%10, %9, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%11) : (i1) -> ()
}
]

instance : ToString LLVM.Op :=

def test5_commuted_x_y_before := [llvm|
{
^0(%arg220 : i64, %arg221 : i64):
  %0 = llvm.mlir.constant(-1) : i64
  %1 = llvm.xor %arg221, %arg220 : i64
  %2 = llvm.xor %arg220, %0 : i64
  %3 = llvm.or %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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 ashrslt_03_09_exact_before := [llvm|
{
^0(%arg12 : i4):
  %0 = llvm.mlir.constant(3 : i4) : i4
  %1 = llvm.mlir.constant(-7 : i4) : i4
  %2 = llvm.ashr exact %arg12, %0 : i4
  %3 = llvm.icmp "slt" %2, %1 : i4
  "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 testi16i8_com_after := [llvm|
{
^0(%arg11 : i16):
  %0 = llvm.mlir.constant(128 : i16) : i16
  %1 = llvm.mlir.constant(256 : i16) : i16
  %2 = llvm.add %arg11, %0 : i16
  %3 = llvm.icmp "ult" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

def ashr_sub_nsw_before := [llvm|
{
^0(%arg48 : i17, %arg49 : i17):
  %0 = llvm.mlir.constant(16 : i17) : i17
  %1 = llvm.sub %arg48, %arg49 overflow<nsw> : i17
  %2 = llvm.ashr %1, %0 : i17
  "llvm.return"(%2) : (i17) -> ()
}
]

def alive_AndOrXor_2263_src :=
[sllvm| {
^bb0(%B : i64, %op0 : i64):
  %v1 = llvm.xor %op0, %B : i64
  %v2 = llvm.or %op0, %v1 : i64
  llvm.return %v2 : i64
}]

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

@[simp_denote]
def trunc_llvm_32_to_16 := [LV| {
  ^entry (%lhs: i32):
    %0 = llvm.trunc %lhs : i32 to i16
    llvm.return %0 : i16
  }]

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

def positive_samevar_shlnuwnsw_ashrexact_after := [llvm|
{
^0(%arg27 : i8, %arg28 : i8):
  "llvm.return"(%arg27) : (i8) -> ()
}
]

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

Max in Init.Prelude

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 shl1_nsw_not_exact_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg11 overflow<nsw,nuw> : i8
  %2 = llvm.sdiv %arg10, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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 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 test5_after := [llvm|
{
^0(%arg192 : i1):
  %0 = llvm.zext %arg192 : i1 to i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def different_size_sext_sext_sle_after := [llvm|
{
^0(%arg12 : i7, %arg13 : i4):
  %0 = llvm.sext %arg13 : i4 to i7
  %1 = llvm.icmp "sle" %arg12, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def altMerge (x y : Stream α) : Stream α :=
  Stream.corec (β := Stream α × Stream α × ConsumeFrom) (x, y, .left) fun ⟨x, y, consume⟩ =>
    match consume with
      | .left  =>
        let x0 := x.head
        let x := x.tail
        let nextConsume := match x0 with
          | some _ => .right
          | none   => .left
        (x0, x, y, nextConsume)
      | .right =>
        let y0 := y.head
        let y := y.tail
        let nextConsume := match y0 with
          | some _ => .left
          | none   => .right
        (y0, x, y, nextConsume)

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

def shl_shl_before := [llvm|
{
^0(%arg50 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(28 : i32) : i32
  %2 = llvm.shl %arg50, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

instance [Monad m] : Monad (e.toMonad m) :=

def ne_commuted_equal_minus_1_before := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i8) : i8
  %3 = llvm.sdiv %0, %arg1 : i8
  %4 = llvm.add %arg0, %1 : i8
  %5 = llvm.icmp "ne" %arg0, %2 : i8
  %6 = llvm.icmp "uge" %3, %4 : i8
  %7 = llvm.and %5, %6 : i1
  "llvm.return"(%7) : (i1) -> ()
}
]

inductive TermKind (wcard : Nat) : Type
| bool
| bv (w : WidthExpr wcard)  : TermKind wcard
| prop
| nat
| int

def testi64i32_before := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.ashr %arg8, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.xor %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

instance : HydrablePackedBitvecToSubstitutionValue GenBVPred GenBVExpr where
  packedBitVecToSubstitutionValue := packedBitVecToSubstitutionValue

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

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

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

def main7a_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i32, %arg86 : i32):
  %0 = llvm.or %arg85, %arg86 : i32
  %1 = llvm.and %arg84, %0 : i32
  %2 = llvm.icmp "ne" %1, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def n0_after := [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 overflow<nuw> : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.icmp "ugt" %arg9, %3 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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 t1_before := [llvm|
{
^0(%arg12 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.sub %0, %arg12 overflow<nsw> : i8
  %2 = llvm.icmp "sge" %1, %arg12 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

def trunc_sandwich_min_shift1_after := [llvm|
{
^0(%arg68 : i32):
  %0 = llvm.mlir.constant(21 : i32) : i32
  %1 = llvm.lshr %arg68, %0 : i32
  %2 = llvm.trunc %1 overflow<nsw,nuw> : i32 to i12
  "llvm.return"(%2) : (i12) -> ()
}
]

instance : Lean.ToExpr RegIndex := inherit

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

def icmp_select_var_both_fold_after := [llvm|
{
^0(%arg80 : i8, %arg81 : i8, %arg82 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "eq" %arg80, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def xor_and_or_before := [llvm|
{
^0(%arg6 : i1, %arg7 : i1, %arg8 : i1):
  %0 = llvm.or %arg8, %arg6 : i1
  %1 = llvm.and %arg6, %arg7 : i1
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

    |

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

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

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

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

def or_ne_notY_eq_1s_fail_bad_not_before := [llvm|
{
^0(%arg39 : i8, %arg40 : i8):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.xor %arg40, %0 : i8
  %2 = llvm.or %arg39, %1 : i8
  %3 = llvm.icmp "ne" %2, %arg39 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

inductive Vars (σ : Type) (ι : Type) (n : Nat)
| state (s : Inputs σ (n + 1))
| inputs (is : Inputs ι n)
| outputs (os : Fin n) 
deriving DecidableEq, Hashable

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

def fold_nested_logic_zext_icmp_before := [llvm|
{
^0(%arg87 : i64, %arg88 : i64, %arg89 : i64, %arg90 : i64):
  %0 = llvm.icmp "sgt" %arg87, %arg88 : i64
  %1 = llvm.zext %0 : i1 to i8
  %2 = llvm.icmp "slt" %arg87, %arg89 : i64
  %3 = llvm.zext %2 : i1 to i8
  %4 = llvm.and %1, %3 : i8
  %5 = llvm.icmp "eq" %arg87, %arg90 : i64
  %6 = llvm.zext %5 : i1 to i8
  %7 = llvm.or %4, %6 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

def and_orn_cmp_3_logical_after := [llvm|
{
^0(%arg182 : i72, %arg183 : i72, %arg184 : i72):
  %0 = llvm.mlir.constant(42 : i72) : i72
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ugt" %arg182, %arg183 : i72
  %3 = llvm.icmp "ugt" %arg184, %0 : i72
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def worklistRun_init_post (inits : Array S) (final : S → Bool)
    (map : Std.HashMap S State) (m : RawCNFA A) :=
  (forall sa, sa ∈ map ↔ sa ∈ inits) ∧
  (∀ s a, m.tr s a = ∅) ∧
  ∀ sa s, map[sa]? = some s → (s ∈ m.initials) ∧ (s ∈ m.finals ↔ final sa)

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

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

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

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

def sext_sub_after := [llvm|
{
^0(%arg20 : i8, %arg21 : i1):
  %0 = llvm.zext %arg21 : i1 to i8
  %1 = llvm.add %arg20, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def test3_before := [llvm|
{
^0(%arg10 : i15):
  %0 = llvm.mlir.constant(-16384 : i15) : i15
  %1 = llvm.xor %arg10, %0 : i15
  %2 = llvm.add %1, %0 : i15
  "llvm.return"(%2) : (i15) -> ()
}
]

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

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

def atZero (f : LoopBody t) : t → t := fun v => f 0 v

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

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

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

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

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

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

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

def two_inst_macro_proof (w : Nat) :
    two_inst_macro w ⊑ two_inst_macro w :=

def xor_with_or_disjoint_ab_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.or disjoint %arg26, %arg27 : i32
  %1 = llvm.xor %arg26, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

def n2_before := [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 %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def sub_ashr_and_i32_nuw_nsw_before := [llvm|
{
^0(%arg23 : i32, %arg24 : i32):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.sub %arg24, %arg23 overflow<nsw,nuw> : i32
  %2 = llvm.ashr %1, %0 : i32
  %3 = llvm.and %2, %arg23 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

Ideal in Mathlib.RingTheory.Ideal.Defs

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

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

Lean.Meta.isDefEq in Lean.Meta.Basic

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

instance {cmp} : Fintype (NFA'.autSignedCmp cmp).σ :=

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

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

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

def t0_after := [llvm|
{
^0(%arg43 : i32, %arg44 : i32):
  %0 = llvm.mlir.constant(30 : i32) : i32
  %1 = llvm.lshr %arg43, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

private def mkHeader (kind : String) (id : Name) (levelParams : List Name) (type : Expr) (safety : DefinitionSafety) (sig : Bool := true) : MetaM MessageData := do
  let mut attrs := #[]
  match (← getReducibilityStatus id) with
  | ReducibilityStatus.irreducible =>   attrs := attrs.push m!"irreducible"
  | ReducibilityStatus.reducible =>     attrs := attrs.push m!"reducible"
  | ReducibilityStatus.semireducible => pure ()

  if defeqAttr.hasTag (← getEnv) id then
    attrs := attrs.push m!"defeq"

  let mut m : MessageData := m!""
  unless attrs.isEmpty do
    m := m ++ "@[" ++ MessageData.joinSep attrs.toList ", " ++ "] "

  match safety with
  | DefinitionSafety.unsafe  => m := m ++ "unsafe "
  | DefinitionSafety.partial => m := m ++ "partial "
  | DefinitionSafety.safe    => pure ()

  if isProtected (← getEnv) id then
    m := m ++ "protected "

  let id' ← match privateToUserName? id with
    | some id' =>
      m := m ++ "private "
      pure id'
    | none =>
      pure id

  if sig then
    return m!"{m}{kind} {id'}{levelParamsToMessageData levelParams} : {type}"
  else
    return m!"{m}{kind}"

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

def llvm_rem_lower_riscv_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)] where
  lhs := rem_llvm_32
  rhs := rem_riscv_32
  correct := by admit /- proof elided -/

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

def test4_after := [llvm|
{
^0(%arg22 : i108, %arg23 : i108):
  %0 = llvm.add %arg23, %arg22 : i108
  "llvm.return"(%0) : (i108) -> ()
}
]

def test6_before := [llvm|
{
^0(%arg17 : i57, %arg18 : i57):
  %0 = llvm.and %arg17, %arg18 : i57
  %1 = llvm.sub %arg17, %0 : i57
  "llvm.return"(%1) : (i57) -> ()
}
]

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 t4_ugt_slt_65536_before := [llvm|
{
^0(%arg54 : i32, %arg55 : i32, %arg56 : i32):
  %0 = llvm.mlir.constant(65536 : i32) : i32
  %1 = llvm.mlir.constant(65535 : i32) : i32
  %2 = llvm.icmp "slt" %arg54, %0 : i32
  %3 = "llvm.select"(%2, %arg55, %arg56) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ugt" %arg54, %1 : i32
  %5 = "llvm.select"(%4, %3, %arg54) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

instance instTransformTy : MLIR.AST.TransformTy DC 0 where
  mkTy := mkTy

structure Item where
 name : String
 tac : Syntax

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

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

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

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

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

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

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

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

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

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

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

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

def test_add_sub_const_lhs_RHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %res0 = mod_arith.constant 4 : !R
    %res1 = mod_arith.sub %res0, %x : !R
    return %res1 : !R
}]

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

def MetaLLVM.instantiate (vals : Vector Expr φ) : DialectMetaMorphism (MetaLLVM φ) q(LLVM) where
  mapTy := fun
  | .bitvec w =>
    mkApp (mkConst ``Ty.bitvec) <| w.metaInstantiate vals
  mapOp :=
    fun
    | .binary w binOp =>
      let w := w.metaInstantiate vals
      mkApp2 (mkConst ``Op.binary) w (toExpr binOp)
    | .unary w unOp =>
      let w := w.metaInstantiate vals

       
      let mapWidth (w : ConcreteOrMVar Nat φ) : Q(ConcreteOrMVar Nat 0) :=
        let w : Q(Nat) := w.metaInstantiate vals
        q(.concrete $w)

Function.LeftInverse in Init.Data.Function

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

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

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

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

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

abbrev NameExt := SimplePersistentEnvExtension (Name × Name) (NameMap Name)

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_0_logical_before := [llvm|
{
^0(%arg51 : 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(false) : i1
  %5 = llvm.and %arg51, %0 : i32
  %6 = llvm.icmp "ne" %5, %1 : i32
  %7 = llvm.and %arg51, %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 alive_AndOrXor_1683_1_src :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.icmp.ugt %a, %b : i64
  %v2 = llvm.icmp.eq %a, %b : i64
  %v3 = llvm.or %v1, %v2 : i1
  llvm.return %v3 : i1
}]

def zext_or_masked_bit_test_before := [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 : 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) -> ()
}
]

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

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

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

BitVec.signExtend in Init.Data.BitVec.Basic

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

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

def test59_after := [llvm|
{
^0(%arg122 : i8, %arg123 : i8):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(48 : i32) : i32
  %2 = llvm.mlir.constant(4 : i8) : i8
  %3 = llvm.zext %arg122 : i8 to i32
  %4 = llvm.shl %3, %0 overflow<nsw,nuw> : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.lshr %arg123, %2 : i8
  %7 = llvm.zext nneg %6 : i8 to i32
  %8 = llvm.or disjoint %5, %7 : i32
  %9 = llvm.zext nneg %8 : i32 to i64
  "llvm.return"(%9) : (i64) -> ()
}
]

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

def lowmask_add_zext_commute_before := [llvm|
{
^0(%arg233 : i16, %arg234 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mul %arg234, %arg234 : i32
  %2 = llvm.zext %arg233 : i16 to i32
  %3 = llvm.add %1, %2 : i32
  %4 = llvm.and %3, %0 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def hoist_logic_op_with_same_opcode_hands_32 : List (Σ Γ, LLVMPeepholeRewriteRefine 32 Γ) :=
  [⟨_, AndTruncTrunc⟩,
  ⟨_, OrTruncTrunc⟩,
  ⟨_, XorTruncTrunc⟩]

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

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

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

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

instance {cmp} : DecidableEq (NFA'.autSignedCmp cmp).σ :=

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

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

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

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

def different_size_zext_zext_slt_after := [llvm|
{
^0(%arg18 : i7, %arg19 : i4):
  %0 = llvm.zext %arg19 : i4 to i7
  %1 = llvm.icmp "ult" %arg18, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

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

def liftLast3 n : Fin 3 → Fin (n + 3)
| 0 => n
| 1 => n + 1
| 2 => Fin.last (n + 2)

def example01 := [RV64_com| {
^bb0(%0 : !i64, %1 : !i64):
  
  
 
    %5 = "add"(%0, %0) : (!i64, !i64) -> (!i64)
  
  "ret" (%0) : (!i64) -> ()
 }]

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

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

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

def or_and3_before := [llvm|
{
^0(%arg104 : i1, %arg105 : i1, %arg106 : i32, %arg107 : i32):
  %0 = llvm.icmp "eq" %arg106, %arg107 : i32
  %1 = llvm.or %arg104, %0 : i1
  %2 = "llvm.select"(%1, %arg104, %arg105) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

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

def ult_to_slt_after := [llvm|
{
^0(%arg32 : i8, %arg33 : i8):
  %0 = llvm.icmp "slt" %arg32, %arg33 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

def mul_add_to_mul_6_before := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mul %arg26, %arg27 overflow<nsw> : i32
  %2 = llvm.mul %1, %0 overflow<nsw> : i32
  %3 = llvm.add %1, %2 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def ZMod.toFin (x : ZMod q) : Fin q := (finEquiv q).invFun x

instance : Functor Signature where
  map := fun f ⟨sig, regSig, returnTypes, effKind⟩ =>
    ⟨f <$> sig, f <$> regSig, f <$> returnTypes, effKind⟩

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

def State.cseCom {α}
  {lets : Lets d Γstart .pure Γ}
  (s : State d lets)
  (com: Com d Γ .pure α) :
  { com' : Com d Γ .pure α
    // ∀ (V : Ctxt.Valuation Γstart), com.denote (lets.denote V) = com'.denote (lets.denote V) } :=
  match com with
  | .rets vs =>
      let ⟨vs', hvs'⟩ := s.vars2vars vs
      ⟨.rets vs', by admit /- proof elided -/
        ⟩
  | .var e body =>
      let ⟨⟨e', he'⟩, v'?⟩ := s.cseExpr e
      match v'? with
      | .none =>  
        let s' := s.consNewExpr2Cache (e := e')
         
        let ⟨body', hbody'⟩ := s'.cseCom body
        ⟨.var e' body',  by admit /- proof elided -/
            ⟩
      | .some ⟨v', hv'⟩ =>
        let s' := s.consOldExpr2Cache (enew := e') (eold := e) (henew := by admit /- proof elided -/
        )
          (vold := v') (hv := by admit /- proof elided -/
          )
          
        let ⟨body', hbody'⟩ := s'.cseCom body
        
        ⟨.var e body' 
        , by admit /- proof elided -/
        ⟩

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

@[simp_llvm_option]
def mul {w : Nat} (x y : IntW w) (flags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w := do
  let x' ← x
  let y' ← y

  if flags.nsw ∧ BitVec.smulOverflow x' y' then
    .poison
  else if flags.nuw ∧ BitVec.umulOverflow x' y' then
    .poison
  else
    mul? x' y'

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

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

def test14_commuted_after := [llvm|
{
^0(%arg174 : i32, %arg175 : i32):
  %0 = llvm.xor %arg174, %arg175 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def positive_and_odd_ne_before := [llvm|
{
^0(%arg42 : i32):
  %0 = llvm.mlir.constant(2 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.srem %arg42, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "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 ashrslt_02_06_exact_after := [llvm|
{
^0(%arg31 : i4):
  %0 = llvm.mlir.constant(true) : i1
  "llvm.return"(%0) : (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 op1 : Op 0 := [mlir_op| %1 = llvm.mlir.constant(31) : i32]

def t0_after := [llvm|
{
^0(%arg51 : i8, %arg52 : i8, %arg53 : i8):
  %0 = llvm.add %arg52, %arg53 : i8
  %1 = llvm.sub %arg51, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def ripple_nsw4_before := [llvm|
{
^0(%arg17 : i16, %arg18 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg18, %0 : i16
  %3 = llvm.and %arg17, %1 : i16
  %4 = llvm.add %3, %2 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

@[simp]
def evalBinop' (op : Binop) (b1 b2 : Prop) : Prop :=
  match op with
  | .and => b1 ∧ b2
  | .or => b1 ∨ b2
  | .impl => b1 → b2
  | .equiv => b1 ↔ b2

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

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

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

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

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

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

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

def PackedFloat.toBV (pf : PackedFloat e M) : BitVec (1 + e + M) :=
  let bvSign := BitVec.ofBool pf.sign
  bvSign ++ pf.ex ++ pf.sig

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

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

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

def mul16_low_before := [llvm|
{
^0(%arg24 : i16, %arg25 : i16):
  %0 = llvm.mlir.constant(255 : i16) : i16
  %1 = llvm.mlir.constant(8 : i16) : i16
  %2 = llvm.and %arg24, %0 : i16
  %3 = llvm.lshr %arg24, %1 : i16
  %4 = llvm.and %arg25, %0 : i16
  %5 = llvm.lshr %arg25, %1 : i16
  %6 = llvm.mul %5, %2 : i16
  %7 = llvm.mul %4, %3 : i16
  %8 = llvm.mul %4, %2 : i16
  %9 = llvm.add %6, %7 : i16
  %10 = llvm.shl %9, %1 : i16
  %11 = llvm.add %10, %8 : i16
  "llvm.return"(%11) : (i16) -> ()
}
]

instance [ToString w] : ToString (Option w) where
  toString
    | some x => s!"(some {toString x})"
    | none   => "(none)"

Int.negOfNat in Init.Data.Int.Basic

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

def trunc_lshr_big_mask_after := [llvm|
{
^0(%arg8 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(31 : i6) : i6
  %2 = llvm.lshr %arg8, %0 : i8
  %3 = llvm.trunc %2 overflow<nuw> : i8 to i6
  %4 = llvm.and %3, %1 : i6
  "llvm.return"(%4) : (i6) -> ()
}
]

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

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

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

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

Lean.initSearchPath in Lean.Util.Path

def or_lshr_before := [llvm|
{
^0(%arg628 : i8, %arg629 : i8, %arg630 : i8, %arg631 : i8):
  %0 = llvm.lshr %arg628, %arg631 : i8
  %1 = llvm.lshr %arg629, %arg631 : i8
  %2 = llvm.or %0, %arg630 : i8
  %3 = llvm.or %1, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def proj (f : Fin m → Fin n) (M : NFA' n) : NFA' m where
  σ := _
  M := M.M.proj f

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

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

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

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

def always_false [DecidableEq α] (c : Circuit α) : Bool :=
   nonempty c = false

def test_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.icmp "ugt" %arg1, %0 : i32
  %2 = llvm.icmp "sgt" %arg1, %0 : i32
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

RV64.ctz in RISCV.Instructions

def sdiv_mul_shl_nsw_before := [llvm|
{
^0(%arg193 : i5, %arg194 : i5, %arg195 : i5):
  %0 = llvm.mul %arg193, %arg194 overflow<nsw> : i5
  %1 = llvm.shl %arg193, %arg195 overflow<nsw> : i5
  %2 = llvm.sdiv %0, %1 : i5
  "llvm.return"(%2) : (i5) -> ()
}
]

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

def narrow_zext_ashr_keep_trunc_after := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.sext %arg8 : i8 to i16
  %2 = llvm.sext %arg9 : i8 to i16
  %3 = llvm.add %1, %2 overflow<nsw> : i16
  %4 = llvm.lshr %3, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def or_xor_tree_1011_after := [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.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

@[simp_denote]
def intro_example_correct_rhs := [LV| {
  ^entry (%arg0: i64):
    %r1 = "builtin.unrealized_conversion_cast" (%arg0) : (i64) -> (!riscv.reg)
    %c = slli %r1, 2 : !riscv.reg
    %rd = "builtin.unrealized_conversion_cast" (%c) : (!riscv.reg) -> (i64)
    llvm.return %rd : i64
  }]

instance {test : ConcreteCliTest} : ToString (toType test.ty) where
  toString :=
    match test.ty with
    | bitvec w => inferInstanceAs (ToString (PoisonOr <| BitVec w)) |>.toString

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

def test11_before := [llvm|
{
^0(%arg43 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.icmp "ule" %arg43, %0 : i1
  "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 t2_const_lshr_shl_eq_before := [llvm|
{
^0(%arg91 : i32, %arg92 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.lshr %arg91, %0 : i32
  %3 = llvm.shl %arg92, %0 : i32
  %4 = llvm.and %3, %2 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

@[simp]
def Env.getElem_ofEnvFin (envFin : EnvFin w n) (i : Nat) (h : i < n) :
    (Env.ofEnvFin envFin)[i]'(by simp [Env.length_ofEnvFin, h]) = envFin ⟨i, by omega⟩ :=

def or_or_xor_commute1_before := [llvm|
{
^0(%arg103 : i4, %arg104 : i4, %arg105 : i4):
  %0 = llvm.or %arg103, %arg105 : i4
  %1 = llvm.or %arg105, %arg104 : i4
  %2 = llvm.xor %0, %1 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

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 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 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 lshr_add_xor_fail_after := [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 overflow<nuw> : i8
  %5 = llvm.xor %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def test9_before := [llvm|
{
^0(%arg91 : i32):
  %0 = llvm.mlir.constant(64 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.mul %arg91, %0 : i32
  %3 = llvm.urem %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

def scalar_i32_lshr_and_negC_ne_after := [llvm|
{
^0(%arg31 : i32, %arg32 : i32):
  %0 = llvm.mlir.constant(262143 : i32) : i32
  %1 = llvm.lshr %arg31, %arg32 : i32
  %2 = llvm.icmp "ugt" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

def PR38021_before := [llvm|
{
^0(%arg0 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(-63 : i8) : i8
  %2 = llvm.lshr %arg0, %0 : i8
  %3 = llvm.add %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

def src_is_mask_zext_after := [llvm|
{
^0(%arg131 : i16, %arg132 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i16) : i16
  %2 = llvm.lshr %0, %arg132 : i8
  %3 = llvm.zext %2 : i8 to i16
  %4 = llvm.xor %arg131, %1 : i16
  %5 = llvm.icmp "ule" %4, %3 : i16
  "llvm.return"(%5) : (i1) -> ()
}
]

def addAux' (carryIn : Bool) (x y : BitStream) (i : Nat) :  Bool × Bool :=
  let carryIn : Bool := match i with
    | 0 => carryIn
    | i + 1 => (addAux' carryIn x y i).2
  Prod.swap (BitVec.adcb (x i) (y i) carryIn)

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

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 eqToZero (expr: GenBVExpr w) : BoolExpr GenBVPred :=
  .literal <| GenBVPred.bin expr BVBinPred.eq (zero w)

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

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

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

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

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

def scalar_i16_shl_and_signbit_eq_after := [llvm|
{
^0(%arg33 : i16, %arg34 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.shl %arg33, %arg34 : i16
  %2 = llvm.icmp "sgt" %1, %0 : i16
  "llvm.return"(%2) : (i1) -> ()
}
]

Std.Tactic.BVDecide.BoolExpr.literal in Std.Tactic.BVDecide.Bitblast.BoolExpr.Basic

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

Std.Format.align in Init.Data.Format.Basic

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

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

def lor_bor_left1_before := [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
  %2 = llvm.or %1, %arg66 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def icmp_ult_8_before := [llvm|
{
^0(%arg12 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.mlir.constant(4095) : i64
  %2 = llvm.shl %arg12, %0 overflow<nuw> : i64
  %3 = llvm.icmp "ult" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

@[simp_denote]
def shl_llvm_32 := [LV| {
  ^entry (%x: i32, %y: i32):
    %1 = llvm.shl %x, %y : i32
    llvm.return %1 : i32
  }]

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

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

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

def t3_no_extrause_before := [llvm|
{
^0(%arg18 : i8, %arg19 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg19, %0 : i8
  %2 = llvm.icmp "ult" %1, %arg18 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

instance : MLIR.AST.TransformReturn (Handshake) 0 where
  mkReturn := mkReturn

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

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

def test85_after := [llvm|
{
^0(%arg60 : i32):
  %0 = llvm.mlir.constant(2130706432 : i32) : i32
  %1 = llvm.mlir.constant(23 : i32) : i32
  %2 = llvm.add %arg60, %0 : i32
  %3 = llvm.lshr %2, %1 : i32
  %4 = llvm.trunc %3 : i32 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def add_negative_low_bound_reject_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_negative_low_bound_reject_llvm
  rhs := add_negative_low_bound_reject_riscv

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

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

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

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

def State.add? (e : Expr) : GenM Expr := do
  match ← get? e with
  | some x => pure x
  | none =>
    if e.isFVar || e.isBVar then pure e else
    let x ← mkFreshExprMVar (some (.const ``Nat [])) (userName := `w)
    setMapping e x
    modify fun s => { s with invMapping := s.invMapping.insert x e }
    pure x

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

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

def positive_biggerlshr_before := [llvm|
{
^0(%arg60 : i8):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.lshr %arg60, %0 : i8
  %3 = llvm.shl %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def icmp_slt_0_or_icmp_sgt_0_i64_fail0_before := [llvm|
{
^0(%arg72 : i64):
  %0 = llvm.mlir.constant(0) : i64
  %1 = llvm.mlir.constant(63) : i64
  %2 = llvm.icmp "slt" %arg72, %0 : i64
  %3 = llvm.lshr %arg72, %1 : i64
  %4 = llvm.zext %2 : i1 to i64
  %5 = llvm.or %3, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

def test_after := [llvm|
{
^0(%arg0 : i64):
  %0 = llvm.mlir.constant(4294967295) : i64
  %1 = llvm.and %arg0, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def sdiv_icmp5_before := [llvm|
{
^0(%arg10 : i64):
  %0 = llvm.mlir.constant(-5) : i64
  %1 = llvm.mlir.constant(1) : i64
  %2 = llvm.sdiv exact %arg10, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (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) -> ()
}
]

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

instance : LawfulMonad LLVM.m :=

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

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

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

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

def t0_exact_before := [llvm|
{
^0(%arg9 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.mlir.constant(0) : i64
  %2 = llvm.lshr exact %arg9, %0 : i64
  %3 = llvm.sub %1, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

def alive_Select_859'_tgt :=
[sllvm| {
^bb0(%a : i1, %b : i1):
  %v1 = llvm.mlir.constant -1 : i1
  %v2 = llvm.xor %a, %v1 : i1
  %v3 = llvm.or %v2, %b : i1
  llvm.return %v3 : i1
}]

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

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 test_before := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(13 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.icmp "ugt" %arg1, %0 : i32
  %3 = llvm.icmp "eq" %arg1, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def ashr_mul_before := [llvm|
{
^0(%arg99 : i8, %arg100 : i8):
  %0 = llvm.mlir.constant(8 : i20) : i20
  %1 = llvm.sext %arg99 : i8 to i20
  %2 = llvm.sext %arg100 : i8 to i20
  %3 = llvm.mul %1, %2 : i20
  %4 = llvm.ashr %3, %0 : i20
  %5 = llvm.trunc %4 : i20 to i16
  "llvm.return"(%5) : (i16) -> ()
}
]

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

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

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

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

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

def visitSRA : List (Σ Γ, LLVMPeepholeRewriteRefine 64 Γ) :=
  [⟨_, visitSRA_0⟩,
   ⟨_, visitSRA_Neg1⟩]

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

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

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

def 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 fold_icmp_shl_nuw_c2_indivisible_before := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(63 : i32) : i32
  %2 = llvm.shl %0, %arg4 overflow<nuw> : i32
  %3 = llvm.icmp "ult" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

structure NatFSM (wcard tcard bcard ncard icard pcard : Nat) (v : Nondep.WidthExpr) where
  toFsm : FSM (StateSpace wcard tcard bcard ncard icard pcard)

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

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

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

@[simp_denote]
def rem_llvm_8 := [LV| {
  ^entry (%x: i8, %y: i8):
    %1 = llvm.srem %x, %y : i8
    llvm.return %1 : i8
  }]

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

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

instance : Monad SLLVM.m :=

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

def trunc_sandwich_min_shift1_after := [llvm|
{
^0(%arg68 : i32):
  %0 = llvm.mlir.constant(21 : i32) : i32
  %1 = llvm.lshr %arg68, %0 : i32
  %2 = llvm.trunc %1 overflow<nsw,nuw> : i32 to i12
  "llvm.return"(%2) : (i12) -> ()
}
]

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

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

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

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

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

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

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

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

def vars [DecidableEq α] : Circuit α → List α
  | tru => []
  | fals => []
  | var _ x => [x]
  | and c₁ c₂ => (vars c₁ ++ vars c₂).dedup
  | or c₁ c₂ => (vars c₁ ++ vars c₂).dedup
  | xor c₁ c₂ => (vars c₁ ++ vars c₂).dedup

def icmp_select_implied_cond_swapped_select_after := [llvm|
{
^0(%arg56 : i8, %arg57 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "eq" %arg56, %0 : i8
  %3 = llvm.icmp "eq" %arg57, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (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 test5_after := [llvm|
{
^0(%arg2 : i7):
  %0 = llvm.mlir.constant(-24 : i7) : i7
  %1 = llvm.and %arg2, %0 : i7
  "llvm.return"(%1) : (i7) -> ()
}
]

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

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

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 select_replace_udiv_non_speculatable_after := [llvm|
{
^0(%arg1 : i32, %arg2 : i32):
  "llvm.return"(%arg2) : (i32) -> ()
}
]

def masked_or_A_slightly_optimized_after := [llvm|
{
^0(%arg119 : i32):
  %0 = llvm.mlir.constant(-40 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg119, %0 : i32
  %3 = llvm.icmp "eq" %2, %1 : i32
  "llvm.return"(%3) : (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 main3f_like_before := [llvm|
{
^0(%arg139 : i32, %arg140 : i32, %arg141 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.and %arg139, %arg140 : i32
  %3 = llvm.icmp "ne" %2, %0 : i32
  %4 = llvm.and %arg139, %arg141 : i32
  %5 = llvm.icmp "ne" %4, %0 : i32
  %6 = llvm.or %3, %5 : i1
  %7 = "llvm.select"(%6, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

IO.FS.Stream.ofHandle in Init.System.IO

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

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

def llvm_srl_lower_riscv_exact_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := lshr_llvm_exact_64
  rhs := srl_riscv_64

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

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

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

def 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 q : Nat := 42

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 or_and_not_constant_commute1_after := [llvm|
{
^0(%arg110 : i32, %arg111 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.and %arg110, %0 : i32
  %2 = llvm.or %1, %arg111 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

def getOutputWidth (opStx : MLIR.AST.Op 0) :
    Except TransformError Nat := do
  match opStx.res with
  | res::[] =>
    match res.2 with
    | .int _ (.concrete w) => pure w
    | _ => throw <| .generic s!"The operation {opStx.name} must output an integer type"
  | _ => throw <| .generic s!"The operation {opStx.name} must have a single output"

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

def not_or_or_and_not_and_and_commute3_after := [llvm|
{
^0(%arg187 : i32, %arg188 : i32, %arg189 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg188 : i32
  %3 = llvm.xor %arg187, %1 : i32
  %4 = llvm.xor %arg189, %2 : i32
  %5 = llvm.or %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def bigAnd (constraints : List (BoolExpr α)) : BoolExpr α :=
  foldConstraints (BoolExpr.const true) constraints Gate.and

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

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

def and_zext_eq_zero_before := [llvm|
{
^0(%arg28 : i32, %arg29 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.icmp "eq" %arg28, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.lshr %arg28, %arg29 : i32
  %5 = llvm.xor %4, %1 : i32
  %6 = llvm.and %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

def is_rem4_neg_i16_after := [llvm|
{
^0(%arg54 : i16):
  %0 = llvm.mlir.constant(-32765 : i16) : i16
  %1 = llvm.mlir.constant(-32768 : i16) : i16
  %2 = llvm.and %arg54, %0 : i16
  %3 = llvm.icmp "ugt" %2, %1 : i16
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def test5_after := [llvm|
{
^0(%arg95 : i32, %arg96 : i8):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.zext nneg %arg96 : i8 to i32
  %3 = llvm.shl %0, %2 overflow<nuw> : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.and %arg95, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

def test2_before := [llvm|
{
^0(%arg30 : i1, %arg31 : i1):
  %0 = llvm.and %arg30, %arg31 : i1
  %1 = llvm.and %0, %arg30 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def exampleSink := [DCxComb_com| {
  ^entry(%0: !TokenStream):
    %src = "DCxComb.sink" (%0) : (!TokenStream) -> (!TokenStream)
    "return" (%src) : (!TokenStream) -> ()
  }]

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

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

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

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

def test42_after := [llvm|
{
^0(%arg208 : i32, %arg209 : i32, %arg210 : i32):
  %0 = llvm.mul %arg209, %arg210 : i32
  %1 = llvm.and %0, %arg208 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def andn_or_cmp_4_logical_after := [llvm|
{
^0(%arg158 : i32, %arg159 : i32, %arg160 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "ne" %arg158, %arg159 : i32
  %3 = llvm.icmp "ugt" %arg160, %0 : i32
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def test68_xor_after := [llvm|
{
^0(%arg162 : i32, %arg163 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.lshr %arg162, %0 : i32
  %3 = llvm.and %2, %1 : i32
  %4 = llvm.xor %arg163, %3 : i32
  "llvm.return"(%4) : (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 or_xor_tree_0110_before := [llvm|
{
^0(%arg27 : i32, %arg28 : i32, %arg29 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mul %arg27, %0 : i32
  %2 = llvm.mul %arg28, %0 : i32
  %3 = llvm.mul %arg29, %0 : i32
  %4 = llvm.xor %1, %2 : i32
  %5 = llvm.xor %3, %2 : i32
  %6 = llvm.xor %1, %5 : i32
  %7 = llvm.or %4, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def t0_ult_slt_128_after := [llvm|
{
^0(%arg78 : i32, %arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(-16 : i32) : i32
  %1 = llvm.mlir.constant(127 : i32) : i32
  %2 = llvm.icmp "slt" %arg78, %0 : i32
  %3 = llvm.icmp "sgt" %arg78, %1 : i32
  %4 = "llvm.select"(%2, %arg79, %arg78) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %5 = "llvm.select"(%3, %arg80, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

instance : DialectDenote LLVM := ⟨
  fun o args _ => [Op.denote o args]ₕ
⟩

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

def two_inst_concrete_macro :=
  [llvm()|{
  ^bb0(%arg0: i1):
    %0 = llvm.not %arg0 : i1
    %1 = llvm.not %arg0 : i1
    llvm.return %0 : i1
  }]

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

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

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

Lean.Meta.mkLambdaFVars in Lean.Meta.Basic

def or_not_and_and_not_and_xor_commute5_before := [llvm|
{
^0(%arg274 : i32, %arg275 : i32, %arg276 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg275, %arg276 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %2, %arg274 : i32
  %4 = llvm.xor %arg275, %arg276 : i32
  %5 = llvm.and %4, %arg274 : i32
  %6 = llvm.xor %5, %0 : i32
  %7 = llvm.and %6, %3 : i32
  "llvm.return"(%7) : (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 trunc_ashr_after := [llvm|
{
^0(%arg98 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(-8388608 : i32) : i32
  %2 = llvm.lshr %arg98, %0 : i32
  %3 = llvm.or %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def AttrDict.getAttr {φ} : AttrDict φ → String →  Option (AttrValue φ)
  | .mk attrs, name => attrs.map AttrEntry.destructure |>.lookup name

def Lets.repr (prec : Nat) : Lets d eff Γ t → Format
    | .nil => .align false ++ f!";"
    | .var body e => body.repr prec ++ (.align false ++ f!"{e.print}")

@[match_pattern] abbrev ExpTy.regIndex := isl .regIndex

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

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

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

def abs_diff_signed_slt_swap_wrong_pred1_after := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.sub %arg15, %arg16 overflow<nsw> : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def or_and_or_pat1_before := [llvm|
{
^0(%arg38 : i8, %arg39 : i8, %arg40 : i8, %arg41 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg40 : i8
  %2 = llvm.and %arg38, %arg39 : i8
  %3 = llvm.and %arg38, %arg41 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

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

def buggy_ISEL_pattern : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs:= original_sdiv_srem
  rhs:= combined_sdiv_srem
  correct := by admit /- proof elided -/

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

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

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

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

instance : MLIR.AST.TransformTy LLVMPlusRiscV 0 where
  mkTy tStx := do
  try
    let llvmParse ← InstcombineTransformDialect.mkTy tStx
    return .llvm llvmParse
  catch llvmErr =>
    try
      let riscvParse ← RiscvMkExpr.mkTy tStx
      return .riscv riscvParse
    catch riscvErr =>
        throw <|.generic s!" INTERNAL ERROR : While trying to transform from MLIR AST to dialect specific AST
         the transformation failed. The errors thrown are:
          s!{(toString (repr riscvErr))} and s!{(toString (repr llvmErr ))}"

RV64.sh1add in RISCV.Instructions

def mkCarryAssignCircuitN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
  let carrys := FinEnum.toList p.α |>.map fun s =>
    
    Circuit.xor
      (mkCarryAssignCircuitNAux p s n)
      (Circuit.var true <| Vars.stateN s (n + 1))
  Circuit.bigOr carrys

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

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

def test5_before := [llvm|
{
^0(%arg303 : i32):
  %0 = llvm.and %arg303, %arg303 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def VarName : Type := String

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

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

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

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

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

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

def select_2_before := [llvm|
{
^0(%arg82 : i1, %arg83 : i8, %arg84 : i1, %arg85 : i8, %arg86 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.mlir.constant(45 : i8) : i8
  %3 = llvm.xor %arg85, %0 : i8
  %4 = llvm.xor %arg86, %1 : i8
  %5 = "llvm.select"(%arg84, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %6 = llvm.xor %arg83, %2 : i8
  %7 = "llvm.select"(%arg82, %5, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %8 = llvm.xor %7, %0 : i8
  "llvm.return"(%8) : (i8) -> ()
}
]

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

IO.userError in Init.System.IOError

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

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

def bools_logical_commute0_and2_after := [llvm|
{
^0(%arg102 : i1, %arg103 : i1, %arg104 : i1):
  %0 = "llvm.select"(%arg104, %arg103, %arg102) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

def test47_after := [llvm|
{
^0(%arg197 : i32, %arg198 : i32):
  %0 = llvm.and %arg198, %arg197 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

Lean.Parser.Term.matchAltExpr in Lean.Parser.Term
</all_available_defs>

<all_available_lemmas>
Function.comp_apply in Init.Core
Function.iterate_succ in Mathlib.Logic.Function.Iterate
Nat.cast_add in Mathlib.Data.Nat.Cast.Defs
Nat.cast_one in Mathlib.Data.Nat.Cast.Defs
and_true in Init.SimpLemmas
Int.mul_comm in Init.Data.Int.Lemmas
add_left_iterate in Mathlib.Algebra.Group.Basic
nsmul_eq_mul in Mathlib.Algebra.Ring.Defs

theorem List.getElem_append_left{α : Type u_1} {l₁ l₂ : List α} {i : Nat} (hn : i < l₁.length) :\n(l₁ ++ l₂)[i] = l₁[i]

theorem positive_samevar_shlnuwnsw_proof : positive_samevar_shlnuwnsw_before ⊑ positive_samevar_shlnuwnsw_after

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

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

theorem test19_thm (e e_1 : IntW 1) :
  icmp IntPred.eq (zext 32 e_1) (zext 32 e) ⊑ LLVM.xor (LLVM.xor e_1 e) (const? 1 1)

theorem ashr_mul_sign_bits_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬3#32 ≥ ↑32 →
    ¬(True ∧ (signExtend 16 x_1).smulOverflow (signExtend 16 x) = true ∨ 3#16 ≥ ↑16) →
      truncate 16 ((signExtend 32 x_1 * signExtend 32 x).sshiftRight' 3#32) =
        (signExtend 16 x_1 * signExtend 16 x).sshiftRight' 3#16

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

theorem test_nuw_nsw_and_signed_pred_proof : test_nuw_nsw_and_signed_pred_before ⊑ test_nuw_nsw_and_signed_pred_after

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

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

theorem e_1656 :
     - 3 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) + 1 * (c &&& (a ^^^ b)) - 7 * (b &&&  ~~~(a &&& c)) - 2 * ((a &&& b) ^^^ (b |||  ~~~c)) + 4 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 2 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 2 * ( ~~~c ||| (a ^^^ b)) + 1 *  ~~~(a &&& b) - 1 * (c ||| (a &&& b)) - 7 * (b ^^^  ~~~(a &&& (b &&& c))) + 1 *  ~~~(a &&& (b ^^^ c)) + 4 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 6 *  ~~~(a ||| c) - 7 * ( ~~~c &&&  ~~~(a ^^^ b)) + 10 *  ~~~(a ||| (b ||| c)) + 20 *  ~~~(a ||| ( ~~~b ||| c)) + 13 *  ~~~( ~~~a ||| (b ||| c)) + 22 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 22 * ( ~~~a &&& (b &&& c)) - 3 * (a &&& ( ~~~b &&& c)) + 12 * (a &&& (b &&& c)) = 1 * (b ||| c) + 7 * (b &&& c)

@[simp]
theorem width_eq (ty : LLVM.Ty) : .bitvec (width ty) = ty

theorem test_shl__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 foo_proof : foo_before ⊑ foo_after

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

theorem lshr_32_add_zext_trunc_proof : lshr_32_add_zext_trunc_before ⊑ lshr_32_add_zext_trunc_after

theorem fold_icmp_shl_nuw_c2_non_pow2_thm (e : IntW 32) :
  icmp IntPred.ult (shl (const? 32 48) e { «nsw» := false, «nuw» := true }) (const? 32 192) ⊑
    icmp IntPred.ult e (const? 32 2)

theorem test4c_thm (e : IntW 64) :
  icmp IntPred.slt (trunc 32 (LLVM.or (ashr e (const? 64 63)) (lshr (sub (const? 64 0) e) (const? 64 63))))
      (const? 32 1) ⊑
    icmp IntPred.slt e (const? 64 1)

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

theorem scalar_i32_lshr_and_negC_eq_X_is_constant2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → ofBool (268435456#32 >>> x &&& BitVec.ofInt 32 (-8) == 0#32) = ofBool (25#32 <ᵤ x)

theorem e_2065 :
    2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 7 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 5 * (d ||| (e &&& f)) - 1 * (e ^^^ (d ||| (e &&& f))) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 7 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 1 * (e &&&  ~~~(d &&&  ~~~f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) - 1 * (f ^^^ (d &&& (e ||| f))) + 1 *  ~~~( ~~~d &&& (e ||| f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ||| (d ^^^ e)) + 7 * ((d &&& e) ^^^ (e |||  ~~~f)) - 3 * (e |||  ~~~f) - 1 * ((d |||  ~~~e) &&& (e ^^^ f)) + 5 * ( ~~~e |||  ~~~(d ^^^ f)) + 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 5 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 2 *  ~~~(d ||| f) + 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * (d ^^^ (e ||| f)) - 7 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 11 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 3 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 *  ~~~(d ||| (e ||| f)) + 11 *  ~~~(d ||| ( ~~~e ||| f)) + 12 *  ~~~( ~~~d ||| (e ||| f)) + 41 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 18 * ( ~~~d &&& ( ~~~e &&& f)) + 6 * ( ~~~d &&& (e &&& f)) + 7 * (d &&& ( ~~~e &&& f)) + 21 * (d &&& (e &&& f)) =  - 4 *  ~~~( ~~~d &&& ( ~~~e &&& f))

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

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

theorem sub_select_not_zext_proof : sub_select_not_zext_before ⊑ sub_select_not_zext_after

theorem xor_lshr_proof : xor_lshr_before ⊑ xor_lshr_after

theorem scalar_i32_lshr_and_negC_eq_nonzero_proof : scalar_i32_lshr_and_negC_eq_nonzero_before ⊑ scalar_i32_lshr_and_negC_eq_nonzero_after

theorem udiv_shl_pair_const_proof : udiv_shl_pair_const_before ⊑ udiv_shl_pair_const_after

theorem bv_Select_1105 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.select (LLVM.const? 1 0) e_1 e ⊑ e

theorem icmp_slt_0_xor_icmp_sge_neg2_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 ^^^ zeroExtend 32 (ofBool (BitVec.ofInt 32 (-2) ≤ₛ x)) =
      zeroExtend 32 (ofBool (x <ᵤ BitVec.ofInt 32 (-2)))

@[simp] lemma eval_var' (i : arity) (x : arity → BitStream) : (var' i).eval x = x i

theorem slt_0_proof : slt_0_before ⊑ slt_0_after

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

theorem e_54 :
    11 *  ~~~(x &&&  ~~~x) + 2 *  ~~~y - 16 *  ~~~(x ||| y) - 13 * (x &&&  ~~~y) - 14 * (x &&& y) =  - 3 *  ~~~(x ^^^ y) + 11 *  ~~~(x |||  ~~~y)

theorem lshr_lshr_proof : lshr_lshr_before ⊑ lshr_lshr_after

theorem sub_from_constant_of_sub_from_constant_proof : sub_from_constant_of_sub_from_constant_before ⊑ sub_from_constant_of_sub_from_constant_after

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

theorem and_add_bool_to_select_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → -1#32 + zeroExtend 32 x_1 &&& x = x

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

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

theorem test13_logical_proof : test13_logical_before ⊑ test13_logical_after

theorem lshrugt_03_01_proof : lshrugt_03_01_before ⊑ lshrugt_03_01_after

theorem src_x_and_nmask_ne_thm.extracted_1._2 : ∀ (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 → False

theorem sge_to_ugt_proof : sge_to_ugt_before ⊑ sge_to_ugt_after

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

theorem icmp_slt_0_and_icmp_sgt_neg1_i64_proof : icmp_slt_0_and_icmp_sgt_neg1_i64_before ⊑ icmp_slt_0_and_icmp_sgt_neg1_i64_after

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

theorem p0_proof : p0_before ⊑ p0_after

theorem no_shift_xor_multiuse_cmp_with_xor_thm (e e_1 e_2 e_3 : IntW 32) :
  mul (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2 (LLVM.xor e_2 (const? 32 4096)))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul (LLVM.xor (LLVM.xor (LLVM.and e_3 (const? 32 4096)) e_2) (const? 32 4096))
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

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

theorem mul_add_to_mul_2_thm (e : IntW 16) :
  add (mul e (const? 16 8) { «nsw» := true, «nuw» := false }) e { «nsw» := true, «nuw» := false } ⊑
    mul e (const? 16 9) { «nsw» := true, «nuw» := false }

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

theorem test51_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  x_1 = 1#1 → True ∧ (truncate 32 x &&& BitVec.ofInt 32 (-2) &&& zeroExtend 32 (x_1 ^^^ 1#1) != 0) = true → False

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 substitute_constant_and_eq_eq_logical_proof : substitute_constant_and_eq_eq_logical_before ⊑ substitute_constant_and_eq_eq_logical_after

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

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

theorem not_or_neg_proof : not_or_neg_before ⊑ not_or_neg_after

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

theorem e_1571 :
    11 *  ~~~(b |||  ~~~c) - 6 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 5 * ( ~~~b &&& (a ^^^ c)) + 2 *  ~~~(a ||| ( ~~~b &&& c)) - 2 * (c ^^^ (a ||| (b ||| c))) + 1 * (a ||| (b ^^^ c)) + 1 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) + 7 *  ~~~( ~~~a ||| (b &&& c)) - 6 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) + 9 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) - 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) + 9 * ( ~~~a &&& (b &&& c)) - 14 * (a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) =  - 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 *  ~~~( ~~~a ||| (b ||| c))

theorem test_add_nuw_nsw__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 2147483647#32 == 2147483647#32) = 1#1 →
    ¬(True ∧ (x &&& 2147483647#32).uaddOverflow 1#32 = true) →
      BitVec.ofInt 32 (-2147483648) = (x &&& 2147483647#32) + 1#32

theorem e_1624 :
    2 * (b &&& c) - 1 * (b ^^^  ~~~(a &&& c)) - 6 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 3 *  ~~~(b &&& c) + 1 * (c ^^^ ( ~~~a ||| (b &&& c))) + 1 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 11 * (b &&&  ~~~c) - 7 * (c ^^^  ~~~(a &&& (b ||| c))) - 5 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 5 * ( ~~~a &&& (b ^^^ c)) + 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 2 * (b ^^^ c) - 1 * (a ||| (b &&& c)) + 11 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) + 11 *  ~~~( ~~~a ||| (b ||| c)) - 8 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 7 * ( ~~~a &&& ( ~~~b &&& c)) - 3 * ( ~~~a &&& (b &&& c)) - 3 * (a &&& ( ~~~b &&& c)) + 11 * (a &&& (b &&& c)) =  - 3 * ( ~~~(a ||| b) ||| (b ^^^ c))

lemma NFA'.autUnsignedCmp_correct cmp : autUnsignedCmp cmp |>.correct2 autUnsignedCmpSA cmp.urel

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

theorem e_1821 :
     - 7 * (a ^^^ ( ~~~b ||| c)) + 4 * (c ||| (a &&&  ~~~b)) - 7 * (b &&& (a |||  ~~~c)) + 5 *  ~~~(a &&&  ~~~a) + 11 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 6 * (b ||| (a &&&  ~~~c)) - 5 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 5 *  ~~~(a ||| b) + 11 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) - 6 * (c ^^^  ~~~(a &&& (b &&& c))) - 7 *  ~~~a - 1 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 5 * (c ^^^ (a ||| (b ||| c))) - 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 3 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 3 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 1 * ( ~~~b &&& (a ^^^ c)) - 11 * ( ~~~a ||| (b ^^^ c)) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 *  ~~~(a &&& ( ~~~b &&& c)) + 2 * (b ^^^ (a &&& (b ^^^ c))) - 3 * (c ^^^ (a |||  ~~~b)) + 2 *  ~~~(b &&& c) + 5 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 3 *  ~~~( ~~~a &&& (b &&& c)) - 1 * (b |||  ~~~(a ||| c)) - 6 * (b ||| (a &&& c)) - 2 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) - 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 7 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (b ^^^ ( ~~~a ||| (b ||| c))) - 11 * (a ||| (b ||| c)) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 19 *  ~~~(a ||| (b ||| c)) + 32 *  ~~~(a ||| ( ~~~b ||| c)) + 5 *  ~~~( ~~~a ||| (b ||| c)) + 37 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 20 * ( ~~~a &&& ( ~~~b &&& c)) + 44 * ( ~~~a &&& (b &&& c)) - 22 * (a &&& ( ~~~b &&& c)) + 23 * (a &&& (b &&& c)) =  - 2 * (a ^^^ (b ||| c)) - 1 * (b ^^^  ~~~(a &&&  ~~~c))

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

theorem ne_umin3_proof : ne_umin3_before ⊑ ne_umin3_after

theorem a_false_implies_b_false2_proof : a_false_implies_b_false2_before ⊑ a_false_implies_b_false2_after

theorem e_199 :
    3 * (x ||| y) - 11 *  ~~~(x &&&  ~~~y) + 4 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&&  ~~~x) + 3 * y - 4 * (x &&&  ~~~y) =  - 6 *  ~~~(x ||| y) - 4 *  ~~~(x |||  ~~~y)

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

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

theorem l_proof : l_before ⊑ l_after

theorem e_232 :
    5 *  ~~~(x ^^^ y) + 2 *  ~~~(x &&&  ~~~y) + 5 * (x |||  ~~~y) - 2 *  ~~~(x &&&  ~~~x) - 10 *  ~~~(x ||| y) - 14 * (x &&&  ~~~y) - 10 * (x &&& y) =  - 11 * (x ^^^ y) + 11 *  ~~~(x |||  ~~~y)

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

theorem negtest_near_pow2_cmpval_ashr_slt_noexact_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 1)) (const? 8 5) ⊑ icmp IntPred.slt e (const? 8 10)

theorem positive_trunc_signbit_proof : positive_trunc_signbit_before ⊑ positive_trunc_signbit_after

theorem ashr_C1_add_A_C2_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(x &&& 65535#32) + 5#32 ≥ ↑32 → (6#32).sshiftRight' ((x &&& 65535#32) + 5#32) = 0#32

theorem substitute_constant_or_ne_swap_sle_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 42)) (icmp IntPred.sle e e_1) ⊑
    LLVM.or (icmp IntPred.ne e_1 (const? 8 42)) (icmp IntPred.slt e (const? 8 43))

theorem select_xor_icmp2_thm.extracted_1._6 : ∀ (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_1

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

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

theorem zext_sext_add_icmp_sgt_minus1_thm (e e_1 : IntW 1) :
  icmp IntPred.sgt (add (zext 8 e_1) (sext 8 e)) (const? 8 (-1)) ⊑ LLVM.or e_1 (LLVM.xor e (const? 1 1))

theorem nonexact_ashr_ne_noexactdiv_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-80)).sshiftRight' x != BitVec.ofInt 8 (-31)) = 1#1

theorem t_0_10_proof : t_0_10_before ⊑ t_0_10_after

theorem ashr_lshr_exact_lshr_only_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1) = 1#1 → ¬(True ∧ x_1 >>> x <<< x ≠ x_1 ∨ x ≥ ↑32) → ¬x ≥ ↑32 → x_1 >>> x = x_1.sshiftRight' x

theorem slt_and_not_max_commute_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ne e_1 (const? 8 127)) (icmp IntPred.slt e_1 e) ⊑
    icmp IntPred.slt e_1 e

theorem different_size_sext_sext_sgt_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (signExtend 25 x <ₛ signExtend 25 x_1) = ofBool (signExtend 7 x <ₛ x_1)

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

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

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

theorem AvoidCollision_setWidth_zero (m n : Nat) : setWidth m 0#n = 0#m

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

theorem select_icmp_x_and_8_eq_0_y_xor_8_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 8#32 == 0#32) = 1#1 → True ∧ (x_1 &&& 8#32).msb = true → False

theorem icmp_ne_zext_eq_non_boolean_proof : icmp_ne_zext_eq_non_boolean_before ⊑ icmp_ne_zext_eq_non_boolean_after

theorem PR60818_sgt_proof : PR60818_sgt_before ⊑ PR60818_sgt_after

theorem xor_or_xor_common_op_commute4_proof : xor_or_xor_common_op_commute4_before ⊑ xor_or_xor_common_op_commute4_after

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

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

theorem lshr_xor_thm (e e_1 : IntW 8) :
  shl (LLVM.xor (lshr e_1 (const? 8 3)) (LLVM.srem e (const? 8 42))) (const? 8 3) ⊑
    LLVM.xor (LLVM.and e_1 (const? 8 (-8))) (shl (LLVM.srem e (const? 8 42)) (const? 8 3))

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

theorem e_1459 :
    2 * (z ^^^ t) + 1 * (z |||  ~~~t) + 7 *  ~~~(z &&& t) - 1 *  ~~~(z ^^^ t) + 7 * t + 1 * (z ||| t) - 5 *  ~~~t - 17 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) - 8 * (z &&& t) = 2 *  ~~~(z ||| t)

theorem a_proof : a_before ⊑ a_after

theorem p1_ugt_proof : p1_ugt_before ⊑ p1_ugt_after

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

theorem hoist_ashr_ahead_of_sext_1_thm (e : IntW 8) : ashr (sext 32 e) (const? 32 3) ⊑ sext 32 (ashr e (const? 8 3))

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

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

theorem add_mask_ashr28_i32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(28#32 ≥ ↑32 ∨ 28#32 ≥ ↑32) →
    ¬28#32 ≥ ↑32 → (x.sshiftRight' 28#32 &&& 8#32) + x.sshiftRight' 28#32 = x >>> 28#32 &&& 7#32

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 main7g_thm.extracted_1._2 : ∀ (x x_1 x_2 x_3 x_4 : BitVec 32),
  ¬ofBool (x_4 &&& x_3 == x_4 &&& x_3 &&& x_2) &&& ofBool (x_1 &&& x == x_1 &&& x &&& x_2) = 1#1 →
    1#32 = zeroExtend 32 (ofBool (x_2 &&& (x_4 &&& x_3 ||| x_1 &&& x) != x_4 &&& x_3 ||| x_1 &&& x))

theorem test_logical_and_ne_a_b_proof : test_logical_and_ne_a_b_before ⊑ test_logical_and_ne_a_b_after

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

lemma nonempty_iff [DecidableEq α] (c : Circuit α) :
    nonempty c ↔ ∃ x, eval c x

theorem test13_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ¬8#32 ≥ ↑32 → (x_1 - x <<< 8#32 &&& 128#32) * x <<< 8#32 = (x_1 &&& 128#32) * x <<< 8#32

theorem BitVec.ofFn_getElem_fin {w : Nat} (f : Fin w → Bool) (i : Fin w) :
    (BitVec.ofFn f)[i.val] = f i

theorem or_nontrivial_mask1_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ofBool (truncate 8 x != 127#8) ||

theorem negative_and_odd_proof : negative_and_odd_before ⊑ negative_and_odd_after

theorem ashrslt_01_00_proof : ashrslt_01_00_before ⊑ ashrslt_01_00_after

theorem test10_thm.extracted_1._1 : ∀ (x : BitVec 1), ofBool (1#1 <ᵤ x) = 0#1

theorem no_shift_xor_multiuse_cmp_with_xor_proof : no_shift_xor_multiuse_cmp_with_xor_before ⊑ no_shift_xor_multiuse_cmp_with_xor_after

theorem test9_proof : test9_before ⊑ test9_after

theorem lshrult_03_13_proof : lshrult_03_13_before ⊑ lshrult_03_13_after

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

theorem icmp_ne_sext_slt_allones_nofold_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.slt e (const? 32 (-1)))) e ⊑
    icmp IntPred.ne e (sext 32 (icmp IntPred.slt e (const? 32 (-1))))

theorem test_ashr__exact_is_unsafe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 (-2147483585))) (const? 32 0)) e
      (ashr e (zext 64 (ashr (LLVM.and e_1 (const? 32 (-2147483585))) (const? 32 2)))) ⊑
    ashr e (zext 64 (LLVM.and (ashr e_1 (const? 32 2)) (const? 32 (-536870897))) { «nneg» := true })

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

theorem negative_trunc_not_arg_thm (e e_1 : IntW 32) :
  LLVM.and (icmp IntPred.sgt (trunc 8 e_1) (const? 8 (-1)))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256)) ⊑
    LLVM.and (icmp IntPred.eq (LLVM.and e_1 (const? 32 128)) (const? 32 0))
      (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256))

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 masked_icmps_mask_notallzeros_bmask_mixed_negated_6_logical_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 12)) (const? 32 0)) (const? 1 1)
      (icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 8)

theorem or_or_and_pat2_proof : or_or_and_pat2_before ⊑ or_or_and_pat2_after

theorem exact_lshr_ne_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ 126#8 >>> x <<< x ≠ 126#8 ∨ x ≥ ↑8) → ofBool (126#8 >>> x != 126#8) = ofBool (x != 0#8)

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

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

theorem not_xor_to_or_not1_proof : not_xor_to_or_not1_before ⊑ not_xor_to_or_not1_after

theorem test_ashr__exact_is_unsafe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& BitVec.ofInt 32 (-2147483585) == 0#32) = 1#1 →
    ¬(2#32 ≥ ↑32 ∨ zeroExtend 64 ((x_1 &&& BitVec.ofInt 32 (-2147483585)).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 scf.for.peel_end (n : Nat) (f : Nat → β → β) (seed : β) :
  scf.for.loop f (n + 1) 0 (f n seed) = f n (scf.for.loop f n 0 seed)

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

theorem or_eq_notY_eq_0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ||| x ^^^ -1#8 == x ^^^ -1#8) = ofBool (x_1 &&& x == 0#8)

theorem src_is_mask_sext_thm (e : IntW 16) (e_1 : IntW 8) :
  icmp IntPred.eq
      (LLVM.and (LLVM.xor (sext 16 (lshr (const? 8 31) e_1)) (const? 16 (-1))) (LLVM.xor e (const? 16 123)))
      (const? 16 0) ⊑
    icmp IntPred.ule (LLVM.xor e (const? 16 123)) (zext 16 (lshr (const? 8 31) e_1) { «nneg» := true })

theorem negate_select_of_op_vs_negated_op_nsw_commuted_thm (e : IntW 8) (e_1 : IntW 1) (e_2 : IntW 8) :
  sub e_2 (select e_1 e (sub (const? 8 0) e { «nsw» := true, «nuw» := false })) ⊑
    add (select e_1 (sub (const? 8 0) e) e) e_2

theorem BitVec.add_getElem_succ (x y : BitVec w) (hw : i + 1 < w) : (x + y)[i + 1] =
    (x[i + 1] ^^ (y[i + 1]) ^^ BitVec.carry (i + 1) x y false)

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

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

theorem bmod_ofNat_eq_of_lt (n m : Nat) (h : n < (m + 1) / 2) :
    (↑n : Int).bmod m = ↑(n % m)

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

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

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

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

theorem sub_eq_xor_sub_mul_not_and :
    x - y = (x ^^^ y) - 2 * (~~~ x &&& y)

@[simp_denote]
private theorem valuation_var_last_eq.lemma {Ty : Type} [TyDenote Ty] {Γ : Ctxt Ty} {t : Ty}
  {s : Γ.Valuation} {x : TyDenote.toType t} : (s.cons x) (Ctxt.Var.last Γ t) = x

theorem narrow_zext_xor_proof : narrow_zext_xor_before ⊑ narrow_zext_xor_after

theorem eq_commuted_proof : eq_commuted_before ⊑ eq_commuted_after

theorem test1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), truncate 8 (zeroExtend 64 x_1 + zeroExtend 64 x) = x_1 + x

theorem demorganize_constant2_proof : demorganize_constant2_before ⊑ demorganize_constant2_after

theorem test12_proof : test12_before ⊑ test12_after

theorem AvoidCollision_setWidth_setWidth_succ_eq_setWidth_setWidth_or_twoPow_of_getLsbD_true {x : BitVec w} {i : Nat} (hx : x.getLsbD i = true) :
    setWidth w (x.setWidth (i + 1)) =
      setWidth w (x.setWidth i) ||

theorem main11_thm (e : IntW 32) :
  select
      (LLVM.or (icmp IntPred.eq (LLVM.and e (const? 32 64)) (const? 32 0))
        (icmp IntPred.sge (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 192)) (const? 32 192)) (const? 32 1) (const? 32 2)

theorem t3_exact_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) → 0#64 - x.sshiftRight' 63#64 = x >>> 63#64

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

theorem or_signbit_select_lshr_proof : or_signbit_select_lshr_before ⊑ or_signbit_select_lshr_after

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

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

@[simp, simp_llvm]
theorem isRefinedBy_iff_of_width_neq {x : LLVM.IntW w} {y : LLVM.IntW v} (h : w ≠ v) :
    x ⊑ y ↔ False

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

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

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

theorem neg_not_signbit1_thm (e : IntW 8) :
  sub (const? 32 1) (zext 32 (lshr e (const? 8 7))) ⊑ zext 32 (icmp IntPred.sgt e (const? 8 (-1)))

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

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

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

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 e_811 :
    1 * t + 11 *  ~~~t - 11 *  ~~~(z ||| t) - 12 * (z &&&  ~~~t) - 2 * (z &&& t) =  - 1 * z + 1 *  ~~~(z |||  ~~~t)

theorem test44_proof : test44_before ⊑ test44_after

theorem lshr_16_to_64_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬16#64 ≥ ↑64 → (zeroExtend 64 x_1 + zeroExtend 64 x) >>> 16#64 = zeroExtend 64 (ofBool (x_1 ^^^ -1#16 <ᵤ x))

theorem addhshlhsdivhnegative2_thm (e : IntW 32) :
  add (shl (LLVM.sdiv e (const? 32 (-2147483648))) (const? 32 31)) e ⊑
    add (select (icmp IntPred.eq e (const? 32 (-2147483648))) (const? 32 (-2147483648)) (const? 32 0)) e

theorem eq_21_comm_eq_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(16#32 ≥ ↑32 ∨ 16#32 ≥ ↑32 ∨ 8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
    ¬(8#32 ≥ ↑32 ∨ 8#32 ≥ ↑32) →
      ofBool (truncate 8 (x_1 >>> 16#32) == truncate 8 (x >>> 16#32)) &&&
          ofBool (truncate 8 (x >>> 8#32) == truncate 8 (x_1 >>> 8#32)) =
        ofBool (truncate 16 (x_1 >>> 8#32) == truncate 16 (x >>> 8#32))

theorem liftEffect_eq_pure_cast_of [Pure m] {e₁ e₂} (heq : e₁ = .pure) (hle : e₁ ≤ e₂) :
    liftEffect hle (α := α) (m := m) = fun x => Pure.pure (cast (by subst heq; rfl) x)

theorem t2_symmetry_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 ≤ᵤ x_1 + x) = ofBool (x ≤ᵤ x_1 ^^^ -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)

theorem lshrugt_01_06_exact_proof : lshrugt_01_06_exact_before ⊑ lshrugt_01_06_exact_after

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

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

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

theorem e_1330 :
     - 2 *  ~~~(z ^^^ t) - 11 * (z |||  ~~~t) - 2 *  ~~~t - 11 * (z ||| t) - 11 *  ~~~(z &&& t) - 11 *  ~~~(z &&&  ~~~z) + 37 *  ~~~(z ||| t) + 36 *  ~~~(z |||  ~~~t) + 38 * (z &&& t) =  - 46 * (z &&&  ~~~t) + 3 * t

theorem add3 (x y z : BitVec w) : (x + y + z) = (z + y + x)

theorem icmp_ne_and_z_and_onefail_proof : icmp_ne_and_z_and_onefail_before ⊑ icmp_ne_and_z_and_onefail_after

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

theorem test19_thm (e : IntW 10) :
  sext 10 (ashr (shl (trunc 3 e) (const? 3 2)) (const? 3 2)) ⊑
    sext 10 (sub (const? 3 0) (LLVM.and (trunc 3 e) (const? 3 1)) { «nsw» := true, «nuw» := false })

theorem t9_lshr_proof : t9_lshr_before ⊑ t9_lshr_after

theorem PR1817_1_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (x <ₛ 10#32) = 1#1 → 0#1 = ofBool (x <ᵤ 10#32)

theorem and_signbit_shl_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬8#32 ≥ ↑32 → (x &&& BitVec.ofInt 32 (-65536)) <<< 8#32 = x <<< 8#32 &&& BitVec.ofInt 32 (-16777216)

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

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

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

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

theorem t2_ult_sgt_65536_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult e_2 (const? 32 65536)) e_2
      (select (icmp IntPred.sgt e_2 (const? 32 65535)) e_1 e) ⊑
    select (icmp IntPred.sgt e_2 (const? 32 65535)) e_1
      (select (icmp IntPred.slt e_2 (const? 32 0)) e e_2)

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

theorem test66_proof : test66_before ⊑ test66_after

theorem trunc_sel_equal_sext_proof : trunc_sel_equal_sext_before ⊑ trunc_sel_equal_sext_after

theorem or_sext_sext_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 8),
  signExtend 16 x_1 ||

theorem test_nuw_nsw_and_signed_pred_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬(True ∧ (10#64).ssubOverflow x = true ∨ True ∧ (10#64).usubOverflow x = true) →
    ofBool (10#64 - x <ₛ 3#64) = ofBool (7#64 <ᵤ x)

theorem icmp_sle_x_negy_proof : icmp_sle_x_negy_before ⊑ icmp_sle_x_negy_after

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

theorem t6_no_extrause_proof : t6_no_extrause_before ⊑ t6_no_extrause_after

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

theorem main12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) ||

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

theorem test2_proof : test2_before ⊑ test2_after

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

theorem e_2472 :
     - 2 *  ~~~(d ^^^ ( ~~~e &&& f)) + 5 * (f |||  ~~~(d ^^^ e)) + 1 *  ~~~(d ^^^ (e ^^^ f)) + 2 * (f ^^^ (d |||  ~~~e)) - 1 * (e &&&  ~~~(d &&& f)) - 5 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * ( ~~~d ||| (e ^^^ f)) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * (f &&&  ~~~(d ^^^ e)) - 3 * (d ^^^ e) + 2 *  ~~~d - 2 *  ~~~(d ^^^ ( ~~~e ||| f)) + 5 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * ( ~~~d ||| ( ~~~e &&& f)) - 1 * ( ~~~f &&& (d ^^^ e)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 6 * ((d &&& e) |||  ~~~(e ||| f)) - 6 * (d ^^^ ( ~~~e &&& f)) - 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 * (e ^^^ ( ~~~d ||| (e ^^^ f))) + 7 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * (e ^^^ (d ||| (e &&& f))) + 7 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d &&& e)) - 7 * (e ||| f) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (e ^^^ ( ~~~d ||| (e &&& f))) - 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 4 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d ||| e)) + 3 *  ~~~(d &&& (e ^^^ f)) + 3 * (f &&&  ~~~(d &&& e)) - 3 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 11 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 2 * (e ||| (d ^^^ f)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 * e + 11 *  ~~~(d &&&  ~~~f) - 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 5 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 11 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e |||  ~~~(d ||| f)) + 1 * (d &&& f) + 1 * ( ~~~e |||  ~~~(d ^^^ f)) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& f)) - 2 *  ~~~(d ||| f) + 3 * (f ^^^ (d ||| (e ||| f))) + 4 *  ~~~(d ^^^ (e ||| f)) + 1 * ( ~~~f ||| (d ^^^ e)) - 5 * ((d &&& e) ^^^ (e ||| f)) - 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 4 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 3 * f + 2 * (e ^^^ f) + 7 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 3 * (e &&&  ~~~(d &&&  ~~~f)) - 29 *  ~~~(d ||| (e ||| f)) - 10 *  ~~~(d ||| ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ||| f)) + 6 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 47 * ( ~~~d &&& ( ~~~e &&& f)) - 19 * ( ~~~d &&& (e &&& f)) - 11 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) =  - 5 * ((d &&& e) ||| (d ^^^ (e ^^^ f)))

theorem mul8_low_proof : mul8_low_before ⊑ mul8_low_after

theorem test_invalid_simplify_eq2_proof : test_invalid_simplify_eq2_before ⊑ test_invalid_simplify_eq2_after

theorem shl_nsw_nuw_add_proof : shl_nsw_nuw_add_before ⊑ shl_nsw_nuw_add_after

theorem factorize2_thm.extracted_1._1 : ∀ (x : BitVec 32), 3#32 * x - 2#32 * x = x

theorem test_shift_negative_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧
          ((x_1 ||| BitVec.ofInt 32 (-2147483648)) <<< (x &&& 7#32)).sshiftRight' (x &&& 7#32) ≠
            x_1 ||| BitVec.ofInt 32 (-2147483648) ∨
        x &&& 7#32 ≥ ↑32) →
    ofBool ((x_1 ||| BitVec.ofInt 32 (-2147483648)) <<< (x &&& 7#32) <ₛ 0#32) = 1#1

theorem add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_thm (e e_1 : IntW 32) :
  LLVM.and (LLVM.or (add e_1 (const? 32 16)) e) (const? 32 24) ⊑
    LLVM.and (LLVM.or (LLVM.xor e_1 (const? 32 16)) e) (const? 32 24)

theorem alive_AndOrXor_2367  (w : Nat)   : alive_AndOrXor_2367_src w  ⊑ alive_AndOrXor_2367_tgt w

theorem a_or_b_const_proof : a_or_b_const_before ⊑ a_or_b_const_after

theorem neg_sgt_42_proof : neg_sgt_42_before ⊑ neg_sgt_42_after

theorem scalar_i8_shl_and_signbit_eq_proof : scalar_i8_shl_and_signbit_eq_before ⊑ scalar_i8_shl_and_signbit_eq_after

theorem intMin_slt_zero (h : 0 < w) :
    BitVec.slt (intMin w) 0

theorem icmp_sle11_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 7#8).sshiftRight' 7#8 ≠ x ∨ 7#8 ≥ ↑8) →
    ofBool (x <<< 7#8 ≤ₛ BitVec.ofInt 8 (-2)) = ofBool (x <ₛ 0#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 lshrult_03_10_proof : lshrult_03_10_before ⊑ lshrult_03_10_after

theorem p_commutative4_proof : p_commutative4_before ⊑ p_commutative4_after

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

theorem zext_thm (e : IntW 1) : select e (const? 41 1) (const? 41 0) ⊑ zext 41 e

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

theorem select_icmp_ne_0_and_4096_xor_4096_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 4096)) ⊑
    LLVM.xor (LLVM.xor (LLVM.and e_1 (const? 32 4096)) e) (const? 32 4096)

theorem test2_logical_proof : test2_logical_before ⊑ test2_logical_after

theorem pr33078_4_thm.extracted_1._1 : ∀ (x : BitVec 3),
  ¬13#16 ≥ ↑16 →
    13#16 ≥ ↑16 ∨
        True ∧ signExtend 16 (truncate 8 (signExtend 16 x >>> 13#16)) ≠ signExtend 16 x >>> 13#16 ∨
          True ∧ zeroExtend 16 (truncate 8 (signExtend 16 x >>> 13#16)) ≠ signExtend 16 x >>> 13#16 →
      False

theorem test12_thm.extracted_1._1 : ∀ (x : BitVec 43), ¬42#43 ≥ ↑43 → 0#43 - x.sshiftRight' 42#43 = x >>> 42#43

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

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)

theorem test_mul_nsw__all_are_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 255#32 == 17#32) = 1#1 →
    ¬(True ∧ (x &&& 255#32).smulOverflow 9#32 = true ∨ True ∧ (x &&& 255#32).umulOverflow 9#32 = true) →
      153#32 = (x &&& 255#32) * 9#32

theorem test1_proof : test1_before ⊑ test1_after

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

theorem e_869 :
    4 * (z ^^^ t) + 11 * z + 3 *  ~~~(z &&&  ~~~t) - 3 *  ~~~(z ||| t) - 15 * (z &&&  ~~~t) - 14 * (z &&& t) = 7 *  ~~~(z |||  ~~~t)

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

theorem main11_proof : main11_before ⊑ main11_after

theorem or_test1_proof : or_test1_before ⊑ or_test1_after

theorem a_false_implies_b_false_proof : a_false_implies_b_false_before ⊑ a_false_implies_b_false_after

theorem positive_trunc_base_logical_proof : positive_trunc_base_logical_before ⊑ positive_trunc_base_logical_after

theorem zext_ult_zext_thm (e : IntW 1) (e_1 : IntW 8) :
  icmp IntPred.ult (zext 16 (mul e_1 e_1)) (zext 16 e) ⊑
    LLVM.and (icmp IntPred.eq (mul e_1 e_1) (const? 8 0)) e

theorem ult_to_sgt_proof : ult_to_sgt_before ⊑ ult_to_sgt_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 test_thm.extracted_1._2 : ∀ (x : BitVec 31),
  ¬15#32 ≥ ↑32 →
    ¬(True ∧ (zeroExtend 32 x).uaddOverflow 16384#32 = true ∨ 15#32 ≥ ↑32) →
      truncate 16 ((signExtend 32 x + 16384#32) >>> 15#32) = truncate 16 ((zeroExtend 32 x + 16384#32) >>> 15#32)

theorem bv_AddSub_1152 :
    ∀ (e e_1 : LLVM.IntW 1), LLVM.add e_1 e ⊑ LLVM.xor e_1 e

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

theorem lshrugt_01_07_proof : lshrugt_01_07_before ⊑ lshrugt_01_07_after

theorem main14_logical_proof : main14_logical_before ⊑ main14_logical_after

theorem e_1855 :
     - 7 * ( ~~~b &&& (a ^^^ c)) - 1 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) + 4 *  ~~~( ~~~a ||| (b &&& c)) + 2 * (c ^^^  ~~~(a ||| b)) - 3 * ((a |||  ~~~b) &&& (b ^^^ c)) - 5 *  ~~~(a ||| ( ~~~b &&& c)) + 2 * ( ~~~c ||| (a ^^^ b)) + 2 * (c ^^^ (a ||| ( ~~~b &&& c))) - 2 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 2 * (c ^^^  ~~~(a |||  ~~~b)) - 6 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 1 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 7 *  ~~~(a &&& (b &&& c)) + 7 * (b ^^^ (a &&& (b ||| c))) + 4 *  ~~~(a &&& b) + 1 *  ~~~(a &&& c) + 7 *  ~~~( ~~~a ||| (b ^^^ c)) - 11 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 2 * (b ^^^  ~~~(a &&& c)) + 1 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) - 3 * (b ^^^  ~~~(a &&&  ~~~c)) + 2 * (b ^^^  ~~~(a &&& (b ||| c))) - 5 * (a ||| ( ~~~b ||| c)) + 1 *  ~~~(a ||| b) - 1 *  ~~~b - 11 * (c &&& (a ^^^ b)) - 2 * (c ||| (a ^^^ b)) + 1 *  ~~~( ~~~a &&& (b ^^^ c)) - 1 * ((a &&&  ~~~b) ||| (b ^^^ c)) + 5 * (b ^^^ (a &&& c)) + 5 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 5 * (c ^^^ (a ||| ( ~~~b ||| c))) + 3 * (b ^^^ ( ~~~a &&& (b ||| c))) + 3 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 1 * ((b &&& c) ||| (a &&& (b ||| c))) - 2 *  ~~~(a |||  ~~~c) + 21 *  ~~~(a ||| (b ||| c)) + 4 *  ~~~(a ||| ( ~~~b ||| c)) - 9 *  ~~~( ~~~a ||| (b ||| c)) - 19 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) + 22 * (a &&& ( ~~~b &&& c)) = 1 * (a &&& (b &&& c)) + 11 * (c ^^^  ~~~(a ||| ( ~~~b &&& c)))

theorem icmp_eq_and_pow2_shl_pow2_negative1_proof : icmp_eq_and_pow2_shl_pow2_negative1_before ⊑ icmp_eq_and_pow2_shl_pow2_negative1_after

theorem or_basic_commuted_thm (e : IntW 16) :
  LLVM.or (icmp IntPred.ne (LLVM.and e (const? 16 (-256))) (const? 16 32512))
      (icmp IntPred.ne (trunc 8 e) (const? 8 69)) ⊑
    icmp IntPred.ne e (const? 16 32581)

theorem uge_or_max_commute_proof : uge_or_max_commute_before ⊑ uge_or_max_commute_after

@[simp] theorem regArgs_changeVars : (e.changeVars f).regArgs = e.regArgs

theorem positive_sameconst_shlnuw_proof : positive_sameconst_shlnuw_before ⊑ positive_sameconst_shlnuw_after

theorem ult_swap_and_max_proof : ult_swap_and_max_before ⊑ ult_swap_and_max_after

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

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

theorem and_not_xor_common_op_proof : and_not_xor_common_op_before ⊑ and_not_xor_common_op_after

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

theorem and_add_bool_to_select_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → -1#32 + zeroExtend 32 x_1 &&& x = x

@[simp_riscv] lemma toType_bv : TyDenote.toType (Ty.riscv (.bv)) = BitVec 64

theorem icmp_select_var_select_thm.extracted_1._13 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (x_1 == 0#8) = 1#1 ∧ x_2 = 1#1 → ofBool (x_1 == 0#8) = 1#1 → ¬True → ofBool (x == x_1) = 1#1

theorem sge_or_max_proof : sge_or_max_before ⊑ sge_or_max_after

theorem substitute_constant_and_eq_eq_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e_1 e) ⊑
    LLVM.and (icmp IntPred.eq e_1 (const? 8 42)) (icmp IntPred.eq e (const? 8 42))

theorem e_658 :
     - 2 * (x ^^^ y) + 2 * x - 11 *  ~~~(x &&&  ~~~x) + 1 *  ~~~y - 2 * (x ||| y) - 1 * (x |||  ~~~y) + 2 * y + 11 *  ~~~(x ||| y) + 13 *  ~~~(x |||  ~~~y) + 10 * (x &&& y) =  - 13 * (x &&&  ~~~y)

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

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

@[simp_denote (high)] -- high priority so that this is tried before the `reduceIsRefinedBy` simproc
theorem pure_isRefinedBy_pure (x : α) (y : β) :
  (pure x : Id _) ⊑ (pure y : Id _) ↔ x ⊑ y

theorem test6a_thm (e : IntW 55) : shl (mul e (const? 55 3)) (const? 55 1) ⊑ mul e (const? 55 6)

theorem lshrugt_02_15_thm (e : IntW 4) : icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 (-1)) ⊑ const? 1 0

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

theorem test25_proof : test25_before ⊑ test25_after

theorem t0_thm (e e_1 e_2 e_3 : IntW 32) :
  LLVM.xor (LLVM.and (icmp IntPred.eq e_3 e_2) (icmp IntPred.eq e_1 e)) (const? 1 1) ⊑
    LLVM.or (icmp IntPred.ne e_3 e_2) (icmp IntPred.ne e_1 e)

theorem e_2491 :
     - 7 * (e ^^^ (d |||  ~~~f)) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 11 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 * (d &&&  ~~~e) + 2 * (e ^^^  ~~~(d &&& (e &&& f))) + 3 * ((d ||| e) &&& (e ^^^ f)) - 11 *  ~~~( ~~~d &&& (e &&& f)) - 1 * (d ^^^ (e ^^^ f)) + 1 * (e |||  ~~~f) - 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * (f ^^^ (d &&& e)) + 4 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 6 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (f |||  ~~~(d ^^^ e)) + 4 *  ~~~( ~~~d &&& (e ||| f)) - 11 * (f ^^^ (d ||| ( ~~~e ||| f))) - 5 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 6 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (d ^^^ (e ||| f)) + 2 *  ~~~f + 5 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * (e &&& (d ^^^ f)) + 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (e ||| f) - 11 * (e ^^^  ~~~(d &&& f)) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 5 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 3 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 1 * (f ||| (d ^^^ e)) + 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 2 * (f |||  ~~~(d |||  ~~~e)) + 5 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 2 * ( ~~~f &&& (d ^^^ e)) + 4 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 11 *  ~~~(d ^^^ (e ||| f)) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 7 * ((d ^^^ e) &&& (d ^^^ f)) - 2 * ( ~~~e ||| (d ^^^ f)) - 2 * (d ^^^ (e &&& f)) + 1 * (e &&&  ~~~f) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * ((d &&& f) ^^^ (e ||| f)) + 2 * d + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * f + 2 *  ~~~(d ^^^ (e &&& f)) + 5 * (e &&&  ~~~(d ^^^ f)) + 1 *  ~~~(d &&& (e ||| f)) - 11 *  ~~~e - 7 * (d ||| (e &&& f)) + 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * (d &&& ( ~~~e ||| f)) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 *  ~~~(d &&&  ~~~f) - 7 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (d ||| (e ^^^ f)) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 7 * (e ^^^ (d &&& (e ||| f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 6 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 11 * (e &&& (d |||  ~~~f)) - 2 * ( ~~~(d ^^^ e) |||  ~~~(d ^^^ f)) + 1 * (d |||  ~~~e) + 5 * (e ^^^ (d &&& ( ~~~e ||| f))) + 3 * (f ^^^ (d ||| (e ||| f))) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ (d ||| (e &&& f))) - 1 *  ~~~(d &&& (e ^^^ f)) + 47 *  ~~~(d ||| (e ||| f)) - 26 *  ~~~(d ||| ( ~~~e ||| f)) + 58 *  ~~~( ~~~d ||| (e ||| f)) + 28 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 62 * ( ~~~d &&& ( ~~~e &&& f)) + 52 * ( ~~~d &&& (e &&& f)) + 24 * (d &&& ( ~~~e &&& f)) + 24 * (d &&& (e &&& f)) = 11 *  ~~~(d &&&  ~~~e) + 3 * (f ||| (d &&&  ~~~e))

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

theorem not_and_and_or_not_or_or_commute1_proof : not_and_and_or_not_or_or_commute1_before ⊑ not_and_and_or_not_or_or_commute1_after

theorem ashrslt_03_01_exact_proof : ashrslt_03_01_exact_before ⊑ ashrslt_03_01_exact_after

@[grind ., simp, aesop 50% unsafe]
lemma RawCNFA.WF.trans_src_lt'' [LawfulBEq A] {m : RawCNFA A} (hwf : m.WF) :
    ∀ {s a s'}, s' ∈ m.tr s a → s ∈ m.states

theorem n2_proof : n2_before ⊑ n2_after

theorem lshrult_02_01_proof : lshrult_02_01_before ⊑ lshrult_02_01_after

theorem smear_set_bit_proof : smear_set_bit_before ⊑ smear_set_bit_after

theorem test_negative_combined_sub_signed_overflow_proof : test_negative_combined_sub_signed_overflow_before ⊑ test_negative_combined_sub_signed_overflow_after

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

theorem main3_logical_proof : main3_logical_before ⊑ main3_logical_after

theorem mul_mask_pow2_eq0_proof : mul_mask_pow2_eq0_before ⊑ mul_mask_pow2_eq0_after

@[simp] theorem negAux_succ (x : BitStream) (n : Nat) : x.negAux (n + 1) =
    let borrow

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

theorem scalar_i32_signbit_lshr_and_eq_X_is_constant1_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (lshr (const? 32 (-2147483648)) e) (const? 32 12345)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and (lshr (const? 32 (-2147483648)) e { «exact» := true }) (const? 32 12345))
      (const? 32 0)

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → 46#599 ≥ ↑599 → False

theorem ashr_add_fail_proof : ashr_add_fail_before ⊑ ashr_add_fail_after

theorem test_zext1_thm (e e_1 : IntW 1) :
  select e_1 (zext 32 e) (const? 32 0) ⊑ zext 32 (select e_1 e (const? 1 0))

theorem xor_signbit_ashr_proof : xor_signbit_ashr_before ⊑ xor_signbit_ashr_after

theorem ult_and_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.ult e_1 e) (icmp IntPred.eq e_1 (const? 8 (-1))) (const? 1 0) ⊑ const? 1 0

theorem nonexact_lshr_ne_noexactlog_proof : nonexact_lshr_ne_noexactlog_before ⊑ nonexact_lshr_ne_noexactlog_after

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

theorem test15_thm (e e_1 : IntW 8) :
  mul (LLVM.and (LLVM.xor e_1 e) (LLVM.xor (LLVM.xor e (const? 8 33)) e_1)) (LLVM.xor (LLVM.xor e (const? 8 33)) e_1) ⊑
    mul (LLVM.and (LLVM.xor e_1 e) (LLVM.xor (LLVM.xor e e_1) (const? 8 33)))
      (LLVM.xor (LLVM.xor e e_1) (const? 8 33))

theorem n9_proof : n9_before ⊑ n9_after

theorem xor_or_xor_proof : xor_or_xor_before ⊑ xor_or_xor_after

theorem test2_proof : test2_before ⊑ test2_after

theorem e_1454 :
    2 * z - 2 * (z ||| t) + 2 *  ~~~(z &&&  ~~~t) + 7 *  ~~~t + 5 *  ~~~z + 1 *  ~~~(z &&& t) - 26 *  ~~~(z ||| t) - 17 *  ~~~(z |||  ~~~t) - 19 * (z &&&  ~~~t) - 13 * (z &&& t) =  - 11 *  ~~~(z &&&  ~~~z)

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

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

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

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

theorem flip_masked_bit_proof : flip_masked_bit_before ⊑ flip_masked_bit_after

theorem test_sub_nuw__none_are_safe_proof : test_sub_nuw__none_are_safe_before ⊑ test_sub_nuw__none_are_safe_after

theorem lshrult_03_13_exact_proof : lshrult_03_13_exact_before ⊑ lshrult_03_13_exact_after

theorem zext_zext_eq_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.eq e_1 e

theorem ashr_ult_exact_proof : ashr_ult_exact_before ⊑ ashr_ult_exact_after

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

theorem test3i_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(29#32 ≥ ↑32 ∨ 29#32 ≥ ↑32) →
    zeroExtend 32 (ofBool (x_1 >>> 29#32 ||| 35#32 == x >>> 29#32 ||| 35#32)) =
      zeroExtend 32 (ofBool (-1#32 <ₛ x_1 ^^^ x))

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

theorem e_1935 :
    4 * (a &&& (b ^^^ c)) + 11 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 11 * (a &&& c) - 3 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 5 *  ~~~(a &&& ( ~~~b &&& c)) - 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 2 * (b ||| (a ^^^ c)) + 11 * (c &&&  ~~~(a &&&  ~~~b)) - 2 * ( ~~~(a ||| b) |||  ~~~(a ^^^ (b ^^^ c))) + 4 * ((a ^^^ b) |||  ~~~(a ^^^ c)) + 2 * (c ^^^ (a &&&  ~~~b)) - 3 * (c ^^^  ~~~(a ||| b)) - 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 7 *  ~~~(a &&&  ~~~c) - 3 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) + 2 * (c ^^^ ( ~~~a ||| (b &&& c))) - 2 * (c ^^^ (a ||| b)) - 1 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 1 * (b ^^^ (a |||  ~~~c)) - 3 * (c ||| (a &&&  ~~~b)) + 5 *  ~~~(b &&&  ~~~c) + 11 * b + 1 * a - 5 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 1 * ((a ^^^ b) &&& (a ^^^ c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) - 6 * ((a ||| b) &&&  ~~~(b ^^^ c)) - 1 *  ~~~(a |||  ~~~b) + 4 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 1 * (b ^^^ (a ||| c)) - 1 * (a |||  ~~~b) - 1 * (a ||| (b &&& c)) - 6 * (b |||  ~~~(a ||| c)) - 2 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 1 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 5 * (c ^^^ (a &&& ( ~~~b ||| c))) + 3 * ((a ||| b) &&& (b ^^^ c)) - 1 *  ~~~(a |||  ~~~c) - 11 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ^^^ (a &&&  ~~~c)) + 11 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 2 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * (b ^^^ (a &&& ( ~~~b ||| c))) - 12 *  ~~~(a ||| (b ||| c)) - 15 *  ~~~(a ||| ( ~~~b ||| c)) - 15 *  ~~~( ~~~a ||| (b ||| c)) + 10 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 16 * ( ~~~a &&& ( ~~~b &&& c)) - 19 * ( ~~~a &&& (b &&& c)) - 15 * (a &&& ( ~~~b &&& c)) - 27 * (a &&& (b &&& c)) =  - 11 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c)))

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

theorem ashrslt_01_12_proof : ashrslt_01_12_before ⊑ ashrslt_01_12_after

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

theorem and_umax_muchless_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 12#32) = 1#1 → 12#32 &&& BitVec.ofInt 32 (-32) = x &&& BitVec.ofInt 32 (-32)

theorem lshr_and_proof : lshr_and_before ⊑ lshr_and_after

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

theorem sle_and_min_logical_proof : sle_and_min_logical_before ⊑ sle_and_min_logical_after

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

theorem ashr_lshr_cst2_proof : ashr_lshr_cst2_before ⊑ ashr_lshr_cst2_after

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

theorem t0_thm (e e_1 : IntW 8) :
  sub (LLVM.and (sub (const? 8 0) e_1) e) e ⊑ sub (const? 8 0) (LLVM.and e (add e_1 (const? 8 (-1))))

theorem not_invert_signbit_splat_mask2_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (sext 16 (LLVM.xor (ashr e_1 (const? 8 6)) (const? 8 (-1)))) e ⊑
    LLVM.and e (sext 16 (LLVM.xor (ashr e_1 (const? 8 6)) (const? 8 (-1))))

theorem lt_signed_to_large_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (signExtend 32 x <ₛ BitVec.ofInt 32 (-1024)) = 0#1

theorem select_icmp_ne_0_and_1073741824_xor_8_proof : select_icmp_ne_0_and_1073741824_xor_8_before ⊑ select_icmp_ne_0_and_1073741824_xor_8_after

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

theorem lt_unsigned_to_large_signed_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (zeroExtend 32 x <ₛ 1024#32) = 1#1

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

theorem ult_2_proof : ult_2_before ⊑ ult_2_after

theorem test15i_proof : test15i_before ⊑ test15i_after

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

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

theorem test_or4_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 2147483647#32 <ₛ x) = 1#1 → ofBool (x <ₛ 0#32) = ofBool (x_1 &&& 2147483647#32 <ᵤ x)

theorem e_26 :
     - 2 * (x ^^^ y) + 3 * y - 12 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) - 14 * (x &&& y) =  - 11 * (x ||| y)

theorem sub_select_sext_thm (e : IntW 64) (e_1 : IntW 1) :
  sub (select e_1 (const? 64 64) e) (sext 64 e_1) ⊑ select e_1 (const? 64 65) e

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

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

theorem set_bits_proof : set_bits_before ⊑ set_bits_after

theorem bools_multi_uses1_logical_proof : bools_multi_uses1_logical_before ⊑ bools_multi_uses1_logical_after

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 negative_trunc_not_arg_logical_proof : negative_trunc_not_arg_logical_before ⊑ negative_trunc_not_arg_logical_after

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

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

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

theorem trunc_nuw_xor_thm (e e_1 : IntW 8) :
  trunc 1 (LLVM.xor e_1 e) { «nsw» := false, «nuw» := true } ⊑ icmp IntPred.ne e_1 e

theorem slt_zero_eq_i1_proof : slt_zero_eq_i1_before ⊑ slt_zero_eq_i1_after

theorem ne_umax4_proof : ne_umax4_before ⊑ ne_umax4_after

theorem n3_constmask_samemask_thm (e e_1 : IntW 32) :
  LLVM.and (LLVM.or e_1 (const? 32 (-65281))) (LLVM.or e (const? 32 (-65281))) ⊑
    LLVM.or (LLVM.and e_1 e) (const? 32 (-65281))

theorem drop_both_trunc_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  ¬(True ∧ signExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x ∨
        True ∧ zeroExtend 16 (truncate 8 (x_1 &&& 255#16 &&& x)) ≠ x_1 &&& 255#16 &&& x) →
    truncate 8 (x_1 &&& 255#16 &&& x) = truncate 8 (x_1 &&& x)

theorem test38_proof : test38_before ⊑ test38_after

theorem trunc_shl_33_i32_i64_proof : trunc_shl_33_i32_i64_before ⊑ trunc_shl_33_i32_i64_after

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

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

@[simp] theorem Valuation.comap_cons_consRight {Γ Δ : Ctxt Ty} (Γv : Valuation Γ) (f : Hom Δ Γ) :
    comap (Γv.cons x) (f.consRight) = comap Γv f

theorem Eqn.denoteFin_eq_add {w : Nat} (eqn : Eqn) (env : EnvFin (w + 1) eqn.numVars) :
    eqn.denoteFin env = 2 * eqn.denoteFin env.getNonLsbs + eqn.denoteFin env.getLsb

theorem icmp_ugt_32_proof : icmp_ugt_32_before ⊑ icmp_ugt_32_after

theorem e_1010 :
     - 6 * (z ||| t) - 11 * (z |||  ~~~t) - 1 * z - 2 *  ~~~(z &&&  ~~~z) - 3 *  ~~~(z |||  ~~~t) + 20 * (z &&&  ~~~t) + 9 * (z &&& t) =  - 2 *  ~~~(z ||| t) - 11 *  ~~~(z &&&  ~~~t)

theorem select_icmp_ne_0_and_4096_or_4096_proof : select_icmp_ne_0_and_4096_or_4096_before ⊑ select_icmp_ne_0_and_4096_or_4096_after

theorem lshrugt_01_13_proof : lshrugt_01_13_before ⊑ lshrugt_01_13_after

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

theorem t7_proof : t7_before ⊑ t7_after

theorem canonicalize_logic_first_and0_proof : canonicalize_logic_first_and0_before ⊑ canonicalize_logic_first_and0_after

theorem lt_unsigned_to_small_signed_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (zeroExtend 32 x <ₛ 17#32) = ofBool (x <ᵤ 17#8)

theorem or_ugt_proof : or_ugt_before ⊑ or_ugt_after

theorem ashr_overshift_thm (e : IntW 32) : ashr (ashr e (const? 32 15)) (const? 32 17) ⊑ ashr e (const? 32 31)

private theorem Int.lt_of_neg {i : Int} (hi : i < - 1) : i < i / 2

theorem e_1466 :
    1 *  ~~~(z ^^^ t) + 3 *  ~~~t + 4 *  ~~~(z &&& t) + 2 * (z |||  ~~~t) + 11 * t - 2 * (z ^^^ t) + 7 *  ~~~(z &&&  ~~~t) - 20 *  ~~~(z ||| t) - 23 *  ~~~(z |||  ~~~t) - 1 * (z &&&  ~~~t) - 15 * (z &&& t) = 6 * z - 3 *  ~~~z

theorem add_or_and_commutative_proof : add_or_and_commutative_before ⊑ add_or_and_commutative_after

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

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

theorem exact_lshr_ne_opposite_msb_proof : exact_lshr_ne_opposite_msb_before ⊑ exact_lshr_ne_opposite_msb_after

theorem scalar_i8_shl_ule_const_proof : scalar_i8_shl_ule_const_before ⊑ scalar_i8_shl_ule_const_after

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

theorem slt_positive_multip_rem_zero_proof : slt_positive_multip_rem_zero_before ⊑ slt_positive_multip_rem_zero_after

theorem add_shl_same_amount_nuw_proof : add_shl_same_amount_nuw_before ⊑ add_shl_same_amount_nuw_after

theorem main13_logical_proof : main13_logical_before ⊑ main13_logical_after

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

theorem fold_select_trunc_nsw_false_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ signExtend 8 (truncate 1 x_1) ≠ x_1) → ¬truncate 1 x_1 = 1#1 → x_1 = 0#8

theorem main4f_like_proof : main4f_like_before ⊑ main4f_like_after

theorem n3_constmask_samemask_thm (e e_1 : IntW 32) :
  add (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) ⊑
    add (LLVM.and e_1 (const? 32 65280)) (LLVM.and e (const? 32 65280)) { «nsw» := true, «nuw» := true }

theorem test_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.sdiv e (const? 32 12)) (const? 32 (-6)) ⊑
    icmp IntPred.ult (add e (const? 32 71)) (const? 32 (-12))

theorem not_eq_neg_sub_one :
    ~~~ x = - x - 1

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

theorem shl_xor_lshr_comm_proof : shl_xor_lshr_comm_before ⊑ shl_xor_lshr_comm_after

theorem test_shl_nsw__nsw_is_safe_thm.extracted_1._1 : ∀ (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 ||

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 p_commutative2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  True ∧ (x_1 &&& (x_2 ^^^ -1#32) &&& (x &&& x_2) != 0) = true → False

theorem sle_or_not_min_commute_proof : sle_or_not_min_commute_before ⊑ sle_or_not_min_commute_after

theorem bools_multi_uses2_logical_proof : bools_multi_uses2_logical_before ⊑ bools_multi_uses2_logical_after

theorem negate_lowbitmask_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 &&& 1#8 == 0#8) = 1#1 → 0#8 - (x_1 &&& 1#8) &&& x = x

theorem test_invert_demorgan_logical_and_thm.extracted_1._4 : ∀ (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) &&& ofBool (x != 0#64)

theorem sle_smin4_proof : sle_smin4_before ⊑ sle_smin4_after

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

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

theorem t0_proof : t0_before ⊑ t0_after

theorem sdiv6_thm (e : IntW 32) :
  mul (LLVM.sdiv e (const? 32 3) { «exact» := true }) (const? 32 (-3)) ⊑ sub (const? 32 0) e

theorem t20_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ¬x ≥ ↑16 → x_1 - truncate 8 (BitVec.ofInt 16 (-42) <<< x) = x_1 + truncate 8 (42#16 <<< x)

theorem sext_xor_sub_proof : sext_xor_sub_before ⊑ sext_xor_sub_after

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

theorem shl_and_and_fail_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(4#8 ≥ ↑8 ∨ 5#8 ≥ ↑8) → x_1 <<< 4#8 &&& (x <<< 5#8 &&& 88#8) = x_1 <<< 4#8 &&& (x <<< 5#8 &&& 64#8)

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

theorem ashrslt_01_08_exact_proof : ashrslt_01_08_exact_before ⊑ ashrslt_01_08_exact_after

@[simp_llvm_option]
theorem LLVM.IntW.value_isRefinedBy_iff (a : BitVec w) (b? : PoisonOr (BitVec w)) :
    value a ⊑ b? ↔ b? = value a

theorem negate_add_with_single_negatible_operand_proof : negate_add_with_single_negatible_operand_before ⊑ negate_add_with_single_negatible_operand_after

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

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

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

theorem t1_proof : t1_before ⊑ t1_after

theorem mul_of_pow2s_proof : mul_of_pow2s_before ⊑ mul_of_pow2s_after

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

theorem zext_sub_const_proof : zext_sub_const_before ⊑ zext_sub_const_after

theorem gt_unsigned_to_large_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (BitVec.ofInt 32 (-1024) <ₛ zeroExtend 32 x) = 1#1

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

theorem sub_not_proof : sub_not_before ⊑ sub_not_after

theorem select_non_const_sides_thm (e e_1 : IntW 64) (e_2 : IntW 1) :
  sub (select e_2 e_1 e) (zext 64 e_2) ⊑ select e_2 (add e_1 (const? 64 (-1))) e

theorem mul64_low_thm (e e_1 : IntW 64) :
  add
      (shl
        (add (mul (lshr e_1 (const? 64 32)) (LLVM.and e (const? 64 4294967295)))
          (mul (LLVM.and e_1 (const? 64 4294967295)) (lshr e (const? 64 32))))
        (const? 64 32))
      (mul (LLVM.and e_1 (const? 64 4294967295)) (LLVM.and e (const? 64 4294967295))) ⊑
    mul e e_1

theorem or_basic_proof : or_basic_before ⊑ or_basic_after

theorem zext_nneg_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ (x &&& 32767#16).msb = true) →
    zeroExtend 24 (x &&& 32767#16) &&& 8388607#24 = zeroExtend 24 (x &&& 32767#16)

theorem lshrult_01_14_exact_proof : lshrult_01_14_exact_before ⊑ lshrult_01_14_exact_after

theorem lsb_mask_sign_sext_commuted_proof : lsb_mask_sign_sext_commuted_before ⊑ lsb_mask_sign_sext_commuted_after

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

theorem scalar_i16_shl_ult_const_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬8#16 ≥ ↑16 → ofBool (x <<< 8#16 <ᵤ 1024#16) = ofBool (x &&& 252#16 == 0#16)

theorem absdiff_proof : absdiff_before ⊑ absdiff_after

theorem ashrslt_02_11_proof : ashrslt_02_11_before ⊑ ashrslt_02_11_after

theorem demorgan_nor_use2b_proof : demorgan_nor_use2b_before ⊑ demorgan_nor_use2b_after

theorem same_signbit_wrong_type_proof : same_signbit_wrong_type_before ⊑ same_signbit_wrong_type_after

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

theorem sel_false_val_is_a_masked_ashr_of_true_val2_proof : sel_false_val_is_a_masked_ashr_of_true_val2_before ⊑ sel_false_val_is_a_masked_ashr_of_true_val2_after

theorem trunc_shl_nsw_nuw_31_i32_i64_proof : trunc_shl_nsw_nuw_31_i32_i64_before ⊑ trunc_shl_nsw_nuw_31_i32_i64_after

theorem test14_proof : test14_before ⊑ test14_after

theorem n9_thm (e : IntW 64) :
  sub (const? 32 0) (trunc 32 (lshr e (const? 64 62))) ⊑
    sub (const? 32 0) (trunc 32 (lshr e (const? 64 62)) { «nsw» := true, «nuw» := true })
      { «nsw» := true, «nuw» := false }

@[simp]
theorem toBitVec_xor (a b : BitStream) :
    (a ^^^ b).toBitVec w = a.toBitVec w ^^^ b.toBitVec w

theorem ne_commuted_equal_minus_1_proof : ne_commuted_equal_minus_1_before ⊑ ne_commuted_equal_minus_1_after

theorem bool_add_ashr_thm (e e_1 : IntW 1) :
  ashr (add (zext 2 e_1) (zext 2 e)) (const? 2 1) ⊑
    ashr (add (zext 2 e_1) (zext 2 e) { «nsw» := false, «nuw» := true }) (const? 2 1)

theorem test6_thm.extracted_1._1 : ∀ (x : BitVec 55), ¬1#55 ≥ ↑55 → x <<< 1#55 * 3#55 = x * 6#55

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

theorem n0_proof : n0_before ⊑ n0_after

theorem bv_AndOrXor_2453 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.xor (LLVM.icmp LLVM.IntPred.slt e_1 e) (LLVM.const? 1 (-1)) ⊑ LLVM.icmp LLVM.IntPred.sge e_1 e

theorem a_false_implies_b_false_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬ofBool (10#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) = 1#1 → False

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

theorem lshr_eq_msb_low_last_zero_proof : lshr_eq_msb_low_last_zero_before ⊑ lshr_eq_msb_low_last_zero_after

theorem e_1800 :
     - 1 * (b ^^^ (a |||  ~~~c)) - 6 * (c ||| (a &&& b)) + 3 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 7 *  ~~~(b |||  ~~~c) - 1 *  ~~~(b &&&  ~~~c) + 5 *  ~~~(a ||| b) + 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * (c ^^^ (a &&& b)) - 11 * (c ^^^ (a &&&  ~~~b)) - 2 * (c ^^^ (a ||| (b &&& c))) - 11 * ((b &&& c) ||| (a &&& (b ||| c))) + 4 * (b ^^^ (a &&&  ~~~c)) - 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 1 * (b &&& (a ||| c)) - 1 * (b &&&  ~~~c) + 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * ( ~~~a ||| (b ||| c)) - 5 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 2 *  ~~~b + 5 *  ~~~(a |||  ~~~c) + 4 * (b ^^^  ~~~(a |||  ~~~c)) - 2 * (b ^^^ (a ||| c)) + 4 * (a &&& ( ~~~b ||| c)) - 3 * ((a &&& b) |||  ~~~(b ||| c)) + 3 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * (a &&&  ~~~b) - 1 * (c &&&  ~~~(a ^^^ b)) + 5 * ((a ||| b) &&& (b ^^^ c)) + 2 *  ~~~(a &&& ( ~~~b ||| c)) + 3 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 7 * (a ||| (b &&& c)) + 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) + 17 *  ~~~( ~~~a ||| (b ||| c)) + 25 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 35 * ( ~~~a &&& (b &&& c)) + 30 * (a &&& ( ~~~b &&& c)) + 29 * (a &&& (b &&& c)) =  - 27 * ( ~~~a &&& ( ~~~b &&& c))

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

theorem negtest_near_pow2_cmpval_ashr_slt_noexact_proof : negtest_near_pow2_cmpval_ashr_slt_noexact_before ⊑ negtest_near_pow2_cmpval_ashr_slt_noexact_after

theorem negate_select_of_op_vs_negated_op_nsw_commuted_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1)
  (x_2 : BitVec 8), ¬x_1 = 1#1 → ¬(True ∧ (0#8).ssubOverflow x = true) → x_2 - (0#8 - x) = x + x_2

theorem syncMap₂_eq_syncMap₂ {f : α → β → γ}
    (hxs : xs ~ xs') (hys : ys ~ ys') :
    syncMap₂ f xs ys ~ syncMap₂ f xs' ys'

theorem scalar_i32_shl_and_signbit_eq_X_is_constant1_proof : scalar_i32_shl_and_signbit_eq_X_is_constant1_before ⊑ scalar_i32_shl_and_signbit_eq_X_is_constant1_after

theorem Factor.denote_eq_toNat_reflect {w : Nat} (xs : Env w) (f : Factor) :
  f.denote xs = (f.reflect xs |>.toNat)

theorem signed_sign_bit_extract_trunc_proof : signed_sign_bit_extract_trunc_before ⊑ signed_sign_bit_extract_trunc_after

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

theorem neg_not_signbit3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → 7#8 ≥ ↑8 ∨ True ∧ (0#32).ssubOverflow (zeroExtend 32 (x.sshiftRight' 7#8)) = true → False

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

theorem icmp_equality_test_commute_select2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 64),
  ¬ofBool (x_2 == x_1) ^^^ 1#1 = 1#1 → ofBool (x == x_1) = ofBool (x_2 == x)

@[simp] theorem lt_length (v : Γ.Var t) : v.1 < Γ.length

@[simp]
lemma BitVec.transport_getElem (f : Fin n2 → Fin n1) (bv : BitVec n1) (i : Nat) (hlt : i < n2) :
    (bv.transport f)[i] = bv.getLsbD (f ⟨i, hlt⟩)

theorem lshr_exact_ne_0_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (lshr e_1 e { «exact» := true }) (const? 32 0) ⊑ icmp IntPred.ne e_1 (const? 32 0)

theorem t2_symmetry_thm (e e_1 : IntW 8) :
  icmp IntPred.uge (add e_1 e) e_1 ⊑ icmp IntPred.ule e (LLVM.xor e_1 (const? 8 (-1)))

theorem only_one_masked_proof : only_one_masked_before ⊑ only_one_masked_after

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

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

theorem test_invalid_simplify_select_1_thm (e : IntW 8) :
  select (icmp IntPred.eq e (const? 8 0)) (const? 8 1) (sub e (const? 8 1)) ⊑
    select (icmp IntPred.eq e (const? 8 0)) (const? 8 1) (add e (const? 8 (-1)))

theorem badimm2_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(6#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 6#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      ¬15#16 ≥ ↑16 → 6#8 ≥ ↑8 ∨ 8#16 ≥ ↑16 ∨ True ∧ zeroExtend 16 (truncate 8 (x >>> 8#16)) ≠ x >>> 8#16 → False

theorem shl_trunc_bigger_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 3#24 ≥ ↑24) →
    ¬(9#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 24 (x.sshiftRight' 9#32)) ≠ x.sshiftRight' 9#32) →
      truncate 24 (x.sshiftRight' 12#32) <<< 3#24 = truncate 24 (x.sshiftRight' 9#32) &&& BitVec.ofInt 24 (-8)

theorem udiv_i32_multiuse_proof : udiv_i32_multiuse_before ⊑ udiv_i32_multiuse_after

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

theorem shl_xor_xor_bad_mask_distribute_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(1#8 ≥ ↑8 ∨ 1#8 ≥ ↑8) →
    ¬1#8 ≥ ↑8 → x_1 <<< 1#8 ^^^ (x <<< 1#8 ^^^ BitVec.ofInt 8 (-68)) = (x ^^^ x_1) <<< 1#8 ^^^ BitVec.ofInt 8 (-68)

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 lshrult_01_09_proof : lshrult_01_09_before ⊑ lshrult_01_09_after

theorem e_38 :
    11 * (x ||| y) + 5 *  ~~~x - 2 *  ~~~(x ||| y) - 16 *  ~~~(x |||  ~~~y) - 11 * (x &&& y) = 3 *  ~~~y + 8 * (x &&&  ~~~y)

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

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

theorem Tensor1d.extract_fill [Inhabited α] (t: Tensor1d α):
  (t.extract left len).fill v = (t.fill v).extract left len

theorem eq_3210_proof : eq_3210_before ⊑ eq_3210_after

@[simp] theorem size_var : (var e body : Com d Γ eff t).size = body.size + 1

theorem positive_different_trunc_both_proof : positive_different_trunc_both_before ⊑ positive_different_trunc_both_after

theorem shift_xor_multiuse_cmp_thm (e e_1 e_2 e_3 : IntW 32) :
  mul (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_2 (LLVM.or e_2 (const? 32 2048)))
      (select (icmp IntPred.ne (const? 32 0) (LLVM.and e_3 (const? 32 4096))) e_1 e) ⊑
    mul (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) (LLVM.or e_2 (const? 32 2048)) e_2)
      (select (icmp IntPred.eq (LLVM.and e_3 (const? 32 4096)) (const? 32 0)) e e_1)

theorem logical_and_logical_and_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 ∨ ofBool (x_1 &&& (1#8 <<< x ||| 1#8) == 1#8 <<< x ||| 1#8) = 1#1 →
      False

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

theorem splat_mul_unknown_lz_thm (e : IntW 32) :
  icmp IntPred.eq (lshr (mul (zext 128 e) (const? 128 18446744078004518913)) (const? 128 95)) (const? 128 0) ⊑
    icmp IntPred.sgt e (const? 32 (-1))

theorem not_sub_one_eq_not_add_one :
    ~~~ (x - 1) = ~~~ x + 1

theorem ashr_ugt_13_proof : ashr_ugt_13_before ⊑ ashr_ugt_13_after

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

theorem test11_thm (e : IntW 23) :
  shl (lshr (mul e (const? 23 3)) (const? 23 11)) (const? 23 12) ⊑
    LLVM.and (mul e (const? 23 6)) (const? 23 (-4096))

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

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

theorem bitwise_or_bitwise_or_icmps_comm2_proof : bitwise_or_bitwise_or_icmps_comm2_before ⊑ bitwise_or_bitwise_or_icmps_comm2_after

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

@[simp]
theorem or_shiftRight_and_shiftLeft_distrib {x y z : BitVec w} {n : Nat} :
    (z ||| x >>> n &&& y) <<< n = z <<< n ||

theorem test87_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(True ∧ (signExtend 32 x).smulOverflow 16#32 = true ∨ 16#32 ≥ ↑32) →
    ¬12#16 ≥ ↑16 → truncate 16 ((signExtend 32 x * 16#32).sshiftRight' 16#32) = x.sshiftRight' 12#16

theorem lshrugt_02_01_exact_proof : lshrugt_02_01_exact_before ⊑ lshrugt_02_01_exact_after

theorem p0_proof : p0_before ⊑ p0_after

theorem trunc_lshr_zext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (zeroExtend 32 x >>> 6#32) = x >>> 6#8

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

theorem e_2073 :
     - 7 * (e &&& (d ^^^ f)) - 1 * (d ^^^ ( ~~~e &&& f)) - 6 *  ~~~( ~~~d ||| (e ^^^ f)) - 1 * (d ||| ( ~~~e ||| f)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 4 *  ~~~(d &&&  ~~~d) + 7 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 *  ~~~(d &&& f) - 3 * (f ^^^ ( ~~~d ||| (e ||| f))) + 2 *  ~~~(d &&& (e ||| f)) + 11 *  ~~~(d ||| (e &&& f)) + 3 * (e ^^^ (d ||| f)) - 3 * ( ~~~d ||| ( ~~~e &&& f)) - 2 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 11 * ((d &&& f) ^^^ (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 11 *  ~~~(d ^^^ (e &&& f)) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 3 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 11 * (d &&& (e ||| f)) - 11 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 1 * (f ^^^  ~~~(d ||| e)) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 4 * (e ^^^ (d &&& (e ||| f))) - 1 * (e |||  ~~~f) - 6 * ( ~~~f &&&  ~~~(d ^^^ e)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 6 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 *  ~~~(d &&& e) + 2 *  ~~~( ~~~d &&& (e ||| f)) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ||| (d &&& f)) + 14 *  ~~~(d ||| (e ||| f)) - 18 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) - 16 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 11 * ( ~~~d &&& ( ~~~e &&& f)) - 22 * (d &&& ( ~~~e &&& f)) - 9 * (d &&& (e &&& f)) = 30 * ( ~~~d &&& (e &&& f)) - 7 * (d &&& f)

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

theorem scalar_i8_shl_ugt_const_proof : scalar_i8_shl_ugt_const_before ⊑ scalar_i8_shl_ugt_const_after

theorem bool_add_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → (zeroExtend 2 x_1 + zeroExtend 2 x) >>> 1#2 = zeroExtend 2 (x_1 &&& x)

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

theorem and_or_not_not_commute2_proof : and_or_not_not_commute2_before ⊑ and_or_not_not_commute2_after

theorem test_logical_and_ne_a_b_proof : test_logical_and_ne_a_b_before ⊑ test_logical_and_ne_a_b_after

theorem shl_add_nuw_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 5#32 = true ∨ x + 5#32 ≥ ↑32) → x ≥ ↑32 → False

theorem negate_xor_thm.extracted_1._1 : ∀ (x : BitVec 4), 0#4 - (x ^^^ 5#4) = (x ^^^ BitVec.ofInt 4 (-6)) + 1#4

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

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

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

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

theorem lshrugt_02_03_proof : lshrugt_02_03_before ⊑ lshrugt_02_03_after

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

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

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

theorem scalar_i32_lshr_and_negC_eq_X_is_constant2_proof : scalar_i32_lshr_and_negC_eq_X_is_constant2_before ⊑ scalar_i32_lshr_and_negC_eq_X_is_constant2_after

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

theorem test22_logical_proof : test22_logical_before ⊑ test22_logical_after

theorem lshrult_03_04_proof : lshrult_03_04_before ⊑ lshrult_03_04_after

theorem bitwise_and_logical_and_icmps_comm1_proof : bitwise_and_logical_and_icmps_comm1_before ⊑ bitwise_and_logical_and_icmps_comm1_after

theorem mul_two :
  (bw r (mulMax (bw p a) (bw 2 (2#2))))  =
  (bw r ((bw p a) <<< 1))

theorem and_two_ranges_to_mask_and_range_proof : and_two_ranges_to_mask_and_range_before ⊑ and_two_ranges_to_mask_and_range_after

theorem const_sub_sub_const_proof : const_sub_sub_const_before ⊑ const_sub_sub_const_after

theorem ugt_or_not_min_commute_proof : ugt_or_not_min_commute_before ⊑ ugt_or_not_min_commute_after

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

theorem main_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(6#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) → 5#8 ≥ ↑8 ∨ True ∧ ((truncate 8 x ^^^ -1#8) <<< 5#8 &&& 64#8).msb = true → False

theorem test25_thm (e : IntW 32) : icmp IntPred.ugt (LLVM.and e (const? 32 2)) (const? 32 2) ⊑ const? 1 0

theorem tryFactorization_xor_lshr_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(x ≥ ↑32 ∨ x ≥ ↑32) →
    ¬x ≥ ↑32 → 5#32 >>> x ^^^ (BitVec.ofInt 32 (-3)).sshiftRight' x = (BitVec.ofInt 32 (-8)).sshiftRight' x

theorem factorize4_proof : factorize4_before ⊑ factorize4_after

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

theorem sub_shl_same_amount_nuw_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  ¬(True ∧ x_2 <<< x_1 >>> x_1 ≠ x_2 ∨
        x_1 ≥ ↑64 ∨ True ∧ x <<< x_1 >>> x_1 ≠ x ∨ x_1 ≥ ↑64 ∨ True ∧ (x_2 <<< x_1).usubOverflow (x <<< x_1) = true) →
    True ∧ x_2.usubOverflow x = true ∨ True ∧ (x_2 - x) <<< x_1 >>> x_1 ≠ x_2 - x ∨ x_1 ≥ ↑64 → False

theorem andn_or_cmp_2_logical_proof : andn_or_cmp_2_logical_before ⊑ andn_or_cmp_2_logical_after

theorem absdiff_thm.extracted_1._1 : ∀ (x x_1 : BitVec 64),
  ofBool (x_1 <ᵤ x) = 1#1 →
    (signExtend 64 (ofBool (x_1 <ᵤ x)) ^^^ x_1 - x) - signExtend 64 (ofBool (x_1 <ᵤ x)) = 0#64 - (x_1 - x)

theorem ashr_2_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ¬1#2 ≥ ↑2 → True ∧ (zeroExtend 2 x_1).uaddOverflow (zeroExtend 2 x) = true ∨ 1#2 ≥ ↑2 → False

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

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

theorem test19a_thm (e : IntW 39) :
  icmp IntPred.eq (ashr e (const? 39 2)) (const? 39 (-1)) ⊑ icmp IntPred.ugt e (const? 39 (-5))

@[simp]
theorem Term.toBV_binWidthRel {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv)
    (k : WidthBinaryRelationKind)
    (wa wb : WidthExpr wcard) :
  Term.toBV benv nenv ienv penv tenv (.binWidthRel k wa wb) =
    match k with

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

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

theorem t3_exact_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨ 63#64 ≥ ↑64) →
    ¬(True ∧ x >>> 63#64 <<< 63#64 ≠ x ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 ∨
              True ∧ zeroExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64) →
      0#32 - truncate 32 (x.sshiftRight' 63#64) = truncate 32 (x >>> 63#64)

theorem and_ne_with_one_bit_diff_constants2_proof : and_ne_with_one_bit_diff_constants2_before ⊑ and_ne_with_one_bit_diff_constants2_after

theorem test_ashr__exact_is_safe_proof : test_ashr__exact_is_safe_before ⊑ test_ashr__exact_is_safe_after

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

theorem annihilate_xor_common_op_commute2_thm.extracted_1._1 : ∀ (x x_1 x_2 x_3 : BitVec 4),
  x_3 * x_3 ^^^ (x_2 ^^^ x_1) ^^^ x ^^^ x_2 = x_1 ^^^ x_3 * x_3 ^^^ x

theorem shl_lshr_pow2_const_case1_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 6#16 ≥ ↑16) → ¬ofBool (x == 7#16) = 1#1 → 4#16 <<< x >>> 6#16 &&& 8#16 = 0#16

theorem test_shl_nuw__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨
        True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
          zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64 →
      False

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

theorem slt_smin2_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (select (icmp IntPred.slt e_1 e) e_1 e) e ⊑ icmp IntPred.slt e_1 e

theorem e_2423 :
    1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 6 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) - 3 * (d &&& f) + 2 * (f ||| (d ^^^ e)) - 6 * (d ||| (e ||| f)) + 5 * (d ||| e) - 1 *  ~~~(d ^^^ f) - 1 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 11 * (e ^^^ (d &&& ( ~~~e ||| f))) - 1 * ((e &&& f) ||| (d &&& (e ||| f))) - 1 * (e ||| (d &&& f)) + 11 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 2 * (e ^^^  ~~~(d ||| f)) + 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~( ~~~d &&& (e ^^^ f)) + 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 * ((d ||| e) &&& (e ^^^ f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 *  ~~~( ~~~d ||| (e &&& f)) + 1 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (e ||| (d &&&  ~~~f)) - 1 *  ~~~(d ^^^ (e &&& f)) + 2 * d + 1 *  ~~~(d |||  ~~~f) + 3 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * (f &&&  ~~~(d &&& e)) + 3 * (e ^^^ (d ||| (e &&& f))) - 11 * (e &&&  ~~~f) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 6 * (f ^^^ (d |||  ~~~e)) + 1 * (e &&& f) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 2 * ( ~~~f ||| (d ^^^ e)) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 5 * (f &&& (d ^^^ e)) - 2 * (f ^^^ (d ||| (e &&& f))) - 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 1 * (f ^^^ (d ||| e)) + 5 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 11 * (e |||  ~~~(d |||  ~~~f)) - 2 *  ~~~(e &&& f) - 7 * (f ^^^ (d &&& e)) - 11 *  ~~~(e ||| f) + 1 * (d ||| (e &&& f)) - 7 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 * (d ^^^ (e ||| f)) + 2 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) + 1 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 4 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 1 *  ~~~(d ||| ( ~~~e &&& f)) + 5 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 5 * (f ^^^  ~~~(d &&&  ~~~e)) - 11 * (e |||  ~~~(d ||| f)) - 5 * (d ^^^ (e ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 11 * ( ~~~d &&& (e ^^^ f)) + 4 * (e ^^^ (d ||| f)) + 3 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 7 *  ~~~(d ||| (e ^^^ f)) - 1 *  ~~~(e &&&  ~~~f) - 7 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 28 *  ~~~(d ||| (e ||| f)) - 2 *  ~~~(d ||| ( ~~~e ||| f)) - 14 *  ~~~( ~~~d ||| (e ||| f)) + 21 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 8 * ( ~~~d &&& (e &&& f)) - 7 * (d &&& ( ~~~e &&& f)) - 11 * (d &&& (e &&& f)) =  - 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 4 * (f ^^^  ~~~( ~~~d &&& (e ||| f)))

theorem sle_and_min_proof : sle_and_min_before ⊑ sle_and_min_after

theorem alive_constant_fold_10: forall (w : Nat), TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt w (0)) %v0
  dsl_ret %v1
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v000 := unit: ;
  %v001 := op:const (Bitvec.ofInt w (0)) %v000;
  %v100 := pair:%v001 %v001;
  %v101 := op:add w %v100;
  %v110 := pair:%v101 %v001;
  %v111 := op:add w %v110;
  %v120 := pair:%v111 %v001;
  %v121 := op:add w %v120;
  %v130 := pair:%v121 %v001;
  %v131 := op:add w %v130;
  %v140 := pair:%v131 %v001;
  %v141 := op:add w %v140;
  %v150 := pair:%v141 %v001;
  %v151 := op:add w %v150;
  %v160 := pair:%v151 %v001;
  %v161 := op:add w %v160;
  %v170 := pair:%v161 %v001;
  %v171 := op:add w %v170;
  %v180 := pair:%v171 %v001;
  %v181 := op:add w %v180;
  %v190 := pair:%v181 %v001;
  %v191 := op:add w %v190
  dsl_ret %v191
  ]

theorem test_shl__nuw_is_safe_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ofBool (x_1 &&& 1073741822#32 == 0#32) = 1#1 →
    2#32 ≥ ↑32 ∨
        True ∧ (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)).msb = true ∨
          zeroExtend 64 (x_1 <<< 2#32 &&& BitVec.ofInt 32 (-8)) ≥ ↑64 →
      False

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

theorem PR60818_eq_commuted_proof : PR60818_eq_commuted_before ⊑ PR60818_eq_commuted_after

theorem lshrugt_02_15_exact_proof : lshrugt_02_15_exact_before ⊑ lshrugt_02_15_exact_after

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

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

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

theorem or_not_and_commute4_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true → False

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

theorem sel_zext_proof : sel_zext_before ⊑ sel_zext_after

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

theorem test21_proof : test21_before ⊑ test21_after

theorem test8_thm (e : IntW 32) :
  icmp IntPred.ugt (LLVM.udiv (const? 32 4) e) (const? 32 3) ⊑ icmp IntPred.ult e (const? 32 2)

theorem rem_euclid_pow2_true_arm_folded_proof : rem_euclid_pow2_true_arm_folded_before ⊑ rem_euclid_pow2_true_arm_folded_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_1_logical_after

theorem e_2204 :
    4 * (e ^^^ (d ||| (e &&& f))) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 11 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 *  ~~~(d |||  ~~~e) - 2 * (d |||  ~~~e) - 7 * ((d ^^^ e) &&& (d ^^^ f)) - 1 *  ~~~(d &&&  ~~~d) + 5 * (e ^^^  ~~~(d &&& (e &&& f))) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) - 6 *  ~~~(d ^^^ ( ~~~e ||| f)) - 2 * (f ^^^ (d &&& ( ~~~e ||| f))) + 5 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 5 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 6 * (e ^^^  ~~~(d ||| (e &&& f))) - 1 * ((d &&& e) |||  ~~~(e ||| f)) + 5 *  ~~~(d |||  ~~~f) - 11 *  ~~~(d ^^^ (e ||| f)) + 1 * (e |||  ~~~(d ^^^ f)) + 11 * (e &&&  ~~~f) - 6 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 3 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 6 * (d &&& (e ||| f)) + 7 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (e ^^^ (d |||  ~~~f)) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 5 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 11 * (f ^^^  ~~~(d &&& (e &&& f))) - 5 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 *  ~~~(d &&& e) - 7 * (d &&& f) - 1 * (e ^^^  ~~~(d &&& f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 1 * (d &&&  ~~~e) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 2 *  ~~~(e ||| f) + 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 2 *  ~~~(d &&& ( ~~~e ||| f)) - 11 *  ~~~(d ||| (e ||| f)) - 40 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) - 11 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 6 * ( ~~~d &&& ( ~~~e &&& f)) + 15 * ( ~~~d &&& (e &&& f)) + 21 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 3 * (d ||| ( ~~~e &&& f)) - 1 * ((d |||  ~~~e) &&& (e ^^^ f))

theorem select_icmp_ne_pow2_thm (e : IntW 8) :
  select (icmp IntPred.ne (LLVM.and e (const? 8 4)) (const? 8 0)) (LLVM.xor e (const? 8 4)) e ⊑
    LLVM.and e (const? 8 (-5))

theorem t2_proof : t2_before ⊑ t2_after

theorem ExtEq.trans {Γ Δ Ξ : Context Ty} : Γ.ExtEq Δ → Δ.ExtEq Ξ → Γ.ExtEq Ξ

theorem lshrult_01_02_proof : lshrult_01_02_before ⊑ lshrult_01_02_after

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

theorem test7_proof : test7_before ⊑ test7_after

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

theorem addhshlhsdivhscalar1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-64) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-64) == -1) = true ∨ 6#8 ≥ ↑8) →
    (64#8 == 0 || 8 != 1 && x == intMin 8 && 64#8 == -1) = true → False

theorem FSM.not_eq (a : FSM arity) : (~~~ a) = composeUnaryAux FSM.not a

theorem e_1490 :
     - 11 * t + 5 *  ~~~(z &&&  ~~~t) - 3 *  ~~~t + 3 * (z ||| t) - 7 *  ~~~z - 1 *  ~~~(z &&& t) - 11 *  ~~~(z &&&  ~~~z) + 2 * (z |||  ~~~t) + 22 *  ~~~(z |||  ~~~t) + 10 * (z &&&  ~~~t) + 12 * (z &&& t) =  - 15 *  ~~~(z ||| t)

theorem test26_proof : test26_before ⊑ test26_after

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

theorem land_lor_left2_proof : land_lor_left2_before ⊑ land_lor_left2_after

theorem e_1810 :
     - 1 * (c ^^^  ~~~(a &&&  ~~~b)) + 4 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 11 * ( ~~~(a ||| b) |||  ~~~(b ^^^ c)) + 7 * (c ^^^  ~~~(a &&& (b &&& c))) + 2 * (a ||| ( ~~~b &&& c)) - 2 * (b |||  ~~~(a ^^^ c)) + 4 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 2 * (a &&& c) + 2 *  ~~~(a ^^^ (b ||| c)) + 2 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 3 * (b &&& (a ||| c)) + 1 * (b ^^^  ~~~(a &&& (b &&& c))) - 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 11 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 5 *  ~~~(a &&&  ~~~b) - 6 * (a ||| (b &&& c)) + 4 * (c |||  ~~~(a ||| b)) + 3 *  ~~~(a ||| ( ~~~b &&& c)) - 11 *  ~~~(a &&&  ~~~c) - 3 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 1 * ((a &&& c) |||  ~~~(b ||| c)) + 2 * (c ^^^ (a ||| (b &&& c))) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 1 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) - 11 * (a ||| (b ||| c)) + 11 * (b |||  ~~~(a |||  ~~~c)) + 1 * (b ^^^ (a &&&  ~~~c)) + 7 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 7 * ((a |||  ~~~b) &&& (b ^^^ c)) - 2 * (c ^^^ (a &&& (b ||| c))) - 18 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~(a ||| ( ~~~b ||| c)) - 9 *  ~~~( ~~~a ||| (b ||| c)) - 22 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 28 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * ( ~~~a &&& (b &&& c)) + 25 * (a &&& ( ~~~b &&& c)) - 22 * (a &&& (b &&& c)) =  - 1 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 *  ~~~(a ||| (b &&& c))

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

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

theorem test55_thm (e : IntW 32) :
  sext 64 (LLVM.and (LLVM.or (trunc 16 e) (const? 16 (-32574))) (const? 16 (-25350))) ⊑
    sext 64 (LLVM.or (LLVM.and (trunc 16 e) (const? 16 7224)) (const? 16 (-32574)) { «disjoint» := true })

theorem or_and_shifts2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 4#32 ≥ ↑32) →
    3#32 ≥ ↑32 ∨ 4#32 ≥ ↑32 ∨ True ∧ (x <<< 3#32 &&& 896#32 &&& (x >>> 4#32 &&& 7#32) != 0) = true → False

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

theorem e_282 :
     - 7 * (x ||| y) + 11 * (x |||  ~~~y) - 3 *  ~~~(x &&& y) - 8 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) - 8 * (x &&&  ~~~y) - 4 * (x &&& y) =  - 7 * (x ^^^ y)

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

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

theorem land_land_right2_proof : land_land_right2_before ⊑ land_land_right2_after

theorem OrZextOr_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ||| 3#3) ||

theorem different_size_zext_zext_slt_thm.extracted_1._1 : ∀ (x : BitVec 4) (x_1 : BitVec 7),
  ofBool (zeroExtend 25 x_1 <ₛ zeroExtend 25 x) = ofBool (x_1 <ᵤ zeroExtend 7 x)

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

theorem test11b_proof : test11b_before ⊑ test11b_after

theorem lshrugt_02_08_proof : lshrugt_02_08_before ⊑ lshrugt_02_08_after

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

theorem ne_smax4_proof : ne_smax4_before ⊑ ne_smax4_after

theorem t7_ashr_proof : t7_ashr_before ⊑ t7_ashr_after

theorem shl_add_add_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(2#8 ≥ ↑8 ∨ 2#8 ≥ ↑8) → ¬2#8 ≥ ↑8 → x_1 <<< 2#8 + (x <<< 2#8 + 48#8) = (x + x_1) <<< 2#8 + 48#8

theorem not_not_false_proof : not_not_false_before ⊑ not_not_false_after

theorem test_sub_nuw_nsw__none_are_safe_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 1#32) = 1#1 → 2147483647#32 = BitVec.ofInt 32 (-2147483648) - x

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

theorem icmp_sgt1_proof : icmp_sgt1_before ⊑ icmp_sgt1_after

theorem icmp_equality_test_swift_optional_pointers_proof : icmp_equality_test_swift_optional_pointers_before ⊑ icmp_equality_test_swift_optional_pointers_after

@[simp] theorem get_map (xs : HVector A as) (f : (a : α) → A a → B a) :
    (xs.map f).get i = f _ (xs.get i)

theorem lshrugt_01_14_exact_proof : lshrugt_01_14_exact_before ⊑ lshrugt_01_14_exact_after

theorem xor_of_icmps_commute_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (0#64 <ₛ x) ^^^ ofBool (x == 1#64) = ofBool (1#64 <ₛ x)

theorem add_mask_ashr27_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(27#32 ≥ ↑32 ∨ 27#32 ≥ ↑32) →
    27#32 ≥ ↑32 ∨ 27#32 ≥ ↑32 ∨ True ∧ (x.sshiftRight' 27#32 &&& 8#32).saddOverflow (x.sshiftRight' 27#32) = true →
      False

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

theorem icmp_sgt8_proof : icmp_sgt8_before ⊑ icmp_sgt8_after

theorem reduce_xor_common_op_commute0_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  x_2 ^^^ x_1 ^^^ x ||

theorem select_1_thm.extracted_1._15 : ∀ (x x_1 : BitVec 8) (x_2 x_3 : BitVec 1),
  ¬x_3 = 1#1 → ¬x_2 = 1#1 → x ^^^ 123#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-124)

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

theorem main4b_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 7))
        (icmp IntPred.ne (LLVM.and e (const? 32 16)) (const? 32 0)) (const? 1 0))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 23)) (const? 32 23))

@[simp] lemma CNFA.autEq_stateMax : autEq.m.stateMax = 1

theorem e_1933 :
    7 * ((a ||| b) &&& (b ^^^ c)) + 3 * ( ~~~a ||| (b ||| c)) - 1 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 6 * ((a &&& b) ^^^ (b ||| c)) + 4 * (a ^^^ c) - 5 * (b |||  ~~~(a ^^^ c)) - 1 * (c ^^^ (a ||| (b ||| c))) - 1 * ((a &&& b) ||| (b ^^^ c)) - 6 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * ( ~~~a &&& ( ~~~b ||| c)) + 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 5 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) - 2 * (b &&& c) + 2 *  ~~~(a &&& b) + 1 *  ~~~(a ^^^ (b ||| c)) + 1 * (c ^^^  ~~~(a &&& ( ~~~b &&& c))) + 11 * ((a ^^^ b) &&& (a ^^^ c)) + 11 *  ~~~(a ^^^ c) - 1 * (c ^^^  ~~~(a |||  ~~~b)) + 4 * (c ^^^ (a &&&  ~~~b)) + 1 * (b ^^^ (a &&& (b ^^^ c))) - 2 * ((b &&&  ~~~c) |||  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 6 * (c ^^^  ~~~( ~~~a &&& (b ||| c))) - 3 * (c |||  ~~~(a ||| b)) + 2 * ((a &&& b) |||  ~~~(b |||  ~~~c)) + 1 * ( ~~~a ||| ( ~~~b &&& c)) - 1 * (a ^^^ ( ~~~b ||| c)) + 1 * (a ||| ( ~~~b ||| c)) - 7 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 5 * ( ~~~a &&& (b ^^^ c)) + 5 * (b ^^^  ~~~(a ||| ( ~~~b &&& c))) - 7 * (a &&& (b ||| c)) + 4 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 4 * (b ||| (a &&&  ~~~c)) + 3 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 1 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 2 * (b ^^^ ( ~~~a ||| (b ^^^ c))) - 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 1 * (c &&& (a |||  ~~~b)) - 11 * (b ^^^ c) + 7 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 2 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 11 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 5 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 2 *  ~~~(a ||| (b ||| c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) - 2 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) - 18 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) = 16 *  ~~~( ~~~a ||| (b ||| c))

theorem testi16i8_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬15#16 ≥ ↑16 → ¬ofBool (-1#16 <ₛ x) = 1#1 → truncate 8 (x.sshiftRight' 15#16) ^^^ 27#8 = BitVec.ofInt 8 (-28)

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

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

theorem e_1283 :
     - 11 * t - 6 *  ~~~t + 4 *  ~~~(z &&&  ~~~t) - 7 *  ~~~z - 1 *  ~~~(z ^^^ t) - 6 * (z ^^^ t) + 10 *  ~~~(z ||| t) + 12 * (z &&&  ~~~t) + 8 * (z &&& t) =  - 20 *  ~~~(z |||  ~~~t)

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

theorem lshr_sext_i1_to_i128_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬42#128 ≥ ↑128 → ¬x = 1#1 → signExtend 128 x >>> 42#128 = 0#128

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

@[simp]
lemma accepts_cast {M : NFA α σ} (h : σ = ς): (h ▸ M).accepts = M.accepts

theorem and_not_or_or_not_or_xor_commute2_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬((x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true ∨
        (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true) →
    (x_2 == 0 || 32 != 1 && 42#32 == intMin 32 && x_2 == -1) = true → False

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

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬1#32 ≥ ↑32 → (x_1 ||| x <<< 1#32) &&& 1#32 = x_1 &&& 1#32

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

theorem trunc_shl_ashr_var_thm.extracted_1._2 : ∀ (x x_1 : BitVec 64),
  ¬(x ≥ ↑64 ∨ 2#64 ≥ ↑64) →
    ¬(x ≥ ↑64 ∨ 2#32 ≥ ↑32) → truncate 32 (x_1.sshiftRight' x <<< 2#64) = truncate 32 (x_1.sshiftRight' x) <<< 2#32

theorem or_basic_thm (e : IntW 16) :
  LLVM.or (icmp IntPred.ne (trunc 8 e) (const? 8 127))
      (icmp IntPred.ne (LLVM.and e (const? 16 (-256))) (const? 16 17664)) ⊑
    icmp IntPred.ne e (const? 16 17791)

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

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

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

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

theorem badimm2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(6#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 6#8 == truncate 8 (x >>> 8#16)) = 1#1 →
      6#8 ≥ ↑8 ∨ 8#16 ≥ ↑16 ∨ True ∧ zeroExtend 16 (truncate 8 (x >>> 8#16)) ≠ x >>> 8#16 → False

theorem test14_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.and e (const? 8 (-128))) (const? 8 0) ⊑ icmp IntPred.slt e (const? 8 0)

theorem bitwise_or_bitwise_or_icmps_proof : bitwise_or_bitwise_or_icmps_before ⊑ bitwise_or_bitwise_or_icmps_after

theorem icmp_slt_0_and_icmp_sge_neg1_i32_proof : icmp_slt_0_and_icmp_sge_neg1_i32_before ⊑ icmp_slt_0_and_icmp_sge_neg1_i32_after

theorem lshr_mul_times_5_div_4_exact_thm (e : IntW 32) :
  lshr (mul e (const? 32 5) { «nsw» := true, «nuw» := false }) (const? 32 2) { «exact» := true } ⊑
    add e (lshr e (const? 32 2) { «exact» := true }) { «nsw» := true, «nuw» := false }

theorem udiv_illegal_type_proof : udiv_illegal_type_before ⊑ udiv_illegal_type_after

theorem ashrsgt_03_03_exact_proof : ashrsgt_03_03_exact_before ⊑ ashrsgt_03_03_exact_after

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

theorem lshr_add_exact_thm (e e_1 : IntW 8) :
  lshr (LLVM.and e_1 (const? 8 (-4))) (LLVM.and e (const? 8 2)) ⊑
    lshr (LLVM.and e_1 (const? 8 (-4))) (LLVM.and e (const? 8 2)) { «exact» := true }

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

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

theorem XorZextXor_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ^^^ 3#3) ^^^ 12#5 = zeroExtend 5 x ^^^ 15#5

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

theorem negate_sext_proof : negate_sext_before ⊑ negate_sext_after

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

theorem lshrugt_03_05_proof : lshrugt_03_05_before ⊑ lshrugt_03_05_after

theorem test_sext4_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → x ^^^ 1#1 = 1#1 → -1#32 = signExtend 32 1#1

theorem test_sub__nsw_is_safe_proof : test_sub__nsw_is_safe_before ⊑ test_sub__nsw_is_safe_after

theorem or_xor_tree_0001_proof : or_xor_tree_0001_before ⊑ or_xor_tree_0001_after

theorem trunc_shl_zext_32_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬4#16 ≥ ↑16 → ¬4#32 ≥ ↑32 → zeroExtend 32 (truncate 16 x <<< 4#16) = x <<< 4#32 &&& 65520#32

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

theorem no_shift_xor_multiuse_or_proof : no_shift_xor_multiuse_or_before ⊑ no_shift_xor_multiuse_or_after

@[simp]
lemma autMsb_states : s ∈ CNFA.autMsbSet.m.states ↔ s < 2

theorem e_1813 :
     - 3 *  ~~~(a &&&  ~~~b) - 7 *  ~~~(a ^^^ (b &&& c)) + 11 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 3 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) - 2 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 2 * (b &&&  ~~~(a ^^^ c)) + 4 * ( ~~~b ||| (a ^^^ c)) + 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 7 * (b ^^^ (a &&& c)) - 5 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 3 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 11 * (c ||| (a &&& b)) + 1 * ((a ^^^ b) &&& (a ^^^ c)) - 6 * (c ^^^ (a ||| (b ||| c))) + 1 * ((a &&& c) |||  ~~~(b ||| c)) + 1 *  ~~~(a ^^^ ( ~~~b &&& c)) + 3 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * ( ~~~a &&& (b ^^^ c)) - 6 *  ~~~(a &&& b) - 2 * ((a &&& b) |||  ~~~(b ||| c)) + 1 * ( ~~~b &&& (a ^^^ c)) - 3 * (a &&& b) + 1 *  ~~~(a ^^^ (b ^^^ c)) - 11 * ((a &&& b) ^^^  ~~~(a ^^^ (b &&& c))) + 5 * (c ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 5 * ( ~~~a ||| ( ~~~b ||| c)) - 1 * ( ~~~c ||| (a ^^^ b)) + 11 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 6 * (c ^^^ ( ~~~a ||| (b ||| c))) - 2 * (b ^^^  ~~~(a &&& c)) + 1 * (c ^^^ ( ~~~a ||| (b &&& c))) - 1 * (a ||| (b ||| c)) + 10 *  ~~~(a ||| (b ||| c)) + 25 *  ~~~(a ||| ( ~~~b ||| c)) + 6 *  ~~~( ~~~a ||| (b ||| c)) + 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 36 * ( ~~~a &&& ( ~~~b &&& c)) + 25 * ( ~~~a &&& (b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) + 33 * (a &&& (b &&& c)) = 1 *  ~~~(b |||  ~~~c)

theorem zext_sext_add_icmp_slt_1_rhs_not_const_proof : zext_sext_add_icmp_slt_1_rhs_not_const_before ⊑ zext_sext_add_icmp_slt_1_rhs_not_const_after

theorem test4_proof : test4_before ⊑ test4_after

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

@[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 test84_thm (e : IntW 32) :
  trunc 8 (lshr (add e (const? 32 (-16777216)) { «nsw» := true, «nuw» := false }) (const? 32 23) { «exact» := true }) ⊑
    trunc 8 (lshr (add e (const? 32 2130706432)) (const? 32 23))

theorem p0_ult_65536_proof : p0_ult_65536_before ⊑ p0_ult_65536_after

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

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

theorem icmp_eq_sext_eq_zero_proof : icmp_eq_sext_eq_zero_before ⊑ icmp_eq_sext_eq_zero_after

theorem n11_proof : n11_before ⊑ n11_after

@[simp] theorem appendList_eq : Γ ++ tys = Γ ++ ⟨tys⟩

theorem slt_smin4_proof : slt_smin4_before ⊑ slt_smin4_after

theorem test15_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬1#32 ≥ ↑32 →
    ¬(1#32 ≥ ↑32 ∨ True ∧ (8#32).ssubOverflow (x.sshiftRight' 1#32) = true) →
      8#64 - signExtend 64 (x.sshiftRight' 1#32) = signExtend 64 (8#32 - x.sshiftRight' 1#32)

theorem max_of_min_swap_proof : max_of_min_swap_before ⊑ max_of_min_swap_after

theorem mul_constant_eq_nsw_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (mul e_1 (const? 32 6) { «nsw» := true, «nuw» := false })
      (mul e (const? 32 6) { «nsw» := true, «nuw» := false }) ⊑
    icmp IntPred.eq e_1 e

theorem e_443 :
    7 * y - 11 * (x |||  ~~~y) + 2 *  ~~~(x ^^^ y) - 7 *  ~~~y + 2 * (x ||| y) + 11 *  ~~~x + 5 *  ~~~(x ||| y) - 20 *  ~~~(x |||  ~~~y) =  - 16 * (x &&&  ~~~y)

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

theorem sdiv_icmp4_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.sdiv e (const? 64 (-5)) { «exact» := true }) (const? 64 0) ⊑
    icmp IntPred.eq e (const? 64 0)

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

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

theorem t0_thm (e e_1 e_2 e_3 : IntW 8) (e_4 : IntW 1) :
  select (select (LLVM.xor e_4 (const? 1 1)) (icmp IntPred.eq e_3 e_2) (const? 1 0)) e_1 e ⊑
    select (select e_4 (const? 1 1) (icmp IntPred.ne e_3 e_2)) e e_1

theorem e_537 :
    2 *  ~~~(x &&& y) - 7 * y + 4 * (x ^^^ y) - 11 *  ~~~x - 2 * x + 5 * (x ||| y) - 6 *  ~~~(x ^^^ y) + 15 *  ~~~(x ||| y) + 10 * (x &&& y) = 9 * (x &&&  ~~~y) - 7 *  ~~~(x |||  ~~~y)

theorem t3_ult_sgt_neg1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 16#32 <ᵤ 144#32) = 1#1 → ofBool (127#32 <ₛ x_1) = 1#1 → x_1 = x

theorem and_signbit_select_lshr_proof : and_signbit_select_lshr_before ⊑ and_signbit_select_lshr_after

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

theorem e_797 :
     - 6 * (z ||| t) - 1 * t - 7 *  ~~~(z ||| t) + 7 * (z &&&  ~~~t) + 8 * (z &&& t) = 1 * z - 7 *  ~~~z

theorem logic_and_logic_or_6_thm (e e_1 e_2 : IntW 1) :
  select (select e_2 e_1 (const? 1 0)) (const? 1 1) (select e e_2 (const? 1 0)) ⊑
    select e_2 (select e_1 (const? 1 1) e) (const? 1 0)

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

theorem test53_proof : test53_before ⊑ test53_after

theorem zext_nneg_sext_sgt_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (zext 32 e_1 { «nneg» := true }) (sext 32 e) ⊑ icmp IntPred.sgt e_1 e

theorem test_sub_0_Y_ne_0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (0#8 - x != 0#8) = ofBool (x != 0#8)

theorem ult_swap_or_not_max_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != -1#8) = 1#1 → ofBool (x_1 <ᵤ x) = ofBool (x_1 != -1#8)

theorem main6d_logical_proof : main6d_logical_before ⊑ main6d_logical_after

theorem pr51551_2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-7) ||| 1#32).smulOverflow x = true) →
    ofBool ((x_1 &&& BitVec.ofInt 32 (-7) ||| 1#32) * x &&& 1#32 == 0#32) = ofBool (x &&& 1#32 == 0#32)

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

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

theorem test33b_proof : test33b_before ⊑ test33b_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 12#32 == 0#32) ||

@[simp] theorem borrow_zero (x y : BitStream) : (x.borrow y 0) = (!(x 0) && y 0)

theorem test15g_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 8#32 != 0#32) = 1#1 → -1#32 = x ||

theorem ugt_swap_or_not_min_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ult e_1 e) (icmp IntPred.ne e (const? 8 0)) ⊑
    icmp IntPred.ne e (const? 8 0)

theorem sle_swap_or_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == BitVec.ofInt 8 (-128)) ||

theorem ne_210_proof : ne_210_before ⊑ ne_210_after

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

theorem sub_dec_proof : sub_dec_before ⊑ sub_dec_after

theorem n3_constmask_samemask_proof : n3_constmask_samemask_before ⊑ n3_constmask_samemask_after

theorem ashrslt_03_11_proof : ashrslt_03_11_before ⊑ ashrslt_03_11_after

theorem self_EqualUpTo_ofBitVecZext_toBitVec (x : BitStream) :
  EqualUpTo w x (BitStream.ofBitVecZext (x.toBitVec w))

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

theorem t10_shl_nuw_flag_preservation_proof : t10_shl_nuw_flag_preservation_before ⊑ t10_shl_nuw_flag_preservation_after

theorem test11_thm.extracted_1._2 : ∀ (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) →
      truncate 64 (zeroExtend 128 x_1 <<< (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)

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

theorem lshr_shl_demand1_thm (e : IntW 8) :
  LLVM.or (shl (lshr (const? 8 28) e) (const? 8 3)) (const? 8 7) ⊑
    LLVM.or (lshr (const? 8 (-32)) e) (const? 8 7)

theorem e_1917 :
    7 *  ~~~(a ||| (b ^^^ c)) + 4 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) - 3 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 6 * (b ^^^ (a &&&  ~~~c)) - 6 * ((a ||| b) &&& (b ^^^ c)) + 2 * (b &&&  ~~~(a &&&  ~~~c)) - 6 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 6 * (b &&&  ~~~(a &&& c)) + 4 * (b ^^^ (a &&& (b ||| c))) - 6 * (c &&& (a ^^^ b)) + 1 * (b |||  ~~~(a ||| c)) + 4 * (b ^^^  ~~~( ~~~a &&& (b ^^^ c))) + 1 *  ~~~(a &&& ( ~~~b &&& c)) + 5 * ( ~~~b ||| (a ^^^ c)) - 3 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 11 * ((a &&& b) ^^^ (a ^^^ (b &&& c))) + 1 * (a &&& ( ~~~b ||| c)) + 1 *  ~~~( ~~~a &&& (b ||| c)) - 1 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 2 * (c ^^^ (a &&&  ~~~b)) + 4 * (b |||  ~~~(a ^^^ c)) - 7 * (b ^^^ (a |||  ~~~c)) + 7 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) - 1 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 7 * ( ~~~c |||  ~~~(a ^^^ b)) + 3 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * ( ~~~c &&& (a ^^^ b)) - 11 *  ~~~(a ^^^ (b ||| c)) - 1 * (b |||  ~~~(a |||  ~~~c)) - 2 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 11 * ((a &&& b) ^^^ (b |||  ~~~c)) + 11 * (b ^^^  ~~~(a &&& (b &&& c))) + 5 * ((a &&& b) |||  ~~~(b ||| c)) + 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) + 11 * (c ^^^ (a &&& ( ~~~b ||| c))) + 1 * (c |||  ~~~(a |||  ~~~b)) + 4 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) + 5 *  ~~~(a |||  ~~~c) - 7 * (b ^^^  ~~~(a |||  ~~~c)) + 5 * (b ||| (a ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 7 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 2 *  ~~~(a ||| ( ~~~b ||| c)) - 42 *  ~~~( ~~~a ||| (b ||| c)) + 9 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 44 * ( ~~~a &&& ( ~~~b &&& c)) - 10 * ( ~~~a &&& (b &&& c)) - 8 * (a &&& ( ~~~b &&& c)) - 28 * (a &&& (b &&& c)) = 11 *  ~~~(a ||| (b ||| c))

theorem t3_const_after_fold_lshr_shl_ne_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(32#32 - x_1 ≥ ↑32 ∨ x_1 + -1#32 ≥ ↑32) →
    ¬31#32 ≥ ↑32 →
      ofBool (x_2 >>> (32#32 - x_1) &&& x <<< (x_1 + -1#32) != 0#32) = ofBool (x_2 >>> 31#32 &&& x != 0#32)

theorem ashr_not_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬5#8 ≥ ↑8 → (x ^^^ -1#8).sshiftRight' 5#8 = x.sshiftRight' 5#8 ^^^ -1#8

theorem lshr_or_or_no_const_proof : lshr_or_or_no_const_before ⊑ lshr_or_or_no_const_after

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

theorem test13_thm.extracted_1._1 : ∀ (x : BitVec 32),
  3#32 ≥ ↑32 ∨ True ∧ (x >>> 3#32 &&& 1#32).saddOverflow (-1#32) = true → False

theorem t3_singlebit_thm (e e_1 : IntW 32) :
  icmp IntPred.ne
      (LLVM.and (shl e_1 (sub (const? 32 32) e))
        (trunc 32 (lshr (const? 64 65536) (zext 64 (add e (const? 32 (-16)))))))
      (const? 32 0) ⊑
    icmp IntPred.ne (LLVM.and e_1 (const? 32 1)) (const? 32 0)

theorem PR45977_f1_proof : PR45977_f1_before ⊑ PR45977_f1_after

theorem sub_const_add_const_proof : sub_const_add_const_before ⊑ sub_const_add_const_after

theorem urem_i32_c_multiuse_thm (e : IntW 8) :
  add (zext 32 e) (urem (zext 32 e) (const? 32 10)) ⊑
    add (urem (zext 32 e) (const? 32 10)) (zext 32 e) { «nsw» := true, «nuw» := true }

theorem sle_or_not_min_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 != BitVec.ofInt 8 (-128)) ||

theorem masked_or_A_slightly_optimized_thm (e : IntW 32) :
  LLVM.or (icmp IntPred.ult e (const? 32 8)) (icmp IntPred.eq (LLVM.and e (const? 32 39)) e) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 (-40))) (const? 32 0)

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

theorem p_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  True ∧ (x_2 &&& x_1 &&& (x &&& (x_1 ^^^ -1#32)) != 0) = true → False
</all_available_lemmas>

<local_ctx>
import Mathlib.Logic.Function.Iterate

import Mathlib.Tactic.Linarith

import LeanMLIR.Framework

import LeanMLIR.Tactic

import LeanMLIR.ErasedContext

import LeanMLIR.Util

open LeanMLIR

open Ctxt(Var)

namespace ScfFunctor

open TyDenote

class HasTy (d : Dialect) (DenotedTy : Type) [TyDenote d.Ty] [DialectSignature d] where
    ty : d.Ty
    denote_eq : toType ty = DenotedTy := by admit /- proof elided -/

inductive Scf.Op (Op' Ty' : Type) (m') [TyDenote Ty'] [DialectSignature ⟨Op', Ty', m'⟩]
    [DialectDenote ⟨Op', Ty', m'⟩] : Type _
  | coe (o : Op')
  | iterate (k : ℕ) 
  | run (inputty : Ty')  
  | if (inputty retty' : Ty')  
  | for (ty : Ty')
  deriving DecidableEq, Repr

def Scf (d : Dialect) [TyDenote d.Ty] [DialectSignature d] [DialectDenote d] : Dialect where
  Op := Scf.Op d.Op d.Ty d.m
  Ty := d.Ty
  m  := d.m

namespace Scf

section InheritedInstances

variable {d : Dialect} [TyDenote d.Ty] [DialectSignature d] [DialectDenote d]

end InheritedInstances

abbrev LoopBody (t : Type) : Type := Int → t → t

namespace LoopBody

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

def atZero (f : LoopBody t) : t → t := fun v => f 0 v

end LoopBody

namespace LoopBody.IndexInvariant

end LoopBody.IndexInvariant

namespace LoopBody.counterDecorator

end LoopBody.counterDecorator

variable [TyDenote d.Ty] [DialectSignature d] [DialectDenote d]
  [B : HasBool d] [N : HasNat d] [Z : HasInt d]

open Ctxt (Valuation) in

end Scf

namespace Arith

inductive Ty
| int
| bool
| nat
 deriving DecidableEq, Repr

inductive Op
  | add : Op  
  | add_nat : Op  
  | axpy : Op  
  | neg : Op  
  | const : (val : ℤ) → Op
  | const_nat : (val : ℕ) → Op

abbrev Arith : Dialect := {Op, Ty}

end Arith

abbrev ScfArith := Scf Arith

open LeanMLIR.SingleReturnCompat (Com Expr)

@[simp_denote] def cst (n : ℤ) : Expr ScfArith Γ .pure .int  :=
  Expr.mk
    (op := .coe <| .const n)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .nil)
    (regArgs := .nil)

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

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

@[simp_denote] def axpy {Γ : Ctxt _} (a : Var Γ .int) (x : Var Γ .nat) (b: Var Γ .int) :
    Expr ScfArith Γ .pure .int :=
  Expr.mk
    (op := .coe <| .axpy)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .cons x <| .cons b .nil)
    (regArgs := .nil)

@[simp_denote] def neg {Γ : Ctxt _} (a : Var Γ .int) : Expr ScfArith Γ .pure .int :=
  Expr.mk
    (op := .coe <| .neg)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .nil)
    (regArgs := .nil)

@[simp_denote] def iterate {Γ : Ctxt _} (k : Nat) (input : Var Γ Arith.Ty.int)
    (body : Com ScfArith ⟨[.int]⟩ .impure .int) : Expr ScfArith Γ .impure .int :=
  Expr.mk
    (op := .iterate k)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons input .nil)
    (regArgs := HVector.cons body HVector.nil)

@[simp_denote]
def run {Γ : Ctxt _} {t : Arith.Ty} (v : Var Γ t) (body : Com ScfArith ⟨[t]⟩ .impure t) :
    Expr ScfArith Γ .impure t :=
  Expr.mk
    (op := .run t)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons v .nil)
    (regArgs := HVector.cons body <| HVector.nil)

@[simp_denote] def for_ {Γ : Ctxt Arith.Ty} {t : Arith.Ty}
    (start step : Var Γ Arith.Ty.int)
    (niter : Var Γ Arith.Ty.nat) (v : Var Γ t) (body : Com ScfArith ⟨[.int, t]⟩ .impure t) :
      Expr ScfArith Γ .impure t :=
  Expr.mk
    (op := .for t)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons start <| .cons step <| .cons niter <| .cons v .nil)
    (regArgs := HVector.cons body <| HVector.nil)

namespace ForAddToMul

def lhs (vincrement : ℤ) : Com ScfArith ⟨[  .nat,   .int]⟩ .impure .int :=
    Com.letPure (cst 0) <|
    Com.letPure  (cst 1) <|
    Com.var (for_ (t := .int)
                        ⟨  1, rfl⟩
                        ⟨  0, rfl⟩
                        ⟨  2, rfl⟩
                        ⟨  3, rfl⟩ (
      Com.letPure (cst vincrement) <|
      Com.letPure (add ⟨0, rfl⟩ ⟨2, rfl⟩) 
      <| Com.ret ⟨0, rfl⟩)) <|
  Com.ret ⟨0, rfl⟩

def rhs (vincrement : ℤ) : Com ScfArith ⟨[  .nat,   .int]⟩ .pure .int :=
  Com.var (cst vincrement) <|
  Com.var (axpy ⟨0, rfl⟩ ⟨1, rfl⟩ ⟨2, rfl⟩) <|
  Com.ret ⟨0, rfl⟩

open Scf in

open Arith in
</local_ctx>

<target_theorem>
theorem correct : Com.denote (lhs v0) = Com.denote (rhs v0) :=
</target_theorem>

