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>
Vector in Init.Data.Vector.Basic
Fin in Init.Prelude
String in Init.Prelude
Unit in Init.Prelude
List in Init.Prelude
Field in Mathlib.Algebra.Field.Defs
Bool in Init.Prelude
DecidableEq in Init.Prelude
FinEnum in Mathlib.Data.FinEnum
Hashable in Init.Prelude
Sum in Init.Core
Sum.elim in Init.Data.Sum.Basic
Sum.inl in Init.Core
Sum.inr in Init.Core
Nat in Init.Prelude
Repr in Init.Data.Repr
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Nat.max in Init.Data.Nat.Basic
Nat.min in Init.Data.Nat.Basic
BitVec in Init.Prelude
BitVec.ofBool in Init.Data.BitVec.Basic
BitVec.ofNat in Init.Prelude

syntax "min" : MLIR.Pretty.uniform_op

macro_rules
  | `(mlir_op| $res:mlir_op_operand = const ($x)
      $[: $outer_type]? ) => do
      let outer_type ← outer_type.getDM `(mlir_type| _)
      `(mlir_op| $res:mlir_op_operand = "const"()
          {val = $x:num : $outer_type} : ($outer_type) -> ($outer_type) )

macro_rules
  | `(mlir_op| $res:mlir_op_operand = li ($x)
     $[: $outer_type]?  ) => do
      let outer_type ← outer_type.getDM `(mlir_type| _ )
      `(mlir_op| $res:mlir_op_operand = "li"()
          {imm = $x:num : $outer_type } : ($outer_type) -> ($outer_type))

macro_rules
| `(mlir_op| $res:mlir_op_operand = $op1:MLIR.Pretty.RV.opWithImmediate $reg1 , $x : $t)  => do
    let some opName := MLIR.EDSL.Pretty.extractOpName op1.raw
      | Macro.throwUnsupported
    `(mlir_op| $res:mlir_op_operand = $opName ($reg1) {imm = $x:num : $t} : ($t) -> ($t) )

macro_rules
| `(mlir_op| $res:mlir_op_operand = $op1:MLIR.Pretty.RV.opWithShamt $reg1 , $x  : $t )  => do
    let some opName := MLIR.EDSL.Pretty.extractOpName op1.raw
      | Macro.throwUnsupported
    `(mlir_op| $res:mlir_op_operand = $opName ($reg1) {shamt = $x:num : $t}  : ($t) -> ($t) )

def composeBinaryAux'
    (p : FSM Bool)
    (qtrue : FSM α)
    (qfalse : FSM α) :
    FSM α :=
  p.compose (α)
    (λ _ => α)
    (λ _ i => i)
    (λ b => match b with
      | true => qtrue
      | false => qfalse)

structure FSM (arity : Type) : Type 1 where
   
  ( α  : Type )
  [ i : FinEnum α ]
  [ h : Hashable α ]
  [ dec_eq : DecidableEq α ]
   
  ( initCarry : α → Bool )
   
  outputCirc : Circuit (α ⊕ arity)
  nextStateCirc : α → Circuit (α ⊕ arity)

inductive Circuit (α : Type u) : Type u
  | tru : Circuit α
  | fals : Circuit α
   
  | var : (positive: Bool) → α → Circuit α
  | and : Circuit α → Circuit α → Circuit α
  | or : Circuit α → Circuit α → Circuit α
  | xor : Circuit α → Circuit α → Circuit α
deriving Repr, DecidableEq

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

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 latchImmediate (initVal : Bool) : FSM Bool where
  α := Unit
  initCarry := fun _ => initVal
  outputCirc :=
    let xval := Circuit.var true (inr false)
    let control := Circuit.var true (inr true)
    let state := Circuit.var true (inl ())
    Circuit.ite control xval state
  nextStateCirc := fun () =>
    let xval := Circuit.var true (inr false)
    let control := Circuit.var true (inr true)
    let state := Circuit.var true (inl ())
    Circuit.ite control xval state

def ite (cond t f : Circuit α) : Circuit α :=
  (cond &&& t) ||| (~~~ cond &&& f)

structure TermFSM (wcard tcard bcard ncard icard pcard : Nat) (t : Nondep.Term) where
  toFsmZext : FSM (StateSpace wcard tcard bcard ncard icard pcard)
  width : NatFSM wcard tcard bcard ncard icard pcard t.width

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

inductive StateSpace (wcard tcard bcard ncard icard pcard : Nat)
| widthVar (v : Fin wcard)
| termVar (v : Fin tcard)
| predVar (v : Fin pcard)
| boolVar (v : Fin bcard)
deriving DecidableEq, Repr, Hashable

inductive Term
| ofNat (w : WidthExpr) (n : Nat) : Term
| var (v : Nat) (w : WidthExpr) : Term
| add (w : WidthExpr) (a b : Term) : Term
| zext (a : Term) (wnew : WidthExpr) : Term
| setWidth (a : Term) (wnew : WidthExpr) : Term
| sext (a : Term) (wnew : WidthExpr) : Term
| bor (w : WidthExpr) (a b : Term) : Term
| band (w : WidthExpr) (a b : Term) : Term
| bxor (w : WidthExpr) (a b : Term) : Term
| bnot (w : WidthExpr)  (a : Term) : Term
| boolVar (v : Nat) : Term
| boolConst (b : Bool) : Term
| shiftl (w : WidthExpr) (a : Term) (k : Nat) : Term
| bvOfBool (b : Term) : Term
| binWidthRel (k : WidthBinaryRelationKind) (wa wb : WidthExpr) : Term
| binRel (k : BinaryRelationKind) (w : WidthExpr)
    (a : Term) (b : Term) : Term
| or (p1 p2 : Term) : Term
| and (p1 p2 : Term) : Term
| pvar (v : Nat) : Term
| boolBinRel (k : BoolBinaryRelationKind)
    (a b : Term) : Term
deriving DecidableEq, Inhabited, Repr, Lean.ToExpr

inductive WidthExpr where
| const : Nat → WidthExpr
| var : Nat → WidthExpr
| max : WidthExpr → WidthExpr → WidthExpr
| min : WidthExpr → WidthExpr → WidthExpr
| addK : WidthExpr → Nat → WidthExpr
| kadd : Nat → WidthExpr → WidthExpr
deriving Inhabited, Repr, Hashable, DecidableEq, Lean.ToExpr

def Term.width (t : Term) : WidthExpr :=
  match t with

| .ofNat w _n => w
  | .var _v w => w
  | .add w _a _b => w
  | .zext _a wnew => wnew
  | .setWidth _a wnew => wnew
  | .sext _a wnew => wnew
  | .bor w _a _b => w
  | .band w _a _b => w
  | .bxor w _a _b => w
  | .bnot w _a => w
  | .boolVar _v => WidthExpr.const 1 
  | .boolConst _b => WidthExpr.const 1
  | .shiftl w _a _k => w
  | .bvOfBool _b => WidthExpr.const 1
  | binWidthRel _k wa wb => WidthExpr.const 0
  | binRel _k w _a _b => w
  | or _p1 _p2 => WidthExpr.const 0
  | and _p1 _p2 => WidthExpr.const 0
  | pvar _v => WidthExpr.const 0
  | boolBinRel _k _a _b => WidthExpr.const 0

inductive WidthExpr where
| const : Nat → WidthExpr
| var : Nat → WidthExpr
| max : WidthExpr → WidthExpr → WidthExpr
| min : WidthExpr → WidthExpr → WidthExpr
| addK : WidthExpr → Nat → WidthExpr
| kadd : (k : Nat) → (v : WidthExpr) → WidthExpr
deriving Inhabited, Repr, Hashable, DecidableEq, Lean.ToExpr

structure HNatFSMToBitstream {wcard : Nat} {v : WidthExpr wcard} {tcard : Nat} {bcard : Nat} {pcard : Nat}
   (fsm : NatFSM wcard tcard bcard ncard icard pcard (.ofDep v)) : Prop where
  heq :
    ∀ (wenv : Fin wcard → Nat)
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream),
    (henv : HWidthEnv fsmEnv wenv) →
      fsm.toFsm.eval fsmEnv =
      BitStream.ofNatUnary (v.toNat wenv)

def WidthExpr.toNat (e : WidthExpr wcard) (env : WidthExpr.Env wcard) : Nat :=
  match e with
  | .const n => n
  | .var v => env v
  | .min v w => Nat.min (v.toNat env) (w.toNat env)
  | .max v w => Nat.max (v.toNat env) (w.toNat env)
  | .addK v k => v.toNat env + k
  | .kadd k v => k + v.toNat env

inductive WidthExpr (wcard : Nat) : Type
| const (n : Nat) :  WidthExpr wcard
| var : (v : Fin wcard) → WidthExpr wcard
| min : (v w : WidthExpr wcard) → WidthExpr wcard
| max : (v w : WidthExpr wcard) → WidthExpr wcard
| addK : (v : WidthExpr wcard) → (k : Nat) → WidthExpr wcard
| kadd : (k : Nat) → (v : WidthExpr wcard) → WidthExpr wcard

abbrev WidthExpr.Env (wcard : Nat) : Type :=
  Fin wcard → Nat

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

structure HPredicateEnv {wcard tcard bcard ncard icard pcard : Nat}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (penv : Fin pcard → Prop) : Prop where
    heq_width : ∀ (v : Fin pcard),
      fsmEnv (StateSpace.predVar v) = BitStream.ofProp (penv v)

def BitStream : Type := Nat → Bool

abbrev ofNatUnary (n : Nat) : BitStream :=
  fun i => decide (i < n)

structure HPredFSMToBitStream {pcard : Nat}
  {tctx : Term.Ctx wcard tcard}
  {p : Term bcard ncard icard pcard tctx .prop}
  (fsm : TermFSM wcard tcard bcard ncard icard pcard
    (.ofDepTerm p)) : Prop where
  heq :
    ∀ {wenv : WidthExpr.Env wcard}
      (benv : Term.BoolEnv bcard)
      (nenv : Term.NatEnv ncard)
      (ienv : Term.IntEnv icard)
      (penv : Predicate.Env pcard) (tenv : tctx.Env wenv)
      (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream),
      (htenv : HTermEnv fsmEnv tenv benv) →
      (hpenv : HPredicateEnv fsmEnv penv) →
        p.toBV benv nenv ienv penv tenv  ↔ (fsm.toFsmZext.eval fsmEnv = .negOne)

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

def Term.BoolEnv (bcard : Nat) : Type := Fin bcard → Bool

def Term.IntEnv (icard : Nat) : Type := Fin icard → Nat

structure HTermFSMToBitStream {w : WidthExpr wcard}
  {tctx : Term.Ctx wcard tcard}
  {t : Term bcard ncard icard pcard tctx (.bv w)}
  (fsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm t)) : Prop where
  heq :
    ∀ {wenv : WidthExpr.Env wcard}
      (benv : Term.BoolEnv bcard)
      (nenv : Term.NatEnv ncard)
      (ienv : Term.IntEnv icard)
      (penv : Predicate.Env pcard) (tenv : tctx.Env wenv)
      (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream),
      (henv : HTermEnv fsmEnv tenv benv) →
        fsm.toFsmZext.eval fsmEnv =
        BitStream.ofBitVecZext (t.toBV benv nenv ienv penv tenv)

def Predicate.Env (pcard : Nat) : Type :=
  Fin pcard → Prop

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

structure HTermEnv {wcard tcard bcard : Nat}
    {wenv : Fin wcard → Nat} {tctx : Term.Ctx wcard tcard}
    (fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream)
    (tenv : tctx.Env wenv)
    (benv : Term.BoolEnv bcard) : Prop
  extends HWidthEnv fsmEnv wenv where
    heq_term : ∀ (v : Fin tcard),
      fsmEnv (StateSpace.termVar v) = BitStream.ofBitVecZext (tenv v)
    heq_bool : ∀ (v : Fin bcard),
      fsmEnv (StateSpace.boolVar v) = BitStream.ofBool (benv v)

noncomputable def BitStream.ofBool (b : Bool) : BitStream := fun _i => b

abbrev Term.Ctx.Env
  (tctx : Term.Ctx wcard tcard)
  (wenv : WidthExpr.Env wcard) :=
  (v : Fin tcard) → BitVec ((tctx v).toNat wenv)

abbrev ofBitVecZext {w} (x : BitVec w) : BitStream :=
  fun i => x.getLsbD i

def Term.NatEnv (ncard : Nat) : Type := Fin ncard → Nat

def Term.toBV {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (penv : Predicate.Env pcard)
    (tenv : tctx.Env wenv)
    (t : Term bcard ncard icard pcard tctx k) : k.denote wenv :=
match t with
| .ofNat w n => BitVec.ofNat (w.toNat wenv) n
| .boolConst b => b
| .var v => tenv.get v.1 v.2
| .add (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a + b
| .zext a v => (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)
| .setWidth a v => (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)
| .sext a v => (a.toBV benv nenv ienv penv tenv).signExtend (v.toNat wenv)
| .bor a b (w := w) =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a ||| b
| .band (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a &&& b
| .bxor (w := w) a b =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    let b : BitVec (w.toNat wenv) := (b.toBV benv nenv ienv penv tenv)
    a ^^^ b
| .bnot (w := w) a =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    ~~~ a
| .boolVar v => benv v
| .shiftl (w := w) a k =>
    let a : BitVec (w.toNat wenv) := (a.toBV benv nenv ienv penv tenv)
    a <<< k
| .bvOfBool b => BitVec.ofBool (b.toBV benv nenv ienv penv tenv)

| .binWidthRel rel wa wb =>
  match rel with
  | .eq => wa.toNat wenv = wb.toNat wenv
  | .le => wa.toNat wenv ≤ wb.toNat wenv
| .binRel rel _w a b =>
  match rel with
  | .eq => a.toBV benv nenv ienv penv tenv = b.toBV benv nenv ienv penv tenv
  | .ne => a.toBV benv nenv ienv penv tenv ≠ b.toBV benv nenv ienv penv tenv
  | .ult => (a.toBV benv nenv ienv penv tenv).ult (b.toBV benv nenv ienv penv tenv) = true
  | .ule => (a.toBV benv nenv ienv penv tenv).ule (b.toBV benv nenv ienv penv tenv) = true
  | .slt => (a.toBV benv nenv ienv penv tenv).slt (b.toBV benv nenv ienv penv tenv) = true
  | .sle => (a.toBV benv nenv ienv penv tenv).sle (b.toBV benv nenv ienv penv tenv) = true
| .and p1 p2 => p1.toBV benv nenv ienv penv tenv  ∧ p2.toBV benv nenv ienv penv tenv
| .or p1 p2 => p1.toBV benv nenv ienv penv tenv ∨ p2.toBV benv nenv ienv penv tenv
| .boolBinRel rel a b =>
  match rel with
  
  | .eq => (a.toBV benv nenv ienv penv tenv) = (b.toBV benv nenv ienv penv tenv)
| .pvar v => penv v

inductive Term {wcard tcard : Nat} (bcard : Nat) (ncard : Nat) (icard : Nat) (pcard : Nat)
  (tctx : Term.Ctx wcard tcard) : TermKind wcard → Type

| ofNat (w : WidthExpr wcard) (n : Nat) : Term bcard ncard icard pcard tctx (.bv w)
 
| var (v : Fin tcard) : Term bcard ncard icard pcard tctx (.bv (tctx v))
 
| add (a : Term bcard ncard icard pcard tctx (.bv w))
  (b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| shiftl (a : Term bcard ncard icard pcard tctx (.bv w)) (k : Nat) : Term bcard ncard icard pcard tctx (.bv w)
 
| bor (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| band (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| bxor (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| bnot (a : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| zext (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| setWidth (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| sext (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| bvOfBool (b : Term bcard ncard icard pcard tctx .bool) : Term bcard ncard icard pcard tctx (.bv (.const 1))

| boolConst (b : Bool) : Term bcard ncard icard pcard tctx .bool
| boolVar (v : Fin bcard) : Term bcard ncard icard pcard tctx .bool
| binWidthRel (k : WidthBinaryRelationKind) (wa wb : WidthExpr wcard) :
    Term bcard ncard icard pcard tctx .prop
| binRel
    (k : BinaryRelationKind)
    (w : WidthExpr wcard)
    (a : Term bcard ncard icard pcard tctx (.bv w))
    (b : Term bcard ncard icard pcard tctx (.bv w)) :
    Term bcard ncard icard pcard tctx .prop
| and (p1 p2 : Term bcard ncard icard pcard tctx (.prop)) : Term bcard ncard icard pcard tctx (.prop)
| or (p1 p2 : Term bcard ncard icard pcard tctx (.prop)) : Term bcard ncard icard pcard tctx (.prop)
| pvar (v : Fin pcard) : Term bcard ncard icard pcard tctx (.prop)

| boolBinRel
  (k : BoolBinaryRelationKind)
  (a b : Term bcard ncard icard pcard tctx .bool) :
  Term bcard ncard icard pcard tctx (.prop)

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

inductive BinaryRelationKind
| eq
| ne
| ule
| slt
| sle
| ult 
deriving DecidableEq, Repr, Inhabited, Lean.ToExpr

inductive WidthBinaryRelationKind
| eq
| le

deriving DecidableEq, Repr, Inhabited, Lean.ToExpr

abbrev ofBitVecSext {w} (x : BitVec w) : BitStream :=
  fun i => if i < w then x.getLsbD i else x.msb

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

def zext_nneg_sext_ule_op0_wide_before := [llvm|
{
^0(%arg46 : i9, %arg47 : i8):
  %0 = llvm.zext nneg %arg46 : i9 to i32
  %1 = llvm.sext %arg47 : i8 to i32
  %2 = llvm.icmp "ule" %0, %1 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def test1_after := [llvm|
{
^0(%arg2 : i33):
  "llvm.return"(%arg2) : (i33) -> ()
}
]

structure MedusaSynthGeneralizeConfig where
  output : MedusaSynthGeneralizeConfig.Output := .thmStmt

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

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

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

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

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

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

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

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

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

def mul_constant_eq_before := [llvm|
{
^0(%arg140 : i32, %arg141 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mul %arg140, %0 : i32
  %2 = llvm.mul %arg141, %0 : i32
  %3 = llvm.icmp "eq" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

def foo1_or_before := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg155 : i32
  %3 = llvm.shl %0, %arg156 : i32
  %4 = llvm.and %2, %arg154 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %3, %arg154 : i32
  %7 = llvm.icmp "ne" %6, %1 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

def set_to_set_decomposebittest_after := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.and %arg11, %0 : i8
  %3 = llvm.or disjoint %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def xw' : MultiWidth.Nondep.WidthExpr := .var 0

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

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

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

def demorgan_nand_apint1_before := [llvm|
{
^0(%arg36 : i7, %arg37 : i7):
  %0 = llvm.mlir.constant(-1 : i7) : i7
  %1 = llvm.xor %arg36, %0 : i7
  %2 = llvm.and %1, %arg37 : i7
  %3 = llvm.xor %2, %0 : i7
  "llvm.return"(%3) : (i7) -> ()
}
]

def test7_after := [llvm|
{
^0(%arg2 : i1024):
  "llvm.return"(%arg2) : (i1024) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

LE.le in Init.Prelude

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

NFA.eval in Mathlib.Computability.NFA

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

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

def xor_icmp_true_unsigned_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.icmp "ugt" %arg7, %0 : i32
  %3 = llvm.icmp "ult" %arg7, %1 : i32
  %4 = llvm.xor %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

structure Item where
 name : String
 tac : Syntax

instance : Fintype (StateSpace wcard tcard bcard ncard icard pcard) where
  elems :=
    let ws : Finset (Fin wcard) := Finset.univ
    let ts : Finset (Fin tcard) := Finset.univ
    let bs : Finset (Fin bcard) := Finset.univ
    let ps : Finset (Fin pcard) := Finset.univ
    let ws := ws.image StateSpace.widthVar
    let ts := ts.image StateSpace.termVar
    let bs := bs.image StateSpace.boolVar
    let ps := ps.image StateSpace.predVar
    ws ∪ ts ∪ bs ∪ ps
  complete := by admit /- proof elided -/

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

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

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


example (op : Comb.Op) : DialectSignature.effectKind (d := DCxComb) (.comb op) = .pure := rfl



example (op : Comb.Op) : DialectSignature.regSig (d := DCxComb) (.comb op) = [] := rfl

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

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

inductive Op
| fst (t : Ty2)
| snd (t : Ty2)
| branch (t : Ty2)
| merge (t : Ty2)
| altMerge (t : Ty2)
| fork (t : Ty2)
| controlMerge (t : Ty2)
| join (t : Ty2)
| mux (t : Ty2)
| sink (t : Ty2)
| sync (t : Ty2)
| supp (t : Ty2)
| not
deriving Inhabited, DecidableEq, Repr, Lean.ToExpr

def and_zext_zext_after := [llvm|
{
^0(%arg58 : i8, %arg59 : i4):
  %0 = llvm.zext %arg59 : i4 to i8
  %1 = llvm.and %arg58, %0 : i8
  %2 = llvm.zext nneg %1 : i8 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

IO.getEnv in Init.System.IO

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

StateT.run in Init.Control.State

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

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

def dont_narrow_zext_ashr_keep_trunc_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(1 : i16) : i16
  %1 = llvm.sext %arg0 : i8 to i16
  %2 = llvm.sext %arg1 : 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 test2_before := [llvm|
{
^0(%arg59 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(32 : i32) : i32
  %2 = llvm.and %arg59, %0 : i32
  %3 = llvm.and %arg59, %1 : i32
  %4 = llvm.add %2, %3 : i32
  "llvm.return"(%4) : (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 mul_splat_fold_no_nuw_after := [llvm|
{
^0(%arg79 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.lshr %arg79, %0 : i32
  %2 = llvm.add %arg79, %1 overflow<nsw> : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def addsub_combine_constants_before := [llvm|
{
^0(%arg14 : i7, %arg15 : i7):
  %0 = llvm.mlir.constant(42 : i7) : i7
  %1 = llvm.mlir.constant(10 : i7) : i7
  %2 = llvm.add %arg14, %0 : i7
  %3 = llvm.sub %1, %arg15 : i7
  %4 = llvm.add %2, %3 overflow<nsw> : i7
  "llvm.return"(%4) : (i7) -> ()
}
]

def test10b_after := [llvm|
{
^0(%arg105 : i32, %arg106 : i32):
  %0 = llvm.or %arg105, %arg106 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def slt_zero_ult_i1_after := [llvm|
{
^0(%arg10 : i32, %arg11 : i1):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "slt" %arg10, %0 : i32
  %3 = llvm.xor %arg11, %1 : i1
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

NFA.accept in Mathlib.Computability.NFA

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

def udiv_x_by_const_cmp_x_before := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(123 : i32) : i32
  %1 = llvm.udiv %arg14, %0 : i32
  %2 = llvm.icmp "slt" %1, %arg14 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def sdiv_exact_eq_9_no_of_before := [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.sdiv exact %arg8, %2 : i8
  %4 = llvm.icmp "eq" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def IsRefinedBy {as} {bs} : HVector A as → HVector B bs → Prop
  | .nil, .nil => True
  | .cons x xs, .cons y ys => x ⊑ y ∧ xs.IsRefinedBy ys
  | _, _ => False

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 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 test_add_nuw__none_are_safe_after := [llvm|
{
^0(%arg34 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.add %arg34, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

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

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

@[simp, reducible]
def MOp.UnaryOp.outTy (w : Width φ) : MOp.UnaryOp φ → MTy φ
| .trunc w' _ => .bitvec w'
| .zext w' _ => .bitvec w'
| .sext w' => .bitvec w'
| _ => .bitvec w

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

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

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

def main_before := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(-17 : i8) : i8
  %1 = llvm.mlir.constant(122 : i8) : i8
  %2 = llvm.mlir.constant(6 : i8) : i8
  %3 = llvm.mlir.constant(7 : i8) : i8
  %4 = llvm.mlir.constant(64 : i8) : i8
  %5 = llvm.trunc %arg2 : i32 to i8
  %6 = llvm.or %5, %0 : i8
  %7 = llvm.and %5, %1 : i8
  %8 = llvm.xor %7, %0 : i8
  %9 = llvm.shl %8, %2 : i8
  %10 = llvm.xor %9, %8 : i8
  %11 = llvm.xor %6, %10 : i8
  %12 = llvm.lshr %11, %3 : i8
  %13 = llvm.mul %12, %4 : i8
  %14 = llvm.zext %13 : i8 to i32
  "llvm.return"(%14) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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

def t1_before := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.zext %arg11 : i8 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

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

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

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

inductive Ty (q : ℕ) where
| integer
| modLike
deriving DecidableEq, Repr, Inhabited

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

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 xor_or2_before := [llvm|
{
^0(%arg158 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.xor %arg158, %0 : i8
  %3 = llvm.or %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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 corec {α} {β} (s0 : β) (f : β → (Option α × β)) : Stream α :=
  Stream'.corec (f · |>.fst) (f · |>.snd) s0

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

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

Lean.Parser.mkAtomicInfo in Lean.Parser.Basic

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

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

def slt_zero_ult_i1_fail2_after := [llvm|
{
^0(%arg6 : i32, %arg7 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg7 : i1 to i32
  %2 = llvm.ashr %arg6, %0 : i32
  %3 = llvm.icmp "ugt" %2, %1 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

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

List.zip in Init.Data.List.Basic

def udiv_mul_shl_nuw_after := [llvm|
{
^0(%arg166 : i5, %arg167 : i5, %arg168 : i5):
  %0 = llvm.lshr %arg167, %arg168 : i5
  "llvm.return"(%0) : (i5) -> ()
}
]

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

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

def cstInt {Γ : Ctxt _} (z :Int) : Expr (FHE q n) Γ .pure [.integer] :=
  Expr.mk
    (op := .const_int z)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .nil)
    (regArgs := .nil)

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

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

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

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

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

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

def n2_before := [llvm|
{
^0(%arg10 : i16):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(-2147483648 : i32) : i32
  %2 = llvm.zext %arg10 : i16 to i32
  %3 = llvm.shl %2, %0 : i32
  %4 = llvm.and %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32_after := [llvm|
{
^0(%arg55 : i32, %arg56 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.xor %arg56, %arg55 : i32
  %2 = llvm.icmp "sgt" %1, %0 : i32
  %3 = llvm.zext %2 : i1 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def ule_swap_or_not_min_before := [llvm|
{
^0(%arg264 : i8, %arg265 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.icmp "uge" %arg265, %arg264 : i8
  %2 = llvm.icmp "ne" %arg264, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def rewriteAt
    (lhs rhs : Com d Γ₁ .pure ts₁)
    (hlhs : ∀ t (v : Var Γ₁ t), ⟨t, v⟩ ∈ lhs.vars)
    (pos : ℕ) (target : Com d Γ₂ eff t₂) :
    Option (Com d Γ₂ eff t₂) := do
  let splitRes ← splitProgramAt pos target
  if h : ts₁ = splitRes.midTypes then
    let m ← matchArgRes splitRes.top lhs.toLets splitRes.midRet (h ▸ lhs.returnVars)
    let m := m.toHom <| by
      subst h; exact hlhs
    let rhs := rhs.changeVars m
    let zip := splitRes.insertPureCom splitRes.midRet (cast (by admit /- proof elided -/
    ) rhs)
    return zip.toCom
  else none

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

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

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

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

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

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

def 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 alive_AndOrXor_2663_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%a : _, %b : _):
  %v1 = llvm.icmp.ule %a, %b
  %v2 = llvm.icmp.ne %a, %b
  %v3 = llvm.icmp.uge %a, %b
  llvm.return %v3 : i1
}]

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

def or_xor_or_before := [llvm|
{
^0(%arg156 : i8):
  %0 = llvm.mlir.constant(33 : i8) : i8
  %1 = llvm.mlir.constant(12 : i8) : i8
  %2 = llvm.mlir.constant(7 : i8) : i8
  %3 = llvm.or %arg156, %0 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

@[reducible]
instance [Monad d.m] : DialectDenote (Scf d) where
  denote
    | .coe o', args', regArgs' =>
        let denote' := DialectDenote.denote o'
        by
         exact denote' args' regArgs'
    | .if t t', (.cons (cond ) (.cons v .nil)),
         (.cons (f : Ctxt.Valuation ⟨[t]⟩ → d.m (HVector toType [t'])) (.cons (g : _ → _) .nil)) =>
         let body := if B.denote_eq ▸ cond then f else g
      body (Ctxt.Valuation.nil.cons v)
    | .run _t, (.cons v .nil), (.cons (f : _ → _) .nil) =>
        f (Ctxt.Valuation.nil.cons v)
    | .for ty, (.cons istart (.cons istep (.cons niter (.cons vstart .nil)))),
        (.cons (f : _  → _) .nil) => do
        let istart : ℤ := Z.denote_eq ▸ istart
        let istep : ℤ := Z.denote_eq ▸ istep
        let niter : ℕ := N.denote_eq ▸ niter
        let f' : LoopBody (d.m ⟦ty⟧) := fun i v => do
          let v ← v
          let i := Z.denote_eq.symm ▸ i
          let xs ← f (Valuation.ofPair i v)
          return xs.get (0 : Fin 1)
        let to_iterate := f'.counterDecorator (α := d.m ⟦ty⟧) (δ := istep)
        let loop_fn := niter.iterate (op := to_iterate)
        let x ← (loop_fn (istart, pure vstart)).2
        return [x]ₕ

    | .iterate k, (.cons (x) .nil), (.cons (f : _ → _) .nil) => do
      let x : ℤ := Z.denote_eq ▸ x
      let coe : ℤ = toType Z.ty := Z.denote_eq.symm
      let f' (v : d.m ℤ) : d.m ℤ := do
        let v ← v
        let xs ← f (Ctxt.Valuation.nil.cons (cast coe v))
        let x := xs.getN 0
        return coe ▸ x
      let y ← (k.iterate f' (pure x))
      return [cast Z.denote_eq.symm y]ₕ

def zext_zext_ule_op0_wide_after := [llvm|
{
^0(%arg76 : i9, %arg77 : i8):
  %0 = llvm.zext %arg77 : i8 to i9
  %1 = llvm.icmp "ule" %arg76, %0 : i9
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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

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

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

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

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

StateM in Init.Control.State

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

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

def test_const_shr_and_1_ne_0_i1_negative_before := [llvm|
{
^0(%arg2 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.lshr %0, %arg2 : i1
  %3 = llvm.and %2, %0 : i1
  %4 = llvm.icmp "ne" %3, %1 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def ashr_xor_before := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.srem %arg47, %0 : i32
  %4 = llvm.ashr %arg46, %1 : i32
  %5 = llvm.xor %3, %4 : i32
  %6 = llvm.ashr %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

def changeFpExprWidth (bvExpr: FpExpr w) (target: Nat) : FpExpr target :=
  if h : w = target then
    (h ▸ bvExpr)
  else
    match bvExpr with
    | .var idx => (FpExpr.var idx : FpExpr target)
    | .bin lhs op rhs =>
      FpExpr.bin
        (changeFpExprWidth lhs target)
        op
        (changeFpExprWidth rhs target)
    | .const val =>
      
      
      
      FpExpr.const (val.setWidth _)

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

Lean.FileMap.ofString in Lean.Data.Position

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

def add_positive_low_bound_accept_test: LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_positive_low_bound_accept_llvm
  rhs := add_positive_low_bound_accept_riscv

@[match_pattern] abbrev bitvec (w : Nat) : LLVM.Ty :=
  MTy.bitvec (.concrete w)

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

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

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

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

def or_not_and_and_not_and_xor_commute5_after := [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 %arg274, %2 : i32
  %4 = llvm.xor %arg275, %arg276 : i32
  %5 = llvm.and %4, %arg274 : i32
  %6 = llvm.xor %5, %3 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

Lean.Elab.Term.synthesizeSyntheticMVarsNoPostponing in Lean.Elab.SyntheticMVars

unsafe def main : IO Unit := do
  initSearchPath (← findSysroot)
  Lean.withImportModules #[{ module := `Lean.Elab.Tactic.BVDecide}, {module := `Std.Tactic.BVDecide}]
      (opts := {}) (trustLevel := 0) fun env => do
    let ctxCore : Core.Context := { fileName := "SynthCadicalFile", fileMap := FileMap.ofString "" }
    let sCore : Core.State :=  { env }
    let ctxMeta : Meta.Context := {}
    let sMeta : Meta.State := {}
    let ctxTerm : Term.Context :=  { declName? := .some (Name.mkSimple s!"problem")}
    let sTerm : Term.State := {}
    let mut pix := 0
    for p in Bits.testPredicates do
      pix := pix + 1
      IO.println s!"testing predicate '{pix}'"
      let nIters : Nat := 2
      for i in [0:nIters] do
        IO.println s!"Iteration #{i + 1}/{nIters}"
        let fsm := predicateEvalEqFSM p
        
        let ((out, circuitStats), tElapsedCadical) ← timeElapsedMs do
          let ((out, circuitStats), _coreState, _metaState, _termState) ←
            fsm.toFSM.decideIfZerosVerified 5 |>.toIO ctxCore sCore ctxMeta sMeta ctxTerm sTerm
          return (out, circuitStats)
        let b := out.isSuccess
        
        IO.println s!" (cadical)  is all zeroes: '{b}' | stats: '{repr circuitStats}' | time: '{tElapsedCadical}' ms"
        IO.println "
  return ()

def sub_3_after := [llvm|
{
^0(%arg105 : i128, %arg106 : i1, %arg107 : i128, %arg108 : i128):
  %0 = llvm.mlir.constant(-124 : i128) : i128
  %1 = llvm.mlir.constant(-2 : i128) : i128
  %2 = llvm.xor %arg108, %0 : i128
  %3 = "llvm.select"(%arg106, %arg107, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i128, i128) -> i128
  %4 = llvm.add %3, %arg105 : i128
  %5 = llvm.sub %1, %4 : i128
  "llvm.return"(%5) : (i128) -> ()
}
]

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

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

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

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

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

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

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

def eval (assign : Std.HashMap Nat BVExpr.PackedBitVec) : FpPredicate → Bool
  | bin lhs op rhs =>
    match op with
    | .eq => (lhs.eval assign) = (rhs.eval assign)

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

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

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

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

abbrev BitVecs.empty : BitVecs n := ⟨0, List.Vector.replicate n .nil⟩

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

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

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

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

    |

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

def toCom (zip : Zipper d Γ_in eff ty) : Com d Γ_in eff ty :=
  go zip.top zip.bot
  where
    go : {Γ_mid : _} → Lets d Γ_in eff Γ_mid → Com d Γ_mid eff ty → Com d Γ_in eff ty
      | _, .nil, com          => com
      | _, .var body e, com  => go body (.var e com)

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

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

@[elab_as_elim, induction_eliminator]
def Expr.recOn {motive : Expr Op Γ ty → Sort u}
    (mk : ∀ varName op ty_eq args regions, motive (Expr.mk varName op ty_eq args regions)) :
    ∀ e, motive e
  | ⟨⟨varName, op, args, regions⟩, h⟩ =>
      have := by admit /- proof elided -/

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

def mul_may_overflow_after := [llvm|
{
^0(%arg8 : i32, %arg9 : i32):
  %0 = llvm.mlir.constant(4294967296 : i34) : i34
  %1 = llvm.zext %arg8 : i32 to i34
  %2 = llvm.zext %arg9 : i32 to i34
  %3 = llvm.mul %1, %2 : i34
  %4 = llvm.icmp "ult" %3, %0 : i34
  %5 = llvm.zext %4 : i1 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def llvm_zext_lower_riscv_1_to_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 1)] :=
  {lhs:= zext_llvm_1_to_64, rhs:= zext_riscv_1_to_64}

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

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

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

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

def mul_of_bool_no_lz_other_op_after := [llvm|
{
^0(%arg85 : i32, %arg86 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def not_ashr_const_before := [llvm|
{
^0(%arg138 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %0, %arg138 : i8
  %3 = llvm.xor %2, %1 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

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

def Tensor2d.transpose (t: Tensor2d α) : Tensor2d α where
  size0 := t.size1
  size1 := t.size0
  val := fun ix0 => fun ix1 => t.val ix1 ix0

List.insert in Init.Data.List.Basic

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

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

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

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

def commute_int_constant_to_rhs: List (Σ Γ, RISCVPeepholeRewrite  Γ) :=
  [⟨_, commute_int_constant_to_rhs_add⟩,
  ⟨_, commute_int_constant_to_rhs_mul⟩,
  ⟨_, commute_int_constant_to_rhs_and⟩,
  ⟨_, commute_int_constant_to_rhs_or⟩,
  ⟨_, commute_int_constant_to_rhs_xor⟩,
  ⟨_, commute_int_constant_to_rhs_mulhu⟩]

Lean.mkApp6 in Lean.Expr

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

@[simp_riscv]
def neg_pseudo (rs1_val : BitVec 64) : BitVec 64 :=
  RV64.sub rs1_val 0

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

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

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

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

def bool_zext_before := [llvm|
{
^0(%arg172 : i1):
  %0 = llvm.mlir.constant(15 : i16) : i16
  %1 = llvm.sext %arg172 : i1 to i16
  %2 = llvm.lshr %1, %0 : i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

def ashr_lowmask_before := [llvm|
{
^0(%arg267 : i32):
  %0 = llvm.mlir.constant(24 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.ashr %arg267, %0 : i32
  %3 = llvm.and %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

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

HAppend in Init.Prelude

def worklistRun' (final : S → Bool) (inits : Array S) (hinits : inits.toList.Nodup) (f : S → Array (A × S)) : RawCNFA A :=
  let st0 := worklist.initState _ _ inits hinits final
  go st0
where go (st0 : worklist.St A S) : RawCNFA A :=
  if hemp : st0.worklist.isEmpty then st0.m else
  let sa? := st0.worklist.back?
  match heq : sa? with
  | some sa =>
    let wl := st0.worklist.pop
    let st1 := { st0 with worklist := wl,
                          worklist_nodup := by admit /- proof elided -/

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 testi64i32_before := [llvm|
{
^0(%arg8 : i64):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.lshr %arg8, %0 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.trunc %arg8 : i64 to i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %3 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

def foo1_or_signbit_lshr_without_shifting_signbit_both_sides_before := [llvm|
{
^0(%arg100 : i32, %arg101 : i32, %arg102 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.shl %arg100, %arg101 : i32
  %2 = llvm.icmp "slt" %1, %0 : i32
  %3 = llvm.shl %arg100, %arg102 : i32
  %4 = llvm.icmp "slt" %3, %0 : i32
  %5 = llvm.and %2, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

def positive_samevar_shlnuw_before := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.shl %arg30, %arg31 overflow<nuw> : i32
  %1 = llvm.lshr %0, %arg31 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

OneHom in Mathlib.Algebra.Group.Hom.Defs

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

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

def test_mul_one_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R):
    %one = mod_arith.constant 1 : !R
    %mul = mod_arith.mul %one, %x : !R
    return %mul : !R
}]

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

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

def ashrslt_03_13_exact_after := [llvm|
{
^0(%arg8 : i4):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (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 test_mul_nsw__nuw_is_safe_after := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(268435457 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg9, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

@[reducible]
instance [TyDenote d.Ty] [DialectSignature d] [DialectDenote d]
    [B : HasBool d] [N : HasNat d] [I : HasInt d] : DialectSignature (Scf d) where
   signature
   | .coe o => signature (d:=d) o
    | .if t t' => ⟨[B.ty, t], [(⟨[t]⟩, [t']), (⟨[t]⟩, [t'])], [t'], .impure⟩
      
      
      
      
      
    | .for t => ⟨[ I.ty,  I.ty,  N.ty, t], [(⟨[I.ty, t]⟩, [t])], [t], .impure⟩
    | .run t => ⟨[t], [(⟨[t]⟩, [t])], [t], .impure⟩
    | .iterate _k => ⟨[I.ty], [(⟨[I.ty]⟩, [I.ty])], [I.ty], .impure⟩

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

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

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

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

instance  [Mul α] : Mul (Holor α ds) where
  mul := Holor.pointwise_mul

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

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

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

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

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

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

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

def oppositesign_before := [llvm|
{
^0(%arg32 : i16, %arg33 : i16):
  %0 = llvm.mlir.constant(-32768 : i16) : i16
  %1 = llvm.mlir.constant(32767 : i16) : i16
  %2 = llvm.or %arg32, %0 : i16
  %3 = llvm.and %arg33, %1 : i16
  %4 = llvm.add %2, %3 : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

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

abbrev Context := Ctxt LLVM.Ty

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

def alive_AddSub_1164_tgt  (w : Nat)  :=
[llvm( w )| {
^bb0(%a : _, %b : _):
  %v1 = llvm.mlir.constant 0
  %v2 = llvm.sub %v1, %a
  %v3 = llvm.sub %b, %a
  llvm.return %v3
}]

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

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

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

def fold_add_sdiv_srem_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(4 : i32) : i32
  %2 = llvm.sdiv %arg9, %0 : i32
  %3 = llvm.shl %2, %1 : i32
  %4 = llvm.srem %arg9, %0 : i32
  %5 = llvm.add %3, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def foo_before := [llvm|
{
^0(%arg113 : i32, %arg114 : i32, %arg115 : i32, %arg116 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.icmp "slt" %arg113, %arg114 : i32
  %2 = llvm.sext %1 : i1 to i32
  %3 = llvm.and %arg115, %2 : i32
  %4 = llvm.xor %2, %0 : i32
  %5 = llvm.and %arg116, %4 : i32
  %6 = llvm.or %3, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

instance RawCNFA_Inhabited : Inhabited (RawCNFA A) where
  default := RawCNFA.empty

instance : Repr (AttrValue φ) where
  reprPrec x _ := docAttrVal x

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

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

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

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

def drop_nsw_trunc_after := [llvm|
{
^0(%arg13 : i16, %arg14 : i16):
  %0 = llvm.and %arg13, %arg14 : i16
  %1 = llvm.trunc %0 : i16 to i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

def alive_AddSub_1043_src  :=
[sllvm| {
^bb0(%C1 : i64, %Z : i64, %RHS : i64):
  %v1 = llvm.and %Z, %C1 : i64
  %v2 = llvm.xor %v1, %C1 : i64
  %v3 = llvm.mlir.constant 1 : i64
  %v4 = llvm.add %v2, %v3 : i64
  %v5 = llvm.add %v4, %RHS : i64
  llvm.return %v5 : i64
}]

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

def mul_of_bool_no_lz_other_op_after := [llvm|
{
^0(%arg85 : i32, %arg86 : i8):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def test_sext_zext_before := [llvm|
{
^0(%arg14 : i16):
  %0 = llvm.zext %arg14 : i16 to i32
  %1 = llvm.sext %0 : i32 to i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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

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

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

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

@[match_pattern] abbrev or (w : Nat) (flag : DisjointFlag := {disjoint := false} ) : LLVM.Op :=
  MOp.or (.concrete w) flag

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

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

def xor_common_op_commute0_after := [llvm|
{
^0(%arg208 : i8, %arg209 : i8):
  %0 = llvm.or %arg209, %arg208 : i8
  "llvm.return"(%0) : (i8) -> ()
}
]

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

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

def not_ashr_bitwidth_mask_before := [llvm|
{
^0(%arg105 : i8, %arg106 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.ashr %arg105, %0 : i8
  %3 = llvm.xor %2, %1 : i8
  %4 = llvm.and %3, %arg106 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def narrow_sext_and_after := [llvm|
{
^0(%arg56 : i16, %arg57 : i32):
  %0 = llvm.trunc %arg57 : i32 to i16
  %1 = llvm.and %arg56, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

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

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

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

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

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

instance : ToString FpBinaryPredKind := ⟨FpBinaryPredKind.toString⟩

RV64.slli in RISCV.Instructions

instance {Γ : Ctxt Ty} {Γ' : DerivedCtxt Γ} :
    CoeHead (DerivedCtxt (Γ' : Ctxt Ty)) (DerivedCtxt Γ) where
  coe := fun ⟨Γ'', diff⟩ => ⟨Γ'', Γ'.diff + diff⟩

def select_of_zext_rw : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%cond: i1, %true_val: i32, %false_val: i32):
      %0 = llvm.select %cond, %true_val, %false_val : i32
      %1 = llvm.zext %0 : i32 to i64
      llvm.return %1 : i64
  }]
  rhs := [LV| {
    ^entry (%cond: i1, %true_val: i32, %false_val: i32):
      %0 = llvm.zext %true_val : i32 to i64
      %1 = llvm.zext %false_val : i32 to i64
      %2 = llvm.select %cond, %0, %1 : i64
      llvm.return %2 : i64
  }]

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

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

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

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

@[simp_denote]
def srli_riscv :=
  [LV| {
    ^entry (%arg: i16):
    %a =  "builtin.unrealized_conversion_cast" (%arg) : (i16) -> (!i64)
    %0 =slli %a, 48 : !i64
    %1 =srli %0, 54 : !i64
    %2 = "builtin.unrealized_conversion_cast" (%1) : (!i64) -> (i16)
    llvm.return %2 :i16
  }]

def negate_ashr_before := [llvm|
{
^0(%arg126 : i8, %arg127 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.ashr %arg127, %0 : i8
  %2 = llvm.sub %arg126, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def CNFA.toNFA (m : CNFA n) : NFA (BitVec n) m.m.states where
  start := { s | s.val ∈ m.m.initials }
  accept := { s | s.val ∈ m.m.finals }
  step s₁ a := { s₂ | s₂.val ∈ m.m.tr s₁.val a }

def sge_smin4_before := [llvm|
{
^0(%arg73 : i32, %arg74 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg73, %0 : i32
  %2 = llvm.icmp "slt" %arg74, %1 : i32
  %3 = "llvm.select"(%2, %arg74, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "sle" %1, %3 : i32
  "llvm.return"(%4) : (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 udiv_common_divisor_before := [llvm|
{
^0(%arg65 : i1, %arg66 : i5, %arg67 : i5, %arg68 : i5):
  %0 = llvm.udiv %arg67, %arg66 : i5
  %1 = llvm.udiv %arg68, %arg66 : i5
  %2 = "llvm.select"(%arg65, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  "llvm.return"(%2) : (i5) -> ()
}
]

Language.instMembershipList in Mathlib.Computability.Language

def different_size_zext_zext_ugt_before := [llvm|
{
^0(%arg28 : i7, %arg29 : i4):
  %0 = llvm.zext %arg28 : i7 to i25
  %1 = llvm.zext %arg29 : i4 to i25
  %2 = llvm.icmp "ugt" %0, %1 : i25
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

def alive_AndOrXor_709_src :=
[sllvm| {
^bb0(%a : i64, %b : i64, %d : i64):
  %v1 = llvm.and %a, %b : i64
  %v2 = llvm.and %a, %d : i64
  %v3 = llvm.icmp.eq %v1, %b : i64
  %v4 = llvm.icmp.eq %v2, %d : i64
  %v5 = llvm.and %v3, %v4 : i1
  llvm.return %v5 : i1
}]

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

def llvm_const_lower_riscv_li_39 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_39, rhs:= liRiscv_39,
   correct := by admit /- proof elided -/

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

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

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

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

def foo1_or_before := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg155 : i32
  %3 = llvm.shl %0, %arg156 : i32
  %4 = llvm.and %2, %arg154 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %3, %arg154 : i32
  %7 = llvm.icmp "ne" %6, %1 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

def nfa' : NFA' n :=
  { σ := _, M := nfa inits final f }

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

def and_or1_wrong_operand_before := [llvm|
{
^0(%arg176 : i1, %arg177 : i1, %arg178 : i1, %arg179 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg176, %0 : i1
  %2 = llvm.or %1, %arg178 : i1
  %3 = "llvm.select"(%2, %arg179, %arg177) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def lshr_mul_times_3_div_2_exact_before := [llvm|
{
^0(%arg31 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mul %arg31, %0 overflow<nsw> : i32
  %3 = llvm.lshr exact %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def is_ascii_alphabetic_after := [llvm|
{
^0(%arg248 : i32):
  %0 = llvm.mlir.constant(-33 : i32) : i32
  %1 = llvm.mlir.constant(-65 : i32) : i32
  %2 = llvm.mlir.constant(26 : i32) : i32
  %3 = llvm.and %arg248, %0 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.icmp "ult" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

def narrow_sext_xor_before := [llvm|
{
^0(%arg48 : i16, %arg49 : i32):
  %0 = llvm.sext %arg48 : i16 to i32
  %1 = llvm.xor %0, %arg49 : i32
  %2 = llvm.trunc %1 : i32 to i16
  "llvm.return"(%2) : (i16) -> ()
}
]

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

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

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

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

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

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

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

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

def n8_wrong_pred3_before := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.sub %arg8, %arg9 : i8
  %1 = llvm.icmp "ne" %0, %arg8 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def alive_InstCombineShift__279_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%X : _, %C : _):
  %v1 = llvm.lshr %X, %C
  %v2 = llvm.shl %v1, %C
  llvm.return %v2
}]

def select_mul_icmp_before := [llvm|
{
^0(%arg284 : i32, %arg285 : i32, %arg286 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.icmp "eq" %arg284, %0 : i32
  %2 = llvm.mul %arg284, %arg286 : i32
  %3 = "llvm.select"(%1, %2, %arg285) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def addhshlhsdivhscalar1_before := [llvm|
{
^0(%arg18 : i8):
  %0 = llvm.mlir.constant(-64 : i8) : i8
  %1 = llvm.mlir.constant(6 : i8) : i8
  %2 = llvm.sdiv %arg18, %0 : i8
  %3 = llvm.shl %2, %1 : i8
  %4 = llvm.add %3, %arg18 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

def shl1_nsw_not_exact_before := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg11 overflow<nsw> : i8
  %2 = llvm.sdiv %arg10, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

def t0_after := [llvm|
{
^0(%arg41 : i1, %arg42 : i8, %arg43 : i8, %arg44 : i8, %arg45 : i8):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.icmp "ne" %arg42, %arg43 : i8
  %2 = "llvm.select"(%arg41, %1, %0) <{"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_logic_and_logic_or2_before := [llvm|
{
^0(%arg51 : i1, %arg52 : i1, %arg53 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = "llvm.select"(%arg53, %0, %arg51) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %3 = "llvm.select"(%arg51, %arg52, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = llvm.xor %3, %2 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

List.isEmpty in Init.Data.List.Basic

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

def trunc_ashr_before := [llvm|
{
^0(%arg83 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i36) : i36
  %1 = llvm.mlir.constant(8 : i36) : i36
  %2 = llvm.zext %arg83 : i32 to i36
  %3 = llvm.or %2, %0 : i36
  %4 = llvm.ashr %3, %1 : i36
  %5 = llvm.trunc %4 : i36 to i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

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

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

def llvm_zext_lower_riscv_8_to_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 8)] :=
  {lhs:= zext_llvm_8_to_64, rhs:= zext_riscv_8_to_64}

def xor_andn_commute2_after := [llvm|
{
^0(%arg70 : i33, %arg71 : i33):
  %0 = llvm.mlir.constant(42 : i33) : i33
  %1 = llvm.udiv %0, %arg71 : i33
  %2 = llvm.or %arg70, %1 : i33
  "llvm.return"(%2) : (i33) -> ()
}
]

List.Mem in Init.Data.List.Basic

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

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

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

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

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

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

def trunc_equality_nsw_sext_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i8):
  %0 = llvm.sext %arg15 : i8 to i32
  %1 = llvm.icmp "ne" %arg14, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

def negation_of_increment_via_or_disjoint_before := [llvm|
{
^0(%arg81 : i8, %arg82 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.or disjoint %arg82, %0 : i8
  %2 = llvm.sub %arg81, %1 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def ashr_xor_after := [llvm|
{
^0(%arg46 : i32, %arg47 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(12 : i32) : i32
  %2 = llvm.mlir.constant(7 : i32) : i32
  %3 = llvm.srem %arg47, %0 : i32
  %4 = llvm.ashr %arg46, %1 : i32
  %5 = llvm.ashr %3, %2 : i32
  %6 = llvm.xor %4, %5 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

@[simp_denote] def if_ {Γ : Ctxt _} {t t': Arith.Ty}
  (cond : Var Γ Arith.Ty.bool) (v : Var Γ t) (then_ else_ : Com ScfArith ⟨[t]⟩ .impure t') :
    Expr ScfArith Γ .impure t' :=
  Expr.mk
    (op := .if t t')
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons cond <| .cons v .nil)
    (regArgs := HVector.cons then_ <| HVector.cons else_ <| HVector.nil)

def test8_after := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(32) : i64
  %1 = llvm.zext %arg79 : i32 to i64
  %2 = llvm.zext %arg80 : i32 to i64
  %3 = llvm.shl %2, %0 overflow<nuw> : i64
  %4 = llvm.or disjoint %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

@[simp_denote]
def srli_riscv_i64 :=
  [LV| {
    ^entry (%arg: i64):
    %a = "builtin.unrealized_conversion_cast" (%arg) : (i64) -> (!i64)
    %0 = srli %a, 8 : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

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

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

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

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

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

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

def test55_before := [llvm|
{
^0(%arg129 : i32):
  %0 = llvm.mlir.constant(-32574 : i16) : i16
  %1 = llvm.mlir.constant(-25350 : i16) : i16
  %2 = llvm.trunc %arg129 : i32 to i16
  %3 = llvm.or %2, %0 : i16
  %4 = llvm.and %3, %1 : i16
  %5 = llvm.sext %4 : i16 to i64
  "llvm.return"(%5) : (i64) -> ()
}
]

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

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

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

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

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

def worklist.St.meas (st : worklist.St A S) : ℕ :=
  Finset.card $ Finset.univ |>.filter fun x => x ∉ st.map.keys ∨ x ∈ st.worklist.toList

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

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

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

def test_add_mul_neg_one_lhs_LHS := [mod_arith q, hq| {
  ^bb0(%x : !R, %y : !R):
    %neg_one = mod_arith.constant 41 : !R
    %mul = mod_arith.mul %neg_one, %x : !R
    %add = mod_arith.add %mul, %y : !R
    return %add : !R
}]

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

def ugt_swap_and_not_min_commute_after := [llvm|
{
^0(%arg66 : i8, %arg67 : i8):
  %0 = llvm.icmp "ult" %arg67, %arg66 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

def negate_select_of_op_vs_negated_op_nsw_xyyx_before := [llvm|
{
^0(%arg14 : i8, %arg15 : i8, %arg16 : i8, %arg17 : i1):
  %0 = llvm.sub %arg14, %arg15 overflow<nsw> : i8
  %1 = llvm.sub %arg15, %arg14 overflow<nsw> : i8
  %2 = "llvm.select"(%arg17, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %arg16, %2 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def or_xor_xor_normal_variant1_after := [llvm|
{
^0(%arg17 : i1, %arg18 : i1):
  %0 = llvm.xor %arg17, %arg18 : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

def lor_land_left1_after := [llvm|
{
^0(%arg78 : i1, %arg79 : i1):
  "llvm.return"(%arg78) : (i1) -> ()
}
]

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

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

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

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

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

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

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

def lshr_and_sub_before := [llvm|
{
^0(%arg53 : i8, %arg54 : 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 %arg53, %0 : i8
  %4 = llvm.lshr %arg54, %1 : i8
  %5 = llvm.and %4, %2 : i8
  %6 = llvm.sub %3, %5 : i8
  %7 = llvm.shl %6, %1 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

def pr33078_4_after := [llvm|
{
^0(%arg2 : i3):
  %0 = llvm.mlir.constant(13 : i16) : i16
  %1 = llvm.sext %arg2 : i3 to i16
  %2 = llvm.lshr %1, %0 : i16
  %3 = llvm.trunc %2 overflow<nsw,nuw> : i16 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

def add_nuw_nsw_or_and_after := [llvm|
{
^0(%arg7 : i32, %arg8 : i32):
  %0 = llvm.add %arg7, %arg8 overflow<nsw,nuw> : i32
  "llvm.return"(%0) : (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 generalizeOfBoolTac : TacticM Unit := do
  let g ← getMainGoal
  let g ← generalizeOfBool g
  replaceMainGoal [g]

def main7d_logical_after := [llvm|
{
^0(%arg59 : i32, %arg60 : i32, %arg61 : i32, %arg62 : i32, %arg63 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg60, %arg62 : i32
  %2 = llvm.and %arg61, %arg63 : i32
  %3 = llvm.and %arg59, %1 : i32
  %4 = llvm.icmp "ne" %3, %1 : i32
  %5 = llvm.and %arg59, %2 : i32
  %6 = llvm.icmp "ne" %5, %2 : i32
  %7 = "llvm.select"(%4, %0, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %8 = llvm.zext %7 : i1 to i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

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

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

def sub_1_after := [llvm|
{
^0(%arg113 : i8, %arg114 : i1, %arg115 : i8, %arg116 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.xor %arg116, %0 : i8
  %2 = "llvm.select"(%arg114, %arg115, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.add %2, %arg113 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

def shl_add_lshr_before := [llvm|
{
^0(%arg154 : i32, %arg155 : i32, %arg156 : i32):
  %0 = llvm.shl %arg154, %arg155 overflow<nuw> : i32
  %1 = llvm.add %0, %arg156 overflow<nuw> : i32
  %2 = llvm.lshr %1, %arg155 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

def test3_before := [llvm|
{
^0(%arg11 : i23):
  %0 = llvm.mlir.constant(127 : i23) : i23
  %1 = llvm.mlir.constant(128 : i23) : i23
  %2 = llvm.and %arg11, %0 : i23
  %3 = llvm.and %2, %1 : i23
  "llvm.return"(%3) : (i23) -> ()
}
]

def simplify_neg_maxmin : RISCVPeepholeRewrite [Ty.riscv (.bv) ] where
  lhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = neg %x : !riscv.reg
      %1 = max %x, %0 : !riscv.reg
      %2 = neg %1 : !riscv.reg
      ret %2 : !riscv.reg
  }]
  rhs := [LV| {
    ^entry (%x: !riscv.reg):
      %0 = neg %x : !riscv.reg
      %1 = min %x, %0 : !riscv.reg
      ret %1 : !riscv.reg
  }]

@[simp_denote]
def llvm_shl_lower_riscv_64: LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := shl_llvm_64
  rhs := shl_riscv_64

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

def or_and_or_pat4_after := [llvm|
{
^0(%arg26 : i8, %arg27 : i8, %arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg28 : i8
  %2 = llvm.or %arg29, %arg26 : i8
  %3 = llvm.and %2, %arg27 : i8
  %4 = llvm.or %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

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

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

BitVec.setWidth in Init.Data.BitVec.Basic

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

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

def shift_trunc_wrong_cmp_before := [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 : i32 to i8
  %4 = llvm.icmp "slt" %3, %1 : i8
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

def lshr_mul_times_5_div_4_exact_2_before := [llvm|
{
^0(%arg23 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.mul %arg23, %0 overflow<nuw> : i32
  %3 = llvm.lshr exact %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def and_ne_with_one_bit_diff_constants1_before := [llvm|
{
^0(%arg364 : i32):
  %0 = llvm.mlir.constant(51 : i32) : i32
  %1 = llvm.mlir.constant(50 : i32) : i32
  %2 = llvm.icmp "ne" %arg364, %0 : i32
  %3 = llvm.icmp "ne" %arg364, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

def llvm_const_lower_riscv_li26 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM26, rhs:= liRiscv26,
   correct := by admit /- proof elided -/

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

def ashr_ashr_before := [llvm|
{
^0(%arg7 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(7 : i32) : i32
  %2 = llvm.ashr %arg7, %0 : i32
  %3 = llvm.ashr %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

def test15_before := [llvm|
{
^0(%arg6 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(8) : i64
  %2 = llvm.ashr %arg6, %0 : i32
  %3 = llvm.sext %2 : i32 to i64
  %4 = llvm.sub %1, %3 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

def negate_zext_after := [llvm|
{
^0(%arg96 : i8, %arg97 : i1):
  %0 = llvm.sext %arg97 : i1 to i8
  %1 = llvm.add %arg96, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

@[match_pattern] abbrev unary  (w : Nat) (op : MOp.UnaryOp 0) : LLVM.Op :=
  MOp.unary (.concrete w) op

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

def test_invert_demorgan_or2_before := [llvm|
{
^0(%arg15 : i64, %arg16 : i64, %arg17 : i64):
  %0 = llvm.mlir.constant(23) : i64
  %1 = llvm.mlir.constant(59) : i64
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.icmp "ugt" %arg15, %0 : i64
  %4 = llvm.icmp "ugt" %arg16, %1 : i64
  %5 = llvm.or %3, %4 : i1
  %6 = llvm.icmp "ugt" %arg17, %1 : i64
  %7 = llvm.or %5, %6 : i1
  %8 = llvm.xor %7, %2 : i1
  "llvm.return"(%8) : (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 both_after := [llvm|
{
^0(%arg17 : i8, %arg18 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.shl %0, %arg17 overflow<nsw> : i8
  %2 = llvm.shl %0, %arg18 overflow<nsw> : i8
  %3 = llvm.icmp "ugt" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

def masked_or_allones_logical_before := [llvm|
{
^0(%arg126 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(39 : i32) : i32
  %2 = llvm.mlir.constant(true) : i1
  %3 = llvm.and %arg126, %0 : i32
  %4 = llvm.icmp "eq" %3, %0 : i32
  %5 = llvm.and %arg126, %1 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = "llvm.select"(%4, %2, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (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 bools2_logical_commute1_and1_before := [llvm|
{
^0(%arg49 : i1, %arg50 : i1, %arg51 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.xor %arg51, %0 : i1
  %3 = llvm.and %arg49, %arg51 : i1
  %4 = "llvm.select"(%2, %arg50, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %5 = "llvm.select"(%3, %0, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

def shl_add_lshr_flag_preservation_before := [llvm|
{
^0(%arg157 : i32, %arg158 : i32, %arg159 : i32):
  %0 = llvm.shl %arg157, %arg158 overflow<nuw> : i32
  %1 = llvm.add %0, %arg159 overflow<nsw,nuw> : i32
  %2 = llvm.lshr exact %1, %arg158 : i32
  "llvm.return"(%2) : (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 t0_before := [llvm|
{
^0(%arg22 : i32, %arg23 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.xor %arg22, %0 : i32
  %3 = llvm.add %2, %arg23 : i32
  %4 = llvm.add %3, %1 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def ofInt (x : Int) : FSM (Fin 0) :=
  match x with
  | .ofNat n => ofNat n
  | .negSucc n =>
      composeUnaryAux neg (ofNat (n + 1))

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

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

instance : Functor RegionSignature where
  map := RegionSignature.map

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

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

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

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

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

unsafe def elabIntoTermTactic {α : Type} (expectedType : Expr) (stx : Lean.Syntax) :
    Elab.Tactic.TacticM α := do
  let expr ← Lean.Elab.Tactic.elabTerm stx none
  let _ ← Meta.isDefEq (← Meta.inferType expr) expectedType
  Elab.Term.synthesizeSyntheticMVarsNoPostponing
  let expr ← instantiateMVars expr
  Meta.evalExpr α expectedType expr

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

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

def sub_sel_op1_before := [llvm|
{
^0(%arg11 : i1):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(41 : i32) : i32
  %2 = "llvm.select"(%arg11, %0, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %3 = llvm.sub %0, %2 overflow<nsw> : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

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

partial def Expr.print (e : Expr d Γ eff t) : Format :=
  let regions :=
    match h : e.regArgs.length with
    | 0 => f!""
    | 1 =>
      let reg := e.regArgs.getN 0 (by admit /- proof elided -/
      )
      f!" ({reg.print})"
    | _ =>
      let regs :=
        e.regArgs.mapToList (Format.align true ++ Com.print ·)
        |> f!", ".joinSep
        |> Format.nest 2
      f!" ({regs})"
  Format.align true ++ f!"{e.printResultList}\"{printOpName e.op}\"{e.printArgs}{printAttributes e.op}{regions} : {e.printType}"

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

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

@[simp_denote]
def shl_riscv_16 := [LV| {
  ^entry (%reg1: i16, %reg2: i16 ):
    %0 = "builtin.unrealized_conversion_cast"(%reg1) : (i16) -> (!i64)
    %1 = "builtin.unrealized_conversion_cast"(%reg2) : (i16) -> (!i64)
    %2 = sll %0, %1 : !i64
    %3 = "builtin.unrealized_conversion_cast"(%2) : (!i64) -> (i16)
    llvm.return %3 : i16
  }]

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

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

RV64.pack in RISCV.Instructions

def n11_wrong_pred3_before := [llvm|
{
^0(%arg8 : i8, %arg9 : i8):
  %0 = llvm.add %arg8, %arg9 : i8
  %1 = llvm.icmp "ne" %0, %arg9 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def sext_shl_mask_before := [llvm|
{
^0(%arg7 : i16, %arg8 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.sext %arg7 : i16 to i32
  %2 = llvm.shl %1, %arg8 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

def AttrEntry.destructure {φ} : AttrEntry φ → String × AttrValue φ
  | .mk name value => (name,value)

@[simp_llvm_option]
def add {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.saddOverflow x' y' then
    .poison
  else if flags.nuw ∧ BitVec.uaddOverflow x' y' then
    .poison
  else
    add? x' y'

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

def ne_basic_equal_minus_7_before := [llvm|
{
^0(%arg28 : i8, %arg29 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(-7 : i8) : i8
  %2 = llvm.add %arg28, %0 : i8
  %3 = llvm.icmp "ne" %arg28, %1 : i8
  %4 = llvm.icmp "ule" %2, %arg29 : i8
  %5 = llvm.and %3, %4 : i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def add_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) :=[
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_noflags_1),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nsw_flag_1),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_flag_1),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_nsw_flag_1),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_noflags_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nsw_flag_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_flag_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_nsw_flag_8),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_noflags_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nsw_flag_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_flag_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_nsw_flag_16),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_noflags_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nsw_flag_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_flag_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_nsw_flag_32),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_noflags_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nsw_flag_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_flag_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_add_lower_riscv_nuw_nsw_flag_64),
]

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

def or_shl_after := [llvm|
{
^0(%arg640 : i8, %arg641 : i8, %arg642 : i8, %arg643 : i8):
  %0 = llvm.or %arg640, %arg641 : i8
  %1 = llvm.shl %0, %arg643 : i8
  %2 = llvm.or %1, %arg642 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

Int.cast in Init.Data.Int.Basic

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

CoeOut in Init.Coe

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

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

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

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

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

@[simp_denote]
def srai_riscv_i64 :=
  [LV| {
    ^entry (%arg: i64):
    %a = "builtin.unrealized_conversion_cast" (%arg) : (i64) -> (!i64)
    %0 = srai %a, 9 : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i64)
    llvm.return %1 : i64
  }]

def ne_210_after := [llvm|
{
^0(%arg76 : i32, %arg77 : i32):
  %0 = llvm.trunc %arg76 : i32 to i24
  %1 = llvm.trunc %arg77 : i32 to i24
  %2 = llvm.icmp "ne" %0, %1 : i24
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

def orn_and_cmp_2_partial_logical_after := [llvm|
{
^0(%arg6 : i16, %arg7 : i16, %arg8 : i1):
  %0 = llvm.icmp "slt" %arg6, %arg7 : i16
  %1 = llvm.or %arg8, %0 : i1
  "llvm.return"(%1) : (i1) -> ()
}
]

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

BitVec.reverse in Init.Data.BitVec.Basic

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

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 bad_add0_after := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg2 overflow<nuw> : i32
  %2 = llvm.add %1, %arg3 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

def CollectState.mkNatEnvCons (nenv : Expr) (n : Expr) : SolverM Expr := do
  let out ← mkAppM (``MultiWidth.Term.NatEnv.cons) #[nenv, n]
  debugCheck out
  return out

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

inductive Term {wcard tcard : Nat} (bcard : Nat) (ncard : Nat) (icard : Nat) (pcard : Nat)
  (tctx : Term.Ctx wcard tcard) : TermKind wcard → Type







 
| ofNat (w : WidthExpr wcard) (n : Nat) : Term bcard ncard icard pcard tctx (.bv w)
 
| var (v : Fin tcard) : Term bcard ncard icard pcard tctx (.bv (tctx v))
 
| add (a : Term bcard ncard icard pcard tctx (.bv w))
  (b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| shiftl (a : Term bcard ncard icard pcard tctx (.bv w)) (k : Nat) : Term bcard ncard icard pcard tctx (.bv w)
 
| bor (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| band (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| bxor (a b : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| bnot (a : Term bcard ncard icard pcard tctx (.bv w)) : Term bcard ncard icard pcard tctx (.bv w)
 
| zext (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| setWidth (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| sext (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) : Term bcard ncard icard pcard tctx (.bv v)
 
| bvOfBool (b : Term bcard ncard icard pcard tctx .bool) : Term bcard ncard icard pcard tctx (.bv (.const 1))

| boolConst (b : Bool) : Term bcard ncard icard pcard tctx .bool
| boolVar (v : Fin bcard) : Term bcard ncard icard pcard tctx .bool
| binWidthRel (k : WidthBinaryRelationKind) (wa wb : WidthExpr wcard) :
    Term bcard ncard icard pcard tctx .prop
| binRel
    (k : BinaryRelationKind)
    (w : WidthExpr wcard)
    (a : Term bcard ncard icard pcard tctx (.bv w))
    (b : Term bcard ncard icard pcard tctx (.bv w)) :
    Term bcard ncard icard pcard tctx .prop
| and (p1 p2 : Term bcard ncard icard pcard tctx (.prop)) : Term bcard ncard icard pcard tctx (.prop)
| or (p1 p2 : Term bcard ncard icard pcard tctx (.prop)) : Term bcard ncard icard pcard tctx (.prop)
| pvar (v : Fin pcard) : Term bcard ncard icard pcard tctx (.prop) 






| boolBinRel
  (k : BoolBinaryRelationKind)
  (a b : Term bcard ncard icard pcard tctx .bool) :
  Term bcard ncard icard pcard tctx (.prop)

def a_or_b_const2_before := [llvm|
{
^0(%arg6 : i32, %arg7 : i32, %arg8 : i32, %arg9 : i32):
  %0 = llvm.icmp "eq" %arg6, %arg8 : i32
  %1 = llvm.icmp "ne" %arg7, %arg9 : i32
  %2 = llvm.and %0, %1 : i1
  %3 = llvm.icmp "ne" %arg6, %arg8 : i32
  %4 = llvm.icmp "eq" %arg7, %arg9 : i32
  %5 = llvm.and %3, %4 : i1
  %6 = llvm.or %2, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

abbrev BVNRel n := ∀ ⦃w⦄, List.Vector (BitVec w) n → Prop

def ashr_icmp2_after := [llvm|
{
^0(%arg26 : i64):
  %0 = llvm.mlir.constant(16) : i64
  %1 = llvm.icmp "slt" %arg26, %0 : i64
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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 canonicalize_logic_first_or0_nsw_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(112 : i32) : i32
  %1 = llvm.mlir.constant(15 : i32) : i32
  %2 = llvm.add %arg39, %0 overflow<nsw> : i32
  %3 = llvm.or %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

def mkTermFsmNondep (wcard tcard bcard ncard icard pcard : Nat) (p : Nondep.Term) :
  (TermFSM wcard tcard bcard ncard icard pcard p) :=
    let fsm := mkTermFSM wcard tcard bcard ncard icard pcard p
    { toFsmZext := ~~~ fsm.toFsmZext, width := fsm.width }

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

structure BVExprWrapper where
  width : Nat
  bvExpr: GenBVExpr width

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

def trunc_sel_smaller_zext_after := [llvm|
{
^0(%arg69 : i64, %arg70 : i1):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(42 : i32) : i32
  %2 = llvm.trunc %arg69 : i64 to i32
  %3 = llvm.and %2, %0 : i32
  %4 = "llvm.select"(%arg70, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def urem_i32_before := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.zext %arg21 : i8 to i32
  %1 = llvm.zext %arg22 : i8 to i32
  %2 = llvm.urem %0, %1 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

Union in Init.Core
</all_available_defs>

<all_available_lemmas>
BitVec.msb_eq_getLsbD_last in Init.Data.BitVec.Lemmas

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

theorem test16_proof : test16_before ⊑ test16_after

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

theorem t2_symmetry_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ofBool (x_1 + x <ᵤ x_1) = ofBool (x_1 ^^^ -1#8 <ᵤ x)

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

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

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

theorem scalar_i8_shl_uge_const_thm (e : IntW 8) :
  icmp IntPred.uge (shl e (const? 8 5)) (const? 8 64) ⊑
    icmp IntPred.ne (LLVM.and e (const? 8 6)) (const? 8 0)

omit [LawfulBEq A] [Fintype S] in
lemma processOneElem_rel_preserve :
    s₂ ~[st.rel] sa' →
    s₂ ~[(processOneElem A S final s₁ st (a, sa)).rel] sa'

theorem src_x_and_nmask_eq_proof : src_x_and_nmask_eq_before ⊑ src_x_and_nmask_eq_after

theorem test18_thm (e : IntW 128) : sub (shl e (const? 128 2)) (shl e (const? 128 2)) ⊑ const? 128 0

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

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

theorem trunc_equality_both_sext_proof : trunc_equality_both_sext_before ⊑ trunc_equality_both_sext_after

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

theorem ashr_ule_exact_proof : ashr_ule_exact_before ⊑ ashr_ule_exact_after

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 badimm1_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 9#16 ≥ ↑16) →
    ¬ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 9#16)) = 1#1 →
      ¬15#16 ≥ ↑16 →
        7#8 ≥ ↑8 ∨
            9#16 ≥ ↑16 ∨
              True ∧ signExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 ∨
                True ∧ zeroExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 →
          False

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

theorem test_invert_demorgan_and3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + (x ^^^ -1#32) &&& 4095#32 == 0#32) = ofBool (x - x_1 &&& 4095#32 == 4095#32)

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

theorem test35_with_trunc_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (0#32 ≤ₛ truncate 32 x) = 1#1 → ¬ofBool (x &&& 2147483648#64 == 0#64) = 1#1 → 60#32 = 100#32

theorem test10_proof : test10_before ⊑ test10_after

theorem sext_multiuse_proof : sext_multiuse_before ⊑ sext_multiuse_after

theorem mul_constant_eq_proof : mul_constant_eq_before ⊑ mul_constant_eq_after

theorem icmp_eq_zext_ne_non_boolean_thm (e : IntW 32) :
  icmp IntPred.eq (zext 32 (icmp IntPred.ne e (const? 32 2))) e ⊑
    icmp IntPred.eq e (const? 32 1)

theorem testi16i8_ne_proof : testi16i8_ne_before ⊑ testi16i8_ne_after

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

@[simp] theorem Com.returnVars_rets : returnVars (rets vs : Com d Γ eff t) = vs

theorem ashr_can_be_lshr_2_thm (e : IntW 32) :
  trunc 32 (ashr (shl (LLVM.or (zext 64 e) (const? 64 4278190080)) (const? 64 34)) (const? 64 32) { «exact» := true })
      { «nsw» := true, «nuw» := false } ⊑
    LLVM.or (shl e (const? 32 2)) (const? 32 (-67108864))

theorem R.representative_fromPoly :
    forall a : (ZMod q)[X], (R.fromPoly (n:=n) a).representative = a %ₘ (f q n)

theorem test_shl_nsw__nuw_is_safe_proof : test_shl_nsw__nuw_is_safe_before ⊑ test_shl_nsw__nuw_is_safe_after

theorem lshrult_03_09_proof : lshrult_03_09_before ⊑ lshrult_03_09_after

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

theorem sgt_3_impliesF_eq_2_thm (e e_1 : IntW 8) :
  icmp IntPred.eq (select (icmp IntPred.sgt e_1 (const? 8 3)) (const? 8 2) e) e_1 ⊑
    select (icmp IntPred.slt e_1 (const? 8 4)) (icmp IntPred.eq e e_1) (const? 1 0)

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_after

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

theorem alive_AndOrXor_2627 : alive_AndOrXor_2627_src ⊑ alive_AndOrXor_2627_tgt

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

theorem badimm1_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 9#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 == truncate 8 (x >>> 9#16)) = 1#1 →
      7#8 ≥ ↑8 ∨
          9#16 ≥ ↑16 ∨
            True ∧ signExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 ∨
              True ∧ zeroExtend 16 (truncate 8 (x >>> 9#16)) ≠ x >>> 9#16 →
        False

theorem or_or_logic_and_1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1), ¬x_1 ||

theorem select_add_icmp_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.eq e_2 (const? 32 0)) (add e_2 e_1) e ⊑
    select (icmp IntPred.eq e_2 (const? 32 0)) e_1 e

theorem shl_ashr_pow2_const_case1_thm (e : IntW 16) :
  LLVM.and (ashr (shl (const? 16 4) e) (const? 16 6)) (const? 16 8) ⊑
    select (icmp IntPred.eq e (const? 16 7)) (const? 16 8) (const? 16 0)

theorem add_select_zext_proof : add_select_zext_before ⊑ add_select_zext_after

theorem e_822 :
     - 7 *  ~~~(z &&&  ~~~t) - 2 * t + 7 * (z |||  ~~~t) - 7 * (z &&&  ~~~t) + 2 * (z &&& t) =  - 9 *  ~~~(z |||  ~~~t)

theorem bv_AndOrXor_1733 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.or (LLVM.icmp LLVM.IntPred.ne e (LLVM.const? w 0)) (LLVM.icmp LLVM.IntPred.ne e_1 (LLVM.const? w 0)) ⊑
        LLVM.icmp LLVM.IntPred.ne (LLVM.or e e_1) (LLVM.const? w 0)

theorem test46_proof : test46_before ⊑ test46_after

theorem ashr_slt_exact_near_pow2_cmpval_proof : ashr_slt_exact_near_pow2_cmpval_before ⊑ ashr_slt_exact_near_pow2_cmpval_after

theorem icmp_sgt7_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ (x <<< 1#8).sshiftRight' 1#8 ≠ x ∨ 1#8 ≥ ↑8) → ofBool (124#8 <ₛ x <<< 1#8) = ofBool (62#8 <ₛ x)

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

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

theorem 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 icmp_equality_test_commute_icmp2_proof : icmp_equality_test_commute_icmp2_before ⊑ icmp_equality_test_commute_icmp2_after

theorem scalar_i16_signbit_lshr_and_eq_proof : scalar_i16_signbit_lshr_and_eq_before ⊑ scalar_i16_signbit_lshr_and_eq_after

theorem neg_signbit_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → 0#32 - zeroExtend 32 (x >>> 7#8) = signExtend 32 (x.sshiftRight' 7#8)

theorem test_zext3_thm.extracted_1._2 : ∀ (x : BitVec 1), x = 1#1 → ¬x ^^^ 1#1 = 1#1 → 0#32 = zeroExtend 32 0#1

lemma Bisim.comp {M₁ : NFA A σ1} {M₂ : NFA A σ₂} {M₃ : NFA A σ₃}  :
    M₁.Bisim M₂ → M₂.Bisim M₃ → M₁.Bisim M₃

theorem uge_to_sgt_proof : uge_to_sgt_before ⊑ uge_to_sgt_after

private theorem Int.lt_of_neg {i : Int} (hi : i < - 1) : i < i / 2

theorem n8_wrong_pred3_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (sub e_1 e) e_1 ⊑ icmp IntPred.ne e (const? 8 0)

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

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

theorem e_1410 :
     - 6 * z - 3 *  ~~~z - 11 * (z ^^^ t) - 5 *  ~~~(z &&&  ~~~t) - 1 * t - 1 *  ~~~(z &&& t) + 7 *  ~~~(z ||| t) + 21 *  ~~~(z |||  ~~~t) + 18 * (z &&&  ~~~t) + 10 * (z &&& t) =  - 2 *  ~~~(z ^^^ t)

theorem gt_unsigned_to_large_negative_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (BitVec.ofInt 32 (-1024) <ₛ zeroExtend 32 x) = 1#1

theorem p3_sgt_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (65534#32 <ₛ x) = 1#1 → ¬ofBool (x <ₛ 65535#32) = 1#1 → False

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

@[simp]
theorem Term.denote_width_zero  (t : Term) (env : Env 0) :
    t.denote env = 0

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

theorem sext_diff_i1_xor_sub_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  True ∧ (zeroExtend 64 x).saddOverflow (signExtend 64 x_1) = true → False

theorem lshrugt_01_14_proof : lshrugt_01_14_before ⊑ lshrugt_01_14_after

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

theorem e_1780 :
    1 * (a &&& b) + 5 * (a |||  ~~~b) - 1 * a - 2 *  ~~~(a ||| c) + 7 *  ~~~(a &&& (b &&& c)) + 11 * b - 2 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 5 * ( ~~~b |||  ~~~(a ^^^ c)) - 2 * (c ^^^  ~~~(a |||  ~~~b)) + 1 * ((a &&& b) ^^^ (b |||  ~~~c)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 3 * (a &&& (b ||| c)) + 1 * (b ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 2 * (c ^^^  ~~~(a &&&  ~~~b)) + 1 * (a ^^^ ( ~~~b ||| c)) - 5 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 5 * ((b &&& c) ^^^  ~~~(a &&& (b ^^^ c))) + 5 * (a ^^^ ( ~~~b &&& c)) + 5 *  ~~~(a &&&  ~~~a) + 11 * (b ^^^ (a ||| (b ||| c))) + 3 * (c ^^^  ~~~(a ||| (b &&& c))) + 3 * ((a ^^^ b) ||| (a ^^^ c)) + 2 * (b ||| (a &&& c)) - 1 * ( ~~~a ||| ( ~~~b ||| c)) + 11 * c - 5 * ( ~~~a &&& (b ||| c)) + 3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 1 * (a ^^^ c) - 9 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) - 31 *  ~~~( ~~~a ||| (b ||| c)) - 38 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 40 * ( ~~~a &&& ( ~~~b &&& c)) - 33 * ( ~~~a &&& (b &&& c)) - 44 * (a &&& ( ~~~b &&& c)) - 42 * (a &&& (b &&& c)) = 1 * (c &&& (a ||| b))

theorem or_and_not_not_proof : or_and_not_not_before ⊑ or_and_not_not_after

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

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

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

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

theorem modulo4_proof : modulo4_before ⊑ modulo4_after

theorem ashr_1_proof : ashr_1_before ⊑ ashr_1_after

theorem src4_proof : src4_before ⊑ src4_after

theorem test2_proof : test2_before ⊑ test2_after

theorem ashrslt_01_03_proof : ashrslt_01_03_before ⊑ ashrslt_01_03_after

@[simp]
theorem ofBitVecZextMsb_eq_concat_ofBitVecZext (x : BitVec w) :
    ofBitVecZextMsb x = (ofBitVecZext x).concat false

theorem test11_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 2#32 != 0#32) = 1#1 → 1#1 = ofBool (1#32 <ᵤ x)

theorem bv_239 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.mul (LLVM.sub (LLVM.const? w 0) e_1) (LLVM.sub (LLVM.const? w 0) e) ⊑ LLVM.mul e_1 e

theorem carry_neg (x : Unit → BitStream) : ∀ (n : ℕ), neg.carry x (n+1) =
    fun _ => (BitStream.negAux (x ()) n).2

theorem trunc_shl_7_i8_i64_thm.extracted_1._1 : ∀ (x : BitVec 64), ¬7#64 ≥ ↑64 → 7#8 ≥ ↑8 → False

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

theorem lshr_and_thm (e e_1 : IntW 8) :
  shl (LLVM.and (lshr e_1 (const? 8 6)) (LLVM.srem e (const? 8 42))) (const? 8 6) ⊑
    LLVM.and e_1 (shl (LLVM.srem e (const? 8 42)) (const? 8 6))

theorem sext_zext_ult_known_nonneg_proof : sext_zext_ult_known_nonneg_before ⊑ sext_zext_ult_known_nonneg_after

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

theorem bools2_logical_commute0_and1_proof : bools2_logical_commute0_and1_before ⊑ bools2_logical_commute0_and1_after

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

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

theorem ule_swap_and_min_commute_logical_proof : ule_swap_and_min_commute_logical_before ⊑ ule_swap_and_min_commute_logical_after

theorem test8_logical_proof : test8_logical_before ⊑ test8_logical_after

theorem select_non_const_sides_thm.extracted_1._4 : ∀ (x x_1 : BitVec 64) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → x - zeroExtend 64 x_2 = x

theorem rewrite_a_snd (stream_d : Stream α) (stream_c : Stream (BitVec 1)):
    (HandshakeOp.branch stream_d stream_c).snd =
    (HandshakeOp.supp (HandshakeOp.fork stream_d).fst (HandshakeOp.fork stream_c).fst)

theorem urem_i32_multiuse_thm (e e_1 : IntW 8) :
  mul (urem (zext 32 e_1) (zext 32 e)) (add (zext 32 e_1) (zext 32 e)) ⊑
    mul (urem (zext 32 e_1) (zext 32 e)) (add (zext 32 e_1) (zext 32 e) { «nsw» := true, «nuw» := true })
      { «nsw» := true, «nuw» := true }

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 and_zext_eq_even_proof : and_zext_eq_even_before ⊑ and_zext_eq_even_after

theorem mul_select_zext_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → 1#64 * zeroExtend 64 x_1 = 0#64

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

theorem bools_logical_commute0_and2_thm.extracted_1._9 : ∀ (x x_1 : BitVec 1),
  ¬x_1 ^^^ 1#1 = 1#1 → ¬x_1 = 1#1 → 0#1 = 1#1 → False

theorem add_nosignbit_select_shl_proof : add_nosignbit_select_shl_before ⊑ add_nosignbit_select_shl_after

theorem test_mul__nuw_is_safe_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x &&& 268435457#32 == 268435456#32) = 1#1 →
    ¬(True ∧ (x &&& 268435457#32).umulOverflow 9#32 = true) →
      BitVec.ofInt 32 (-1879048192) = (x &&& 268435457#32) * 9#32

@[simp] lemma eval_bOr :
  ∀ {s : List α} {f : α → Circuit β} {g : β → Bool},
    eval (bOr s f) g = ∃ a ∈ s, eval (f a) g

theorem src_is_mask_and_proof : src_is_mask_and_before ⊑ src_is_mask_and_after

theorem p1_scalar_urem_by_nonconst_proof : p1_scalar_urem_by_nonconst_before ⊑ p1_scalar_urem_by_nonconst_after

theorem slt_proof : slt_before ⊑ slt_after

theorem negtest_near_pow2_cmpval_isnt_close_to_pow2_thm (e : IntW 8) :
  icmp IntPred.slt (ashr e (const? 8 1) { «exact» := true }) (const? 8 6) ⊑
    icmp IntPred.slt e (const? 8 12)

theorem lshrugt_01_01_proof : lshrugt_01_01_before ⊑ lshrugt_01_01_after

theorem e_1141 :
    4 * t - 1 * z + 5 *  ~~~(z &&&  ~~~z) + 4 * (z |||  ~~~t) + 7 *  ~~~(z &&& t) - 16 *  ~~~(z ||| t) - 16 * (z &&&  ~~~t) - 12 * (z &&& t) =  - 1 * (z ^^^ t) + 17 *  ~~~(z |||  ~~~t)

theorem a_proof : a_before ⊑ a_after

theorem lshr_eq_both_equal_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool (127#8 >>> x == 127#8) = ofBool (x == 0#8)

theorem BitVec.even_mul_eq_shiftLeft_mul_of_eq_mul_two
    (w : Nat) (x : BitVec w) (n e : Nat) (he : e = n * 2) :
    (BitVec.ofNat w e) * x = (BitVec.ofNat w n) * (x <<< (1 : Nat))

theorem or_to_nxor4_proof : or_to_nxor4_before ⊑ or_to_nxor4_after

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

theorem test2_proof : test2_before ⊑ test2_after

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

theorem lshrult_02_08_exact_proof : lshrult_02_08_exact_before ⊑ lshrult_02_08_exact_after

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

theorem t3_proof : t3_before ⊑ t3_after

theorem test3_proof : test3_before ⊑ test3_after

theorem slt_zero_slt_i1_fail_proof : slt_zero_slt_i1_fail_before ⊑ slt_zero_slt_i1_fail_after

theorem left_shift_add_1 (hu : u >= r) (hs : s >= r) :
  (bw r (shlMax (bw s (addMax (bw p a) (bw q b))) (bw t c)))  =
  (bw r (addMax (bw u (shlMax (bw p a) (bw t c))) (bw u (shlMax (bw q b) (bw t c)))))

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

theorem test13_proof : test13_before ⊑ test13_after

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

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

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

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

theorem lshrugt_02_15_proof : lshrugt_02_15_before ⊑ lshrugt_02_15_after

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

theorem e_351 :
    5 *  ~~~(x &&&  ~~~y) - 6 * (x ||| y) - 1 * (x ^^^ y) - 1 * y - 4 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) + 8 * (x &&&  ~~~y) + 2 * (x &&& y) = 1 *  ~~~(x &&& y)

theorem test11_proof : test11_before ⊑ test11_after

theorem and_nosignbit_select_lshr_proof : and_nosignbit_select_lshr_before ⊑ and_nosignbit_select_lshr_after

theorem corec₂_eq_corec_of_corec₂ (streamInt: DCOp.ValueStream Int) :
    (corec₂ streamInt fun x => (x 0, x 0, x.tail)).1 ≈
    corec
      ((corec₂ streamInt fun (x : DCOp.ValueStream Int) =>
            (match x 0 with
              | some val => (x 0, some (), x.tail)
              | none => (none, none, x.tail))).1,
        (corec₂
            (corec₂ streamInt fun x =>
                (match x 0 with
                  | some val => (x 0, some (), x.tail)
                  | none => (none, none, x.tail))).2
            fun x => Id.run (x 0, x 0, tail x)).1)
      fun x =>
      match x.1 0, x.2 0 with

theorem add_shl_same_amount_partial_nsw2_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 6),
  ¬(x_1 ≥ ↑6 ∨
        True ∧ (x <<< x_1).sshiftRight' x_1 ≠ x ∨ x_1 ≥ ↑6 ∨ True ∧ (x_2 <<< x_1).saddOverflow (x <<< x_1) = true) →
    ¬x_1 ≥ ↑6 → x_2 <<< x_1 + x <<< x_1 = (x_2 + x) <<< x_1

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

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

theorem test17_thm (e e_1 : IntW 8) :
  mul (LLVM.or (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.or (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 scalar_i32_lshr_and_signbit_eq_proof : scalar_i32_lshr_and_signbit_eq_before ⊑ scalar_i32_lshr_and_signbit_eq_after

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

theorem shl_add_add_no_const_thm (e e_1 e_2 e_3 : IntW 8) :
  add (shl e_3 e_2) (add (shl e_1 e_2) e) ⊑ add (shl (add e_1 e_3) e_2) e

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

theorem test1_thm (e e_1 : IntW 17) :
  LLVM.and (LLVM.or (LLVM.and e_1 (const? 17 7)) (LLVM.and e (const? 17 8))) (const? 17 7) ⊑
    LLVM.and e_1 (const? 17 7)

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

theorem Tensor2d'.map_error (f : α → β) : (Tensor2d'.error α).map f = Tensor2d'.error β

theorem test18_proof : test18_before ⊑ test18_after

theorem shl_lshr_demand3_thm (e : IntW 8) :
  LLVM.or (lshr (shl (const? 8 40) e) (const? 8 3)) (const? 8 (-64)) ⊑
    LLVM.or (lshr (shl (const? 8 40) e) (const? 8 3) { «exact» := true }) (const? 8 (-64))
      { «disjoint» := true }

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

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

theorem foo1_or_signbit_lshr_without_shifting_signbit_logical_proof : foo1_or_signbit_lshr_without_shifting_signbit_logical_before ⊑ foo1_or_signbit_lshr_without_shifting_signbit_logical_after

theorem test34_proof : test34_before ⊑ test34_after

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

theorem ashrslt_03_07_proof : ashrslt_03_07_before ⊑ ashrslt_03_07_after

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

theorem test1_proof : test1_before ⊑ test1_after

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

theorem lshrult_01_02_proof : lshrult_01_02_before ⊑ lshrult_01_02_after

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

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 333),
  ¬70368744177664#333 = 0 → x % 70368744177664#333 = x &&& 70368744177663#333

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

theorem ashr_pow2_ugt_proof : ashr_pow2_ugt_before ⊑ ashr_pow2_ugt_after

theorem width_1_char_2 (x : BitVec w) (hw : w = 1) : x + x = 0#w

theorem cmpne_xor_cst1_proof : cmpne_xor_cst1_before ⊑ cmpne_xor_cst1_after

theorem ashrslt_01_10_exact_proof : ashrslt_01_10_exact_before ⊑ ashrslt_01_10_exact_after

theorem test_or2_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ≤ₛ -1#32) = 1#1 → ¬ofBool (x_1 <ₛ 0#32) = 1#1 → 1#1 = ofBool (x &&& 2147483647#32 <ₛ x_1)

theorem lshr_eq_opposite_msb_proof : lshr_eq_opposite_msb_before ⊑ lshr_eq_opposite_msb_after

theorem or_and2_proof : or_and2_before ⊑ or_and2_after

theorem positive_biggerlshr_shlnsw_thm (e : IntW 8) :
  shl (lshr e (const? 8 6)) (const? 8 3) { «nsw» := true, «nuw» := false } ⊑
    LLVM.and (lshr e (const? 8 3)) (const? 8 24)

@[bv_automata_nnf↓] theorem not_ite {_ : Decidable p} (q r : Prop) : (¬ite p q r) = ite p (¬q) (¬r)

theorem test67_thm (e : IntW 1) (e_1 : IntW 32) :
  icmp IntPred.eq
      (trunc 8
        (ashr
          (LLVM.xor
            (shl (LLVM.and e_1 (LLVM.xor (zext 32 e) (const? 32 1))) (const? 32 24) { «nsw» := true, «nuw» := true })
            (const? 32 (-16777216)))
          (const? 32 24) { «exact» := true }))
      (const? 8 0) ⊑
    const? 1 0

theorem canonicalize_logic_first_and0_nsw_thm (e : IntW 8) :
  LLVM.and (add e (const? 8 48) { «nsw» := true, «nuw» := false }) (const? 8 (-10)) ⊑
    add (LLVM.and e (const? 8 (-10))) (const? 8 48) { «nsw» := true, «nuw» := false }

theorem Expr.eff_le {Γ : Ctxt d.Ty} {ty} (e : Expr d Γ eff ty) :
  DialectSignature.effectKind e.op ≤ eff

theorem test7_logical_proof : test7_logical_before ⊑ test7_logical_after

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 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 slt_negative_multip_rem_zero_thm (e : IntW 8) :
  icmp IntPred.slt (mul e (const? 8 (-7)) { «nsw» := true, «nuw» := false }) (const? 8 21) ⊑
    icmp IntPred.sgt e (const? 8 (-3))

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

theorem not_xor_eq_and_add_not_or :
    ~~~ (x ^^^ y) = (x &&& y) + ~~~ (x ||| y)

theorem e_833 :
     - 1 *  ~~~(z ^^^ t) + 12 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) + 9 * (z &&& t) =  - 3 * (z ||| t) + 11 * (z |||  ~~~t)

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

theorem lshr_32_add_not_known_32_leading_zeroes_proof : lshr_32_add_not_known_32_leading_zeroes_before ⊑ lshr_32_add_not_known_32_leading_zeroes_after

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

theorem ugt_rem_zero_nsw_thm (e : IntW 8) :
  icmp IntPred.ugt (mul e (const? 8 7) { «nsw» := true, «nuw» := true }) (const? 8 21) ⊑
    icmp IntPred.ugt e (const? 8 3)

theorem n6_proof : n6_before ⊑ n6_after

theorem t3_ult_sgt_neg1_proof : t3_ult_sgt_neg1_before ⊑ t3_ult_sgt_neg1_after

theorem trunc_sel_equal_sext_thm.extracted_1._1 : ∀ (x : BitVec 1), ¬x = 1#1 → signExtend 32 42#16 = 42#32

theorem test_sub_127_Y_eq_127_proof : test_sub_127_Y_eq_127_before ⊑ test_sub_127_Y_eq_127_after

lemma Predicate.evalFin_eq_eval (p : Predicate)
   (varsList : List BitStream) (varsFin : Fin p.arity → BitStream)
   (hvars : ∀ (i : Fin p.arity), varsList.getD i default = (varsFin i)) :
    Predicate.evalFin p varsFin  = Predicate.eval p varsList

theorem or_xor_xor_normal_variant3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 16),
  x_1 ^^^ x_1 &&& x ||

theorem icmp_mul_nsw_slt_proof : icmp_mul_nsw_slt_before ⊑ icmp_mul_nsw_slt_after

theorem select_constants_and_icmp_ne0_zero_tval_thm.extracted_1._2 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 → ¬x = 1#1 → ofBool (0#8 &&& 12#8 != 0#8) = 1#1 ^^^ 1#1

theorem negative4_proof : negative4_before ⊑ negative4_after

theorem add_select_not_sext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (sext 64 (LLVM.xor e (const? 1 1))) ⊑
    select e (const? 64 64) (const? 64 0)

theorem sext_sext_sge_op0_narrow_thm (e : IntW 8) (e_1 : IntW 5) :
  icmp IntPred.sge (sext 32 e_1) (sext 32 e) ⊑ icmp IntPred.sle e (sext 8 e_1)

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_proof : icmp_slt_0_or_icmp_sgt_0_i64_fail0_before ⊑ icmp_slt_0_or_icmp_sgt_0_i64_fail0_after

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

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

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

theorem test6a_thm.extracted_1._1 : ∀ (x : BitVec 55), ¬1#55 ≥ ↑55 → (x * 3#55) <<< 1#55 = x * 6#55

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

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

theorem trunc_sandwich_max_sum_shift_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(20#32 ≥ ↑32 ∨ 11#12 ≥ ↑12) →
    31#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32 ∨
          True ∧ zeroExtend 32 (truncate 12 (x >>> 31#32)) ≠ x >>> 31#32 →
      False

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

theorem or0 (w : Nat) (a b : BitVec w) : (a < b) ∨ (b ≤ a)

theorem fast_div_201_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(8#16 ≥ ↑16 ∨ 8#16 ≥ ↑16 ∨ 1#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) →
    ¬(True ∧ (zeroExtend 16 x).smulOverflow 71#16 = true ∨
          True ∧ (zeroExtend 16 x).umulOverflow 71#16 = true ∨
            8#16 ≥ ↑16 ∨
              True ∧
                  signExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠ (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                True ∧
                    zeroExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠
                      (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                  1#8 ≥ ↑8 ∨
                    True ∧ (zeroExtend 16 x).smulOverflow 71#16 = true ∨
                      True ∧ (zeroExtend 16 x).umulOverflow 71#16 = true ∨
                        8#16 ≥ ↑16 ∨
                          True ∧
                              signExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠
                                (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                            True ∧
                                zeroExtend 16 (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) ≠
                                  (zeroExtend 16 x * 71#16) >>> 8#16 ∨
                              True ∧
                                  ((x - truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>> 1#8).uaddOverflow
                                      (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) =
                                    true ∨
                                7#8 ≥ ↑8) →
      (truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16) +
            (x - truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>> 1#8) >>>
          7#8 =
        ((x - truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>> 1#8 +
            truncate 8 ((zeroExtend 16 x * 71#16) >>> 8#16)) >>>
          7#8

theorem e_2105 :
    1 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 11 *  ~~~(e &&& f) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 7 * ((d ||| e) &&& (e ^^^ f)) - 5 * (f ||| (d &&& e)) - 2 * (f &&& (d ||| e)) + 3 * ( ~~~f |||  ~~~(d ^^^ e)) - 5 * (f ^^^  ~~~(d &&& (e &&& f))) + 7 * (f ^^^  ~~~(d ||| (e &&& f))) + 2 * (d ||| e) + 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 1 * (e ^^^ (d &&& (e ^^^ f))) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 11 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 7 * (e ^^^  ~~~(d |||  ~~~f)) - 11 * (f ^^^ (d &&& (e ||| f))) - 2 * (e ^^^ (d &&&  ~~~f)) - 2 *  ~~~(d |||  ~~~f) - 1 *  ~~~( ~~~d ||| (e &&& f)) + 3 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 *  ~~~(d &&&  ~~~e) + 5 * (e ^^^ (d &&& ( ~~~e ||| f))) - 2 * ( ~~~e &&&  ~~~(d ^^^ f)) + 2 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 11 * ( ~~~f &&&  ~~~(d ^^^ e)) - 2 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 1 * (d ^^^ f) + 11 * ((d &&& f) |||  ~~~(e ||| f)) - 11 * (f ^^^ (d &&&  ~~~e)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 2 * (d ^^^ (e &&& f)) + 2 * (f ^^^ ( ~~~d ||| (e ||| f))) - 17 *  ~~~(d ||| (e ||| f)) + 17 *  ~~~(d ||| ( ~~~e ||| f)) + 25 *  ~~~( ~~~d ||| (e ||| f)) + 35 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 54 * ( ~~~d &&& ( ~~~e &&& f)) + 31 * ( ~~~d &&& (e &&& f)) + 2 * (d &&& (e &&& f)) =  - 10 * (d &&& ( ~~~e &&& f))

theorem fold_inverted_icmp_preds_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 <ₛ x_1) = 1#1 → ¬ofBool (x_1 ≤ₛ x_2) = 1#1 → False

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

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

theorem test54_proof : test54_before ⊑ test54_after

theorem slt_positive_multip_rem_zero_thm (e : IntW 8) :
  icmp IntPred.slt (mul e (const? 8 7) { «nsw» := true, «nuw» := false }) (const? 8 21) ⊑
    icmp IntPred.slt e (const? 8 3)

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

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

theorem icmp_shl_nsw_sge1_proof : icmp_shl_nsw_sge1_before ⊑ icmp_shl_nsw_sge1_after

theorem e_1733 :
    1 * (b ^^^  ~~~(a &&& (b ^^^ c))) - 2 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 4 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 7 *  ~~~(a ^^^ ( ~~~b ||| c)) + 11 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| (b ||| c))) - 7 * (b &&&  ~~~(a &&&  ~~~c)) - 6 *  ~~~(a ||| b) - 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) - 1 * (b &&& (a |||  ~~~c)) - 3 * ((a &&& b) |||  ~~~(b ||| c)) - 2 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 5 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) - 7 * (b &&&  ~~~(a ^^^ c)) + 1 * b - 3 *  ~~~(a &&& ( ~~~b ||| c)) - 2 * (c &&& (a ^^^ b)) + 1 * (a ||| (b &&& c)) + 3 *  ~~~( ~~~a ||| (b ^^^ c)) - 5 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 7 * (a ||| ( ~~~b ||| c)) - 1 * (c &&& (a ||| b)) + 36 *  ~~~(a ||| (b ||| c)) + 6 *  ~~~(a ||| ( ~~~b ||| c)) - 5 *  ~~~( ~~~a ||| (b ||| c)) + 25 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * ( ~~~a &&& ( ~~~b &&& c)) + 31 * ( ~~~a &&& (b &&& c)) - 4 * (a &&& ( ~~~b &&& c)) + 28 * (a &&& (b &&& c)) = 2 * (b ||| (a &&&  ~~~c))

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

theorem masked_or_allzeroes_notoptimised_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 15#32 == 0#32) = 1#1 →
    ofBool (x &&& 39#32 == 0#32) = ofBool (x &&& 15#32 == 0#32) ||

theorem eq_optimized_highbits_cmp_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ x <ᵤ 33554432#32) &&& ofBool (truncate 25 x == truncate 25 x_1) = ofBool (x_1 == x)

theorem bv_AddSub_1624 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.sub (LLVM.or e e_1) (LLVM.xor e e_1) ⊑ LLVM.and e e_1

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

theorem test21_proof : test21_before ⊑ test21_after

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

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

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

theorem bools_multi_uses1_proof : bools_multi_uses1_before ⊑ bools_multi_uses1_after

theorem xor_with_or_disjoint_ba_thm (e e_1 : IntW 32) : LLVM.xor e_1 (LLVM.or e_1 e { «disjoint» := true }) ⊑ e

theorem add_shl_same_amount_partial_nsw1_proof : add_shl_same_amount_partial_nsw1_before ⊑ add_shl_same_amount_partial_nsw1_after

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

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

theorem ashr_can_be_lshr_thm (e : IntW 32) :
  trunc 16 (ashr e (const? 32 16) { «exact» := true }) { «nsw» := true, «nuw» := false } ⊑
    trunc 16 (lshr e (const? 32 16) { «exact» := true }) { «nsw» := false, «nuw» := true }

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

theorem logical_and_bitwise_and_icmps_comm1_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.eq e (const? 8 42)) (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)))
      (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.eq e (const? 8 42)) (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)))
      (const? 1 0)

theorem one_side_fold_eq_proof : one_side_fold_eq_before ⊑ one_side_fold_eq_after

theorem ripple_no_nsw2_proof : ripple_no_nsw2_before ⊑ ripple_no_nsw2_after

theorem unmasked_shlop_insufficient_mask_shift_amount_proof : unmasked_shlop_insufficient_mask_shift_amount_before ⊑ unmasked_shlop_insufficient_mask_shift_amount_after

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

theorem positive_and_odd_eq_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.srem e (const? 32 2)) (const? 32 1) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 (-2147483647))) (const? 32 1)

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

theorem ashrslt_02_13_proof : ashrslt_02_13_before ⊑ ashrslt_02_13_after

theorem lshr_eq_both_equal_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 127) e) (const? 8 127) ⊑ icmp IntPred.eq e (const? 8 0)

lemma TermBinop.alt_lang {t₁ t₂ : Term} (op : TermBinop) :
  (op.subst_arity' ▸ (op.subst t₁ t₂).language) =
    let lop : Set (BitVecs 3) := op.openTerm_arity ▸ op.openTerm.language
    let lop' : Set (BitVecs ((t₁.arity ⊔ t₂.arity) + 3)) := lop.lift (liftLast3 (max t₁.arity t₂.arity))
    let l₁ := t₁.language.lift (liftMaxSuccSucc1 t₁.arity t₂.arity)
    let l₂ := t₂.language.lift (liftMaxSuccSucc2 t₁.arity t₂.arity)
    let l := l₁ ∩ l₂ ∩ lop'
    l.proj (liftOp _)

theorem ashr_exact_add_negative_shift_negative_proof : ashr_exact_add_negative_shift_negative_before ⊑ ashr_exact_add_negative_shift_negative_after

@[simp] theorem getElem?_cons_zero (t : Ty)           : (Γ.cons t)[0]? = some t

theorem a_or_b_const_proof : a_or_b_const_before ⊑ a_or_b_const_after

theorem and_not_xor_common_op_proof : and_not_xor_common_op_before ⊑ and_not_xor_common_op_after

theorem n1_proof : n1_before ⊑ n1_after

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

theorem and_or3_proof : and_or3_before ⊑ and_or3_after

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

theorem lshr_16_add_not_known_16_leading_zeroes_proof : lshr_16_add_not_known_16_leading_zeroes_before ⊑ lshr_16_add_not_known_16_leading_zeroes_after

theorem t0_proof : t0_before ⊑ t0_after

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

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

theorem positive_biggerLshr_shlnuw_lshrexact_proof : positive_biggerLshr_shlnuw_lshrexact_before ⊑ positive_biggerLshr_shlnuw_lshrexact_after

theorem test2_proof : test2_before ⊑ test2_after

theorem shift_trunc_signbit_test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬24#32 ≥ ↑32 → ofBool (truncate 8 (x >>> 24#32) <ₛ 0#8) = ofBool (x <ₛ 0#32)

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

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

theorem test21_thm.extracted_1._1 : ∀ (x : BitVec 32), signExtend 32 (truncate 8 x) &&& 255#32 = x &&& 255#32

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 or_and1_proof : or_and1_before ⊑ or_and1_after

theorem ashr_ult_14_proof : ashr_ult_14_before ⊑ ashr_ult_14_after

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

theorem select_add_icmp_bad_proof : select_add_icmp_bad_before ⊑ select_add_icmp_bad_after

theorem test5_thm (e : IntW 32) :
  add (sext 64 (ashr e (const? 32 1))) (const? 64 1073741823) ⊑
    sext 64 (add (ashr e (const? 32 1)) (const? 32 1073741823) { «nsw» := true, «nuw» := false })

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

theorem t6_ugt_sgt_65536_thm.extracted_1._7 : ∀ (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 = x_2

theorem slt_zero_eq_i1_proof : slt_zero_eq_i1_before ⊑ slt_zero_eq_i1_after

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

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

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

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

theorem or_xor_or_thm.extracted_1._1 : ∀ (x : BitVec 8),
  (x ||| 33#8) ^^^ 12#8 ||

theorem src_srem_shl_demand_max_signbit_thm (e : IntW 32) :
  LLVM.and (shl (LLVM.srem e (const? 32 2)) (const? 32 30)) (const? 32 (-2147483648)) ⊑
    LLVM.and (LLVM.srem e (const? 32 2)) (const? 32 (-2147483648))

theorem pr33078_4_proof : pr33078_4_before ⊑ pr33078_4_after

theorem uge_umin1_proof : uge_umin1_before ⊑ uge_umin1_after

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 ashr_sgt_overflow_thm (e : IntW 8) : icmp IntPred.sgt (ashr e (const? 8 1)) (const? 8 63) ⊑ const? 1 0

theorem shl_and_proof : shl_and_before ⊑ shl_and_after

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

theorem slt_smin3_proof : slt_smin3_before ⊑ slt_smin3_after

@[simp] theorem tail_corec : tail (corec b f) = corec (f b).snd f

theorem sub_sext_mask1_trunc_lshr_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬15#64 ≥ ↑64 →
    ¬(48#64 ≥ ↑64 ∨
          63#64 ≥ ↑64 ∨
            True ∧ signExtend 64 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)) ≠ (x <<< 48#64).sshiftRight' 63#64 ∨
              True ∧ (truncate 8 ((x <<< 48#64).sshiftRight' 63#64)).saddOverflow 10#8 = true) →
      10#32 - signExtend 32 (truncate 8 (x >>> 15#64) &&& 1#8) =
        zeroExtend 32 (truncate 8 ((x <<< 48#64).sshiftRight' 63#64) + 10#8)

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

theorem e_2476 :
    3 * (e ^^^  ~~~(d &&& (e &&& f))) + 11 * (d |||  ~~~f) + 2 * (f ^^^  ~~~(d &&& (e &&& f))) - 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 11 * ((d ^^^ e) ||| (d ^^^ f)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 7 * (e ^^^ (d ||| f)) - 11 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ( ~~~d ||| (e ^^^ f)) + 2 * (f |||  ~~~(d ||| e)) - 5 *  ~~~( ~~~d &&& (e &&& f)) + 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 4 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 *  ~~~(d ||| e) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 6 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 2 * (d ||| e) + 3 * ((e &&& f) ||| (d &&& (e ||| f))) + 7 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 3 * (d &&& ( ~~~e ||| f)) + 1 * ( ~~~e &&&  ~~~(d ^^^ f)) - 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * (e &&&  ~~~(d &&& f)) - 1 * ( ~~~e &&& (d ^^^ f)) - 11 * (e ^^^ ( ~~~d &&& (e ||| f))) + 3 * (f ^^^ (d ||| (e &&& f))) + 5 *  ~~~(d ||| (e ^^^ f)) + 3 *  ~~~(d ^^^ (e ||| f)) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 * (e ^^^ (d ||| (e ^^^ f))) - 2 * (e |||  ~~~(d |||  ~~~f)) + 1 * ((d ||| e) &&& (e ^^^ f)) - 2 * (d &&& (e ^^^ f)) + 2 * (f ^^^ ( ~~~d ||| (e ||| f))) + 4 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * (e &&& (d ||| f)) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 1 * (e ^^^ (d &&&  ~~~f)) - 5 * (e ^^^ f) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) + 11 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 1 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * (f &&&  ~~~(d ^^^ e)) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (e ^^^  ~~~(d |||  ~~~f)) - 11 * (d &&& e) - 6 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 3 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 3 * (f ^^^  ~~~(d ||| (e &&& f))) + 5 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 5 *  ~~~( ~~~d ||| (e &&& f)) - 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) - 3 *  ~~~( ~~~d &&& (e ||| f)) + 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 1 *  ~~~(d &&&  ~~~d) - 3 * (e ^^^ (d ||| ( ~~~e &&& f))) + 7 *  ~~~(d &&& e) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 7 * (e &&&  ~~~f) - 6 * (f ^^^ (d &&& ( ~~~e ||| f))) - 6 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 64 *  ~~~(d ||| (e ||| f)) - 14 *  ~~~(d ||| ( ~~~e ||| f)) + 31 *  ~~~( ~~~d ||| (e ||| f)) + 55 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 29 * ( ~~~d &&& ( ~~~e &&& f)) + 43 * ( ~~~d &&& (e &&& f)) + 11 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) = 1 * (e ||| (d &&& f))

theorem not_signbit_zext_proof : not_signbit_zext_before ⊑ not_signbit_zext_after

theorem e_1368 :
     - 1 *  ~~~(z &&&  ~~~t) + 11 *  ~~~t + 4 *  ~~~z - 5 * (z |||  ~~~t) - 11 * (z ^^^ t) - 1 *  ~~~(z ^^^ t) - 1 * t - 15 *  ~~~(z ||| t) + 2 *  ~~~(z |||  ~~~t) + 8 * (z &&& t) = 2 * (z &&&  ~~~t) - 7 *  ~~~(z &&& t)

theorem zext_nneg_sext_eq_proof : zext_nneg_sext_eq_before ⊑ zext_nneg_sext_eq_after

theorem positive_biggershl_shlnuwnsw_proof : positive_biggershl_shlnuwnsw_before ⊑ positive_biggershl_shlnuwnsw_after

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

theorem test58_proof : test58_before ⊑ test58_after

theorem add_select_not_sext_proof : add_select_not_sext_before ⊑ add_select_not_sext_after

theorem avg_lsb_proof : avg_lsb_before ⊑ avg_lsb_after

theorem test_add_nsw__nsw_is_safe_proof : test_add_nsw__nsw_is_safe_before ⊑ test_add_nsw__nsw_is_safe_after

theorem sge_swap_or_max_proof : sge_swap_or_max_before ⊑ sge_swap_or_max_after

theorem test12_thm (e : IntW 8) :
  icmp IntPred.ne (LLVM.xor e (const? 8 4)) (const? 8 0) ⊑ icmp IntPred.ne e (const? 8 4)

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

theorem denote_multiRewritePeepholeAt (fuel : ℕ)
  (prs : List (Σ Γ, Σ ty, PeepholeRewrite d Γ ty)) (ix : ℕ) (target : Com d Γ₂ eff t₂) :
    (multiRewritePeepholeAt fuel prs ix target).denote = target.denote

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

theorem testi16i8_ne_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(7#8 ≥ ↑8 ∨ 8#16 ≥ ↑16) →
    ofBool ((truncate 8 x).sshiftRight' 7#8 != truncate 8 (x >>> 8#16)) =
      ofBool (x + BitVec.ofInt 16 (-128) <ᵤ BitVec.ofInt 16 (-256))

theorem and2 : ∀ (w : Nat) (x : BitVec w), -1#w &&& x = x

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

theorem main3f_like_proof : main3f_like_before ⊑ main3f_like_after

theorem test_add__nuw_is_safe_proof : test_add__nuw_is_safe_before ⊑ test_add__nuw_is_safe_after

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

theorem test_add_nuw_nsw__none_are_safe_proof : test_add_nuw_nsw__none_are_safe_before ⊑ test_add_nuw_nsw__none_are_safe_after

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

theorem simplify_and_common_op_commute2_proof : simplify_and_common_op_commute2_before ⊑ simplify_and_common_op_commute2_after

theorem select_icmp_and_2147483648_eq_0_xor_2147483648_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& BitVec.ofInt 32 (-2147483648) == 0#32) = 1#1 → x = x ||

theorem Predicate.evalUlt_denote_false_iff {w : Nat} (a b : Term) (vars : List (BitVec w)) :
    evalUlt (a.eval (List.map .ofBitVecSext vars)) (b.eval (List.map .ofBitVecSext vars)) w = false ↔
    (Term.denote w a vars < Term.denote w b vars)

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

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

theorem setWidth_eq_zext (x : BitVec v) : x.zeroExtend w = x.setWidth w

theorem expand_proof : expand_before ⊑ expand_after

theorem xor_lshr_multiuse_proof : xor_lshr_multiuse_before ⊑ xor_lshr_multiuse_after

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

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

@[simp]
lemma BitVec.cons_inj : cons b1 bv1 = cons b2 bv2 ↔ (b1 = b2) ∧ bv1 = bv2

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

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

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

theorem icmp_select_var_both_fold_proof : icmp_select_var_both_fold_before ⊑ icmp_select_var_both_fold_after

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

theorem test11c_proof : test11c_before ⊑ test11c_after

theorem icmp_sgt7_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 124) ⊑
    icmp IntPred.sgt e (const? 8 62)

theorem shl_sub_lshr_reverse_thm (e e_1 e_2 : IntW 32) :
  lshr (sub e_2 (shl e_1 e { «nsw» := false, «nuw» := true }) { «nsw» := true, «nuw» := true }) e { «exact» := true } ⊑
    sub (lshr e_2 e { «exact» := true }) e_1 { «nsw» := true, «nuw» := true }

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

theorem ne_21_logical_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 16))) (trunc 8 (lshr e (const? 32 16)))) (const? 1 1)
      (icmp IntPred.ne (trunc 8 (lshr e_1 (const? 32 8))) (trunc 8 (lshr e (const? 32 8)))) ⊑
    icmp IntPred.ne (trunc 16 (lshr e_1 (const? 32 8))) (trunc 16 (lshr e (const? 32 8)))

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

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

theorem xor_andn_commute3_proof : xor_andn_commute3_before ⊑ xor_andn_commute3_after

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

theorem eq_umin1_proof : eq_umin1_before ⊑ eq_umin1_after

theorem neg_of_sub_from_constant_proof : neg_of_sub_from_constant_before ⊑ neg_of_sub_from_constant_after

theorem test_imply_not2_thm.extracted_1._6 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬ofBool (x_1 == 0#32) = 1#1 → ¬ofBool (x_1 != 0#32) = 1#1 → 0#1 ||

theorem icmp_ne_sext_ne_otherwise_i128_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ofBool (signExtend 128 (ofBool (x != 2#128)) != x) = ofBool (x != -1#128)

theorem multiuse2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ ((x &&& 96#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 96#32 ∨
        True ∧ (x &&& 96#32) <<< 8#32 >>> 8#32 ≠ x &&& 96#32 ∨
          8#32 ≥ ↑32 ∨
            True ∧ ((x &&& 6#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 6#32 ∨
              True ∧ (x &&& 6#32) <<< 8#32 >>> 8#32 ≠ x &&& 6#32 ∨
                8#32 ≥ ↑32 ∨
                  True ∧ ((x &&& 24#32) <<< 8#32).sshiftRight' 8#32 ≠ x &&& 24#32 ∨
                    True ∧ (x &&& 24#32) <<< 8#32 >>> 8#32 ≠ x &&& 24#32 ∨
                      8#32 ≥ ↑32 ∨
                        True ∧ ((x &&& 6#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 6#32 ∨
                          True ∧ (x &&& 6#32) <<< 1#32 >>> 1#32 ≠ x &&& 6#32 ∨
                            1#32 ≥ ↑32 ∨
                              True ∧ ((x &&& 96#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 96#32 ∨
                                True ∧ (x &&& 96#32) <<< 1#32 >>> 1#32 ≠ x &&& 96#32 ∨
                                  1#32 ≥ ↑32 ∨
                                    True ∧ ((x &&& 24#32) <<< 1#32).sshiftRight' 1#32 ≠ x &&& 24#32 ∨
                                      True ∧ (x &&& 24#32) <<< 1#32 >>> 1#32 ≠ x &&& 24#32 ∨ 1#32 ≥ ↑32) →
    ¬(8#32 ≥ ↑32 ∨
          1#32 ≥ ↑32 ∨
            1#32 ≥ ↑32 ∨
              1#32 ≥ ↑32 ∨
                True ∧ (x <<< 1#32 &&& 192#32 &&& (x <<< 1#32 &&& 48#32) != 0) = true ∨
                  True ∧ (x <<< 1#32 &&& 12#32 &&& (x <<< 1#32 &&& 192#32 ||| x <<< 1#32 &&& 48#32) != 0) = true ∨
                    True ∧
                      (x <<< 8#32 &&& 32256#32 &&&
                            (x <<< 1#32 &&& 12#32 ||| (x <<< 1#32 &&& 192#32 ||| x <<< 1#32 &&& 48#32)) !=
                          0) =
                        true) →
      (x &&& 96#32) <<< 8#32 ||

theorem substitute_constant_or_ne_uge_commute_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x ≤ᵤ x_1) = 1#1 → ofBool (x_1 != 42#8) = ofBool (x_1 != 42#8) ||

theorem or_to_nxor4_proof : or_to_nxor4_before ⊑ or_to_nxor4_after

theorem test0_proof : test0_before ⊑ test0_after

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

theorem alive_AndOrXor_1704 : alive_AndOrXor_1704_src ⊑ alive_AndOrXor_1704_tgt

theorem n11_wrong_pred3_proof : n11_wrong_pred3_before ⊑ n11_wrong_pred3_after

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

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

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

theorem fold_eq_lhs_proof : fold_eq_lhs_before ⊑ fold_eq_lhs_after

theorem shl_or_disjoint_lshr_proof : shl_or_disjoint_lshr_before ⊑ shl_or_disjoint_lshr_after

theorem ashr_sge_exact_proof : ashr_sge_exact_before ⊑ ashr_sge_exact_after

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

theorem sextbool_add_commute_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ¬42#32 = 0 → 42#32 = 0 ∨ True ∧ (x_1 % 42#32).saddOverflow (signExtend 32 x) = true → False

theorem ne_irregular_bit_widths_thm.extracted_1._2 : ∀ (x x_1 : BitVec 31),
  ¬(13#31 ≥ ↑31 ∨ 13#31 ≥ ↑31 ∨ 7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31) →
    ¬(7#31 ≥ ↑31 ∨ 7#31 ≥ ↑31) →
      ofBool (truncate 5 (x_1 >>> 13#31) != truncate 5 (x >>> 13#31)) ||

@[simp] theorem Expr.denote_castPureToEff {e : Expr d Γ .pure t} :
    denote (e.castPureToEff eff) = fun V => pure (e.denote V)

theorem test10b_proof : test10b_before ⊑ test10b_after

theorem test23_logical_proof : test23_logical_before ⊑ test23_logical_after

theorem e_2024 :
    3 * (e ^^^  ~~~(d &&&  ~~~f)) + 3 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) + 7 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 *  ~~~( ~~~d ||| (e &&& f)) + 1 * ( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 6 * (d ^^^ f) + 11 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 3 * (e &&&  ~~~(d &&&  ~~~f)) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 7 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 11 * ( ~~~d &&& (e ^^^ f)) + 5 * ( ~~~d ||| (e ^^^ f)) + 2 * (f ^^^ (d &&& (e ||| f))) - 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 4 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 1 * (e &&&  ~~~(d &&& f)) + 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 2 *  ~~~( ~~~d &&& (e ||| f)) + 3 * (f ^^^  ~~~(d &&& (e ||| f))) + 5 * (d &&&  ~~~f) + 4 * (d &&& e) - 6 * ((d &&& e) ||| (e ^^^ f)) - 30 *  ~~~(d ||| (e ||| f)) - 8 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 21 * ( ~~~d &&& ( ~~~e &&& f)) + 1 * (d &&& ( ~~~e &&& f)) = 3 * (d ||| (e ||| f)) + 19 * ( ~~~d &&& (e &&& f))

theorem select_of_symmetric_selects_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32) (x_2 x_3 : BitVec 1),
  x_3 = 1#1 → x_2 = 1#1 → x_2 ^^^ x_3 = 1#1 → x_1 = x

theorem AndZextAnd_thm (e : IntW 3) :
  LLVM.and (zext 5 (LLVM.and e (const? 3 3))) (const? 5 14) ⊑
    zext 5 (LLVM.and e (const? 3 2)) { «nneg» := true }

theorem mul_sel_op0_thm.extracted_1._2 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → ¬(True ∧ (42#32).umod x ≠ 0 ∨ x = 0) → 42#32 / x * x = 42#32

theorem positive_easyinvert_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 8),
  ofBool (x_1 <ₛ 0#8) ^^^ ofBool (x <ₛ 0#16) ^^^ 1#1 = ofBool (x_1 <ₛ 0#8) ^^^ ofBool (-1#16 <ₛ x)

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

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

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

theorem xor_of_icmps_to_ne_commute_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (x <ₛ 6#64) ^^^ ofBool (4#64 <ₛ x) = ofBool (x != 5#64)

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

theorem select_icmp_eq_and_1_0_or_2_proof : select_icmp_eq_and_1_0_or_2_before ⊑ select_icmp_eq_and_1_0_or_2_after

theorem pv_thm (e e_1 : IntW 8) :
  icmp IntPred.ne (LLVM.and (lshr (const? 8 (-1)) e_1) e) e ⊑
    icmp IntPred.ugt e (lshr (const? 8 (-1)) e_1)

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

theorem test24_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → ofBool (14#32 != 0#32) = 1#1

theorem test84_proof : test84_before ⊑ test84_after

theorem shift_no_xor_multiuse_cmp_thm.extracted_1._6 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_3 &&& 1#32 == 0#32) = 1#1 →
    ¬(True ∧ ((x_3 &&& 1#32) <<< 1#32).sshiftRight' 1#32 ≠ x_3 &&& 1#32 ∨
          True ∧ (x_3 &&& 1#32) <<< 1#32 >>> 1#32 ≠ x_3 &&& 1#32 ∨ 1#32 ≥ ↑32) →
      x_2 * x_1 = (x_2 ||| (x_3 &&& 1#32) <<< 1#32) * x_1

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

theorem negate_sext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  x_1 - signExtend 8 x = x_1 + zeroExtend 8 x

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

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

theorem or_proof : or_before ⊑ or_after

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

theorem test31_proof : test31_before ⊑ test31_after

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬x = 0 → ofBool (x_1 / x != 0#32) = ofBool (x ≤ᵤ x_1)

theorem andn_or_cmp_4_logical_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 == x) = 1#1 → ¬ofBool (x_1 != x) = 1#1 → ¬True → ofBool (x_1 != x) = 0#1

@[simp]
theorem flipAccept_accepts (M : NFA α σ) (hc : M.Complete) (hdet : M.Deterministic) :
    M.flipAccept.accepts = M.acceptsᶜ

theorem lshr_pow2_sgt_proof : lshr_pow2_sgt_before ⊑ lshr_pow2_sgt_after

theorem same_source_not_matching_signbits_proof : same_source_not_matching_signbits_before ⊑ same_source_not_matching_signbits_after

theorem substitute_constant_or_ne_uge_commute_proof : substitute_constant_or_ne_uge_commute_before ⊑ substitute_constant_or_ne_uge_commute_after

theorem test9_logical_proof : test9_logical_before ⊑ test9_logical_after

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

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

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

lemma CNFA.autWidth_finals (hn : s < n + 2) : s ∈ (autWidth wp n).m.finals ↔ wp.final? n s

theorem or_ranges_overlap_thm (e : IntW 8) :
  LLVM.or (LLVM.and (icmp IntPred.uge e (const? 8 5)) (icmp IntPred.ule e (const? 8 10)))
      (LLVM.and (icmp IntPred.uge e (const? 8 10)) (icmp IntPred.ule e (const? 8 20))) ⊑
    icmp IntPred.ult (add e (const? 8 (-5))) (const? 8 16)

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

theorem not_logicalOr_not_op1_proof : not_logicalOr_not_op1_before ⊑ not_logicalOr_not_op1_after

theorem select_constants_and_icmp_eq0_zero_tval_proof : select_constants_and_icmp_eq0_zero_tval_before ⊑ select_constants_and_icmp_eq0_zero_tval_after

theorem test_ult_xor_thm (e e_1 : IntW 32) :
  icmp IntPred.ult (LLVM.xor (LLVM.xor e_1 (const? 32 (-1))) e) (LLVM.xor e_1 (const? 32 (-1))) ⊑
    icmp IntPred.ugt (LLVM.xor e e_1) e_1

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

theorem or_simplify_ule_proof : or_simplify_ule_before ⊑ or_simplify_ule_after

theorem positive_biggershl_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ 6#8 ≥ ↑8) → ¬3#8 ≥ ↑8 → x >>> 3#8 <<< 6#8 = x <<< 3#8 &&& BitVec.ofInt 8 (-64)

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

theorem xor_sext_to_sel_thm (e : IntW 32) (e_1 : IntW 1) : LLVM.xor (sext 32 e_1) e ⊑ LLVM.xor e (sext 32 e_1)

theorem ashr_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(5#32 ≥ ↑32 ∨ 7#32 ≥ ↑32) → ¬12#32 ≥ ↑32 → (x.sshiftRight' 5#32).sshiftRight' 7#32 = x.sshiftRight' 12#32

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

theorem sext_sub_const_proof : sext_sub_const_before ⊑ sext_sub_const_after

theorem test59_proof : test59_before ⊑ test59_after

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

theorem n14_wrong_comparison_constant_proof : n14_wrong_comparison_constant_before ⊑ n14_wrong_comparison_constant_after

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

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

theorem reduce_xor_common_op_commute1_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 4),
  x_2 ^^^ x_1 ^^^ x ||

theorem add_umin_simplify_proof : add_umin_simplify_before ⊑ add_umin_simplify_after

theorem test70_proof : test70_before ⊑ test70_after

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

theorem test2_thm (e : IntW 32) :
  icmp IntPred.ugt e (const? 32 0) ⊑ icmp IntPred.ne e (const? 32 0)

theorem lshrugt_02_06_proof : lshrugt_02_06_before ⊑ lshrugt_02_06_after

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

theorem xor_andn_commute2_proof : xor_andn_commute2_before ⊑ xor_andn_commute2_after

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

theorem icmp_equality_test_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 64),
  ofBool (x_2 == x_1) = 1#1 → ofBool (x == x_1) = ofBool (x_2 == x)

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

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

theorem icmp_eq_zext_eq_non_boolean_proof : icmp_eq_zext_eq_non_boolean_before ⊑ icmp_eq_zext_eq_non_boolean_after

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

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

@[simp]
theorem FSM.eval_or' (a b : FSM arity) : (a ||| b).eval env = a.eval env ||

theorem positive_with_aggressive_icmp_logical_proof : positive_with_aggressive_icmp_logical_before ⊑ positive_with_aggressive_icmp_logical_after

theorem scalar_i64_lshr_and_negC_eq_proof : scalar_i64_lshr_and_negC_eq_before ⊑ scalar_i64_lshr_and_negC_eq_after

theorem positive_with_icmp_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 512#32) = 1#1 → ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x <ᵤ 128#32)

theorem n8_wrong_pred3_proof : n8_wrong_pred3_before ⊑ n8_wrong_pred3_after

theorem alive_AddSub_1624  (w : Nat)   : alive_AddSub_1624_src w  ⊑ alive_AddSub_1624_tgt w

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

theorem or_xor_not_proof : or_xor_not_before ⊑ or_xor_not_after

theorem neg_or_add (i : Nat) :
    (b.negAux i).2 = false ∨ (a.addAux b.neg i).2 = false

theorem masked_or_A_proof : masked_or_A_before ⊑ masked_or_A_after

lemma complete_stepSet_sink {M : NFA α σ} :
    .inr () ∈ S → .inr () ∈ M.complete.stepSet S a

theorem select_icmp_sgt_not_smin_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (-1#8 <ₛ x) = 1#1 → ofBool (x <ₛ 0#8) = 1#1 → x = x ^^^ BitVec.ofInt 8 (-127)

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

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

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 masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_0_logical_after

@[grind ., simp, aesop 50% unsafe]
lemma wf_addManyTrans [LawfulBEq A] (m : RawCNFA A) (hwf : m.WF) s as s'
  (hin : s ∈ m.states) (hin' : s' ∈ m.states) :
    (m.addManyTrans as s s').WF

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

theorem uaddo_commute7_proof : uaddo_commute7_before ⊑ uaddo_commute7_after

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

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

theorem e_2296 :
    1 *  ~~~(e &&& f) + 5 * (e ^^^  ~~~(d |||  ~~~f)) - 7 * (d ||| ( ~~~e &&& f)) + 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) + 7 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (e ^^^ (d &&& (e ||| f))) - 2 *  ~~~(d &&&  ~~~e) + 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 11 * (e ^^^ ( ~~~d &&& (e ||| f))) - 5 * (d |||  ~~~e) + 11 *  ~~~(d &&&  ~~~f) - 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * (e &&&  ~~~(d ^^^ f)) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 3 * (f ^^^  ~~~(d &&& e)) - 6 * ( ~~~(d ||| e) ||| (e ^^^ f)) - 1 * (d ||| f) - 1 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * (e ^^^  ~~~(d ||| f)) + 2 * (e ^^^ (d |||  ~~~f)) - 6 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f ^^^ (d &&& ( ~~~e ||| f))) + 2 * (d ||| (e &&& f)) - 11 * ((d &&& e) |||  ~~~(e ^^^ f)) - 1 * (f &&& (d ^^^ e)) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 6 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 7 * ((d ^^^ e) ||| (d ^^^ f)) - 5 * (e ||| (d &&& f)) + 11 *  ~~~(d ||| (e &&& f)) + 5 * (e ^^^ (d ||| (e ^^^ f))) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) - 5 * ((d |||  ~~~e) &&& (e ^^^ f)) + 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) + 2 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 1 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (e |||  ~~~(d ^^^ f)) + 7 *  ~~~(d &&& (e &&& f)) + 5 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 2 *  ~~~(d |||  ~~~f) + 1 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 11 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 5 *  ~~~(d ||| (e ^^^ f)) + 4 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * (f ^^^ (d ||| e)) - 11 *  ~~~(d ^^^ f) - 11 *  ~~~(d ^^^ (e ||| f)) + 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 23 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) + 11 *  ~~~( ~~~d ||| (e ||| f)) + 49 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 12 * ( ~~~d &&& ( ~~~e &&& f)) - 40 * ( ~~~d &&& (e &&& f)) - 1 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) = 6 * ( ~~~(d &&& e) &&& (e ^^^ f))

theorem e_1494 :
     - 1 * (z ^^^ t) - 7 * (z |||  ~~~t) - 6 *  ~~~(z &&&  ~~~z) - 2 *  ~~~z - 5 * t + 2 *  ~~~t - 2 * (z ||| t) - 11 *  ~~~(z &&&  ~~~t) + 24 *  ~~~(z ||| t) + 27 *  ~~~(z |||  ~~~t) + 31 * (z &&& t) =  - 14 * (z &&&  ~~~t)

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

theorem test_proof : test_before ⊑ test_after

theorem ashr_lshr_exact_both_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 (-1))) (lshr e_1 e { «exact» := true })
      (ashr e_1 e { «exact» := true }) ⊑
    ashr e_1 e { «exact» := true }

theorem lshr_add_fail_thm (e : IntW 8) :
  add (lshr (const? 8 16) e) (lshr (const? 8 7) (add e (const? 8 1))) ⊑
    add (lshr (const? 8 16) e) (lshr (const? 8 7) (add e (const? 8 1))) { «nsw» := true, «nuw» := true }

theorem rem_euclid_non_const_pow2_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ (1#8 <<< x == 0 || 8 != 1 && x_1 == intMin 8 && 1#8 <<< x == -1) = true) →
    ¬ofBool (x_1.srem (1#8 <<< x) <ₛ 0#8) = 1#1 → True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

theorem ult_toNat (x y : BitVec n) :
    (BitVec.ult (n := n) x y) = decide (x.toNat < y.toNat)

theorem scalar_i8_shl_ult_const_3_proof : scalar_i8_shl_ult_const_3_before ⊑ scalar_i8_shl_ult_const_3_after

@[simp]
theorem Env.getLsb_getElem {env : Env (w + 1)} (n : Nat) :
    (Env.getLsb env)[n]? = (env[n]?).map (fun (x : BitVec (w + 1)) => BitVec.ofBool (x[0]))

theorem PR24763_proof : PR24763_before ⊑ PR24763_after

theorem select_add_icmp_bad_proof : select_add_icmp_bad_before ⊑ select_add_icmp_bad_after

theorem exact_lshr_eq_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 4) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 2)

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

theorem sub_dec_proof : sub_dec_before ⊑ sub_dec_after

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

theorem t9_ashr_thm (e : IntW 16) (e_1 : IntW 32) :
  ashr (trunc 16 (ashr e_1 (zext 32 (sub (const? 16 32) e)))) (add e (const? 16 (-2))) ⊑
    ashr (trunc 16 (ashr e_1 (zext 32 (sub (const? 16 32) e) { «nneg» := true }))) (add e (const? 16 (-2)))

theorem sub_const_sub_const_thm.extracted_1._1 : ∀ (x : BitVec 32), x - 8#32 - 2#32 = x + BitVec.ofInt 32 (-10)

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

theorem not_or_neg_proof : not_or_neg_before ⊑ not_or_neg_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 3#32 == 1#32) = 1#1 →
    ofBool (x &&& 14#32 != 0#32) = ofBool (x &&& 3#32 == 1#32) &&& ofBool (x &&& 14#32 != 0#32)

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

theorem zext_nneg_i1_proof : zext_nneg_i1_before ⊑ zext_nneg_i1_after

theorem ashr_or_proof : ashr_or_before ⊑ ashr_or_after

theorem xor_or2_proof : xor_or2_before ⊑ xor_or2_after

theorem n10_ashr_lshr_proof : n10_ashr_lshr_before ⊑ n10_ashr_lshr_after

theorem test7_proof : test7_before ⊑ test7_after

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

theorem t1_proof : t1_before ⊑ t1_after

theorem exactly_one_set_signbit_signed_proof : exactly_one_set_signbit_signed_before ⊑ exactly_one_set_signbit_signed_after

theorem shrink_select_proof : shrink_select_before ⊑ shrink_select_after

theorem test5_thm.extracted_1._1 : ∀ (x : BitVec 32), x &&& x = x

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

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

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

theorem test_cast_select_thm.extracted_1._1 : ∀ (x : BitVec 1), x = 1#1 → zeroExtend 32 3#16 = 3#32

@[simp] theorem appendList_eq : Γ ++ tys = Γ ++ ⟨tys⟩

private theorem falseAfterExcluding_false_iff (n i : Nat) {env : Fin 0 → BitStream} :
  (falseAfterExcluding n).eval env i = false ↔ i > n

theorem zext_sub_const_thm (e : IntW 1) : sub (const? 64 42) (zext 64 e) ⊑ select e (const? 64 41) (const? 64 42)

theorem sgt_positive_multip_rem_nz_proof : sgt_positive_multip_rem_nz_before ⊑ sgt_positive_multip_rem_nz_after

theorem test7_proof : test7_before ⊑ test7_after

theorem select_icmp_x_and_8_eq_0_y_xor_8_proof : select_icmp_x_and_8_eq_0_y_xor_8_before ⊑ select_icmp_x_and_8_eq_0_y_xor_8_after

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

theorem sub_select_zext_op_swapped_non_const_args_proof : sub_select_zext_op_swapped_non_const_args_before ⊑ sub_select_zext_op_swapped_non_const_args_after

theorem ashr_lshr_cst2_proof : ashr_lshr_cst2_before ⊑ ashr_lshr_cst2_after

@[simp] theorem toHom_zero {Γ : Ctxt Ty} {h : Valid Γ Γ 0} :
    toHom ⟨0, h⟩ = Hom.id

theorem src_srem_shl_demand_min_signbit_mask_hit_last_demand_proof : src_srem_shl_demand_min_signbit_mask_hit_last_demand_before ⊑ src_srem_shl_demand_min_signbit_mask_hit_last_demand_after

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 andn_or_cmp_4_proof : andn_or_cmp_4_before ⊑ andn_or_cmp_4_after

theorem trunc_nsw_xor_thm (e e_1 : IntW 8) :
  trunc 1 (LLVM.xor e_1 e) { «nsw» := true, «nuw» := false } ⊑ icmp IntPred.ne e_1 e

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

theorem ashrsgt_03_06_proof : ashrsgt_03_06_before ⊑ ashrsgt_03_06_after

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

theorem e_1946 :
    7 * (c &&&  ~~~(a ^^^ b)) + 7 *  ~~~(a ||| (b ^^^ c)) + 2 *  ~~~(a |||  ~~~c) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 5 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 11 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * ((a &&& b) |||  ~~~(b ||| c)) - 1 * ( ~~~c ||| (a ^^^ b)) + 2 * (b ^^^  ~~~( ~~~a &&& (b ||| c))) - 7 * b + 2 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 3 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) - 1 * (c ||| (a &&& b)) + 1 * (b ^^^  ~~~(a &&& (b &&& c))) + 5 * (a ^^^ (b ||| c)) - 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 2 * (b &&& c) - 11 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 2 * (c ^^^  ~~~(a |||  ~~~b)) + 11 *  ~~~(a &&& b) - 11 * (b ^^^ (a ||| ( ~~~b ||| c))) + 5 * (a ^^^ ( ~~~b ||| c)) + 4 * ( ~~~b &&& (a ^^^ c)) + 7 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * (c ^^^  ~~~(a &&& (b ||| c))) - 2 * ((a &&& b) ^^^ (b ||| c)) - 1 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 5 *  ~~~(a ||| b) - 3 * ( ~~~a ||| ( ~~~b ||| c)) + 11 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 2 *  ~~~(a ^^^ (b ||| c)) - 7 *  ~~~(b &&&  ~~~c) + 4 * ((a ^^^ b) ||| (a ^^^ c)) - 1 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 2 * (b ^^^ (a ||| ( ~~~b &&& c))) - 2 * ((a &&& b) ||| (b ^^^ c)) + 2 * (a &&& ( ~~~b ||| c)) - 2 * ( ~~~b &&&  ~~~(a ^^^ c)) - 11 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 6 * (c &&& (a |||  ~~~b)) + 1 * (c ^^^ ( ~~~a &&& (b ||| c))) - 1 * (c ^^^ (a &&& b)) + 5 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 3 * (c ^^^ (a |||  ~~~b)) - 23 *  ~~~(a ||| (b ||| c)) - 2 *  ~~~(a ||| ( ~~~b ||| c)) + 10 *  ~~~( ~~~a ||| (b ||| c)) - 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 4 * ( ~~~a &&& ( ~~~b &&& c)) - 22 * ( ~~~a &&& (b &&& c)) + 17 * (a &&& ( ~~~b &&& c)) + 7 * (a &&& (b &&& c)) = 11 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 6 * (b ^^^ (a |||  ~~~c))

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

@[simp] theorem Expr.varName_mk {varName} {op : Op} {args} {regions : List (Region Op T)} :
    Expr.varName ⟨varName, op, args, regions⟩ = varName

theorem zext_zext_sle_op0_narrow_thm (e : IntW 16) (e_1 : IntW 8) :
  icmp IntPred.sle (zext 32 e_1) (zext 32 e) ⊑ icmp IntPred.uge e (zext 16 e_1)

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

theorem squared_nsw_sgt0_proof : squared_nsw_sgt0_before ⊑ squared_nsw_sgt0_after

theorem test_shl_nuw_nsw__all_are_safe_proof : test_shl_nuw_nsw__all_are_safe_before ⊑ test_shl_nuw_nsw__all_are_safe_after

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

theorem t13_x_is_one_proof : t13_x_is_one_before ⊑ t13_x_is_one_after

theorem demorgan_or_apint1_proof : demorgan_or_apint1_before ⊑ demorgan_or_apint1_after

theorem e_1678 :
    5 * ( ~~~c ||| (a ^^^ b)) + 4 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) + 5 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 1 * ((a &&& b) |||  ~~~(b ^^^ c)) + 2 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 7 *  ~~~(a ||| b) - 6 * (a ||| (b ||| c)) + 2 * (b ^^^ ( ~~~a ||| (b &&& c))) - 3 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 3 * (c |||  ~~~(a |||  ~~~b)) + 11 * (c ^^^  ~~~(a ||| (b &&& c))) + 3 * (c |||  ~~~(a ||| b)) + 4 *  ~~~(a ^^^ ( ~~~b ||| c)) + 5 * (a &&& ( ~~~b ||| c)) + 4 *  ~~~(a &&&  ~~~b) + 1 * (b |||  ~~~(a ^^^ c)) + 4 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) + 4 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 1 *  ~~~(a &&& ( ~~~b &&& c)) - 26 *  ~~~(a ||| (b ||| c)) - 24 *  ~~~( ~~~a ||| (b ||| c)) - 19 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 2 * ( ~~~a &&& ( ~~~b &&& c)) - 18 * ( ~~~a &&& (b &&& c)) - 32 * (a &&& ( ~~~b &&& c)) - 29 * (a &&& (b &&& c)) = 23 *  ~~~(a ||| ( ~~~b ||| c))

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 shl_shl_proof : shl_shl_before ⊑ shl_shl_after

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

theorem ashr1_thm (e : IntW 64) :
  ashr (shl e (const? 64 8)) (const? 64 2) ⊑ ashr (shl e (const? 64 8)) (const? 64 2) { «exact» := true }

theorem test10_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ (x >>> 16#32).umulOverflow 65535#32 = true) →
      zeroExtend 64 (x >>> 16#32) * 65535#64 = zeroExtend 64 (x >>> 16#32 * 65535#32)

theorem or_not_and_commute7_proof : or_not_and_commute7_before ⊑ or_not_and_commute7_after

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

@[simp_sllvm]
theorem PoisonOr.if_then_if_then_poison_eq {α : Type} (c₁ c₂ : Prop) [Decidable c₁] [Decidable c₂]
      (x y : PoisonOr α):
    (if c₁ then (if c₂ then poison else x : no_index _) else y : no_index _) =
    (if c₁ ∧ c₂ then poison else (if c₁ then x else y : no_index _) : no_index _)

theorem scalar_i16_shl_ult_const_proof : scalar_i16_shl_ult_const_before ⊑ scalar_i16_shl_ult_const_after

theorem sext_zext_add_mismatched_exts_proof : sext_zext_add_mismatched_exts_before ⊑ sext_zext_add_mismatched_exts_after

theorem zext_proof : zext_before ⊑ zext_after

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

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

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

theorem logical_or_cond_reuse_proof : logical_or_cond_reuse_before ⊑ logical_or_cond_reuse_after

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

theorem e_1354 :
     - 3 *  ~~~(z &&& t) + 11 *  ~~~t - 5 * (z ^^^ t) + 1 *  ~~~(z &&&  ~~~t) + 11 * t + 1 *  ~~~(z ^^^ t) + 7 * (z ||| t) - 12 *  ~~~(z ||| t) - 11 *  ~~~(z |||  ~~~t) - 22 * (z &&& t) = 12 * (z &&&  ~~~t) - 2 * (z |||  ~~~t)

theorem canonicalize_logic_first_or0_nsw_thm (e : IntW 32) :
  LLVM.or (add e (const? 32 112) { «nsw» := true, «nuw» := false }) (const? 32 15) ⊑
    add (LLVM.or e (const? 32 15)) (const? 32 112) { «nsw» := true, «nuw» := false }

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

theorem lshr_sub_nsw_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.ssubOverflow x = true ∨ 31#32 ≥ ↑32) → (x_1 - x) >>> 31#32 = zeroExtend 32 (ofBool (x_1 <ₛ x))

theorem unfold :
    x ~ y → ∃ n m,
      x.drop (n+1) ~ y.drop (m+1)
      ∧ x.get n = y.get m
      ∧ (∀ i < n, x.get i = none)
      ∧ (∀ j < m, y.get j = none)

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

theorem cmpeq_bitwise_proof : cmpeq_bitwise_before ⊑ cmpeq_bitwise_after

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

theorem test59_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(4#32 ≥ ↑32 ∨ 4#32 ≥ ↑32) →
    ¬(True ∧ (zeroExtend 32 x <<< 4#32).sshiftRight' 4#32 ≠ zeroExtend 32 x ∨
          True ∧ zeroExtend 32 x <<< 4#32 >>> 4#32 ≠ zeroExtend 32 x ∨
            4#32 ≥ ↑32 ∨
              4#8 ≥ ↑8 ∨
                True ∧ (x_1 >>> 4#8).msb = true ∨
                  True ∧ (zeroExtend 32 x <<< 4#32 &&& 48#32 &&& zeroExtend 32 (x_1 >>> 4#8) != 0) = true ∨
                    True ∧ (zeroExtend 32 x <<< 4#32 &&& 48#32 ||| zeroExtend 32 (x_1 >>> 4#8)).msb = true) →
      zeroExtend 64 (zeroExtend 32 x_1 >>> 4#32 ||| zeroExtend 32 x <<< 4#32 &&& 48#32) =
        zeroExtend 64 (zeroExtend 32 x <<< 4#32 &&& 48#32 ||| zeroExtend 32 (x_1 >>> 4#8))

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

theorem ugt_umax1_proof : ugt_umax1_before ⊑ ugt_umax1_after

theorem shl_nuw_add_nsw_nuw_proof : shl_nuw_add_nsw_nuw_before ⊑ shl_nuw_add_nsw_nuw_after

theorem e_1504 :
     - 2 * c + 2 *  ~~~( ~~~a &&& (b ||| c)) - 2 *  ~~~(a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 2 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * ( ~~~a &&& (b &&& c)) - 1 * (a &&& ( ~~~b &&& c)) - 1 * (a &&& (b &&& c)) =  - 1 * (a &&& (b ||| c)) + 2 *  ~~~( ~~~a ||| (b ||| c))

theorem select_icmp_ne_0_and_32_and_not_4096_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 32))) e (LLVM.and e (const? 32 (-4097))) ⊑
    select (icmp IntPred.eq (LLVM.and e_1 (const? 32 32)) (const? 32 0)) (LLVM.and e (const? 32 (-4097)))
      e

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

theorem select_ashr_thm.extracted_1._3 : ∀ (x x_1 : BitVec 128) (x_2 : BitVec 1), ¬x_2 = 1#1 → 0#128 ≥ ↑128 → False

theorem t9_ashr_exact_flag_preservation_proof : t9_ashr_exact_flag_preservation_before ⊑ t9_ashr_exact_flag_preservation_after

@[simp] theorem bv_isRefinedBy_iff (x y : BitVec w) : x ⊑ y ↔ x = y

theorem e_1992 :
    4 * (c ||| (a &&&  ~~~b)) - 1 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 2 * ( ~~~(a &&& b) &&&  ~~~(b ^^^ c)) - 2 * (b ^^^ (a ||| (b ||| c))) + 1 * (b ||| (a &&& c)) - 7 * (b ^^^ (a &&& c)) + 1 * (b ||| (a &&&  ~~~c)) - 1 *  ~~~(a ^^^ (b ^^^ c)) - 2 * (c ^^^  ~~~(a &&& b)) - 2 *  ~~~(a &&& (b ||| c)) + 2 * (b ^^^ c) - 2 *  ~~~(a ||| c) + 4 * (b ^^^ ( ~~~a &&& (b ||| c))) - 1 * ( ~~~a ||| (b ||| c)) - 1 * (c ^^^  ~~~(a &&& (b &&& c))) - 5 * ( ~~~b ||| (a ^^^ c)) + 1 *  ~~~a - 2 * ((a ^^^ b) |||  ~~~(a ^^^ c)) - 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 7 * (b ^^^  ~~~(a &&& (b &&& c))) - 3 * ( ~~~a &&& ( ~~~b ||| c)) - 7 * (b ||| (a ^^^ c)) + 1 * ( ~~~a &&& (b ^^^ c)) - 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 4 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) + 1 *  ~~~(a ^^^ (b ||| c)) + 7 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 11 * ((a &&& b) ^^^ (b ||| c)) + 1 * c + 2 *  ~~~(a &&& b) + 2 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 *  ~~~(a |||  ~~~b) + 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (a ^^^ c) - 11 * (a ||| ( ~~~b ||| c)) + 11 * (c &&&  ~~~(a &&&  ~~~b)) - 3 * ((b &&& c) ||| (a &&& (b ||| c))) - 1 *  ~~~(a ^^^ ( ~~~b ||| c)) - 11 * ((a ||| b) &&& (b ^^^ c)) - 2 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 7 *  ~~~(a ^^^ (b &&& c)) - 1 * ( ~~~c ||| (a ^^^ b)) - 5 * (c &&&  ~~~(a &&& b)) - 1 *  ~~~(a &&&  ~~~c) - 11 *  ~~~( ~~~a &&& (b &&& c)) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 * (a &&&  ~~~b) - 5 * (c ^^^  ~~~( ~~~a &&& (b &&& c))) + 1 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) + 16 *  ~~~(a ||| (b ||| c)) + 57 *  ~~~(a ||| ( ~~~b ||| c)) + 29 *  ~~~( ~~~a ||| (b ||| c)) + 55 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 11 * ( ~~~a &&& ( ~~~b &&& c)) + 25 * ( ~~~a &&& (b &&& c)) + 58 * (a &&& ( ~~~b &&& c)) - 8 * (a &&& (b &&& c)) =  - 3 * (c ^^^ ( ~~~a &&& (b ||| c))) + 6 * ((a ^^^ b) ||| (a ^^^ c))

theorem ashr_ugt_13_proof : ashr_ugt_13_before ⊑ ashr_ugt_13_after

theorem test_sub_nsw__all_are_safe_proof : test_sub_nsw__all_are_safe_before ⊑ test_sub_nsw__all_are_safe_after

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

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

theorem syncMap₃_eq_syncMap₃
    (hxs : xs ~ xs') (hys : ys ~ ys') (hzs : zs ~ zs') :
    syncMap₃ f xs ys zs ~ syncMap₃ f xs' ys' zs'

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

theorem trunc_lshr_trunc_outofrange_thm (e : IntW 64) :
  trunc 8 (lshr (trunc 32 e) (const? 32 25)) ⊑
    trunc 8 (lshr (trunc 32 e) (const? 32 25)) { «nsw» := true, «nuw» := true }

@[simp] theorem Expr.comap_denote_contextHom (e : Expr d Γ .pure ty) (V : Γ.Valuation) :
    (Valuation.comap (e.denote V) e.contextHom) = V

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

theorem test_invert_demorgan_logical_and_thm.extracted_1._6 : ∀ (x x_1 : BitVec 64),
  ¬ofBool (x_1 == 27#64) = 1#1 →
    ¬ofBool (x_1 != 27#64) = 1#1 →
      (ofBool (x_1 == 0#64) ||| 0#1) ^^^ 1#1 = ofBool (x_1 != 0#64) &&& ofBool (x != 0#64)

theorem test2_thm (e e_1 : IntW 16) : trunc 16 (add (zext 64 e_1) (zext 64 e)) ⊑ add e_1 e

theorem substitute_constant_and_eq_eq_commute_logical_proof : substitute_constant_and_eq_eq_commute_logical_before ⊑ substitute_constant_and_eq_eq_commute_logical_after

theorem n2_proof : n2_before ⊑ n2_after

@[simp]
theorem Factor.numVars_term : (Factor.var n).numVars = n + 1

theorem ugt_swap_and_min_commute_logical_proof : ugt_swap_and_min_commute_logical_before ⊑ ugt_swap_and_min_commute_logical_after

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

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

theorem logical_and_logical_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))
      (select (icmp IntPred.ne (LLVM.and e_2 (const? 8 1)) (const? 8 0)) (icmp IntPred.eq e (const? 8 42))
        (const? 1 0))
      (const? 1 0) ⊑
    select
      (icmp IntPred.eq
        (LLVM.and e_2 (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
        (LLVM.or (shl (const? 8 1) e_1 { «nsw» := false, «nuw» := true }) (const? 8 1)))
      (icmp IntPred.eq e (const? 8 42)) (const? 1 0)

omit [LawfulBEq A] [Fintype S] [DecidableEq S] in
lemma worklistRun'_init_wf inits hinits final? :
    let st := worklist.initState A S inits hinits final?
    (StInv A S st.m st.map ∧ worklistRun_init_post A S inits final? st.map st.m)

theorem t6_ugt_sgt_128_proof : t6_ugt_sgt_128_before ⊑ t6_ugt_sgt_128_after

theorem test4_apint_thm (e : IntW 61) :
  LLVM.and (LLVM.xor e (const? 61 (-1))) (const? 61 5) ⊑ LLVM.xor (LLVM.and e (const? 61 5)) (const? 61 5)

theorem lshrugt_02_06_exact_proof : lshrugt_02_06_exact_before ⊑ lshrugt_02_06_exact_after

theorem select_icmp_eq_and_1_0_lshr_fv_proof : select_icmp_eq_and_1_0_lshr_fv_before ⊑ select_icmp_eq_and_1_0_lshr_fv_after

theorem add_assoc_2 (hr : r < q) (hs : s < q) (hu : u >= t) :
  (bw t (addMax (bw u (addMax (bw p a) (bw r b))) (bw s c)))  =
  (bw t (addMax (bw p a) (bw q (addMax (bw r b) (bw s c)))))

theorem denote_insertPureCom_eq_of [LawfulMonad d.m]
    {zip : Zipper d Γ_in eff tys} {vs}
    {newCom : Com d zip.Γ_mid .pure newTys} {V_in : Valuation Γ_in}
    (h : ∀ V : zip.top.ValidDenotation,
        newCom.denote V.val = vs.map V.val) :
    (zip.insertPureCom vs newCom).denote V_in = zip.denote V_in

@[bv_multi_width_normalize] theorem mul_ofBool_eq (x y : Bool) :
  (BitVec.ofBool x) * (BitVec.ofBool y) = BitVec.ofBool (x && y)

theorem sub_from_variable_of_sub_from_constant_thm (e e_1 : IntW 8) : sub e_1 (sub (const? 8 42) e) ⊑ add (add e (const? 8 (-42))) e_1

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

theorem urem_common_divisor_defined_cond_thm (e e_1 e_2 : IntW 5) (e_3 : IntW 1) :
  select e_3 (urem e_2 e_1) (urem e e_1) ⊑ urem (select e_3 e_2 e) e_1

theorem test4_proof : test4_before ⊑ test4_after

theorem lshrult_03_05_exact_proof : lshrult_03_05_exact_before ⊑ lshrult_03_05_exact_after

theorem lshr_by_const_cmp_sge_value_proof : lshr_by_const_cmp_sge_value_before ⊑ lshr_by_const_cmp_sge_value_after

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

theorem ule_swap_or_min_commute_proof : ule_swap_or_min_commute_before ⊑ ule_swap_or_min_commute_after

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

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

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

theorem negate_xor_thm.extracted_1._1 : ∀ (x : BitVec 4), 0#4 - (x ^^^ 5#4) = (x ^^^ BitVec.ofInt 4 (-6)) + 1#4

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

theorem 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 lor_bor_right2_proof : lor_bor_right2_before ⊑ lor_bor_right2_after

theorem e_789 :
    5 * (z ^^^ t) + 3 * t + 5 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) + 2 * (z &&& t) = 5 * (z |||  ~~~t)

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

theorem fold_select_trunc_nsw_false_proof : fold_select_trunc_nsw_false_before ⊑ fold_select_trunc_nsw_false_after

theorem lshrult_03_10_exact_proof : lshrult_03_10_exact_before ⊑ lshrult_03_10_exact_after

theorem shl_nsw_nuw_poison_constant_fold_proof : shl_nsw_nuw_poison_constant_fold_before ⊑ shl_nsw_nuw_poison_constant_fold_after

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

theorem scalar_i32_shl_and_negC_ne_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (LLVM.and (shl e_1 e) (const? 32 (-262144))) (const? 32 0) ⊑
    icmp IntPred.ugt (shl e_1 e) (const? 32 262143)

theorem e_447 :
     - 2 * (x ^^^ y) + 7 *  ~~~(x ^^^ y) + 1 *  ~~~(x &&& y) + 11 *  ~~~(x &&&  ~~~x) - 3 * y - 7 *  ~~~(x |||  ~~~y) - 10 * (x &&&  ~~~y) - 15 * (x &&& y) = 19 *  ~~~(x ||| y)

theorem alive_276_2 : alive_276_2_src ⊑ alive_276_2_tgt

theorem ugt_3_thm (e : IntW 32) :
  icmp IntPred.ugt (trunc 8 e) (const? 8 3) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 252)) (const? 32 0)

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

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

theorem or_and_not_constant_commute3_proof : or_and_not_constant_commute3_before ⊑ or_and_not_constant_commute3_after

theorem test4_proof : test4_before ⊑ test4_after

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

theorem icmp_slt_0_or_icmp_eq_100_i32_fail_proof : icmp_slt_0_or_icmp_eq_100_i32_fail_before ⊑ icmp_slt_0_or_icmp_eq_100_i32_fail_after

theorem eq_umax3_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ᵤ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 == x) = ofBool (x ≤ᵤ x_1 + 3#32)

theorem check_axioms_mba (x y : BitVec w) :
     - 2 *  ~~~(x &&&  ~~~y) + 2 *  ~~~x - 5 *  ~~~(x |||  ~~~y) = 3 * (x &&& y) - 5 * y

theorem sub_select_zext_op_swapped_non_const_args_thm.extracted_1._4 : ∀ (x x_1 : BitVec 6) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → zeroExtend 6 x_2 - x = 0#6 - x

theorem lshrugt_01_10_proof : lshrugt_01_10_before ⊑ lshrugt_01_10_after

theorem ult_umin2_proof : ult_umin2_before ⊑ ult_umin2_after

theorem positive_with_mask_proof : positive_with_mask_before ⊑ positive_with_mask_after

theorem select_icmp_ne_0_and_4096_or_4096_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ne (const? 32 0) (LLVM.and e_1 (const? 32 4096))) e (LLVM.or e (const? 32 4096)) ⊑
    LLVM.or e (LLVM.xor (LLVM.and e_1 (const? 32 4096)) (const? 32 4096))

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

theorem bitwise_or_bitwise_or_icmps_comm2_proof : bitwise_or_bitwise_or_icmps_comm2_before ⊑ bitwise_or_bitwise_or_icmps_comm2_after

theorem sle_swap_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x ≤ₛ x_1) = 1#1 → 0#1 = ofBool (x == BitVec.ofInt 8 (-128))

theorem shl_xor_xor_no_const_proof : shl_xor_xor_no_const_before ⊑ shl_xor_xor_no_const_after

theorem masked_or_allzeroes_proof : masked_or_allzeroes_before ⊑ masked_or_allzeroes_after

theorem exact_ashr_ne_proof : exact_ashr_ne_before ⊑ exact_ashr_ne_after

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

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

theorem sext_diff_i1_xor_sub_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  True ∧ (zeroExtend 64 x).saddOverflow (signExtend 64 x_1) = true → False

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

theorem test14_proof : test14_before ⊑ test14_after

theorem mul_of_pow2_commute_proof : mul_of_pow2_commute_before ⊑ mul_of_pow2_commute_after

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

theorem test_nuw_nsw_and_signed_pred_thm (e : IntW 64) :
  icmp IntPred.slt (sub (const? 64 10) e { «nsw» := true, «nuw» := true }) (const? 64 3) ⊑
    icmp IntPred.ugt e (const? 64 7)

theorem test9_proof : test9_before ⊑ test9_after

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

theorem samesign_commute1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (-1#32 <ₛ x_1 ||| x) ||

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

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

theorem ashrslt_03_01_exact_proof : ashrslt_03_01_exact_before ⊑ ashrslt_03_01_exact_after

theorem positive_biggerLshr_shlnuw_thm (e : IntW 32) :
  lshr (shl e (const? 32 5) { «nsw» := false, «nuw» := true }) (const? 32 10) ⊑ lshr e (const? 32 5)

theorem nomask_lhs_logical_proof : nomask_lhs_logical_before ⊑ nomask_lhs_logical_after

theorem shl_sub_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬63#64 - x ≥ ↑64 →
    ¬(True ∧ BitVec.ofInt 64 (-9223372036854775808) >>> x <<< x ≠ BitVec.ofInt 64 (-9223372036854775808) ∨ x ≥ ↑64) →
      1#64 <<< (63#64 - x) = BitVec.ofInt 64 (-9223372036854775808) >>> x

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

theorem test13_proof : test13_before ⊑ test13_after

theorem fold_icmp_shl_nuw_c2_precondition3_proof : fold_icmp_shl_nuw_c2_precondition3_before ⊑ fold_icmp_shl_nuw_c2_precondition3_after

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

theorem test11_proof : test11_before ⊑ test11_after

theorem lshrult_01_15_exact_proof : lshrult_01_15_exact_before ⊑ lshrult_01_15_exact_after

theorem f_var1_commutative_and_proof : f_var1_commutative_and_before ⊑ f_var1_commutative_and_after

theorem not_lshr_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬5#8 ≥ ↑8 → x >>> 5#8 ^^^ 7#8 = (x ^^^ -1#8) >>> 5#8

theorem e_18 :
    4 * (x |||  ~~~y) - 7 *  ~~~(x ||| y) - 4 * (x &&&  ~~~y) - 7 * (x &&& y) =  - 3 *  ~~~(x &&&  ~~~x) + 3 * (x ^^^ y)

theorem shift_no_xor_multiuse_cmp_proof : shift_no_xor_multiuse_cmp_before ⊑ shift_no_xor_multiuse_cmp_after

theorem shl_nsw_nuw_add_nsw_nuw_proof : shl_nsw_nuw_add_nsw_nuw_before ⊑ shl_nsw_nuw_add_nsw_nuw_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 lshrult_01_01_proof : lshrult_01_01_before ⊑ lshrult_01_01_after

@[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 test3_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 599),
  x = 1#1 → ¬70368744177664#599 = 0 → 46#599 ≥ ↑599 → False

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

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

theorem p0_proof : p0_before ⊑ p0_after

theorem test12_logical_proof : test12_logical_before ⊑ test12_logical_after

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

theorem uaddo_commute4_thm (e e_1 e_2 : IntW 32) :
  select (icmp IntPred.ult (LLVM.xor e_2 (const? 32 (-1))) e_1) e (add e_2 e_1) ⊑
    select (icmp IntPred.ugt e_1 (LLVM.xor e_2 (const? 32 (-1)))) e (add e_2 e_1)

theorem positive_sameconst_proof : positive_sameconst_before ⊑ positive_sameconst_after

theorem scalar_i32_signbit_lshr_and_eq_proof : scalar_i32_signbit_lshr_and_eq_before ⊑ scalar_i32_signbit_lshr_and_eq_after

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail0_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 → x >>> 63#64 ||

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

theorem negate_ashr_thm (e e_1 : IntW 8) : sub e_1 (ashr e (const? 8 7)) ⊑ add (lshr e (const? 8 7)) e_1

theorem positive_with_icmp_logical_proof : positive_with_icmp_logical_before ⊑ positive_with_icmp_logical_after

theorem e_762 :
    1 *  ~~~(z &&&  ~~~z) + 7 * t - 1 * (z |||  ~~~t) - 1 *  ~~~(z |||  ~~~t) =  - 7 * (z &&&  ~~~t) + 7 * (z ||| t)

theorem test_proof : test_before ⊑ test_after

theorem PR42691_6_proof : PR42691_6_before ⊑ PR42691_6_after

@[simp] theorem impure_sup_eq : max impure e  = impure

theorem bv_AddSub_1165 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.add (LLVM.sub (LLVM.const? w 0) e) (LLVM.sub (LLVM.const? w 0) e_1) ⊑ LLVM.sub (LLVM.const? w 0) (LLVM.add e e_1)

theorem e_372 :
    2 *  ~~~(x &&& y) + 1 * y + 5 *  ~~~x + 2 *  ~~~(x ^^^ y) + 2 *  ~~~(x ||| y) + 3 *  ~~~(x |||  ~~~y) + 9 * (x &&&  ~~~y) + 8 * (x &&& y) = 11 *  ~~~(x &&&  ~~~x)

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

theorem nonexact_ashr_eq_noexactlog_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬x ≥ ↑8 → ofBool ((BitVec.ofInt 8 (-90)).sshiftRight' x == BitVec.ofInt 8 (-30)) = 0#1

theorem sext_sext_add_mismatched_types_thm (e : IntW 32) (e_1 : IntW 16) :
  add (sext 64 (ashr e_1 (const? 16 7))) (sext 64 (ashr e (const? 32 9))) ⊑
    add (sext 64 (ashr e_1 (const? 16 7))) (sext 64 (ashr e (const? 32 9))) { «nsw» := true, «nuw» := false }

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

theorem src_is_mask_lshr_thm (e e_1 : IntW 8) (e_2 : IntW 1) (e_3 : IntW 8) :
  icmp IntPred.ne (LLVM.xor e_3 (const? 8 123))
      (LLVM.and (lshr (select e_2 (LLVM.xor e_1 (add e_1 (const? 8 (-1)))) (const? 8 15)) e)
        (LLVM.xor e_3 (const? 8 123))) ⊑
    icmp IntPred.ugt (LLVM.xor e_3 (const? 8 123))
      (lshr (select e_2 (LLVM.xor e_1 (add e_1 (const? 8 (-1)))) (const? 8 15)) e)

theorem test14a_thm (e : IntW 79) :
  lshr (LLVM.and (shl e (const? 79 4)) (const? 79 1234)) (const? 79 4) ⊑ LLVM.and e (const? 79 77)

theorem alive_Select_699 : forall (w : Nat) (A B : Bitvec 1)
, TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (B) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp uge  w %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v2;
  %v8 := op:icmp uge  w %v7;
  %v9 := triple:%v8 %v6 %v2;
  %v10 := op:select 1 %v9
  dsl_ret %v10
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec 1)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (A) %v0;
  %v2 := op:const (B) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp uge  1 %v3;
  %v5 := triple:%v4 %v1 %v2;
  %v6 := op:select 1 %v5;
  %v7 := pair:%v6 %v2;
  %v8 := op:icmp uge  1 %v7;
  %v9 := triple:%v4 %v1 %v2;
  %v10 := op:select 1 %v9
  dsl_ret %v10
  ]

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

theorem ne_21_comm_ne_proof : ne_21_comm_ne_before ⊑ ne_21_comm_ne_after

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

theorem select_icmp_slt_zero_smin_flipped_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬ofBool (x <ₛ 0#8) = 1#1 → x = x &&& 127#8

theorem src_is_notmask_neg_p2_fail_not_invertable_proof : src_is_notmask_neg_p2_fail_not_invertable_before ⊑ src_is_notmask_neg_p2_fail_not_invertable_after

theorem e_968 :
    2 *  ~~~z + 5 *  ~~~(z &&& t) - 2 * t - 7 *  ~~~(z ||| t) - 5 *  ~~~(z |||  ~~~t) - 3 * (z &&&  ~~~t) + 4 * (z &&& t) = 2 * z

theorem Id.map_eq' (x : Id α) (f : α → β) : f <$> x = f x

theorem test19_commutative0_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32 ∨ x ≥ ↑32 ∨ (1#32 <<< x_1 &&& 1#32 <<< x) + 1#32 <<< x = 0) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨
          x_1 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32) →
      x_1 % ((1#32 <<< x_1 &&& 1#32 <<< x) + 1#32 <<< x) = x_1 &&& (1#32 <<< x_1 &&& 1#32 <<< x) + 1#32 <<< x + -1#32

theorem test4_proof : test4_before ⊑ test4_after

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

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

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

@[grind ., simp] lemma RawCNFA.empty_mem_finals {s : State} : s ∉ empty (A := A).finals

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

theorem PR23309v2_thm (e e_1 : IntW 32) :
  trunc 1 (add (add e_1 (const? 32 (-4))) e { «nsw» := false, «nuw» := true }) ⊑ trunc 1 (add e_1 e)

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

theorem test_shl_nuw_nsw__nsw_is_safe_proof : test_shl_nuw_nsw__nsw_is_safe_before ⊑ test_shl_nuw_nsw__nsw_is_safe_after

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

theorem e_1226 :
     - 5 *  ~~~(z ^^^ t) - 5 * (z |||  ~~~t) + 1 *  ~~~z - 3 *  ~~~t + 1 *  ~~~(z &&&  ~~~z) + 12 *  ~~~(z ||| t) - 1 *  ~~~(z |||  ~~~t) + 8 * (z &&&  ~~~t) + 9 * (z &&& t) = 1 *  ~~~(z &&& t)

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

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

@[simp] theorem Valuation.append_appendInr {v : Var Δ t} :
    (V ++ W) v.appendInr = W v

theorem uge_swap_and_max_commute_proof : uge_swap_and_max_commute_before ⊑ uge_swap_and_max_commute_after

theorem sgt_smin3_proof : sgt_smin3_before ⊑ sgt_smin3_after

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

theorem test_lshr_exact__exact_is_unsafe_thm (e : IntW 64) (e_1 : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e_1 (const? 32 63)) (const? 32 0)) e
      (ashr e (zext 64 (lshr (LLVM.and e_1 (const? 32 63)) (const? 32 2) { «exact» := true }))) ⊑
    ashr e (zext 64 (LLVM.and (lshr e_1 (const? 32 2)) (const? 32 15)) { «nneg» := true })

theorem e_821 :
     - 1 * (z ^^^ t) + 1 * (z |||  ~~~t) - 7 * t - 1 *  ~~~(z ||| t) + 6 * (z &&& t) =  - 8 *  ~~~(z |||  ~~~t)

theorem a_true_implies_b_true2_proof : a_true_implies_b_true2_before ⊑ a_true_implies_b_true2_after

theorem fold_add_udiv_urem_without_noundef_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0) →
    10#32 = 0 ∨ 4#32 ≥ ↑32 ∨ 10#32 = 0 ∨ True ∧ ((x / 10#32) <<< 4#32 &&& x % 10#32 != 0) = true → False

theorem not_and_and_or_not_or_or_commute4_proof : not_and_and_or_not_or_or_commute4_before ⊑ not_and_and_or_not_or_or_commute4_after

theorem t0_proof : t0_before ⊑ t0_after

theorem fold_sext_to_and_wrong8_proof : fold_sext_to_and_wrong8_before ⊑ fold_sext_to_and_wrong8_after

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

theorem t0_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 1),
  ¬x_1 = 1#1 → signExtend 8 x_1 + x ^^^ signExtend 8 x_1 = x

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

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

theorem logical_or_logical_or_icmps_comm3_thm.extracted_1._2 : ∀ (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 icmp_select_implied_cond_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x == 0#8) = 1#1 → ofBool (0#8 == x) = 1#1

theorem trunc_equality_both_proof : trunc_equality_both_before ⊑ trunc_equality_both_after

theorem lshrult_01_01_exact_proof : lshrult_01_01_exact_before ⊑ lshrult_01_01_exact_after

theorem lshr_mul_times_5_div_4_exact_proof : lshr_mul_times_5_div_4_exact_before ⊑ lshr_mul_times_5_div_4_exact_after

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

theorem test14_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), ofBool (x_1 == x) = x_1 ^^^ x ^^^ 1#1

theorem one_to_two_mult (hq : q > (p + 2)) (hpq : q > p) :
  (bw p (mulMax (bw 1 (1#1)) (bw p a)))  =
  (bw p (subMax (bw q (mulMax (bw 2 (2#2)) (bw p a))) (bw p a)))

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

theorem slt_smin2_proof : slt_smin2_before ⊑ slt_smin2_after

theorem shl_mul_mask_wrong_mul_const_proof : shl_mul_mask_wrong_mul_const_before ⊑ shl_mul_mask_wrong_mul_const_after

theorem eq_21_comm_eq_proof : eq_21_comm_eq_before ⊑ eq_21_comm_eq_after

theorem ult_or_not_max_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ult e_1 e) (icmp IntPred.ne e_1 (const? 8 (-1))) ⊑
    icmp IntPred.ne e_1 (const? 8 (-1))

theorem test9_thm (e : IntW 32) : trunc 8 (LLVM.and e (const? 32 42)) ⊑ LLVM.and (trunc 8 e) (const? 8 42)

theorem p0_proof : p0_before ⊑ p0_after

theorem ashrsgt_03_02_exact_proof : ashrsgt_03_02_exact_before ⊑ ashrsgt_03_02_exact_after

theorem or_sext_to_sel_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → signExtend 32 x_1 ||

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

theorem e_1197 :
    3 * z - 2 *  ~~~(z &&&  ~~~z) - 3 * (z ||| t) - 11 *  ~~~t + 2 *  ~~~(z &&& t) + 11 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) + 2 * (z &&& t) =  - 11 * (z ^^^ t)

theorem lshrugt_03_06_exact_proof : lshrugt_03_06_exact_before ⊑ lshrugt_03_06_exact_after

theorem basic_preserve_nuw_nsw_thm (e e_1 : IntW 8) :
  LLVM.xor (add (LLVM.xor e_1 (const? 8 (-1))) e { «nsw» := true, «nuw» := true }) (const? 8 (-1)) ⊑
    sub e_1 e { «nsw» := true, «nuw» := true }

theorem e_934 :
    2 *  ~~~(z &&&  ~~~t) - 1 *  ~~~(z &&& t) + 11 * t - 1 *  ~~~(z ||| t) - 12 *  ~~~(z |||  ~~~t) - 17 * (z &&& t) = 3 * (z &&&  ~~~t) - 4 * z

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

theorem AvoidCollision_shiftLeftZeroExtend_eq {x : BitVec w} :
    shiftLeftZeroExtend x n = setWidth (w+n) x <<< n

theorem test16_proof : test16_before ⊑ test16_after

theorem p1_scalar_urem_by_nonconst_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (urem (LLVM.and e_1 (const? 32 128)) (LLVM.or e (const? 32 6))) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e_1 (const? 32 128)) (const? 32 0)

theorem sext_sext_slt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 <ₛ signExtend 32 x) = ofBool (x_1 <ₛ x)

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

theorem uadd_sat_flipped_wrong_bounds4_proof : uadd_sat_flipped_wrong_bounds4_before ⊑ uadd_sat_flipped_wrong_bounds4_after

theorem positive_biggerashr_shlnsw_proof : positive_biggerashr_shlnsw_before ⊑ positive_biggerashr_shlnsw_after

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

theorem and_not_eq_or_sub:
    x &&& ~~~ y = (x ||| y) - y

theorem both_proof : both_before ⊑ both_after
</all_available_lemmas>

<local_ctx>
import Blase.Fast.FiniteStateMachine

import Blase.Vars

import Blase.MultiWidth.Defs

import Blase.KInduction.KInduction

import Lean

namespace MultiWidth

def fsmMsb (x w : FSM α) : FSM α :=
  composeBinaryAux'
    (FSM.latchImmediate false)
    (qfalse := x)
    (qtrue := w)
</local_ctx>

<target_theorem>
theorem eval_fsmMsb_eq_BitStream_ofBitVecSext {wenv : WidthExpr.Env wcard}
    {fsmEnv : StateSpace wcard tcard bcard ncard icard pcard → BitStream}
    {tctx : Term.Ctx wcard tcard}
    (tenv : Term.Ctx.Env tctx wenv)
    (benv : Term.BoolEnv bcard)
    (nenv : Term.NatEnv ncard)
    (ienv : Term.IntEnv icard)
    (w : WidthExpr wcard)
    (x : Term bcard ncard icard pcard tctx (.bv w))
    (xfsm : TermFSM wcard tcard bcard ncard icard pcard (.ofDepTerm x))
    (hxfsm : HTermFSMToBitStream xfsm)
    (wfsm : NatFSM wcard tcard bcard ncard icard pcard (.ofDep w))
    (hwfsm : HNatFSMToBitstream wfsm)
    (htenv : HTermEnv fsmEnv tenv benv) :
    (fsmMsb xfsm.toFsmZext wfsm.toFsm).eval fsmEnv =
      BitStream.ofBitVecSext (x.toBV benv nenv ienv penv tenv) :=
</target_theorem>

