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>
Inhabited in Init.Prelude
Lean.ToExpr in Lean.ToExpr
Nat in Init.Prelude
Repr in Init.Data.Repr
Bool in Init.Prelude
Int.xor in Mathlib.Data.Int.Bitwise
BitVec in Init.Prelude
BitVec.adcb in Init.Data.BitVec.Bitblast
Prod in Init.Prelude
Fin in Init.Prelude
Fin.last in Init.Data.Fin.Basic
List in Init.Prelude
List.Vector in Mathlib.Data.Vector.Defs
BitVec.ofNat in Init.Prelude
BitVec.zero in Init.Data.BitVec.Basic
Fin.castLE in Init.Data.Fin.Basic
Set in Mathlib.Data.Set.Defs
Eq in Init.Prelude
Fin.natAdd in Init.Data.Fin.Basic
List.Vector.nil in Mathlib.Data.Vector.Defs
NeZero in Init.Data.NeZero
BitVec.iunfoldr in Init.Data.BitVec.Folds
Vector in Init.Data.Vector.Basic
Vector.ofFn in Init.Data.Vector.Basic

syntax "xor" : MLIR.Pretty.uniform_op

syntax "max" : 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) )

inductive Term : Type
| var : Nat → Term
 
| zero : Term
 
| negOne : Term
 
| one : Term
 
| ofNat (n : Nat) : Term
 
| and : Term → Term → Term
 
| or : Term → Term → Term
 
| xor : Term → Term → Term
 
| not : Term → Term
 
| add : Term → Term → Term
 
| sub : Term → Term → Term
 
| neg : Term → Term

| shiftL : Term → Nat → Term

deriving Repr, Inhabited, Lean.ToExpr

def sub (x y : BitStream) : BitStream :=
  fun n => (subAux x y n).1

def subAux (x y : BitStream) : Nat → Bool × Bool
  | 0 => (xor (x 0) (y 0), !(x 0) && y 0)
  | n+1 =>
    let borrow := (subAux x y n).2
    let a := x (n + 1)
    let b := y (n + 1)
    (xor a (xor b borrow), !a && b || ((!(xor a b)) && borrow))

def BitStream : Type := Nat → Bool

def add (x y : BitStream) : BitStream :=
  fun n => (addAux x y n).1

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

def neg (x : BitStream) : BitStream :=
  fun n => (negAux x n).1

def negAux (x : BitStream) : Nat → Bool × Bool
  | 0 => (x 0, !(x 0))
  | n+1 =>
    let borrow := (negAux x n).2
    let a := x (n + 1)
    (xor (!a) borrow, !a && borrow)

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 }

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

def Term.language (t : Term) : Set (BitVecs (t.arity + 1)) :=
  { bvs : BitVecs (t.arity + 1) | t.evalFinBV (fun n => bvs.bvs.get n) = bvs.bvs.get t.arity }

@[simp]
def Formula.arity : Formula → Nat
| width _ _ => 0
| atom _ t1 t2 => max t1.arity t2.arity
| msbSet t => t.arity
| unop _ φ => φ.arity
| binop _ φ1 φ2 => max φ1.arity φ2.arity

@[simp] def Term.evalFinBV (t : Term) (vars : Fin (arity t) → BitVec w) : BitVec w :=
  match t with
  | .var n => vars (Fin.last n)
  | .zero    => BitVec.zero w
  | .one     => 1
  | .negOne  => -1
  | .ofNat n => BitVec.ofNat _ n
  | .and t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ &&& x₂
  | .or t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ||| x₂
  | .xor t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ ^^^ x₂
  | .not t     => ~~~(t.evalFinBV vars)
  
  | .add t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ + x₂
  | .sub t₁ t₂ =>
      let x₁ := t₁.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      let x₂ := t₂.evalFinBV (fun i => vars (Fin.castLE (by admit /- proof elided -/
      ) i))
      x₁ - x₂
  | .neg t       => -(t.evalFinBV vars)
  | .shiftL a n => (a.evalFinBV vars) <<< n

@[simp] def Term.arity : Term → Nat
| (var n) => n+1
| zero => 0
| one => 0
| negOne => 0
| ofNat _ => 0
| Term.and t₁ t₂ => max (arity t₁) (arity t₂)
| Term.or t₁ t₂ => max (arity t₁) (arity t₂)
| Term.xor t₁ t₂ => max (arity t₁) (arity t₂)
| Term.not t => arity t
| add t₁ t₂ => max (arity t₁) (arity t₂)
| sub t₁ t₂ => max (arity t₁) (arity t₂)
| neg t => arity t

| shiftL t .. => arity t

def BitVec.transport (f : Fin n2 → Fin n1) (bv : BitVec n1) : BitVec n2 :=
  BitVec.ofFn fun i => bv.getLsbD (f i)

def BitVec.ofFn {w : Nat} (f : Fin w → Bool) : BitVec w :=
  BitVec.iunfoldr (fun i _ => ((), f i)) () |>.2

def List.Vector.transport (v : Vector α m) (f : Fin n → Fin m) : Vector α n :=
  Vector.ofFn fun i => v.get (f i)

def BitVecs'.transport (f : Fin n → Fin m) (bvs' : BitVecs' m): BitVecs' n :=
  bvs'.map fun bv => bv.transport f

def BitVecs.transport (f : Fin n → Fin m) (bvs : BitVecs m) : BitVecs n :=
  { w := bvs.w, bvs := bvs.bvs.transport f }

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

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

def slt_zero_slt_i1_fail_before := [llvm|
{
^0(%arg4 : i32, %arg5 : i1):
  %0 = llvm.mlir.constant(31 : i32) : i32
  %1 = llvm.zext %arg5 : i1 to i32
  %2 = llvm.lshr %arg4, %0 : i32
  %3 = llvm.icmp "slt" %1, %2 : i32
  "llvm.return"(%3) : (i1) -> ()
}
]

List.next in Mathlib.Data.List.Cycle

@[coe]
def toCons {Γ : Ctxt Ty} {t t' : Ty} (var : Var Γ t) : Var (cons t' Γ) t  :=
  ⟨var.1+1, var.2⟩

instance : ToExpr Term where
  toExpr := Term.toExpr
  toTypeExpr := mkConst ``Term

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

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

def badimm4_after := [llvm|
{
^0(%arg25 : i16):
  %0 = llvm.mlir.constant(-128 : i16) : i16
  %1 = llvm.mlir.constant(127 : i16) : i16
  %2 = llvm.mlir.constant(-127 : i8) : i8
  %3 = llvm.mlir.constant(126 : i8) : i8
  %4 = llvm.icmp "slt" %arg25, %0 : i16
  %5 = llvm.icmp "sgt" %arg25, %1 : i16
  %6 = llvm.trunc %arg25 : i16 to i8
  %7 = "llvm.select"(%4, %2, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %8 = "llvm.select"(%5, %3, %7) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%8) : (i8) -> ()
}
]

Std.IdempotentOp in Init.Core

def test_before := [llvm|
{
^0(%arg0 : i1, %arg1 : i1):
  %0 = llvm.add %arg0, %arg1 : 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 test1_after := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.mlir.constant(false) : i1
  "llvm.return"(%0) : (i1) -> ()
}
]

def mul_of_pow2_commute_before := [llvm|
{
^0(%arg81 : i32, %arg82 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(255 : i32) : i32
  %2 = llvm.mlir.constant(1020 : i32) : i32
  %3 = llvm.and %arg81, %0 : i32
  %4 = llvm.and %arg82, %1 : i32
  %5 = llvm.mul %4, %3 : i32
  %6 = llvm.icmp "ugt" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

def sge_swap_or_max_before := [llvm|
{
^0(%arg182 : i8, %arg183 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "sle" %arg183, %arg182 : i8
  %2 = llvm.icmp "eq" %arg182, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

def add_shl_moreOneUse_sh3add_no_ZBA_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := add_shl_moreOneUse_sh3add
  rhs := add_shl_moreOneUse_sh3add_riscv_no_ZBA

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

def test0_before := [llvm|
{
^0(%arg6 : i41, %arg7 : i41, %arg8 : i41):
  %0 = llvm.shl %arg6, %arg8 : i41
  %1 = llvm.shl %arg7, %arg8 : i41
  %2 = llvm.and %0, %1 : i41
  "llvm.return"(%2) : (i41) -> ()
}
]

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

def llvm_const_lower_riscv_li_49 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_49, rhs:= liRiscv_49,
   correct := by admit /- proof elided -/

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

def main_after := [llvm|
{
^0(%arg2 : i32):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(5 : i8) : i8
  %2 = llvm.mlir.constant(64 : i8) : i8
  %3 = llvm.trunc %arg2 : i32 to i8
  %4 = llvm.xor %3, %0 : i8
  %5 = llvm.shl %4, %1 : i8
  %6 = llvm.and %5, %2 : i8
  %7 = llvm.zext nneg %6 : i8 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

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

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

def Term.bcard (t : Term) : Nat :=
  match t with
  | .ofNat _w _n => 0
  | .var _v _w => 0
  | .add _w a b => max (Term.bcard a) (Term.bcard b)
  | .zext a _wnew => (Term.bcard a)
  | .sext a _wnew => (Term.bcard a)
  | .setWidth a _wnew => (Term.bcard a)
  | .bor _w a b => (max (Term.bcard a) (Term.bcard b))
  | .band _w a b => (max (Term.bcard a) (Term.bcard b))
  | .bxor _w a b => (max (Term.bcard a) (Term.bcard b))
  | .bnot _w a => (Term.bcard a)
  | .boolVar v => v + 1
  | .boolConst _b => 0
  | .shiftl _w a _k => (Term.bcard a)
  | bvOfBool b => b.bcard
  | binWidthRel _k _wa _wb => 0
  | binRel _k _w a b => max (Term.bcard a) (Term.bcard b)
  | or p1 p2 => max (Term.bcard p1) (Term.bcard p2)
  | and p1 p2 => max (Term.bcard p1) (Term.bcard p2)
  | pvar _v => 0
  | boolBinRel _k a b => max (a.bcard) (b.bcard)

inductive Ty
| bitvec (w : Nat) : Ty 
deriving DecidableEq, Repr, ToExpr

def bitwise_and_bitwise_and_icmps_comm1_before := [llvm|
{
^0(%arg241 : i8, %arg242 : i8, %arg243 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "eq" %arg242, %0 : i8
  %4 = llvm.and %arg241, %1 : i8
  %5 = llvm.shl %1, %arg243 : i8
  %6 = llvm.and %arg241, %5 : i8
  %7 = llvm.icmp "ne" %4, %2 : i8
  %8 = llvm.icmp "ne" %6, %2 : i8
  %9 = llvm.and %3, %7 : i1
  %10 = llvm.and %8, %9 : i1
  "llvm.return"(%10) : (i1) -> ()
}
]

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

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7_logical_before := [llvm|
{
^0(%arg11 : i32):
  %0 = llvm.mlir.constant(7 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(8 : i32) : i32
  %4 = llvm.mlir.constant(true) : i1
  %5 = llvm.and %arg11, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %arg11, %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 test47_before := [llvm|
{
^0(%arg139 : i8):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.sext %arg139 : i8 to i32
  %2 = llvm.or %1, %0 : i32
  %3 = llvm.zext %2 : i32 to i64
  "llvm.return"(%3) : (i64) -> ()
}
]

class TransformExpr (d : Dialect) (φ : outParam Nat) [DialectSignature d] [TransformTy d φ]  where
  mkExpr   : (Γ : Ctxt d.Ty) → (opStx : AST.Op φ) → ReaderM d (Σ eff ty, Expr d Γ eff ty)

def ConcreteCliTest.printSignature (test : ConcreteCliTest) : String :=
  s!"{test.context.toList.reverse} → {test.ty}"

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

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

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

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

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

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

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

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

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

def sdiv2_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.sdiv exact %arg39, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

def lshr_xor_before := [llvm|
{
^0(%arg65 : i8, %arg66 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(3 : i8) : i8
  %2 = llvm.srem %arg65, %0 : i8
  %3 = llvm.lshr %arg66, %1 : i8
  %4 = llvm.xor %3, %2 : i8
  %5 = llvm.shl %4, %1 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

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

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 not_and_and_or_no_or_commute3_after := [llvm|
{
^0(%arg148 : i32, %arg149 : i32, %arg150 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg150 : i32
  %3 = llvm.xor %arg148, %1 : i32
  %4 = llvm.xor %arg149, %1 : i32
  %5 = llvm.or %2, %4 : i32
  %6 = llvm.and %5, %3 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

instance : AST.TransformReturn LLVM 0 := { mkReturn }

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

def test5_before := [llvm|
{
^0(%arg192 : i1):
  %0 = llvm.zext %arg192 : i1 to i8
  %1 = llvm.zext %0 : i8 to i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

@[simp_denote]
def llvm_urem: Com  LLVMPlusRiscV ⟨[.llvm (.bitvec 64), .llvm (.bitvec 64)]⟩
  .pure (.llvm (.bitvec 64)) := [LV| {
  ^entry (%x: i64, %y: i64 ):
    %1 = llvm.urem    %x, %y : i64
    llvm.return %1 : i64
  }]

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

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

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

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

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

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

@[simp_sllvm]
def srem (x y : LLVM.IntW w) : EffectM (LLVM.IntW w) := do
  if y.canBe 0#w then
    throwUB
  else
    pure <| LLVM.srem x y

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

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

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

def testi32i8_before := [llvm|
{
^0(%arg32 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(7 : i8) : i8
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(127 : i8) : i8
  %4 = llvm.lshr %arg32, %0 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.trunc %arg32 : i32 to i8
  %7 = llvm.ashr %6, %1 : i8
  %8 = llvm.icmp "eq" %7, %5 : i8
  %9 = llvm.ashr %arg32, %2 : i32
  %10 = llvm.trunc %9 : i32 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 ashr_uge_exact_before := [llvm|
{
^0(%arg170 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(10 : i8) : i8
  %2 = llvm.ashr exact %arg170, %0 : i8
  %3 = llvm.icmp "uge" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

def xor_or_xor_common_op_commute6_before := [llvm|
{
^0(%arg65 : i32, %arg66 : i32, %arg67 : i32):
  %0 = llvm.xor %arg67, %arg65 : i32
  %1 = llvm.or %arg65, %arg66 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

instance : Repr (Expr d Γ eff t) where reprPrec expr _ := expr.print

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

PartialOrder in Mathlib.Order.Defs.PartialOrder

instance : Repr (AttrEntry φ) where
  reprPrec x _ := docAttrEntry x

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

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

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

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

instance : BEq FpExprWrapper where
  beq := fun a b =>
    if h : a.width = b.width then
      a.bvExpr = h ▸ b.bvExpr
    else
      false

def or_or_and_complex_after := [llvm|
{
^0(%arg82 : i64):
  %0 = llvm.mlir.constant(8) : i64
  %1 = llvm.mlir.constant(71777214294589695) : i64
  %2 = llvm.mlir.constant(-71777214294589696) : i64
  %3 = llvm.lshr %arg82, %0 : i64
  %4 = llvm.shl %arg82, %0 : i64
  %5 = llvm.and %3, %1 : i64
  %6 = llvm.and %4, %2 : i64
  %7 = llvm.or disjoint %5, %6 : i64
  "llvm.return"(%7) : (i64) -> ()
}
]

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

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

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

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

def test13_before := [llvm|
{
^0(%arg27 : i18):
  %0 = llvm.mlir.constant(3 : i18) : i18
  %1 = llvm.mlir.constant(8 : i18) : i18
  %2 = llvm.mlir.constant(9 : i18) : i18
  %3 = llvm.mul %arg27, %0 : i18
  %4 = llvm.ashr %3, %1 : i18
  %5 = llvm.shl %4, %2 : i18
  "llvm.return"(%5) : (i18) -> ()
}
]

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

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

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

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

def ashr_lshr2_i128_after := [llvm|
{
^0(%arg123 : i128, %arg124 : i128):
  %0 = llvm.ashr %arg123, %arg124 : i128
  "llvm.return"(%0) : (i128) -> ()
}
]

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

def or_not_xor_common_op_commute7_before := [llvm|
{
^0(%arg86 : i8, %arg87 : i8, %arg88 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sub %0, %arg88 : i8
  %3 = llvm.xor %arg86, %1 : i8
  %4 = llvm.xor %arg87, %arg86 : i8
  %5 = llvm.or %2, %3 : i8
  %6 = llvm.or %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def llvm_trunc_riscv_32_to_8_nuw_nsw : LLVMPeepholeRewriteRefine 8 [Ty.llvm (.bitvec 32)] :=
  {lhs:= trunc_llvm_32_to_8_nsw_nuw, rhs:= trunc_riscv_32_to_8_nsw_nuw}

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

def mulh_to_lshr : List (Σ Γ, RISCVPeepholeRewrite Γ) :=
  [
    ⟨_, mulh_to_lshr_2⟩,
    ⟨_, mulh_to_lshr_4⟩,
    ⟨_, mulh_to_lshr_8⟩,
    ⟨_, mulh_to_lshr_16⟩,
    ⟨_, mulh_to_lshr_32⟩,
    ⟨_, mulh_to_lshr_64⟩,
    ⟨_, mulh_to_lshr_128⟩,
    ⟨_, mulh_to_lshr_256⟩,
    ⟨_, mulh_to_lshr_512⟩
  ]

def sextinreg_before := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(-32768 : i32) : i32
  %2 = llvm.mlir.constant(32768 : i32) : i32
  %3 = llvm.and %arg14, %0 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

def test31_after := [llvm|
{
^0(%arg164 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.mlir.constant(10) : i64
  %2 = llvm.and %arg164, %0 : i64
  %3 = llvm.icmp "eq" %2, %1 : i64
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def Substitution.removeMappingFor (σ : Substitution) (v : VarName) : Substitution :=
  List.filter (·.fst != v) σ

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

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

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

def shift_xor_multiuse_cmp_xor_after := [llvm|
{
^0(%arg32 : i32, %arg33 : i32, %arg34 : i32, %arg35 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(2048 : i32) : i32
  %3 = llvm.and %arg32, %0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  %5 = llvm.xor %arg33, %2 : i32
  %6 = "llvm.select"(%4, %5, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = "llvm.select"(%4, %arg35, %arg34) <{"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 t13_x_is_one_before := [llvm|
{
^0(%arg8 : i64, %arg9 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(-16 : i32) : i32
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.sub %0, %arg9 : i32
  %5 = llvm.shl %1, %4 : i32
  %6 = llvm.add %arg9, %2 : i32
  %7 = llvm.zext %6 : i32 to i64
  %8 = llvm.lshr %arg8, %7 : i64
  %9 = llvm.trunc %8 : i64 to i32
  %10 = llvm.and %5, %9 : i32
  %11 = llvm.icmp "ne" %10, %3 : i32
  "llvm.return"(%11) : (i1) -> ()
}
]

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

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

def sext_negate_after := [llvm|
{
^0(%arg29 : i1):
  %0 = llvm.zext %arg29 : i1 to i64
  "llvm.return"(%0) : (i64) -> ()
}
]

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

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

private def tensor2dTest : MLIRTy := [mlir_type| tensor2d]

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

def test14a_before := [llvm|
{
^0(%arg25 : i79):
  %0 = llvm.mlir.constant(4 : i79) : i79
  %1 = llvm.mlir.constant(1234 : i79) : i79
  %2 = llvm.shl %arg25, %0 : i79
  %3 = llvm.and %2, %1 : i79
  %4 = llvm.lshr %3, %0 : i79
  "llvm.return"(%4) : (i79) -> ()
}
]

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

def icmp_and_ashr_multiuse_logical_after := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(240 : i32) : i32
  %1 = llvm.mlir.constant(224 : i32) : i32
  %2 = llvm.mlir.constant(496 : i32) : i32
  %3 = llvm.mlir.constant(432 : i32) : i32
  %4 = llvm.and %arg4, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg4, %2 : i32
  %7 = llvm.icmp "ne" %6, %3 : i32
  %8 = llvm.and %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

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

Set.instMembership in Mathlib.Data.Set.Defs

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

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

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

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

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

def sge_or_not_max_commute_before := [llvm|
{
^0(%arg316 : i8, %arg317 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.icmp "sge" %arg316, %arg317 : i8
  %2 = llvm.icmp "ne" %arg316, %0 : i8
  %3 = llvm.or %2, %1 : i1
  "llvm.return"(%3) : (i1) -> ()
}
]

elab "#fpgeneralize" expr:term : command =>

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

def test67_before := [llvm|
{
^0(%arg113 : i1, %arg114 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(24 : i32) : i32
  %2 = llvm.mlir.constant(-16777216 : i32) : i32
  %3 = llvm.mlir.constant(0 : i8) : i8
  %4 = llvm.zext %arg113 : i1 to i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.and %arg114, %5 : i32
  %7 = llvm.shl %6, %1 overflow<nsw,nuw> : i32
  %8 = llvm.xor %7, %2 : i32
  %9 = llvm.ashr exact %8, %1 : i32
  %10 = llvm.trunc %9 : i32 to i8
  %11 = llvm.icmp "eq" %10, %3 : i8
  "llvm.return"(%11) : (i1) -> ()
}
]

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

RV64.xnor in RISCV.Instructions

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

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

def dont_narrow_zext_ashr_keep_trunc_before := [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.ashr %3, %0 : i16
  %5 = llvm.trunc %4 : i16 to i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

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

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

def and_xor_or8_before := [llvm|
{
^0(%arg652 : i64, %arg653 : i64, %arg654 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg652 : i64
  %2 = llvm.udiv %0, %arg653 : i64
  %3 = llvm.udiv %0, %arg654 : i64
  %4 = llvm.and %2, %1 : i64
  %5 = llvm.xor %3, %4 : i64
  %6 = llvm.or %2, %5 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

BitVec.signExtend in Init.Data.BitVec.Basic

def slt_and_shl_one_after := [llvm|
{
^0(%arg25 : i8, %arg26 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.shl %0, %arg26 overflow<nuw> : i8
  %2 = llvm.and %arg25, %1 : i8
  %3 = llvm.icmp "slt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

instance : AST.TransformExpr (MetaLLVM φ) φ := { mkExpr }

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

def scalar_i32_signbit_shl_and_eq_nonzero_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.shl %0, %arg1 : i32
  %3 = llvm.and %2, %arg0 : i32
  %4 = llvm.icmp "eq" %3, %1 : i32
  "llvm.return"(%4) : (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 "ne" %1, %0 : i8
  "llvm.return"(%2) : (i1) -> ()
}
]

instance : Lean.ToExpr RegIndex := inherit

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

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

def or_disjoint_with_xor_after := [llvm|
{
^0(%arg28 : i32, %arg29 : i32):
  "llvm.return"(%arg29) : (i32) -> ()
}
]

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

def mul_splat_fold_too_narrow_after := [llvm|
{
^0(%arg77 : i2):
  "llvm.return"(%arg77) : (i2) -> ()
}
]

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

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

def mkOutputAssignCircuitLeN {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (n : Nat) :
  Circuit (Vars p.α arity (n + 1)) :=
    let ixs := List.range (n + 1) |>.attach
    let circs := ixs.map fun ⟨i, hi⟩ =>
      mkOutputAssignCircuitN p i |>.map (fun v => v.castLe (by admit /- proof elided -/
      ))
    Circuit.bigOr circs

def negate (bvExpr: GenBVExpr w) : GenBVExpr w :=
  
  GenBVExpr.bin (GenBVExpr.const (BitVec.ofNat w 1)) BVBinOp.add (GenBVExpr.un BVUnOp.not bvExpr)

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

RV64.sllw in RISCV.Instructions

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

def sext_shl_trunc_smaller_after := [llvm|
{
^0(%arg11 : i16, %arg12 : i32):
  %0 = llvm.zext %arg11 : i16 to i32
  %1 = llvm.shl %0, %arg12 : i32
  %2 = llvm.trunc %1 : i32 to i5
  "llvm.return"(%2) : (i5) -> ()
}
]

def unaryOne {o : Nat} : BitVec o := 1

@[simp_llvm_option]
def shl {w : Nat} (x y : IntW w) (flags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w := do
  let x' ← x
  let y' ← y
    
  if flags.nsw ∧ ((x' <<< y').sshiftRight'  y' ≠ x') then
    .poison
  else if flags.nuw ∧ ((x' <<< y') >>> y' ≠ x') then
    .poison
  else
    shl? x' y'

Lean.Name in Init.Prelude

RV64.sexth in RISCV.Instructions

def shl_add_nsw_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8):
  %0 = llvm.mlir.constant(-32 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.or %arg10, %0 : i8
  %3 = llvm.and %arg11, %1 : i8
  %4 = llvm.shl %2, %3 overflow<nsw> : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

def foo_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.add %arg3, %arg2 overflow<nsw> : i32
  %1 = llvm.mul %0, %arg3 overflow<nsw> : i32
  %2 = llvm.mul %arg3, %arg3 overflow<nsw> : i32
  %3 = llvm.sub %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def negate_add_with_single_negatible_operand_depth2_before := [llvm|
{
^0(%arg21 : i8, %arg22 : i8):
  %0 = llvm.mlir.constant(21 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.add %arg21, %0 : i8
  %3 = llvm.mul %2, %arg22 : i8
  %4 = llvm.sub %1, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

structure Item where
 name : String
 tac : Syntax

def udiv2_after := [llvm|
{
^0(%arg30 : i32, %arg31 : i32):
  %0 = llvm.lshr exact %arg30, %arg31 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

def t0_exact_after := [llvm|
{
^0(%arg9 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.ashr exact %arg9, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

def xor_or_xor_common_op_commute5_before := [llvm|
{
^0(%arg68 : i32, %arg69 : i32, %arg70 : i32):
  %0 = llvm.xor %arg68, %arg70 : i32
  %1 = llvm.or %arg68, %arg69 : i32
  %2 = llvm.xor %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

def bitwise_or_bitwise_or_icmps_comm1_before := [llvm|
{
^0(%arg193 : i8, %arg194 : i8, %arg195 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.icmp "eq" %arg194, %0 : i8
  %4 = llvm.and %arg193, %1 : i8
  %5 = llvm.shl %1, %arg195 : i8
  %6 = llvm.and %arg193, %5 : i8
  %7 = llvm.icmp "eq" %4, %2 : i8
  %8 = llvm.icmp "eq" %6, %2 : i8
  %9 = llvm.or %3, %7 : i1
  %10 = llvm.or %8, %9 : i1
  "llvm.return"(%10) : (i1) -> ()
}
]

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

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

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

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

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

Algebra in Mathlib.Algebra.Algebra.Defs

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

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

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

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

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

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

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

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

def Expr.printType (e : Expr d Γ eff ts) : Format :=
  let argTys := e.args.mapToList (@fun t _ => printTy t)
  let argTys := Format.group <| Format.joinSep argTys ", "
  let retTys := ts.map printTy
  let retTys := Format.group <| Format.joinSep retTys ", "
  f!"({argTys}) -> ({retTys})"

def shl_add_lshr_comm_before := [llvm|
{
^0(%arg151 : i32, %arg152 : i32, %arg153 : i32):
  %0 = llvm.shl %arg151, %arg152 overflow<nuw> : i32
  %1 = llvm.mul %arg153, %arg153 : i32
  %2 = llvm.add %1, %0 overflow<nuw> : i32
  %3 = llvm.lshr %2, %arg152 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

def icmp_equality_test_before := [llvm|
{
^0(%arg34 : i64, %arg35 : i64, %arg36 : i64):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "eq" %arg34, %arg36 : i64
  %3 = llvm.icmp "eq" %arg35, %arg36 : i64
  %4 = llvm.icmp "eq" %arg34, %arg35 : i64
  %5 = llvm.xor %3, %0 : i1
  %6 = "llvm.select"(%5, %4, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = "llvm.select"(%2, %3, %6) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (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 }

    |

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

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

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

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

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

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

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

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

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

def ashr_add_fail_before := [llvm|
{
^0(%arg14 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.ashr %0, %arg14 : i8
  %3 = llvm.add %arg14, %1 : i8
  %4 = llvm.ashr %0, %3 : i8
  %5 = llvm.add %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def zext_sext_ugt_known_nonneg_before := [llvm|
{
^0(%arg22 : i8, %arg23 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.and %arg22, %0 : i8
  %2 = llvm.zext %1 : i8 to i32
  %3 = llvm.sext %arg23 : i8 to i32
  %4 = llvm.icmp "ugt" %2, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

def 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 alive_AndOrXor_1280_ABA___AB_src :=
[sllvm| {
^bb0(%A : i64, %B : i64):
  %v1 = llvm.mlir.constant -1 : i64
  %v2 = llvm.xor %A, %v1 : i64
  %v3 = llvm.or %v2, %B : i64
  %v4 = llvm.and %v3, %A : i64
  llvm.return %v4 : i64
}]

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

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

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

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

def udiv {w : Nat} (x y : IntW w) (flag : ExactFlag := {exact := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flag.exact ∧ x'.umod y' ≠ 0 then
    .poison
  else
    udiv? x' y'

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

def beqBitVecInstExpr (width : Expr) : Expr := mkApp2 (.const ``instBEqOfDecidableEq [levelZero]) (mkApp (mkConst ``BitVec) width) (mkApp (.const ``instDecidableEqBitVec []) width)

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

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

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

def match_signed_after := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(172224) : i64
  %1 = llvm.srem %arg15, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

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

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

def sub_negative_constant_lhs_i32_test : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32)] where
  lhs := sub_negative_constant_lhs_llvm_i32
  rhs := sub_negative_constant_lhs_riscv_i32

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

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

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

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

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

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

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

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

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

def 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 trunc_equality_nsw_zext_after := [llvm|
{
^0(%arg16 : i32, %arg17 : i8):
  %0 = llvm.zext %arg17 : i8 to i32
  %1 = llvm.icmp "ne" %arg16, %0 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def t3_exact_after := [llvm|
{
^0(%arg7 : i64):
  %0 = llvm.mlir.constant(63) : i64
  %1 = llvm.lshr exact %arg7, %0 : i64
  "llvm.return"(%1) : (i64) -> ()
}
]

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

def test13_before := [llvm|
{
^0(%arg10 : i79):
  %0 = llvm.mlir.constant(78 : i79) : i79
  %1 = llvm.mlir.constant(0 : i79) : i79
  %2 = llvm.lshr %arg10, %0 : i79
  %3 = llvm.sub %1, %2 : i79
  "llvm.return"(%3) : (i79) -> ()
}
]

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

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

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

def positive_samevar_before := [llvm|
{
^0(%arg62 : i8, %arg63 : i8):
  %0 = llvm.lshr %arg62, %arg63 : i8
  %1 = llvm.shl %0, %arg63 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

def test_ult_xor_after := [llvm|
{
^0(%arg36 : i32, %arg37 : i32):
  %0 = llvm.xor %arg37, %arg36 : i32
  %1 = llvm.icmp "ugt" %0, %arg36 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_7b_logical_before := [llvm|
{
^0(%arg9 : i32):
  %0 = llvm.mlir.constant(6 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(15 : i32) : i32
  %3 = llvm.mlir.constant(8 : i32) : i32
  %4 = llvm.mlir.constant(true) : i1
  %5 = llvm.and %arg9, %0 : i32
  %6 = llvm.icmp "eq" %5, %1 : i32
  %7 = llvm.and %arg9, %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_swap_and_not_max_logical_before := [llvm|
{
^0(%arg116 : i8, %arg117 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "sgt" %arg117, %arg116 : i8
  %3 = llvm.icmp "ne" %arg116, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

def or_test1_before := [llvm|
{
^0(%arg2 : i231, %arg3 : i231):
  %0 = llvm.mlir.constant(1 : i231) : i231
  %1 = llvm.and %arg2, %0 : i231
  %2 = llvm.or %1, %0 : i231
  "llvm.return"(%2) : (i231) -> ()
}
]

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

def IntToString (i: Int): String := i.repr

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

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

def test_invert_demorgan_and3_before := [llvm|
{
^0(%arg5 : i32, %arg6 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(4095 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.xor %arg5, %0 : i32
  %4 = llvm.add %arg6, %3 : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.icmp "eq" %5, %2 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

def foo1_and_after := [llvm|
{
^0(%arg181 : i32, %arg182 : i32, %arg183 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %0, %arg182 overflow<nuw> : i32
  %2 = llvm.shl %0, %arg183 overflow<nuw> : i32
  %3 = llvm.or %1, %2 : i32
  %4 = llvm.and %arg181, %3 : i32
  %5 = llvm.icmp "ne" %4, %3 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

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

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

private def levelParamsToMessageData (levelParams : List Name) : MessageData :=
  match levelParams with
  | []    => ""
  | u::us => Id.run do
    let mut m := m!".\{{u}"
    for u in us do
      m := m ++ ", " ++ toMessageData u
    return m ++ "}"

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

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

def icmp_select_var_select_after := [llvm|
{
^0(%arg83 : i8, %arg84 : i8, %arg85 : i1):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.icmp "eq" %arg83, %0 : i8
  %3 = llvm.icmp "eq" %arg83, %arg84 : i8
  %4 = llvm.xor %arg85, %1 : i1
  %5 = "llvm.select"(%2, %1, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %6 = "llvm.select"(%5, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

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

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

def n12_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.xor %arg0, %0 : i32
  %3 = llvm.add %arg1, %2 : i32
  %4 = llvm.add %3, %1 : i32
  "llvm.return"(%4) : (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 zext_sext_add_icmp_ugt_1_after := [llvm|
{
^0(%arg66 : i1, %arg67 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg66, %0 : i1
  %2 = llvm.and %arg67, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

def WidthPredicate.final? (wp : WidthPredicate) (n : Nat) (s : State) : Bool :=
  decide (wp.sat s n)

def debugCheck (check? : Bool) (e : Expr)  : MetaM Unit :=
    if check?
    then check e
    else return ()

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

def not_signbit_splat_mask2_after := [llvm|
{
^0(%arg107 : i8, %arg108 : i16):
  %0 = llvm.mlir.constant(6 : i8) : i8
  %1 = llvm.ashr %arg107, %0 : i8
  %2 = llvm.sext %1 : i8 to i16
  %3 = llvm.and %arg108, %2 : i16
  "llvm.return"(%3) : (i16) -> ()
}
]

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

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

instance : Refinement (BitVec w) := .ofEq

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

Lean.pp.explicit in Lean.PrettyPrinter.Delaborator.Options

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

def factorize4_before := [llvm|
{
^0(%arg3 : i32, %arg4 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.shl %arg4, %0 : i32
  %2 = llvm.mul %1, %arg3 : i32
  %3 = llvm.mul %arg3, %arg4 : i32
  %4 = llvm.sub %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def mkCarryAssignCircuitNAux {arity : Type _}
  [DecidableEq arity]
  [Fintype arity]
  [Hashable arity]
  (p : FSM arity) (s : p.α) (n : Nat) : Circuit (Vars p.α arity (n + 1)) :=
    (p.nextStateCirc s).map fun v =>
      match v with
        | .inl t => Vars.stateN t n
        | .inr i => Vars.inputN i n

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

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

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

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

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

@[simp]
def _root_.Set.lift (f : Fin n → Fin m) (bvs : Set (BitVecs n)) : Set (BitVecs m) :=
  BitVecs.transport f ⁻¹' bvs

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

def lshr_and_sub_after := [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 overflow<nsw> : i8
  %7 = llvm.shl %6, %1 : i8
  "llvm.return"(%7) : (i8) -> ()
}
]

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

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

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

def scalar_i8_shl_ugt_const_before := [llvm|
{
^0(%arg11 : i8):
  %0 = llvm.mlir.constant(5 : i8) : i8
  %1 = llvm.mlir.constant(63 : i8) : i8
  %2 = llvm.shl %arg11, %0 : i8
  %3 = llvm.icmp "ugt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

def masked_icmps_mask_notallzeros_bmask_mixed_swapped_1b_logical_after := [llvm|
{
^0(%arg47 : 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 %arg47, %0 : i32
  %5 = llvm.icmp "ne" %4, %1 : i32
  %6 = llvm.and %arg47, %2 : i32
  %7 = llvm.icmp "eq" %6, %3 : i32
  %8 = llvm.and %7, %5 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def Hom.delete {Γ : Ctxt Ty} (delv : DeleteRange Γ) : Hom (Γ.delete delv) Γ :=
  fun t' v =>
    let idx :=
      if v.val < delv.start then
        v.val
      else
        v.val + delv.num
    ⟨idx, by admit /- proof elided -/
    ⟩

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

Int.neg in Init.Data.Int.Basic

def positive_samevar_ashrexact_before := [llvm|
{
^0(%arg42 : i8, %arg43 : i8):
  %0 = llvm.ashr exact %arg42, %arg43 : i8
  %1 = llvm.shl %0, %arg43 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

instance : ToString LLVM.Op :=

def select_constant_cmp : List (Σ Γ, LLVMPeepholeRewriteRefine 64  Γ) :=
  [⟨_, select_constant_cmp_true⟩,
  ⟨_, select_constant_cmp_false⟩]

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

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

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

def product.inits_nodup : inits m₁ m₂ |>.toList.Nodup :=

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

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

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

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

def getEqRhs (eq : Expr) : MetaM Expr := do
  check eq
  let eq ← whnf <| ← inferType eq
  let some (_ty, _lhs, rhs) := eq.eq? | throwError m!"unable to infer RHS for equality {eq}"
  let rhs ← instantiateMVars rhs
  rhs.ensureHasNoMVars
  return rhs

def mul_of_pow2s_after := [llvm|
{
^0(%arg79 : i32, %arg80 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def and_not_or_or_not_or_xor_commute2_after := [llvm|
{
^0(%arg319 : i32, %arg320 : i32, %arg321 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sdiv %0, %arg319 : i32
  %3 = llvm.or %arg320, %arg321 : i32
  %4 = llvm.xor %arg320, %arg321 : i32
  %5 = llvm.or %4, %2 : i32
  %6 = llvm.and %3, %5 : i32
  %7 = llvm.xor %6, %1 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

def add_or_sub_comb_i128_commuted3_nuw_nsw_before := [llvm|
{
^0(%arg14 : i128):
  %0 = llvm.mlir.constant(0 : i128) : i128
  %1 = llvm.mul %arg14, %arg14 : i128
  %2 = llvm.sub %0, %1 : i128
  %3 = llvm.or %1, %2 : i128
  %4 = llvm.add %3, %1 overflow<nsw,nuw> : i128
  "llvm.return"(%4) : (i128) -> ()
}
]

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

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

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

def storePure (m : MemorySSAState) (p : SLLVM.Ptr) (x : LLVM.IntW w) : MemorySSAState := do
  let m ← m
  Prod.snd <$> (store p x).run m

@[simp_denote]
def add_b31_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_b31_llvm_i64
  rhs := add_b31_riscv_i64

def test_shl__nsw_is_safe_after := [llvm|
{
^0(%arg72 : i32):
  %0 = llvm.mlir.constant(-83886080 : i32) : i32
  %1 = llvm.mlir.constant(2 : i32) : i32
  %2 = llvm.or %arg72, %0 : i32
  %3 = llvm.shl %2, %1 overflow<nsw> : i32
  %4 = llvm.mul %3, %2 : i32
  %5 = llvm.mul %4, %3 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

def and_logic_and_logic_or_4_before := [llvm|
{
^0(%arg129 : i1, %arg130 : i1, %arg131 : i1):
  %0 = llvm.mlir.constant(false) : i1
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.and %arg130, %arg129 : i1
  %3 = "llvm.select"(%arg131, %arg129, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %4 = "llvm.select"(%2, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

instance :  HydrableSynthesizeWithNoPrecondition ParsedBVExpr GenBVPred GenBVExpr where
 synthesizeWithNoPrecondition := synthesizeWithNoPrecondition

def positive_trunc_signbit_logical_after := [llvm|
{
^0(%arg40 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.icmp "ult" %arg40, %0 : i32
  "llvm.return"(%1) : (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 eq_shift_in_zeros_after := [llvm|
{
^0(%arg84 : i32, %arg85 : i32):
  %0 = llvm.mlir.constant(256 : i32) : i32
  %1 = llvm.xor %arg84, %arg85 : i32
  %2 = llvm.icmp "ult" %1, %0 : i32
  "llvm.return"(%2) : (i1) -> ()
}
]

def sdiv_common_divisor_defined_cond_before := [llvm|
{
^0(%arg41 : i1, %arg42 : i5, %arg43 : i5, %arg44 : i5):
  %0 = llvm.sdiv %arg43, %arg42 : i5
  %1 = llvm.sdiv %arg44, %arg42 : i5
  %2 = "llvm.select"(%arg41, %1, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i5, i5) -> i5
  "llvm.return"(%2) : (i5) -> ()
}
]

def shl_add_and_fail_mismatch_shift_before := [llvm|
{
^0(%arg84 : i8, %arg85 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(123 : i8) : i8
  %2 = llvm.shl %arg84, %0 : i8
  %3 = llvm.lshr %arg85, %0 : i8
  %4 = llvm.add %3, %1 : i8
  %5 = llvm.and %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

Lean.Meta.mkAppM in Lean.Meta.AppBuilder

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

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

structure Term where
  c : Int
  f : Factor
deriving Repr

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

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

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

def ripple_nsw3_after := [llvm|
{
^0(%arg19 : i16, %arg20 : i16):
  %0 = llvm.mlir.constant(-21845 : i16) : i16
  %1 = llvm.mlir.constant(21843 : i16) : i16
  %2 = llvm.and %arg20, %0 : i16
  %3 = llvm.and %arg19, %1 : i16
  %4 = llvm.add %2, %3 overflow<nsw,nuw> : i16
  "llvm.return"(%4) : (i16) -> ()
}
]

def RawCNFA.empty : RawCNFA A := {
  stateMax := 0
  initials := ∅
  finals := ∅
  trans := ∅
}

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

abbrev HasBool (d : Dialect) [TyDenote d.Ty] [DialectSignature d] : Type := HasTy d Bool

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

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

def pack (x : ValueStream α) (y : TokenStream) : ValueStream α :=
  Stream.corec (β := ValueStream α × TokenStream) (x, y) fun ⟨x, y⟩ =>
    match x 0, y 0 with
    | some x₀, some _ => (x₀, (x.tail, y.tail))
    | some _, none => (none, (x, y.tail)) 
    | none, some _ => (none, (x.tail, y)) 
    | none, none => (none, (x.tail, y.tail))

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

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

def no_shift_xor_multiuse_cmp_before := [llvm|
{
^0(%arg96 : i32, %arg97 : i32, %arg98 : i32, %arg99 : i32):
  %0 = llvm.mlir.constant(4096 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.and %arg96, %0 : i32
  %3 = llvm.icmp "ne" %1, %2 : i32
  %4 = llvm.or %arg97, %0 : i32
  %5 = "llvm.select"(%3, %arg97, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %6 = "llvm.select"(%3, %arg98, %arg99) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %7 = llvm.mul %5, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

def src_x_or_mask_ne_before := [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.xor %arg3, %0 : i8
  %5 = llvm.or %3, %4 : i8
  %6 = llvm.icmp "ne" %5, %0 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

def lshr_and_or_disjoint_after := [llvm|
{
^0(%arg43 : i8, %arg44 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(2 : i8) : i8
  %2 = llvm.mlir.constant(52 : i8) : i8
  %3 = llvm.srem %arg43, %0 : i8
  %4 = llvm.shl %3, %1 : i8
  %5 = llvm.and %arg44, %2 : i8
  %6 = llvm.or disjoint %5, %4 : i8
  "llvm.return"(%6) : (i8) -> ()
}
]

def PR52261_after := [llvm|
{
^0(%arg208 : i1):
  %0 = llvm.mlir.constant(2 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

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

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

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

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

@[reducible]
instance : TyDenote ExTy where
  toType
    | .nat => Nat
    | .bool => Bool

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

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 redundant_binop_in_equality_XXorYNeX : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.xor %x, %y : i64
      %1 = llvm.icmp.ne %0, %x : i64
      llvm.return %1 : i1
  }]
  rhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %0 = llvm.mlir.constant (0) : i64
      %1 = llvm.icmp.ne %y, %0 : i64
      llvm.return %1 : i1
  }]

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

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

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

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

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

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

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

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

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

def add_hi_one_lo_negone_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := add_hi_one_lo_negone_llvm_i64
  rhs := add_hi_one_lo_negone_riscv_i64

@[simp_denote]
def add_multiuse_const_riscv_i64 :=
  [LV| {
    ^entry (%x: i64, %y: i64):
    %0 = "li"() {imm = -1 : !i64} : (!i64) -> (!i64)
    %1 = srli %0, 24 : !i64
    %a0 = "builtin.unrealized_conversion_cast" (%x) : (i64) -> (!i64)
    %2 = sub %a0, %1 : !i64
    %a1 = "builtin.unrealized_conversion_cast" (%y) : (i64) -> (!i64)
    %3 = sub %a1, %1 : !i64
    %4 = xor %2, %3 : !i64
    %5 = "builtin.unrealized_conversion_cast" (%4) : (!i64) -> (i64)
    llvm.return %5 : i64
  }]

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

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

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

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

def not_signbit_trunc_before := [llvm|
{
^0(%arg16 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.xor %arg16, %0 : i16
  %3 = llvm.lshr %2, %1 : i16
  %4 = llvm.trunc %3 : i16 to i8
  "llvm.return"(%4) : (i8) -> ()
}
]

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

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

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

def slt_0_before := [llvm|
{
^0(%arg39 : i32):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.trunc %arg39 : i32 to i8
  %2 = llvm.icmp "slt" %1, %0 : i8
  "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 llvm_and_lower_riscv_64 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)]
where
  lhs:= and_llvm_64
  rhs:= and_riscv_64

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

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

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

BitVec.srem in Init.Data.BitVec.Basic

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

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

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

def test13_before := [llvm|
{
^0(%arg44 : i32, %arg45 : i32):
  %0 = llvm.mlir.constant(-1431655767 : i32) : i32
  %1 = llvm.mlir.constant(1431655766 : i32) : i32
  %2 = llvm.mlir.constant(1 : i32) : i32
  %3 = llvm.or %arg44, %0 : i32
  %4 = llvm.xor %3, %1 : i32
  %5 = llvm.add %arg45, %2 : i32
  %6 = llvm.add %5, %4 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

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

def test2_after := [llvm|
{
^0(%arg0 : i52, %arg1 : i52):
  %0 = llvm.icmp "ugt" %arg0, %arg1 : i52
  "llvm.return"(%0) : (i1) -> ()
}
]

def foo1_and_commuted_after := [llvm|
{
^0(%arg172 : i32, %arg173 : i32, %arg174 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mul %arg172, %arg172 : i32
  %2 = llvm.shl %0, %arg173 overflow<nuw> : i32
  %3 = llvm.shl %0, %arg174 overflow<nuw> : i32
  %4 = llvm.or %2, %3 : i32
  %5 = llvm.and %1, %4 : i32
  %6 = llvm.icmp "ne" %5, %4 : i32
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

def test5_before := [llvm|
{
^0(%arg2 : i700):
  %0 = llvm.mlir.constant(288230376151711743 : i700) : i700
  %1 = llvm.or %arg2, %0 : i700
  %2 = llvm.xor %1, %0 : i700
  "llvm.return"(%2) : (i700) -> ()
}
]

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

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

instance : TyDenote (Ty q n) where
toType := fun
  | .index => Nat
  | .integer => Int
  | .tensor => List Int
  | .polynomialLike => (R q n)

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

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

def ashr_pow2_ugt_before := [llvm|
{
^0(%arg67 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(-96 : i8) : i8
  %2 = llvm.ashr %0, %arg67 : i8
  %3 = llvm.icmp "ugt" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

def n15_variable_shamts_after := [llvm|
{
^0(%arg0 : i32, %arg1 : i64, %arg2 : i32, %arg3 : i64):
  %0 = llvm.mlir.constant(0 : i32) : i32
  %1 = llvm.lshr %arg0, %arg2 : i32
  %2 = llvm.shl %arg1, %arg3 : i64
  %3 = llvm.trunc %2 : i64 to i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.icmp "ne" %4, %0 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

inductive TransformError
  | nameAlreadyDeclared (var : String)
  | undeclaredName (var : String)
  | indexOutOfBounds (name : String) (index len : Nat)
  | typeError (expected got : String)
  | widthError {φ} (expected got : Width φ)
  
  
  | unsupportedUnaryOp
  | unsupportedBinaryOp (error : String)
  | unsupportedOp (error : String)
  | unsupportedType
  | generic (error : String)

@[elab_as_elim, induction_eliminator]
def recOn' {motive : Ctxt Ty → Sort*}
    (nil  : motive empty)
    (cons : (Γ : Ctxt Ty) → (t : Ty) → motive Γ → motive (Γ.cons t)) :
    ∀ Γ, motive Γ
  | ⟨[]⟩        => nil
  | ⟨ty :: tys⟩ => cons ⟨tys⟩ ty (recOn' nil cons ⟨tys⟩)

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

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

def or {w : Nat} (l : List (BitVec w)) : BitVec w :=
  List.foldr BitVec.or (BitVec.zero w) l

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

BitVec.allOnes in Init.Data.BitVec.Basic

Nat in Init.Prelude

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

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

def NFA'.autMsbSet : NFA' 1 := ⟨_, NFA.autMsbSet⟩

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

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

def sub_add_reg_x_sub_x_add_y : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64, %y: i64):
      %1 = llvm.add %x, %y : 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 ashrsgt_02_00_exact_after := [llvm|
{
^0(%arg85 : i4):
  %0 = llvm.mlir.constant(0 : i4) : i4
  %1 = llvm.icmp "sgt" %arg85, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

def reassoc_x2_mul_nuw_before := [llvm|
{
^0(%arg18 : i32, %arg19 : i32):
  %0 = llvm.mlir.constant(5 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.mul %arg18, %0 overflow<nuw> : i32
  %3 = llvm.mul %arg19, %1 overflow<nuw> : i32
  %4 = llvm.mul %2, %3 overflow<nuw> : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

def test8_before := [llvm|
{
^0(%arg20 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(32767) : i64
  %2 = llvm.ashr %arg20, %0 : i32
  %3 = llvm.sext %2 : i32 to i64
  %4 = llvm.mul %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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

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

def bigOr {α : Type _}
    (cs : List (Circuit α)) : Circuit α :=
  match cs with
  | [] => Circuit.fals
  | c :: cs =>
    c ||| (Circuit.bigOr cs)

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

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

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

def PostLegalizerCombiner_LLVMIR_64 : List (Σ Γ, LLVMPeepholeRewriteRefine 64  Γ) :=
  hoist_logic_op_with_same_opcode_hands_64 ++
  sub_add_reg ++
  integer_reassoc_combines ++
  sub_to_add ++
  select_same_val ++
  matchMulO ++
  LLVMIR_cast_combines_64 ++
  xor_of_and_with_same_reg_list ++
  LLVMIR_identity_combines_64 ++
  match_selects ++
  idempotent_prop

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

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

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

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

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

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

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

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

def CNFA.autWidth (wp : WidthPredicate) (n : Nat) : CNFA 0 :=
  ⟨RawCNFA.autWidth wp n, RawCNFA.autWidth_wf⟩

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

instance : ToString DCOp.TokenStream where
  toString s := toString (Stream.toList 10 s)

Int.reduceNeg in Lean.Meta.Tactic.Simp.BuiltinSimprocs.Int

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

def mul_mask_pow2_sgt0_before := [llvm|
{
^0(%arg22 : i8):
  %0 = llvm.mlir.constant(44 : i8) : i8
  %1 = llvm.mlir.constant(4 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mul %arg22, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.icmp "sgt" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

@[simp_llvm]
def xor? {w : Nat} (x y : BitVec w) : IntW w :=
  .value <| x ^^^ y

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

def llvm_const_lower_riscv_li1 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM1, rhs:= liRiscv1,
   correct := by admit /- proof elided -/

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

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

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

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

@[match_pattern] abbrev not    : Nat → LLVM.Op := MOp.not    ∘ .concrete

def pr33078_2_after := [llvm|
{
^0(%arg4 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.ashr %arg4, %0 : i8
  %2 = llvm.sext %1 : i8 to i12
  "llvm.return"(%2) : (i12) -> ()
}
]

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

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

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

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

def 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 or_and_shifts2_before := [llvm|
{
^0(%arg13 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.mlir.constant(896 : i32) : i32
  %2 = llvm.mlir.constant(4 : i32) : i32
  %3 = llvm.mlir.constant(7 : i32) : i32
  %4 = llvm.shl %arg13, %0 : i32
  %5 = llvm.and %4, %1 : i32
  %6 = llvm.lshr %arg13, %2 : i32
  %7 = llvm.and %6, %3 : i32
  %8 = llvm.or %5, %7 : i32
  "llvm.return"(%8) : (i32) -> ()
}
]

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

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

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

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

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

def mkTy : MLIR.AST.MLIRType φ → MLIR.AST.ExceptM DC DC.Ty
  | MLIR.AST.MLIRType.undefined s => do
    match s.splitOn "_" with
    | ["TokenStream"] =>
      return .tokenstream
    | ["TokenStream2"] =>
      return .tokenstream2
    | ["ValueStream", w] =>
      match w.toNat? with
      | some w' => return .valuestream w'
      | _ => throw .unsupportedType
    | ["ValueStream2", w] =>
      match w.toNat? with
      | some w' => return .valuestream2 w'
      | _ => throw .unsupportedType
    | ["ValueTokenStream", w] =>
    match w.toNat? with
      | some w' => return .valuetokenstream w'
      | _ => throw .unsupportedType
    | ["VariadicValueTokenStream", w] =>
    match w.toNat? with
      | some w' => return .variadicvaluetokenstream w'
      | _ => throw .unsupportedType
    | _ => throw .unsupportedType
  | _ => throw .unsupportedType

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

instance : DialectToExpr TestDialect where
  toExprM := q(Id)
  toExprDialect := q(TestDialect)

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

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

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

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

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

def precondSynthesisUpdateCache (previousLevelCache synthesisComponents: Std.HashMap (FpExpr w)  PreconditionSynthesisCacheValue)
      (positiveExamples negativeExamples: List (Std.HashMap Nat FpExprWrapper)) (specialConstants : Std.HashMap (FpExpr w) FpExprWrapper)
      (ops : List (FpExpr w → FpExpr w → FpExpr w)) : GeneralizerStateM ParsedFpExpr FpPredicate (Std.HashMap (FpExpr w) PreconditionSynthesisCacheValue) := do
  return {}

@[simp_denote]
def add_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 = addw %a, %b : !i64
    %1 = "builtin.unrealized_conversion_cast" (%0) : (!i64) -> (i32)
    llvm.return %1 : i32
  }]

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

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

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

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

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

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

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

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

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

Union in Init.Core

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

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

Lean.Core.Context in Lean.CoreM

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

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

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

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

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

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

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 ult_swap_and_not_max_after := [llvm|
{
^0(%arg102 : i8, %arg103 : i8):
  %0 = llvm.icmp "ugt" %arg103, %arg102 : i8
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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 and_ne_with_one_bit_diff_constants2_logical_before := [llvm|
{
^0(%arg359 : i19):
  %0 = llvm.mlir.constant(65 : i19) : i19
  %1 = llvm.mlir.constant(193 : i19) : i19
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "ne" %arg359, %0 : i19
  %4 = llvm.icmp "ne" %arg359, %1 : i19
  %5 = "llvm.select"(%3, %4, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%5) : (i1) -> ()
}
]

def rev8_mul_and_lshr_after := [llvm|
{
^0(%arg29 : i8):
  %0 = llvm.mlir.constant(2050) : i64
  %1 = llvm.mlir.constant(139536) : i64
  %2 = llvm.mlir.constant(32800) : i64
  %3 = llvm.mlir.constant(558144) : i64
  %4 = llvm.mlir.constant(65793) : i64
  %5 = llvm.mlir.constant(16) : i64
  %6 = llvm.zext %arg29 : i8 to i64
  %7 = llvm.mul %6, %0 overflow<nsw,nuw> : i64
  %8 = llvm.and %7, %1 : i64
  %9 = llvm.mul %6, %2 overflow<nsw,nuw> : i64
  %10 = llvm.and %9, %3 : i64
  %11 = llvm.or disjoint %8, %10 : i64
  %12 = llvm.mul %11, %4 overflow<nsw,nuw> : i64
  %13 = llvm.lshr %12, %5 : i64
  %14 = llvm.trunc %13 : i64 to i8
  "llvm.return"(%14) : (i8) -> ()
}
]

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

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

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

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

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

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

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

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

def and_sequence_30_rhs (w : Nat)  :=
[llvm( w )| {
^bb0(%C1 : _, %Z : _):
  %v1 = llvm.and %Z,  %C1
  llvm.return %v1
}]

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

def shrink_or_after := [llvm|
{
^0(%arg11 : i6):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.trunc %arg11 : i6 to i3
  %2 = llvm.or %1, %0 : i3
  "llvm.return"(%2) : (i3) -> ()
}
]

def ex1 := [HSxComb_com| {
  ^entry(%0: !Stream_BitVec_1):
    "return" (%0) : (!Stream_BitVec_1) -> ()
  }]

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

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

def bitwise_and_logical_and_icmps_comm3_after := [llvm|
{
^0(%arg223 : i8, %arg224 : i8, %arg225 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "eq" %arg224, %0 : i8
  %4 = llvm.shl %1, %arg225 overflow<nuw> : i8
  %5 = llvm.or %4, %1 : i8
  %6 = llvm.and %arg223, %5 : i8
  %7 = llvm.icmp "eq" %6, %5 : i8
  %8 = "llvm.select"(%7, %3, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%8) : (i1) -> ()
}
]

def alive_AddSub_1176_tgt :=
[sllvm| {
^bb0(%a : i64, %b : i64):
  %v1 = llvm.mlir.constant 0 : i64
  %v2 = llvm.sub %v1, %b : i64
  %v3 = llvm.sub %a, %b : i64
  llvm.return %v3 : i64
}]

@[reducible]
instance : DialectDenote ExOp ExTy where
  denote
    | .add, .cons (a : Nat) (.cons b .nil), _ => a + b
    | .runK (k : Nat), (.cons (v : Nat) .nil), (.cons rgn _nil) =>
      k.iterate (fun val => rgn (fun _ty _var => val)) v

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

def test1_before := [llvm|
{
^0(%arg14 : i32, %arg15 : i32):
  %0 = llvm.icmp "slt" %arg14, %arg15 : i32
  %1 = llvm.zext %0 : i1 to i32
  %2 = llvm.icmp "sgt" %arg14, %arg15 : i32
  %3 = llvm.zext %2 : i1 to i32
  %4 = llvm.and %1, %3 : i32
  %5 = llvm.trunc %4 : i32 to i1
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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 ashr_pow2_ult_before := [llvm|
{
^0(%arg59 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(-96 : i8) : i8
  %2 = llvm.ashr %0, %arg59 : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

@[reducible, simp]
def Op.outTy : Op → Ty
  | .add => .int
  | .sub => .int
  | .constIx _ => .ix
  | .constTensor _ => .tensor2d
  | .constInt _ => .int
  | .map2d | .fill2d => .tensor2d
  | .extract2d => .tensor2d

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

def add_of_mul_before := [llvm|
{
^0(%arg4 : i8, %arg5 : i8, %arg6 : i8):
  %0 = llvm.mul %arg4, %arg5 overflow<nsw> : i8
  %1 = llvm.mul %arg4, %arg6 overflow<nsw> : i8
  %2 = llvm.add %0, %1 overflow<nsw> : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

def sdiv_pow2_256 : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (256) : i64
      %0 = llvm.sdiv %x, %c : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c0 = llvm.mlir.constant (63) : i64
      %c1 = llvm.mlir.constant (56) : i64
      %c2 = llvm.mlir.constant (8) : i64
      %0 = llvm.ashr %x, %c0 : i64
      %1 = llvm.lshr %0, %c1 : i64
      %2 = llvm.add %x, %1 : i64 
      %3 = llvm.ashr %2, %c2 : i64
      llvm.return %3 : i64
  }]

def sub_zext_trunc_lshr_after := [llvm|
{
^0(%arg15 : i64):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.mlir.constant(31 : i32) : i32
  %2 = llvm.mlir.constant(10 : i32) : i32
  %3 = llvm.trunc %arg15 : i64 to i32
  %4 = llvm.shl %3, %0 : i32
  %5 = llvm.ashr %4, %1 : i32
  %6 = llvm.add %5, %2 overflow<nsw> : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

<all_available_lemmas>
Nat.mod_eq_of_lt in Init.Data.Nat.Div.Basic
Nat.add_comm in Init.Data.Nat.Basic
Fin.ext_iff in Init.Data.Fin.Lemmas
Nat.mod_le in Init.Data.Nat.Div.Basic
eq_iff_iff in Init.Core
iff_true in Init.SimpLemmas
ite_cond_eq_true in Init.SimpLemmas

@[ext]
theorem ext {x y : BitStream} (h : ∀ i, x i = y i) : x = y

@[simp]
lemma List.Vector.append_get_ge {x : List.Vector α n} {y : List.Vector α m} {i : Fin (n+m)} (hlt: n ≤ i) :
    (x ++ y).get i = y.get ((i.cast (Nat.add_comm n m) |>.subNat n hlt))

@[simp]
lemma List.Vector.append_get_lt {x : List.Vector α n} {y : List.Vector α m} {i : Fin (n+m)} (hlt: i < n) :
    (x ++ y).get i = x.get (i.castLT hlt)

@[simp]
lemma BitVecs.transport_getElem {bvs : BitVecs m} (f : Fin n → Fin m) (i : Fin n) :
    (bvs.transport f).bvs.get i = bvs.bvs.get (f i)

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 e_539 :
     - 7 * (x ^^^ y) - 3 * (x ||| y) + 3 *  ~~~x - 3 *  ~~~y - 11 *  ~~~(x &&&  ~~~x) - 2 * x + 11 *  ~~~(x ||| y) + 26 * (x &&&  ~~~y) + 16 * (x &&& y) =  - 18 *  ~~~(x |||  ~~~y)

theorem bools_logical_thm (e e_1 e_2 : IntW 1) :
  select (select (LLVM.xor e_2 (const? 1 1)) e_1 (const? 1 0)) (const? 1 1) (select e_2 e (const? 1 0)) ⊑
    select e_2 e e_1

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

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

theorem or_trunc_lshr_small_mask_proof : or_trunc_lshr_small_mask_before ⊑ or_trunc_lshr_small_mask_after

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

theorem ne_smax2_proof : ne_smax2_before ⊑ ne_smax2_after

theorem select_icmp_ne_0_and_32_and_not_4096_proof : select_icmp_ne_0_and_32_and_not_4096_before ⊑ select_icmp_ne_0_and_32_and_not_4096_after

@[simp]
lemma RawCNFA.lift_processState_spec {m : CNFA n₁} {f : Fin n₁ → Fin n₂} :
    s' ∈ (lift.processState m.m f trs s₀).getD (s, b) ∅ ↔
      s' ∈ trs.getD (s, b) ∅ ∨ s = s₀ ∧ s' ∈ m.m.tr s (b.transport f)

theorem xor_i8_to_i64_shl_save_and_ne_thm.extracted_1._2 : ∀ (x : BitVec 64) (x_1 : BitVec 8),
  ofBool (x_1 &&& 1#8 != 0#8) = 1#1 →
    ¬63#64 ≥ ↑64 → x ^^^ BitVec.ofInt 64 (-9223372036854775808) = x ^^^ zeroExtend 64 x_1 <<< 63#64

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

theorem mul8_low_A0_B0_thm (e e_1 : IntW 8) :
  add (shl (add (mul (lshr e_1 (const? 8 4)) e) (mul (lshr e (const? 8 4)) e_1)) (const? 8 4))
      (mul (LLVM.and e_1 (const? 8 15)) (LLVM.and e (const? 8 15))) ⊑
    mul e e_1

theorem f_var1_commutative_and_proof : f_var1_commutative_and_before ⊑ f_var1_commutative_and_after

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

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

theorem neg_mask_proof : neg_mask_before ⊑ neg_mask_after

theorem e_2018 :
    1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 11 * ((d &&& f) ||| (e &&&  ~~~f)) - 6 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * (e ^^^ (d |||  ~~~f)) - 1 * (f ^^^ (d &&&  ~~~e)) - 1 * f + 5 * (f |||  ~~~(d ^^^ e)) + 7 * (e |||  ~~~(d ||| f)) - 1 *  ~~~(d &&&  ~~~f) + 2 * (e ^^^  ~~~(d &&& (e ||| f))) + 2 * ( ~~~f &&&  ~~~(d ^^^ e)) - 7 * (d &&&  ~~~e) + 7 * (e ^^^ f) + 7 * ( ~~~e ||| (d ^^^ f)) - 1 * e - 1 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 6 *  ~~~( ~~~d ||| (e ^^^ f)) + 11 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 2 * (f &&& (d |||  ~~~e)) - 1 * (d ^^^ f) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 5 * (f ^^^ ( ~~~d ||| (e &&& f))) - 7 * (e ^^^ (d &&& ( ~~~e ||| f))) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& f)) + 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 24 *  ~~~(d ||| (e ||| f)) - 13 *  ~~~(d ||| ( ~~~e ||| f)) + 3 *  ~~~( ~~~d ||| (e ||| f)) - 33 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 27 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) - 6 * (d &&& ( ~~~e &&& f)) - 12 * (d &&& (e &&& f)) =  - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 2 * (e ^^^ (d &&&  ~~~f))

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

theorem test_proof : test_before ⊑ test_after

@[simp]
theorem Valuation.ofPair_fst {t₁ t₂ : Ty} (v₁: ⟦t₁⟧) (v₂ : ⟦t₂⟧) :
  (Ctxt.Valuation.ofPair v₁ v₂) ⟨0, by rfl⟩ = v₁

theorem ashrsgt_02_13_exact_proof : ashrsgt_02_13_exact_before ⊑ ashrsgt_02_13_exact_after

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

theorem trunc_shl_33_i32_i64_proof : trunc_shl_33_i32_i64_before ⊑ trunc_shl_33_i32_i64_after

@[simp] theorem Lets.getPureExpr_nil : getPureExpr (.nil : Lets d Γ eff Γ) v = none

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

theorem not_or_or_and_not_and_and_commute1_and_proof : not_or_or_and_not_and_and_commute1_and_before ⊑ not_or_or_and_not_and_and_commute1_and_after

lemma CNFA.autWidth_initials : s ∈ (autWidth wp n).m.initials ↔ s = 0

theorem test13_proof : test13_before ⊑ test13_after

theorem negation_of_increment_via_or_with_no_common_bits_set_proof : negation_of_increment_via_or_with_no_common_bits_set_before ⊑ negation_of_increment_via_or_with_no_common_bits_set_after

theorem and_consts_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (4#32 &&& x == 0#32) ||

theorem icmp_slt_0_or_icmp_sge_neg1_i32_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → x >>> 31#32 ||

theorem commutativity_constant_14_vary_proof : commutativity_constant_14_vary_before ⊑ commutativity_constant_14_vary_after

theorem test_simplify_decrement_invalid_ne_proof : test_simplify_decrement_invalid_ne_before ⊑ test_simplify_decrement_invalid_ne_after

lemma simulFun_sim {m : CNFA n} f :
    m.m.SimulFun M.M f → m.Sim M

@[simp]
theorem Term.toBV_setWidth {wenv : WidthExpr.Env wcard}
    {tctx : Term.Ctx wcard tcard}
    (benv : Term.BoolEnv bcard)
    (tenv : tctx.Env wenv) (a : Term bcard ncard icard pcard tctx (.bv w)) (v : WidthExpr wcard) :
  Term.toBV benv nenv ienv penv tenv (.setWidth a v) = (a.toBV benv nenv ienv penv tenv).zeroExtend (v.toNat wenv)

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

theorem e_2264 :
    2 * (e ^^^ f) + 2 * (e ^^^ (d ||| ( ~~~e &&& f))) - 11 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) + 1 * (f ^^^ (d &&&  ~~~e)) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 *  ~~~(e ^^^ f) + 7 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 7 * ( ~~~f &&& (d ^^^ e)) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d ||| (e ||| f))) - 1 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 5 *  ~~~(d &&& ( ~~~e &&& f)) + 2 *  ~~~(d ^^^ f) + 1 *  ~~~(e &&& f) + 11 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (f &&& (d ^^^ e)) - 1 * (e |||  ~~~f) + 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 2 * (f &&& (d ||| e)) + 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 5 * ( ~~~e &&&  ~~~(d ^^^ f)) + 1 * (e ^^^ (d ||| (e ^^^ f))) - 6 * (e &&& (d ||| f)) - 11 * ( ~~~e &&& (d ^^^ f)) + 2 * (e &&& (d |||  ~~~f)) - 2 * f - 1 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 *  ~~~(d ^^^ ( ~~~e ||| f)) + 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 5 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^  ~~~(d &&& f)) - 7 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 *  ~~~(d &&& f) - 11 * (e |||  ~~~(d |||  ~~~f)) - 11 * (e |||  ~~~(d ^^^ f)) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 3 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 7 *  ~~~( ~~~d ||| (e &&& f)) + 11 * (f |||  ~~~(d ^^^ e)) - 11 * (e |||  ~~~(d ||| f)) + 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 11 * ( ~~~d &&& (e ||| f)) - 5 * (e ||| (d ^^^ f)) + 2 * (e ^^^ (d ||| f)) - 11 *  ~~~(d ||| (e ||| f)) + 23 *  ~~~(d ||| ( ~~~e ||| f)) + 8 *  ~~~( ~~~d ||| (e ||| f)) + 1 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 8 * ( ~~~d &&& ( ~~~e &&& f)) + 9 * ( ~~~d &&& (e &&& f)) - 23 * (d &&& ( ~~~e &&& f)) + 24 * (d &&& (e &&& f)) = 1 * (e ^^^  ~~~(d |||  ~~~f)) - 4 *  ~~~(d ||| f)

theorem PR28476_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x != 0#32) = 1#1 → ¬ofBool (x == 0#32) = 1#1 → False

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

theorem shl_trunc_smaller_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(10#32 ≥ ↑32 ∨ 13#24 ≥ ↑24) →
    ¬3#24 ≥ ↑24 → truncate 24 (x.sshiftRight' 10#32) <<< 13#24 = truncate 24 x <<< 3#24 &&& BitVec.ofInt 24 (-8192)

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

theorem demorgan_plus_and_to_xor_proof : demorgan_plus_and_to_xor_before ⊑ demorgan_plus_and_to_xor_after

theorem ashr_mul_times_5_div_4_exact_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.smulOverflow 5#32 = true ∨ True ∧ (x * 5#32) >>> 2#32 <<< 2#32 ≠ x * 5#32 ∨ 2#32 ≥ ↑32) →
    ¬(True ∧ x >>> 2#32 <<< 2#32 ≠ x ∨ 2#32 ≥ ↑32 ∨ True ∧ x.saddOverflow (x.sshiftRight' 2#32) = true) →
      (x * 5#32).sshiftRight' 2#32 = x + x.sshiftRight' 2#32

theorem lshr_32_add_known_32_leading_zeroes_proof : lshr_32_add_known_32_leading_zeroes_before ⊑ lshr_32_add_known_32_leading_zeroes_after

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

theorem a_true_implies_b_false_thm (e e_1 : IntW 1) (e_2 : IntW 8) :
  select (icmp IntPred.ugt e_2 (const? 8 20)) (select (icmp IntPred.ult e_2 (const? 8 10)) e_1 e)
      (const? 1 0) ⊑
    select (icmp IntPred.ugt e_2 (const? 8 20)) e (const? 1 0)

theorem xor_add_thm.extracted_1._1 : ∀ (x : BitVec 32),
  True ∧ (73#32).ssubOverflow (x &&& 31#32) = true ∨ True ∧ (73#32).usubOverflow (x &&& 31#32) = true → False

theorem f_var1_commutative_and_proof : f_var1_commutative_and_before ⊑ f_var1_commutative_and_after

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

theorem test14_proof : test14_before ⊑ test14_after

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

theorem t2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8), ¬x ≥ ↑8 → x_1 - BitVec.ofInt 8 (-42) <<< x = 42#8 <<< x + x_1

theorem or_and_not_constant_commute2_proof : or_and_not_constant_commute2_before ⊑ or_and_not_constant_commute2_after

@[simp] lemma eval_simplify : ∀ (c : Circuit α) (f : α → Bool),
    eval (simplify c) f = eval c f

theorem icmp_equality_test_swift_optional_pointers_proof : icmp_equality_test_swift_optional_pointers_before ⊑ icmp_equality_test_swift_optional_pointers_after

theorem src_is_notmask_neg_p2_fail_not_invertable_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (0#8 == 0#8 - (0#8 - x_1 &&& x_1) &&& (x ^^^ 123#8)) =
    ofBool (x_1 ||| 0#8 - x_1 ≤ᵤ x ^^^ BitVec.ofInt 8 (-124))

theorem PR42691_3_logical_thm (e : IntW 32) :
  select (icmp IntPred.sge e (const? 32 0)) (const? 1 1) (icmp IntPred.eq e (const? 32 (-2147483648))) ⊑
    icmp IntPred.ult e (const? 32 (-2147483647))

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

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

theorem sge_swap_and_max_logical_proof : sge_swap_and_max_logical_before ⊑ sge_swap_and_max_logical_after

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

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

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

theorem eq_smax3_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 bor_land_left2_proof : bor_land_left2_before ⊑ bor_land_left2_after

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

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

theorem test59_proof : test59_before ⊑ test59_after

theorem e_2080 :
     - 7 *  ~~~(d ||| (e ^^^ f)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 5 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ||| (d &&&  ~~~f)) + 11 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 1 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) + 11 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * (f ||| (d &&& e)) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) + 11 * (d ||| (e ||| f)) + 1 *  ~~~(d ^^^ f) + 1 * (e |||  ~~~(d ^^^ f)) + 11 * (e ^^^ (d &&&  ~~~f)) - 3 * (e ^^^ (d &&& (e ||| f))) + 7 * (f ^^^ ( ~~~d ||| (e ||| f))) + 1 *  ~~~(d &&& (e ^^^ f)) - 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) - 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 2 * (e ^^^ (d &&& ( ~~~e ||| f))) + 4 * (e ||| (d ^^^ f)) - 11 * (e ^^^ (d &&& f)) + 2 * (d ^^^ (e ^^^ f)) + 2 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 * (e ^^^  ~~~(d &&& (e ||| f))) - 11 * (e ^^^  ~~~(d |||  ~~~f)) + 4 * ( ~~~e |||  ~~~(d ^^^ f)) + 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 1 * (e ^^^ (d &&& (e ^^^ f))) - 2 * f + 3 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) - 22 *  ~~~(d ||| (e ||| f)) - 39 *  ~~~(d ||| ( ~~~e ||| f)) - 52 *  ~~~( ~~~d ||| (e ||| f)) + 4 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 17 * ( ~~~d &&& ( ~~~e &&& f)) - 10 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) - 29 * (d &&& (e &&& f)) = 1 * (e ^^^  ~~~(d ||| (e &&& f))) + 3 * (e &&&  ~~~(d &&&  ~~~f))

theorem ashrslt_01_13_exact_proof : ashrslt_01_13_exact_before ⊑ ashrslt_01_13_exact_after

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

@[simp] theorem Valuation.ofHVector_apply (xs : HVector toType ts)
    (v : Var ⟨ts⟩ t) :
    ofHVector xs v = xs[v]

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

theorem positive_samevar_thm (e e_1 : IntW 32) : lshr (shl e_1 e) e ⊑ LLVM.and (lshr (const? 32 (-1)) e) e_1

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

theorem exact_lshr_eq_both_equal_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 126) e { «exact» := true }) (const? 8 126) ⊑
    icmp IntPred.eq e (const? 8 0)

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

theorem test_imply_not2_thm.extracted_1._4 : ∀ (x : BitVec 1) (x_1 : BitVec 32),
  ofBool (x_1 == 0#32) = 1#1 → ¬ofBool (x_1 != 0#32) = 1#1 → x ||

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

theorem narrow_sext_add_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  truncate 16 (signExtend 32 x_1 + x) = x_1 + truncate 16 x

theorem e_337 :
    7 *  ~~~x - 7 * (x ||| y) + 3 * y - 7 * x - 6 *  ~~~(x ||| y) - 3 *  ~~~(x |||  ~~~y) + 16 * (x &&&  ~~~y) + 10 * (x &&& y) =  - 1 *  ~~~(x ^^^ y) + 2 *  ~~~y

theorem e_2357 :
     - 6 *  ~~~(d ||| (e ^^^ f)) + 1 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 5 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 2 *  ~~~(d ||| f) + 3 * ( ~~~f &&& (d ^^^ e)) + 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * (f ||| (d &&&  ~~~e)) - 6 * (e &&&  ~~~(d ^^^ f)) + 7 *  ~~~(d ^^^ ( ~~~e &&& f)) + 4 * (f ||| (d &&& e)) + 7 * (d ||| (e &&& f)) + 11 * ( ~~~f ||| (d ^^^ e)) - 6 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 5 * (f &&&  ~~~(d &&& e)) + 5 * (d &&& f) - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 2 * (f ^^^ (d ||| (e ||| f))) + 7 * (d ||| (e ||| f)) + 3 * (f ^^^  ~~~(d &&&  ~~~e)) - 3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 1 * (f &&& (d ||| e)) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 2 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 5 * (f ^^^ (d &&& e)) + 7 * ( ~~~e ||| (d ^^^ f)) + 5 * ((d &&& e) |||  ~~~(e ^^^ f)) - 2 * ( ~~~d ||| (e &&& f)) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 1 * (e ^^^  ~~~(d &&&  ~~~f)) - 1 * (e |||  ~~~f) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 5 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 11 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 2 * (e |||  ~~~(d ||| f)) + 4 *  ~~~(d ^^^ e) + 4 * (e ^^^ (d &&& (e ||| f))) - 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 2 * (d &&&  ~~~f) - 1 *  ~~~f + 2 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 1 * (e ^^^ ( ~~~d ||| (e &&& f))) + 11 *  ~~~( ~~~d &&& (e &&& f)) + 3 * (f ^^^  ~~~(d &&& (e ||| f))) - 1 * (e ^^^  ~~~(d &&& f)) - 1 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (d ^^^ (e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 5 *  ~~~(d |||  ~~~f) + 2 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * ((d &&& f) |||  ~~~(e ||| f)) - 7 *  ~~~(d ^^^ (e ||| f)) - 3 *  ~~~( ~~~d &&& ( ~~~e ||| f)) + 7 * (f ^^^  ~~~(d |||  ~~~e)) - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 * (e ^^^ f) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 *  ~~~(e &&&  ~~~f) - 16 *  ~~~(d ||| (e ||| f)) - 17 *  ~~~(d ||| ( ~~~e ||| f)) - 38 *  ~~~( ~~~d ||| (e ||| f)) - 5 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 27 * ( ~~~d &&& ( ~~~e &&& f)) - 6 * ( ~~~d &&& (e &&& f)) - 71 * (d &&& ( ~~~e &&& f)) - 18 * (d &&& (e &&& f)) = 3 * (e ^^^ (d ||| (e &&& f)))

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

theorem ashrslt_02_02_proof : ashrslt_02_02_before ⊑ ashrslt_02_02_after

theorem rem_euclid_2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(8#32 == 0 || 32 != 1 && x == intMin 32 && 8#32 == -1) = true →
    ofBool (-1#32 <ₛ x.srem 8#32) = 1#1 → x.srem 8#32 = x &&& 7#32

theorem lshrugt_02_08_exact_proof : lshrugt_02_08_exact_before ⊑ lshrugt_02_08_exact_after

theorem test66_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (x &&& 4294967296#64 != 0#64) = 1#1 → ofBool (x &&& 4294967296#64 == 0#64) = 1#1 → 40#32 = 42#32

theorem main7d_logical_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& (x_1 &&& x) == x_1 &&& x) = 1#1 →
    ofBool (x_2 &&& (x_1 &&& x) != x_1 &&& x) = 1#1 → ¬0#1 = 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 test4_thm (e e_1 : IntW 67) :
  LLVM.and (LLVM.or e_1 (lshr e (const? 67 66))) (const? 67 2) ⊑ LLVM.and e_1 (const? 67 2)

theorem lshr_shl_pow2_const_case2_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(x ≥ ↑16 ∨ 4#16 ≥ ↑16) → ofBool (x == 12#16) = 1#1 → 8192#16 >>> x <<< 4#16 &&& 32#16 = 32#16

theorem i_thm (e : IntW 8) :
  LLVM.sdiv (LLVM.sdiv e (const? 8 (-3))) (const? 8 (-3)) ⊑ LLVM.sdiv e (const? 8 9)

theorem shrink_or_thm.extracted_1._1 : ∀ (x : BitVec 6),
  truncate 3 (x ||| BitVec.ofInt 6 (-31)) = truncate 3 x ||

theorem lshrult_02_15_exact_proof : lshrult_02_15_exact_before ⊑ lshrult_02_15_exact_after

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

theorem positive_different_trunc_both_proof : positive_different_trunc_both_before ⊑ positive_different_trunc_both_after

theorem fold_and_zext_icmp_proof : fold_and_zext_icmp_before ⊑ fold_and_zext_icmp_after

theorem test_nuw_dropped_proof : test_nuw_dropped_before ⊑ test_nuw_dropped_after

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

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

theorem positive_with_icmp_logical_thm (e : IntW 32) :
  select (icmp IntPred.ult e (const? 32 512)) (icmp IntPred.ult (add e (const? 32 128)) (const? 32 256))
      (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 128)

theorem bools2_logical_commute0_and1_proof : bools2_logical_commute0_and1_before ⊑ bools2_logical_commute0_and1_after

theorem t2_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬63#64 ≥ ↑64 →
    ¬(63#64 ≥ ↑64 ∨
          True ∧ signExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64 ∨
            True ∧ zeroExtend 64 (truncate 32 (x >>> 63#64)) ≠ x >>> 63#64) →
      0#32 - truncate 32 (x.sshiftRight' 63#64) = truncate 32 (x >>> 63#64)

theorem add_smax_simplify2_proof : add_smax_simplify2_before ⊑ add_smax_simplify2_after

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

theorem test_invert_demorgan_or2_thm (e e_1 e_2 : IntW 64) :
  LLVM.xor
      (LLVM.or (LLVM.or (icmp IntPred.ugt e_2 (const? 64 23)) (icmp IntPred.ugt e_1 (const? 64 59)))
        (icmp IntPred.ugt e (const? 64 59)))
      (const? 1 1) ⊑
    LLVM.and (LLVM.and (icmp IntPred.ult e_2 (const? 64 24)) (icmp IntPred.ult e_1 (const? 64 60)))
      (icmp IntPred.ult e (const? 64 60))

theorem toTensor_length_eq_f_deg_plus_1 [Fact (q > 1)] (a : R q n) :
  a.toTensor'.length = 2^n + 1

theorem ne_smax3_proof : ne_smax3_before ⊑ ne_smax3_after

theorem test3_proof : test3_before ⊑ test3_after

theorem test3_proof : test3_before ⊑ test3_after

theorem test38_proof : test38_before ⊑ test38_after

theorem bool_eq0_logical_thm.extracted_1._1 : ∀ (x : BitVec 64),
  ofBool (0#64 <ₛ x) = 1#1 → ofBool (ofBool (x == 1#64) == 0#1) = ofBool (1#64 <ₛ x)

theorem test22_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(2147483647#32 == 0 || 32 != 1 && x &&& 2147483647#32 == intMin 32 && 2147483647#32 == -1) = true →
    ¬2147483647#32 = 0 → (x &&& 2147483647#32).srem 2147483647#32 = (x &&& 2147483647#32) % 2147483647#32

theorem ashr_C1_add_A_C2_i32_proof : ashr_C1_add_A_C2_i32_before ⊑ ashr_C1_add_A_C2_i32_after

theorem shl_lshr_eq_amt_multi_use_proof : shl_lshr_eq_amt_multi_use_before ⊑ shl_lshr_eq_amt_multi_use_after

theorem test_eq_0_and_15_add_3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (x + 3#8 &&& 15#8 == 0#8) = ofBool (x &&& 15#8 == 13#8)

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

theorem AvoidCollision_toInt_signExtend_eq_toInt_bmod_of_le (x : BitVec w) (h : v ≤ w) :
    (x.signExtend v).toInt = x.toInt.bmod (2 ^ v)

theorem sle_and_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 ≤ₛ x) = 1#1 → 0#1 = ofBool (x_1 == BitVec.ofInt 8 (-128))

theorem or_simplify_ugt_fail_thm (e e_1 : IntW 8) :
  icmp IntPred.ugt (LLVM.or (LLVM.and e_1 (const? 8 (-2))) (LLVM.or e (const? 8 1))) (LLVM.or e (const? 8 1)) ⊑
    icmp IntPred.ne (LLVM.or e_1 (LLVM.or e (const? 8 1))) (LLVM.or e (const? 8 1))

theorem eq_basic_equal_minus_1_proof : eq_basic_equal_minus_1_before ⊑ eq_basic_equal_minus_1_after

theorem bool_add_lshr_proof : bool_add_lshr_before ⊑ bool_add_lshr_after

theorem ashrslt_03_09_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 3)) (const? 4 (-7)) ⊑ const? 1 0

theorem lshr_add_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ (42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8) →
    ¬((42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true ∨ 5#8 ≥ ↑8) →
      (x_1 >>> 5#8 + x.srem 42#8) <<< 5#8 = x_1 + x.srem 42#8 <<< 5#8 &&& BitVec.ofInt 8 (-32)

theorem icmp_power2_and_icmp_shifted_mask_8_7_proof : icmp_power2_and_icmp_shifted_mask_8_7_before ⊑ icmp_power2_and_icmp_shifted_mask_8_7_after

theorem t14_x_is_one_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(32#32 - x ≥ ↑32 ∨ zeroExtend 64 (x + BitVec.ofInt 32 (-16)) ≥ ↑64) →
    ofBool (x_1 <<< (32#32 - x) &&& truncate 32 (1#64 >>> zeroExtend 64 (x + BitVec.ofInt 32 (-16))) != 0#32) = 0#1

theorem xor_and_or_proof : xor_and_or_before ⊑ xor_and_or_after

theorem ashr_16_to_64_add_zext_basic_proof : ashr_16_to_64_add_zext_basic_before ⊑ ashr_16_to_64_add_zext_basic_after

theorem or_simplify_ugt_fail_proof : or_simplify_ugt_fail_before ⊑ or_simplify_ugt_fail_after

theorem test_proof : test_before ⊑ test_after

theorem not_lshr_const_proof : not_lshr_const_before ⊑ not_lshr_const_after

theorem icmp_slt_0_or_icmp_add_1_sge_100_i32_fail_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    x >>> 31#32 ||

theorem gt_signed_to_large_unsigned_proof : gt_signed_to_large_unsigned_before ⊑ gt_signed_to_large_unsigned_after

theorem shl_add_nsw_thm (e e_1 : IntW 8) :
  shl (LLVM.or e_1 (const? 8 (-32))) (LLVM.and e (const? 8 2)) ⊑
    shl (LLVM.or e_1 (const? 8 (-32))) (LLVM.and e (const? 8 2)) { «nsw» := true, «nuw» := false }

theorem test2_thm (e e_1 e_2 : IntW 49) : LLVM.xor (ashr e_2 e_1) (ashr e e_1) ⊑ ashr (LLVM.xor e_2 e) e_1

theorem ashr_ugt_noexact_proof : ashr_ugt_noexact_before ⊑ ashr_ugt_noexact_after

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

theorem bitwise_and_logical_and_masked_icmp_allones_poison2_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1)
  (x_2 : BitVec 32),
  ¬ofBool (x_2 &&& 8#32 == 8#32) = 1#1 →
    ofBool (x_2 &&& 8#32 != 0#32) = 1#1 → 0#1 &&& ofBool (x_2 &&& x == x) = x_1 &&& ofBool (x_2 &&& x == x)

theorem select_2_thm.extracted_1._10 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → x ^^^ 45#8 ^^^ -1#8 = x ^^^ BitVec.ofInt 8 (-46)

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

theorem masked_or_allones_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 7#32 == 7#32) = 1#1 → ofBool (x &&& 39#32 == 39#32) = ofBool (x &&& 7#32 == 7#32)

@[simp]
theorem BitVec.intCast_eq_ofInt : ((i : Int) : BitVec w) = BitVec.ofInt w i

theorem test24_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬BitVec.ofInt 32 (-2147483648) = 0 →
    ofBool (x % BitVec.ofInt 32 (-2147483648) != 0#32) = ofBool (x &&& 2147483647#32 != 0#32)

theorem imp_eq (p q : Prop) : (p → q) = (¬ p ∨ q)

theorem sge_swap_and_max_commute_proof : sge_swap_and_max_commute_before ⊑ sge_swap_and_max_commute_after

theorem alive_AndOrXor_2595  (w : Nat)   : alive_AndOrXor_2595_src w  ⊑ alive_AndOrXor_2595_tgt w

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

theorem ult_swap_and_max_commute_proof : ult_swap_and_max_commute_before ⊑ ult_swap_and_max_commute_after

theorem e_1542 :
     - 7 * (a &&& c) - 5 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 6 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 1 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 11 *  ~~~(a ||| (b ||| c)) + 6 *  ~~~(a ||| ( ~~~b ||| c)) - 1 *  ~~~( ~~~a ||| (b ||| c)) + 11 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 1 * ( ~~~a &&& ( ~~~b &&& c)) + 1 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) =  - 13 * (a &&& (b &&& c))

theorem fast_div_201_proof : fast_div_201_before ⊑ fast_div_201_after

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

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

theorem or_logic_or_logic_and_6_thm (e e_1 e_2 : IntW 1) :
  select (LLVM.or e_2 e_1) (select e (const? 1 1) e_1) (const? 1 0) ⊑
    select e_1 (const? 1 1) (select e_2 e (const? 1 0))

theorem ashr_xor_thm (e e_1 : IntW 32) :
  ashr (LLVM.xor (LLVM.srem e_1 (const? 32 42)) (ashr e (const? 32 5))) (const? 32 7) ⊑
    LLVM.xor (ashr e (const? 32 12)) (ashr (LLVM.srem e_1 (const? 32 42)) (const? 32 7))

theorem add_signbit_select_shl_proof : add_signbit_select_shl_before ⊑ add_signbit_select_shl_after

theorem and_to_xor2_proof : and_to_xor2_before ⊑ and_to_xor2_after

theorem not_signbit_alt_xor_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → (x ^^^ BitVec.ofInt 8 (-2)) >>> 7#8 = zeroExtend 8 (ofBool (-1#8 <ₛ x))

theorem icmp_eq_x_invertable_y2_proof : icmp_eq_x_invertable_y2_before ⊑ icmp_eq_x_invertable_y2_after

theorem t1_proof : t1_before ⊑ t1_after

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 urem_constant_dividend_select_of_constants_divisor_0_arm_proof : urem_constant_dividend_select_of_constants_divisor_0_arm_before ⊑ urem_constant_dividend_select_of_constants_divisor_0_arm_after

theorem fold_sext_to_and_wrong9_proof : fold_sext_to_and_wrong9_before ⊑ fold_sext_to_and_wrong9_after

theorem not_ashr_not_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬x ≥ ↑32 → (x_1 ^^^ -1#32).sshiftRight' x ^^^ -1#32 = x_1.sshiftRight' x

theorem lshr_neg_slt_zero_thm (e : IntW 8) :
  icmp IntPred.slt (lshr (const? 8 (-17)) e) (const? 8 0) ⊑ icmp IntPred.eq e (const? 8 0)

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

theorem alive_AndOrXor_698  (w : Nat)   : alive_AndOrXor_698_src w  ⊑ alive_AndOrXor_698_tgt w

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

theorem neg_nsw_slt_0_proof : neg_nsw_slt_0_before ⊑ neg_nsw_slt_0_after

theorem different_size_zext_zext_sgt_proof : different_size_zext_zext_sgt_before ⊑ different_size_zext_zext_sgt_after

theorem lshrult_01_04_proof : lshrult_01_04_before ⊑ lshrult_01_04_after

theorem select_xor_icmp_bad_6_proof : select_xor_icmp_bad_6_before ⊑ select_xor_icmp_bad_6_after

theorem test_shl_nuw__nuw_is_safe_proof : test_shl_nuw__nuw_is_safe_before ⊑ test_shl_nuw__nuw_is_safe_after

theorem substitute_constant_and_eq_eq_proof : substitute_constant_and_eq_eq_before ⊑ substitute_constant_and_eq_eq_after

theorem not_or_eq_not_and_not :
    ~~~ (x ||| y) = ~~~ x &&& ~~~ y

theorem test_negative_nsw_and_unsigned_pred_proof : test_negative_nsw_and_unsigned_pred_before ⊑ test_negative_nsw_and_unsigned_pred_after

theorem test12_thm (e e_1 : IntW 32) :
  mul (LLVM.and (add e_1 (shl e (const? 32 8))) (const? 32 128)) (shl e (const? 32 8)) ⊑
    mul (LLVM.and e_1 (const? 32 128)) (shl e (const? 32 8))

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

theorem const_sub_add_const_thm (e : IntW 32) : add (sub (const? 32 8) e) (const? 32 2) ⊑ sub (const? 32 10) e

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

@[simp] lemma BitVec.lk20 : (2#2 : BitVec 2)[0] = false

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

theorem positive_biggershl_shlnuw_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(3#8 ≥ ↑8 ∨ True ∧ x >>> 3#8 <<< 6#8 >>> 6#8 ≠ x >>> 3#8 ∨ 6#8 ≥ ↑8) →
    ¬(True ∧ x <<< 3#8 >>> 3#8 ≠ x ∨ 3#8 ≥ ↑8) → x >>> 3#8 <<< 6#8 = x <<< 3#8 &&& BitVec.ofInt 8 (-64)

theorem sub_to_xor_or_commuted_proof : sub_to_xor_or_commuted_before ⊑ sub_to_xor_or_commuted_after

theorem scalar_proof : scalar_before ⊑ scalar_after

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

theorem e_1941 :
     - 6 * ( ~~~a ||| (b &&& c)) - 1 * (b ^^^  ~~~(a ||| (b &&& c))) - 7 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) + 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 3 *  ~~~(a ||| ( ~~~b &&& c)) - 1 * (b ^^^ (a &&& (b ^^^ c))) - 6 * (b ^^^  ~~~(a &&&  ~~~c)) - 7 * (a &&& (b ^^^ c)) + 2 *  ~~~(b &&& c) + 11 * (a &&& ( ~~~b ||| c)) + 1 * (b ^^^ (a &&& c)) - 6 *  ~~~( ~~~a &&& ( ~~~b &&& c)) + 4 *  ~~~a - 11 * (c ^^^  ~~~(a &&& (b &&& c))) - 11 *  ~~~(a &&& b) + 5 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) + 3 * (c ^^^ ( ~~~a &&& (b ||| c))) - 1 * (b ^^^ (a ||| (b ^^^ c))) + 7 *  ~~~(b ||| c) - 5 *  ~~~( ~~~a &&& (b ^^^ c)) - 2 * (b &&&  ~~~(a ^^^ c)) - 11 * ((b &&& c) ||| (a &&& (b ||| c))) + 2 * (b ^^^ ( ~~~a &&& (b ||| c))) + 1 * (c ^^^  ~~~(a &&& b)) + 4 * (c ^^^ (a ||| (b ||| c))) + 1 * (c ^^^  ~~~(a ||| b)) + 1 * ((a &&& b) |||  ~~~(b ||| c)) - 6 * (c ^^^  ~~~(a ||| (b &&& c))) + 5 * (b ^^^  ~~~(a &&& c)) + 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 * ( ~~~b |||  ~~~(a ^^^ c)) + 2 * ( ~~~c |||  ~~~(a ^^^ b)) - 2 * (b ||| c) - 11 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 2 * (c ^^^ ( ~~~a ||| (b ||| c))) + 4 *  ~~~(a |||  ~~~c) - 7 * (b &&& c) + 4 * (c ||| (a &&&  ~~~b)) - 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * ((a &&& b) |||  ~~~(b |||  ~~~c)) - 1 *  ~~~c + 4 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 1 *  ~~~(a ||| b) - 1 * b + 24 *  ~~~(a ||| (b ||| c)) + 30 *  ~~~(a ||| ( ~~~b ||| c)) + 7 *  ~~~( ~~~a ||| (b ||| c)) + 30 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 1 * ( ~~~a &&& ( ~~~b &&& c)) + 34 * ( ~~~a &&& (b &&& c)) + 16 * (a &&& ( ~~~b &&& c)) + 16 * (a &&& (b &&& c)) =  - 7 * ( ~~~b ||| (a ^^^ c))

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 select_icmp_eq_0_and_1_xor_1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 64),
  ofBool (x_1 &&& 1#64 == 0#64) = 1#1 → x = x ^^^ truncate 32 x_1 &&& 1#32

theorem urem_common_divisor_defined_cond_thm.extracted_1._1 : ∀ (x x_1 : BitVec 5) (x_2 : BitVec 1),
  ¬(x_2 = 1#1 ∨ x_1 = 0) → x_2 = 1#1 → x_1 = 0 → False

@[simp] theorem map'_nil : map' f g nil = nil

theorem shl_trunc_bigger_ashr_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 3#24 ≥ ↑24) →
    ¬(9#32 ≥ ↑32 ∨ True ∧ signExtend 32 (truncate 24 (x.sshiftRight' 9#32)) ≠ x.sshiftRight' 9#32) →
      truncate 24 (x.sshiftRight' 12#32) <<< 3#24 = truncate 24 (x.sshiftRight' 9#32) &&& BitVec.ofInt 24 (-8)

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

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

theorem f_proof : f_before ⊑ f_after

theorem add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_proof : add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_before ⊑ add_constant_equal_with_the_top_bit_of_demandedbits_insertpt_after

theorem test1_thm.extracted_1._1 : ∀ (x : BitVec 23), x ||

theorem sub_ashr_or_i32_nuw_nsw_proof : sub_ashr_or_i32_nuw_nsw_before ⊑ sub_ashr_or_i32_nuw_nsw_after

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

theorem neg_proof : neg_before ⊑ neg_after

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

theorem test9_thm (e : IntW 1005) : LLVM.and e (const? 1005 (-1)) ⊑ e

theorem add_and_or_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) + (x_1 ||| x) = x_1 + x

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

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

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

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 test19_commutative1_thm (e e_1 : IntW 32) :
  urem e_1 (add (shl (const? 32 1) e) (LLVM.and (shl (const? 32 1) e) (shl (const? 32 1) e_1))) ⊑
    LLVM.and e_1
      (add
        (add (shl (const? 32 1) e { «nsw» := false, «nuw» := true })
          (LLVM.and (shl (const? 32 1) e { «nsw» := false, «nuw» := true })
            (shl (const? 32 1) e_1 { «nsw» := false, «nuw» := true })))
        (const? 32 (-1)))

theorem ashrslt_03_03_thm (e : IntW 4) : icmp IntPred.slt (ashr e (const? 4 3)) (const? 4 3) ⊑ const? 1 1

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

theorem p_constmask2_proof : p_constmask2_before ⊑ p_constmask2_after

theorem test_and3_proof : test_and3_before ⊑ test_and3_after

theorem shl_add_proof : shl_add_before ⊑ shl_add_after

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

theorem ashrslt_02_14_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 (-2)) = 0#1

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

theorem PR2330_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (shl (const? 32 1) e) (const? 32 1)) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 0)

theorem test15b_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 32)) (const? 32 0)) (const? 32 32) (const? 32 0) ⊑
    LLVM.xor (LLVM.and e (const? 32 32)) (const? 32 32)

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

theorem multiuse1_proof : multiuse1_before ⊑ multiuse1_after

theorem lshr_mul_nuw_nsw_proof : lshr_mul_nuw_nsw_before ⊑ lshr_mul_nuw_nsw_after

theorem shrink_and_thm.extracted_1._1 : ∀ (x : BitVec 64),
  True ∧ signExtend 64 (truncate 31 (x &&& 42#64)) ≠ x &&& 42#64 ∨
      True ∧ zeroExtend 64 (truncate 31 (x &&& 42#64)) ≠ x &&& 42#64 →
    False

theorem test_or_eq_a_b_commuted_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 ||

theorem exactly_one_set_signbit_proof : exactly_one_set_signbit_before ⊑ exactly_one_set_signbit_after

theorem positive_samevar_shlnsw_proof : positive_samevar_shlnsw_before ⊑ positive_samevar_shlnsw_after

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

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

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

theorem ashrslt_03_00_exact_proof : ashrslt_03_00_exact_before ⊑ ashrslt_03_00_exact_after

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

theorem sext_zext_uge_known_nonneg_op0_wide_thm.extracted_1._2 : ∀ (x : BitVec 8) (x_1 : BitVec 16),
  ¬(True ∧ (x &&& 12#8).msb = true) →
    ofBool (zeroExtend 32 (x &&& 12#8) ≤ᵤ signExtend 32 x_1) = ofBool (zeroExtend 16 (x &&& 12#8) ≤ᵤ x_1)

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

theorem and_not_or_commute3_proof : and_not_or_commute3_before ⊑ and_not_or_commute3_after

theorem e_1720 :
    3 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) - 5 * (c ^^^ (a &&& ( ~~~b ||| c))) - 3 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) - 3 * (c ^^^  ~~~(a &&& (b &&& c))) - 1 *  ~~~( ~~~a ||| (b ^^^ c)) + 7 * (a &&&  ~~~c) + 7 * (b ^^^  ~~~(a &&& c)) - 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) - 1 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 2 * (b ^^^  ~~~(a ||| (b &&& c))) - 1 * (b ^^^  ~~~(a ||| (b ^^^ c))) - 7 * (c ^^^  ~~~( ~~~a ||| (b &&& c))) + 4 * ((a &&& b) ||| (b ^^^ c)) - 5 * (a &&& ( ~~~b ||| c)) + 1 * ((a ^^^ b) ||| (a ^^^ c)) - 5 * (a |||  ~~~b) + 5 * (a ^^^ (b ^^^ c)) - 11 *  ~~~(a &&& (b &&& c)) - 1 *  ~~~( ~~~a ||| (b &&& c)) + 4 * (c ^^^  ~~~(a &&&  ~~~b)) - 1 * (b &&&  ~~~c) + 5 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 2 * (b ^^^  ~~~( ~~~a ||| (b &&& c))) + 2 * ( ~~~b ||| (a ^^^ c)) + 4 *  ~~~(a ||| (b ||| c)) + 5 *  ~~~(a ||| ( ~~~b ||| c)) + 23 *  ~~~( ~~~a ||| (b ||| c)) + 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 9 * ( ~~~a &&& ( ~~~b &&& c)) + 10 * (a &&& ( ~~~b &&& c)) + 8 * (a &&& (b &&& c)) =  - 24 * ( ~~~a &&& (b &&& c)) - 3 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c)))

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

theorem fold_inverted_icmp_preds_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ofBool (x_3 <ₛ x_2) = 1#1 → ofBool (x_2 ≤ₛ x_3) = 1#1 → x_1 ||

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 sub_3_thm (e e_1 : IntW 128) (e_2 : IntW 1) (e_3 : IntW 128) :
  LLVM.xor (sub e_3 (select e_2 (LLVM.xor e_1 (const? 128 (-1))) (LLVM.xor e (const? 128 123)))) (const? 128 (-1)) ⊑
    sub (const? 128 (-2)) (add (select e_2 e_1 (LLVM.xor e (const? 128 (-124)))) e_3)

theorem lshr_pow2_ult_proof : lshr_pow2_ult_before ⊑ lshr_pow2_ult_after

theorem t7_ugt_sgt_neg1_proof : t7_ugt_sgt_neg1_before ⊑ t7_ugt_sgt_neg1_after

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

theorem positive_sameconst_shlnuw_ashrexact_proof : positive_sameconst_shlnuw_ashrexact_before ⊑ positive_sameconst_shlnuw_ashrexact_after

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

theorem test55_proof : test55_before ⊑ test55_after

theorem ashr_known_pos_exact_proof : ashr_known_pos_exact_before ⊑ ashr_known_pos_exact_after

theorem shl_and_thm (e e_1 : IntW 8) :
  shl (LLVM.and (shl e_1 (const? 8 3)) e) (const? 8 2) ⊑ LLVM.and (shl e_1 (const? 8 5)) (shl e (const? 8 2))

theorem and_xor_or5_proof : and_xor_or5_before ⊑ and_xor_or5_after

theorem not_or_or_and_not_and_and_commute3_proof : not_or_or_and_not_and_and_commute3_before ⊑ not_or_or_and_not_and_and_commute3_after

theorem add_constant_equal_with_the_top_bit_of_demandedbits_pass_proof : add_constant_equal_with_the_top_bit_of_demandedbits_pass_before ⊑ add_constant_equal_with_the_top_bit_of_demandedbits_pass_after

theorem test16_proof : test16_before ⊑ test16_after

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

theorem mkOutEqZeroCircuitLeN_eval_eq_false_iff {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity] (p : FSM arity) (n : Nat)
  (env : Vars p.α arity (n + 1) → Bool) :
  ((mkOutEqZeroCircuitLeN p n).eval env = false) ↔
  (∀ (i : Nat) (hi : i < n + 1),
    env (Vars.outputs ⟨i, by omega⟩) = false)

theorem src_fv_ne_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  ¬x_2 = 1#1 → ofBool (0#8 ||| x != 0#8) = ofBool (x != 0#8) ||

theorem not_proof : not_before ⊑ not_after

theorem test_sub_127_Y_eq_127_proof : test_sub_127_Y_eq_127_before ⊑ test_sub_127_Y_eq_127_after

private theorem decide_eq_eq_decide_iff_decide {P Q : Prop}
  [Decidable P] [Decidable Q] :
  (decide P = decide Q) = decide (P ↔ Q)

theorem xor_1_thm (e e_1 e_2 : IntW 8) (e_3 : IntW 1) :
  LLVM.xor (LLVM.xor (select e_3 (LLVM.xor e_2 (const? 8 (-1))) (LLVM.xor e_1 (const? 8 123))) e) (const? 8 (-1)) ⊑
    LLVM.xor (select e_3 e_2 (LLVM.xor e_1 (const? 8 (-124)))) e

theorem add_1_thm (e e_1 e_2 : IntW 8) (e_3 : IntW 1) :
  LLVM.xor (add (select e_3 (LLVM.xor e_2 (const? 8 (-1))) (LLVM.xor e_1 (const? 8 123))) e) (const? 8 (-1)) ⊑
    sub (select e_3 e_2 (LLVM.xor e_1 (const? 8 (-124)))) e

theorem slt_zero_eq_ne_0_fail1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 →
    ofBool (zeroExtend 32 (ofBool (x != 0#32)) == x.sshiftRight' 31#32) =
      ofBool (x.sshiftRight' 31#32 == zeroExtend 32 (ofBool (x != 0#32)))

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

@[grind ., simp] lemma RawCNFA.empty_mem_tr {s s' : State} : s' ∉ empty (A := A).tr s a

theorem zext_zext_eq_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (zeroExtend 32 x_1 == zeroExtend 32 x) = ofBool (x_1 == x)

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

theorem AvoidCollision_signExtend_not {x : BitVec w} (h : 0 < w) :
    (~~~x).signExtend v = ~~~(x.signExtend v)

theorem oppositesign_proof : oppositesign_before ⊑ oppositesign_after

theorem and_nosignbit_select_shl_proof : and_nosignbit_select_shl_before ⊑ and_nosignbit_select_shl_after

theorem lsb_mask_sign_sext_commuted_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ((x ^^^ -1#32) &&& x + -1#32).sshiftRight' 31#32 = signExtend 32 (ofBool (x == 0#32))

theorem substitute_constant_and_ne_ugt_swap_logical_proof : substitute_constant_and_ne_ugt_swap_logical_before ⊑ substitute_constant_and_ne_ugt_swap_logical_after

theorem slt_zero_ne_ne_b_thm (e e_1 : IntW 32) :
  icmp IntPred.ne (zext 32 (icmp IntPred.ne e_1 e)) (lshr e_1 (const? 32 31)) ⊑
    LLVM.xor (icmp IntPred.slt e_1 (const? 32 0)) (icmp IntPred.ne e_1 e)

theorem squared_nsw_eq0_proof : squared_nsw_eq0_before ⊑ squared_nsw_eq0_after

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

theorem lshr_by_const_cmp_sge_value_proof : lshr_by_const_cmp_sge_value_before ⊑ lshr_by_const_cmp_sge_value_after

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

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

theorem mul_selectp2_x_non_const_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → 1#8 ≥ ↑8 → False

theorem alive_AndOrXor_1705 : alive_AndOrXor_1705_src ⊑ alive_AndOrXor_1705_tgt

theorem main2_proof : main2_before ⊑ main2_after

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

theorem lshr_mul_times_5_div_4_exact_2_thm (e : IntW 32) :
  lshr (mul e (const? 32 5) { «nsw» := false, «nuw» := true }) (const? 32 2) { «exact» := true } ⊑
    add e (lshr e (const? 32 2) { «exact» := true }) { «nsw» := false, «nuw» := true }

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

theorem add_shl_same_amount_constants_proof : add_shl_same_amount_constants_before ⊑ add_shl_same_amount_constants_after

theorem lshr_pow2_ult_equal_constants_thm (e : IntW 32) :
  icmp IntPred.ult (lshr (const? 32 16) e) (const? 32 16) ⊑ icmp IntPred.ne e (const? 32 0)

theorem or_ranges_overlap_proof : or_ranges_overlap_before ⊑ or_ranges_overlap_after

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

theorem icmp_ne_sext_eq_allones_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == -1#32)) != x) = ofBool (x + -1#32 <ᵤ BitVec.ofInt 32 (-2))

theorem PR23309v2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 + BitVec.ofInt 32 (-4)).uaddOverflow x = true) →
    truncate 1 (x_1 + BitVec.ofInt 32 (-4) + x) = truncate 1 (x_1 + x)

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_after

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

theorem select1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32) (x_3 : BitVec 1),
  x_3 = 1#1 → zeroExtend 32 (truncate 8 x_2) = x_2 &&& 255#32

theorem e_1805 :
     - 11 * (c ^^^  ~~~(a &&& (b &&& c))) - 6 * ((a &&& b) |||  ~~~(b ||| c)) + 1 * ( ~~~b &&&  ~~~(a ^^^ c)) - 11 *  ~~~c + 11 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 2 *  ~~~( ~~~a &&& (b ^^^ c)) + 1 * (c &&& (a ^^^ b)) + 1 * (b ||| (a &&&  ~~~c)) + 3 * (c ^^^  ~~~(a ||| (b &&& c))) - 2 * ((a ||| b) &&& (a ^^^ (b ^^^ c))) + 4 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 1 *  ~~~( ~~~a &&& (b ||| c)) + 2 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 11 * (b |||  ~~~(a ||| c)) + 2 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) - 1 * (b ^^^ (a ||| (b &&& c))) + 5 * (b &&&  ~~~(a &&& c)) - 7 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 7 *  ~~~(a ||| b) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 1 * ( ~~~a &&& (b ||| c)) + 11 *  ~~~(a &&&  ~~~c) + 3 * (c ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 7 *  ~~~b - 7 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) - 3 * (b ^^^ (a ||| (b ^^^ c))) + 3 *  ~~~(a &&& b) - 2 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) + 2 *  ~~~(a ||| (b &&& c)) - 2 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 11 * (b &&& (a ^^^ c)) + 3 * (b ||| c) + 11 *  ~~~(a ||| (b ||| c)) + 5 *  ~~~(a ||| ( ~~~b ||| c)) + 16 *  ~~~( ~~~a ||| (b ||| c)) + 29 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 15 * ( ~~~a &&& ( ~~~b &&& c)) - 2 * ( ~~~a &&& (b &&& c)) - 33 * (a &&& ( ~~~b &&& c)) + 25 * (a &&& (b &&& c)) = 5 * (b ^^^  ~~~(a &&& c))

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

@[simp] theorem Com.castPureToEff_rets : (rets v : Com d Γ .pure ty).castPureToEff eff = rets v

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

theorem t1_sub_from_falseval_proof : t1_sub_from_falseval_before ⊑ t1_sub_from_falseval_after

theorem sdiv_shl_pair3_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(True ∧ (x_2 <<< x_1).sshiftRight' x_1 ≠ x_2 ∨
        x_1 ≥ ↑32 ∨
          True ∧ (x_2 <<< x).sshiftRight' x ≠ x_2 ∨
            x ≥ ↑32 ∨ (x_2 <<< x == 0 || 32 != 1 && x_2 <<< x_1 == intMin 32 && x_2 <<< x == -1) = true) →
    ¬(True ∧ 1#32 <<< x_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ x ≥ ↑32) → (x_2 <<< x_1).sdiv (x_2 <<< x) = 1#32 <<< x_1 >>> x

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 icmp_eq_sext_ne_zero_thm (e : IntW 32) :
  icmp IntPred.eq (sext 32 (icmp IntPred.ne e (const? 32 0))) e ⊑
    icmp IntPred.ult (add e (const? 32 1)) (const? 32 2)

theorem p0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(5#8 ≥ ↑8 ∨ True ∧ x <<< 5#8 >>> 5#8 <<< 5#8 ≠ x <<< 5#8 ∨ 5#8 ≥ ↑8) →
    ofBool ((x <<< 5#8).sshiftRight' 5#8 != x) = ofBool (x + BitVec.ofInt 8 (-4) <ᵤ BitVec.ofInt 8 (-8))

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

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

theorem mul_of_sdiv_fail_ub_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smod 6#8 ≠ 0 ∨ (6#8 == 0 || 8 != 1 && x == intMin 8 && 6#8 == -1) = true) →
    x.sdiv 6#8 * BitVec.ofInt 8 (-6) = 0#8 - x

theorem test_mul_nsw__nsw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.or e (const? 32 (-83886080))) (const? 32 (-83886079))) (const? 32 (-754974711))
      (mul (LLVM.or e (const? 32 (-83886080))) (const? 32 9) { «nsw» := true, «nuw» := false }) ⊑
    mul (LLVM.or e (const? 32 (-83886080))) (const? 32 9) { «nsw» := true, «nuw» := false }

theorem icmp_sgt6_thm (e : IntW 8) :
  icmp IntPred.sgt (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 16) ⊑
    icmp IntPred.sgt e (const? 8 8)

theorem foo_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(7#8 ≥ ↑8 ∨ 7#8 ≥ ↑8 ∨ 5#8 ≥ ↑8 ∨ 7#8 ≥ ↑8) →
    ¬(7#8 ≥ ↑8 ∨
          2#8 ≥ ↑8 ∨
            True ∧ (40#8).ssubOverflow (x &&& 84#8) = true ∨
              True ∧ (x &&& 33#8 &&& (40#8 - (x &&& 84#8) &&& 84#8) != 0) = true ∨
                7#8 ≥ ↑8 ∨
                  True ∧
                    ((x &&& 33#8 ||| 40#8 - (x &&& 84#8) &&& 84#8) &&& (x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118)) !=
                        0) =
                      true) →
      (x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118)) >>> 7#8 <<< 5#8 ^^^
          (x &&& 33#8 ||| BitVec.ofInt 8 (-88) - (x &&& 84#8) &&& 84#8 |||
            x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118)) =
        (x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118)) >>> 2#8 &&& 32#8 ^^^
          (x &&& 33#8 ||| 40#8 - (x &&& 84#8) &&& 84#8 ||| x_1 <<< 7#8 ^^^ x &&& BitVec.ofInt 8 (-118))

theorem alive_AndOrXor_2264 : alive_AndOrXor_2264_src ⊑ alive_AndOrXor_2264_tgt

theorem PR42691_4_proof : PR42691_4_before ⊑ PR42691_4_after

theorem e_531 :
     - 7 *  ~~~(x ^^^ y) - 6 * y - 6 *  ~~~(x &&&  ~~~y) + 1 * x + 3 * (x ||| y) + 1 *  ~~~x + 12 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) =  - 15 * (x &&& y)

theorem sub_ashr_or_i32_thm (e e_1 : IntW 32) :
  LLVM.or (ashr (sub e_1 e { «nsw» := true, «nuw» := false }) (const? 32 31)) e ⊑
    select (icmp IntPred.slt e_1 e) (const? 32 (-1)) e

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

theorem bv_276_2 :
    ∀ (e e_1 : LLVM.IntW 5), LLVM.mul (LLVM.udiv e_1 e) (LLVM.sub (LLVM.const? 5 0) e) ⊑ LLVM.sub (LLVM.urem e_1 e) e_1

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

theorem e_1686 :
    11 * ((a &&& c) ^^^  ~~~(a ^^^ ( ~~~b &&& c))) + 3 * (c ^^^  ~~~(a &&& (b ||| c))) + 11 *  ~~~( ~~~a &&& (b ^^^ c)) + 5 * ( ~~~a ||| ( ~~~b ||| c)) + 1 *  ~~~( ~~~a &&& ( ~~~b &&& c)) - 7 *  ~~~(a ^^^ c) - 1 *  ~~~( ~~~a ||| ( ~~~b &&& c)) + 4 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 5 * (b |||  ~~~(a |||  ~~~c)) - 6 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 5 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 1 * ((a ||| b) &&&  ~~~(b ^^^ c)) + 7 * (c &&&  ~~~(a &&& b)) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 1 * (b ^^^  ~~~( ~~~a &&& (b &&& c))) - 2 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 6 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * ( ~~~c &&& (a ^^^ b)) + 11 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) + 11 * (c &&& (a ^^^ b)) - 32 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) - 13 *  ~~~( ~~~a ||| (b ||| c)) - 21 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 17 * ( ~~~a &&& ( ~~~b &&& c)) - 53 * ( ~~~a &&& (b &&& c)) - 27 * (a &&& (b &&& c)) = 27 * (a &&& ( ~~~b &&& c))

theorem lshrugt_02_07_exact_proof : lshrugt_02_07_exact_before ⊑ lshrugt_02_07_exact_after

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

theorem and_ne_with_diff_one_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x != 40#32) = 1#1 → ofBool (x != 39#32) = ofBool (x + BitVec.ofInt 32 (-41) <ᵤ BitVec.ofInt 32 (-2))

theorem t1_thm.extracted_1._1 : ∀ (x : BitVec 16), ¬(x ≥ ↑16 ∨ x ≥ ↑16) → 15#16 - x ≥ ↑16 → False

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

theorem test23_thm (e : IntW 8) :
  LLVM.xor (LLVM.or (LLVM.xor (LLVM.or e (const? 8 (-2))) (const? 8 13)) (const? 8 1)) (const? 8 12) ⊑
    const? 8 (-1)

theorem or_and_or_pat2_proof : or_and_or_pat2_before ⊑ or_and_or_pat2_after

theorem pr40493_proof : pr40493_before ⊑ pr40493_after

theorem test5_proof : test5_before ⊑ test5_after

theorem xor_or_thm.extracted_1._5 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 1),
  x_2 = 1#1 → x_2 ^^^ 1#1 = 1#1 → 1#1 ^^^ 1#1 = ofBool (x ≤ᵤ x_1)

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

theorem eq_21_proof : eq_21_before ⊑ eq_21_after

theorem or_to_nxor_multiuse_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  True ∧ (x_1 &&& x &&& ((x_1 ||| x) ^^^ -1#32) != 0) = true → False

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

theorem test9_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), x_1 ||

theorem PR42691_1_logical_proof : PR42691_1_logical_before ⊑ PR42691_1_logical_after

theorem add_nextStateCirc_eval :
    (add.nextStateCirc ()).eval =
      fun x => x (inr true) && x (inr false) |

theorem eval_eq_negOne_of_mkIndHypCycleBreaking_eval_eq_false_of_mkSafetyCircuit_eval_eq_false'
    (circs : KInductionCircuits (~~~ fsm) K)
    (hCircs : circs.IsLawful)
    (hSafety : ∀ (env : _), (mkSafetyCircuit circs).eval env = false)
    (hIndHyp : ∀ (env : _), (mkIndHypCycleBreaking circs).eval env = false) :
    (∀ (envBitstream : _), (fsm).eval envBitstream = BitStream.negOne)

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

theorem e_112 :
     - 11 *  ~~~(x &&&  ~~~x) + 2 *  ~~~(x ^^^ y) - 3 * y + 9 *  ~~~(x ||| y) + 11 * (x &&&  ~~~y) + 12 * (x &&& y) =  - 14 *  ~~~(x |||  ~~~y)

@[simp]
theorem ctxt_cons {Γ : DerivedCtxt Δ} :
    (Γ.cons ty).ctxt = Γ.ctxt.cons ty

theorem e_2206 :
     - 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 5 * (f ^^^  ~~~(d &&& (e &&& f))) - 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) - 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 7 * (e ^^^  ~~~(d ||| f)) + 2 * ( ~~~f |||  ~~~(d ^^^ e)) - 1 * ((d &&& f) |||  ~~~(e ||| f)) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 1 * (e &&&  ~~~(d ^^^ f)) + 11 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 3 * (f &&&  ~~~(d &&&  ~~~e)) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 1 * (f ||| (d &&& e)) + 2 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) - 2 *  ~~~( ~~~d &&& (e &&& f)) + 3 *  ~~~(d ^^^ ( ~~~e ||| f)) + 4 * (d ^^^ f) - 5 * (e ^^^ (d &&& (e ^^^ f))) + 5 * (d ^^^ (e &&& f)) - 2 * ((d &&& e) |||  ~~~(e ||| f)) + 5 * (f ||| (d &&&  ~~~e)) + 1 * ((d &&& e) |||  ~~~(e |||  ~~~f)) - 7 * (d ^^^ ( ~~~e ||| f)) - 11 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * (f ^^^ (d &&&  ~~~e)) - 1 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d ^^^ e) &&&  ~~~(d ^^^ f)) - 6 * (f ^^^ (d &&& (e ||| f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 5 * (f ||| (d ^^^ e)) - 3 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 4 * f - 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 2 * (f |||  ~~~(d ||| e)) - 11 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 7 *  ~~~(d ^^^ e) - 3 * ( ~~~f ||| (d ^^^ e)) - 3 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 11 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 3 * (d ||| (e ||| f)) + 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 1 * (d ||| e) + 18 *  ~~~(d ||| (e ||| f)) + 15 *  ~~~(d ||| ( ~~~e ||| f)) - 18 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 38 * ( ~~~d &&& ( ~~~e &&& f)) + 26 * ( ~~~d &&& (e &&& f)) - 10 * (d &&& ( ~~~e &&& f)) - 8 * (d &&& (e &&& f)) = 14 *  ~~~( ~~~d ||| (e ||| f)) - 5 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f))

theorem demorgan_or_apint2_proof : demorgan_or_apint2_before ⊑ demorgan_or_apint2_after

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

theorem src_x_and_nmask_uge_thm.extracted_1._3 : ∀ (x : BitVec 8) (x_1 : BitVec 1) (x_2 : BitVec 8),
  x_1 = 1#1 → ¬x ≥ ↑8 → x_1 ^^^ 1#1 = 1#1 → ofBool ((-1#8) <<< x ≤ᵤ x_2 &&& (-1#8) <<< x) = 1#1

theorem rotateleft_9_neg_mask_wide_amount_commute_proof : rotateleft_9_neg_mask_wide_amount_commute_before ⊑ rotateleft_9_neg_mask_wide_amount_commute_after

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

theorem no_masks_with_logical_or_proof : no_masks_with_logical_or_before ⊑ no_masks_with_logical_or_after

theorem splat_mul_known_lz_proof : splat_mul_known_lz_before ⊑ splat_mul_known_lz_after

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

theorem icmp_sle6_thm (e : IntW 8) :
  icmp IntPred.sle (shl e (const? 8 1) { «nsw» := true, «nuw» := false }) (const? 8 16) ⊑
    icmp IntPred.slt e (const? 8 9)

theorem test15e_proof : test15e_before ⊑ test15e_after

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

theorem or_signbit_shl_thm (e : IntW 32) :
  shl (LLVM.or e (const? 32 (-65536))) (const? 32 8) ⊑ LLVM.or (shl e (const? 32 8)) (const? 32 (-16777216))

theorem test_cast_select_proof : test_cast_select_before ⊑ test_cast_select_after

theorem sext_sext_ult_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (signExtend 32 x_1 <ᵤ signExtend 32 x) = ofBool (x_1 <ᵤ x)

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

theorem e_109 :
    1 *  ~~~(x ^^^ y) - 3 * x - 1 *  ~~~(x ||| y) + 6 *  ~~~(x |||  ~~~y) + 10 * (x &&&  ~~~y) + 8 * (x &&& y) = 7 * (x ||| y) - 1 * y

theorem not_signbit_proof : not_signbit_before ⊑ not_signbit_after

theorem icmp_sgt1_proof : icmp_sgt1_before ⊑ icmp_sgt1_after

theorem e_1521 :
    1 * (b &&& c) + 1 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 7 *  ~~~(a &&& (b &&& c)) + 7 * ((a &&& b) |||  ~~~(b ^^^ c)) - 14 *  ~~~(a ||| (b ||| c)) - 7 *  ~~~(a ||| ( ~~~b ||| c)) - 15 *  ~~~( ~~~a ||| (b ||| c)) - 8 * ( ~~~a &&& ( ~~~b &&& c)) - 15 * ( ~~~a &&& (b &&& c)) - 8 * (a &&& (b &&& c)) = 15 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 8 * (a &&& ( ~~~b &&& c))

theorem cmpne_xor_cst3_proof : cmpne_xor_cst3_before ⊑ cmpne_xor_cst3_after

theorem e_678 :
    1 * x + 1 * y - 1 * (x |||  ~~~y) - 1 * (x ||| y) - 7 *  ~~~(x ^^^ y) - 7 *  ~~~x + 22 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) + 7 * (x &&&  ~~~y) + 8 * (x &&& y) = 6 *  ~~~y + 1 *  ~~~(x &&&  ~~~y)

theorem lshrult_01_05_exact_proof : lshrult_01_05_exact_before ⊑ lshrult_01_05_exact_after

theorem bools2_logical_commute1_and1_proof : bools2_logical_commute1_and1_before ⊑ bools2_logical_commute1_and1_after

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

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

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

theorem select_icmp_ne_0_and_32_xor_4096_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (0#32 != x_1 &&& 32#32) = 1#1 → ¬7#32 ≥ ↑32 → x ^^^ 4096#32 = x_1 <<< 7#32 &&& 4096#32 ^^^ x ^^^ 4096#32

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

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

theorem sge_and_max_logical_samesign_proof : sge_and_max_logical_samesign_before ⊑ sge_and_max_logical_samesign_after

theorem or_nosignbit_ashr_proof : or_nosignbit_ashr_before ⊑ or_nosignbit_ashr_after

theorem PR42691_9_logical_proof : PR42691_9_logical_before ⊑ PR42691_9_logical_after

theorem test8_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ (x.sshiftRight' 16#32).smulOverflow 32767#32 = true) →
      signExtend 64 (x.sshiftRight' 16#32) * 32767#64 = signExtend 64 (x.sshiftRight' 16#32 * 32767#32)

theorem addsub_combine_constants_proof : addsub_combine_constants_before ⊑ addsub_combine_constants_after

theorem icmp_ne_sext_sgt_zero_nofold_thm (e : IntW 32) :
  icmp IntPred.ne (sext 32 (icmp IntPred.sgt e (const? 32 0))) e ⊑
    icmp IntPred.ne e (sext 32 (icmp IntPred.sgt e (const? 32 0)))

theorem test8_proof : test8_before ⊑ test8_after

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

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

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

theorem fold_inverted_icmp_preds_reverse_proof : fold_inverted_icmp_preds_reverse_before ⊑ fold_inverted_icmp_preds_reverse_after

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

theorem test2_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1), x_1 &&& x &&& x_1 = x_1 &&& x

theorem not_bool_add_lshr_proof : not_bool_add_lshr_before ⊑ not_bool_add_lshr_after

theorem substitute_constant_and_ne_ugt_swap_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ᵤ x_1) = 1#1 → ofBool (x != 42#8) = ofBool (x <ᵤ x_1) &&& ofBool (x != 42#8)

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

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

theorem test68_xor_proof : test68_xor_before ⊑ test68_xor_after

theorem and_ashr_not_proof : and_ashr_not_before ⊑ and_ashr_not_after

theorem and_zext_zext_thm (e : IntW 4) (e_1 : IntW 8) :
  LLVM.and (zext 16 e_1) (zext 16 e) ⊑ zext 16 (LLVM.and e_1 (zext 8 e)) { «nneg» := true }

theorem e_1577 :
     - 2 * (c |||  ~~~(a ||| b)) - 2 *  ~~~(b |||  ~~~c) + 7 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 5 * ( ~~~b |||  ~~~(a ^^^ c)) + 3 * ( ~~~b ||| (a ^^^ c)) + 4 * (a &&&  ~~~c) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c))) - 2 * ((a ^^^ b) ||| (a ^^^ c)) - 2 * (b ^^^  ~~~(a &&&  ~~~c)) - 18 *  ~~~(a ||| (b ||| c)) - 19 *  ~~~(a ||| ( ~~~b ||| c)) - 19 *  ~~~( ~~~a ||| (b ||| c)) - 3 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 14 * ( ~~~a &&& ( ~~~b &&& c)) - 8 * ( ~~~a &&& (b &&& c)) - 10 * (a &&& (b &&& c)) =  - 7 *  ~~~a

theorem add_shl_same_amount_constants_proof : add_shl_same_amount_constants_before ⊑ add_shl_same_amount_constants_after

theorem test_srem_canonicalize_op0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (0#32).ssubOverflow x_1 = true ∨ (x == 0 || 32 != 1 && 0#32 - x_1 == intMin 32 && x == -1) = true) →
    (x == 0 || 32 != 1 && x_1 == intMin 32 && x == -1) = true ∨ True ∧ (0#32).ssubOverflow (x_1.srem x) = true →
      False

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

theorem uadd_sat_via_add_nonstrict_thm (e e_1 : IntW 32) :
  select (icmp IntPred.ule (add e_1 e) e) (const? 32 (-1)) (add e_1 e) ⊑
    select (icmp IntPred.ugt (add e_1 e) e) (add e_1 e) (const? 32 (-1))

theorem rem_euclid_pow2_true_arm_folded_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ofBool (x.srem 2#32 <ₛ 0#32) = 1#1 → 1#32 = x &&& 1#32

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 t0_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬16#32 ≥ ↑32 →
    zeroExtend 32 x <<< 16#32 &&& BitVec.ofInt 32 (-2147483648) = signExtend 32 x &&& BitVec.ofInt 32 (-2147483648)

theorem bools_logical_commute1_thm.extracted_1._11 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → ¬x_1 = 1#1 → ¬x_1 ^^^ 1#1 = 1#1 → 0#1 = x_2

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

theorem i_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬((BitVec.ofInt 8 (-3) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-3) == -1) = true ∨
        (BitVec.ofInt 8 (-3) == 0 || 8 != 1 && x.sdiv (BitVec.ofInt 8 (-3)) == intMin 8 && BitVec.ofInt 8 (-3) == -1) =
          true) →
    ¬(9#8 == 0 || 8 != 1 && x == intMin 8 && 9#8 == -1) = true →
      (x.sdiv (BitVec.ofInt 8 (-3))).sdiv (BitVec.ofInt 8 (-3)) = x.sdiv 9#8

theorem e_2414 :
    7 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 3 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * (f |||  ~~~(d ||| e)) + 7 * (f |||  ~~~(d ^^^ e)) - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) - 5 *  ~~~(d ^^^ (e ||| f)) - 6 * (e |||  ~~~f) + 3 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 5 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) + 5 * (d ||| (e ^^^ f)) + 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * (d &&&  ~~~f) + 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 7 *  ~~~(d ^^^ ( ~~~e ||| f)) - 3 * (d ^^^ e) - 3 * (e ^^^ ( ~~~d ||| (e ^^^ f))) - 1 *  ~~~(d ||| f) - 3 * (e ^^^ (d ||| f)) - 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 11 * ( ~~~d &&& (e ^^^ f)) - 6 * (f ^^^  ~~~(d ||| e)) + 4 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * (f &&&  ~~~(d &&& e)) - 7 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) + 1 * (f ||| (d &&& e)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) - 6 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 3 * (f |||  ~~~(d |||  ~~~e)) - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (f ^^^ (d &&& (e ||| f))) - 3 * (e ^^^ ( ~~~d ||| (e ||| f))) + 2 *  ~~~(d &&&  ~~~e) - 2 * (f &&& (d |||  ~~~e)) + 2 * (e ^^^ (d &&& (e ^^^ f))) + 1 *  ~~~d + 7 * ( ~~~f ||| (d ^^^ e)) + 1 *  ~~~(e &&&  ~~~f) + 5 *  ~~~(d ||| ( ~~~e &&& f)) + 5 *  ~~~(d &&& ( ~~~e &&& f)) - 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 *  ~~~(d &&& e) - 7 * ( ~~~d ||| (e &&& f)) - 1 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 11 * (d ^^^ (e ^^^ f)) + 4 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (d &&& (e ^^^ f)) - 6 * ( ~~~d ||| (e ^^^ f)) + 11 * (f ^^^  ~~~(d &&& e)) + 11 * (e ^^^  ~~~(d |||  ~~~f)) + 2 * ( ~~~d &&& ( ~~~e ||| f)) + 4 * (d &&& ( ~~~e ||| f)) + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 2 * (e ^^^  ~~~(d ||| (e &&& f))) - 2 *  ~~~(d ||| (e ^^^ f)) - 7 * (f ^^^ (d &&& ( ~~~e ||| f))) + 4 * (e &&&  ~~~(d &&& f)) + 7 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 6 * (d ||| ( ~~~e &&& f)) - 1 * (e &&& f) - 2 *  ~~~(d ^^^ f) - 7 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 *  ~~~(d ||| (e ||| f)) - 24 *  ~~~(d ||| ( ~~~e ||| f)) + 9 *  ~~~( ~~~d ||| (e ||| f)) - 27 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 15 * ( ~~~d &&& ( ~~~e &&& f)) + 19 * ( ~~~d &&& (e &&& f)) + 16 * (d &&& ( ~~~e &&& f)) + 23 * (d &&& (e &&& f)) =  - 3 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f)))

theorem ult_to_slt_proof : ult_to_slt_before ⊑ ult_to_slt_after

theorem t0_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬(True ∧ x.smod 32#8 ≠ 0 ∨ (32#8 == 0 || 8 != 1 && x == intMin 8 && 32#8 == -1) = true) →
    True ∧ x >>> 5#8 <<< 5#8 ≠ x ∨ 5#8 ≥ ↑8 → False

theorem lshrult_02_00_exact_proof : lshrult_02_00_exact_before ⊑ lshrult_02_00_exact_after

theorem test25_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (50#32 ≤ₛ x) &&& ofBool (x <ₛ 100#32) = ofBool (x + BitVec.ofInt 32 (-50) <ᵤ 50#32)

theorem icmp_eq_mul_nsw_nonequal_proof : icmp_eq_mul_nsw_nonequal_before ⊑ icmp_eq_mul_nsw_nonequal_after

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 main3f_like_proof : main3f_like_before ⊑ main3f_like_after

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

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

theorem sub_from_constant_of_sub_from_constant_proof : sub_from_constant_of_sub_from_constant_before ⊑ sub_from_constant_of_sub_from_constant_after

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

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 Nat.add_lt_is_or {a} (a_lt : a < 2^i) :
    2^i + a = 2^i ||

theorem add_and_or_commutative_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) + (x ||| x_1) = x + x_1

theorem test3a_proof : test3a_before ⊑ test3a_after

theorem or_and_or_pat1_proof : or_and_or_pat1_before ⊑ or_and_or_pat1_after

theorem alive_AndOrXor_2243__B__C__A__B___B__A__C : alive_AndOrXor_2243__B__C__A__B___B__A__C_src ⊑ alive_AndOrXor_2243__B__C__A__B___B__A__C_tgt

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

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

theorem modulo32_proof : modulo32_before ⊑ modulo32_after

theorem t12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x <<< 2#32 >>> 2#32 ≠ x ∨ 2#32 ≥ ↑32 ∨ x = 0) → x <<< 2#32 / x = 4#32

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

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

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

theorem negate_zext_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  x_1 - zeroExtend 8 x = x_1 + signExtend 8 x

theorem e_2309 :
     - 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 3 * (f ^^^  ~~~(d &&& (e &&& f))) - 2 * ( ~~~e |||  ~~~(d ^^^ f)) + 5 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) + 5 * (e ^^^  ~~~(d &&& f)) - 6 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 3 *  ~~~(d ||| (e ^^^ f)) - 1 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 3 * (e ^^^ (d ||| (e ||| f))) - 3 * ((d &&& e) |||  ~~~(e ^^^ f)) - 7 * (f ^^^ (d ||| (e ||| f))) - 7 * ( ~~~f |||  ~~~(d ^^^ e)) - 5 * (e ||| (d &&&  ~~~f)) + 3 * (e &&& (d |||  ~~~f)) - 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d ^^^ e) ||| (d ^^^ f)) + 7 *  ~~~(d ^^^ (e ||| f)) - 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 3 * (e ^^^ ( ~~~d &&& (e ||| f))) + 11 * (f ^^^  ~~~(d &&& e)) - 1 * ( ~~~d &&& (e ^^^ f)) + 2 * (f ^^^ (d |||  ~~~e)) + 3 * d - 1 *  ~~~(d &&& f) + 4 *  ~~~(e &&&  ~~~f) + 3 * (d ^^^ e) + 7 *  ~~~( ~~~d ||| (e &&& f)) + 2 * (e ^^^ (d &&& (e ^^^ f))) - 6 * (d &&&  ~~~e) - 1 *  ~~~d + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d &&&  ~~~e)) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 5 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * (d ||| f) + 2 *  ~~~(d |||  ~~~e) + 3 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 1 *  ~~~(e ^^^ f) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 11 * (f ^^^ ( ~~~d &&& (e ||| f))) - 6 * (e &&&  ~~~f) + 1 * (d ^^^ ( ~~~e &&& f)) + 4 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) + 11 * (e |||  ~~~(d ^^^ f)) - 5 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (f ^^^  ~~~(d ||| (e &&& f))) - 7 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) - 1 * (d ^^^ ( ~~~e ||| f)) + 11 * (e ^^^ ( ~~~d ||| (e &&& f))) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 51 *  ~~~(d ||| (e ||| f)) + 26 *  ~~~(d ||| ( ~~~e ||| f)) - 9 *  ~~~( ~~~d ||| (e ||| f)) - 12 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 7 * ( ~~~d &&& ( ~~~e &&& f)) - 1 * ( ~~~d &&& (e &&& f)) - 2 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 1 * (e ^^^ (d &&&  ~~~f)) + 6 * (f ^^^  ~~~(d |||  ~~~e))

theorem c_0_1_0_proof : c_0_1_0_before ⊑ c_0_1_0_after

theorem alive_AndOrXor_2063__X__C1__C2____X__C2__C1__C2  (w : Nat)   : alive_AndOrXor_2063__X__C1__C2____X__C2__C1__C2_src w  ⊑ alive_AndOrXor_2063__X__C1__C2____X__C2__C1__C2_tgt w

theorem wide_source_matching_signbits_proof : wide_source_matching_signbits_before ⊑ wide_source_matching_signbits_after

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

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

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

@[bv_multi_width_normalize] theorem BitVec.nat_mul_eq_ofNat_mul (x : BitVec w) (n : Nat) :
  n * x = BitVec.ofNat w n * x

theorem slt_swap_or_not_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x <ₛ x_1) ||

theorem e_309 :
    1 * x - 3 *  ~~~(x &&& y) + 5 *  ~~~(x &&&  ~~~x) + 11 *  ~~~y - 12 *  ~~~(x ||| y) - 14 * (x &&&  ~~~y) - 5 * (x &&& y) = 1 *  ~~~(x ^^^ y) + 2 *  ~~~(x |||  ~~~y)

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

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

theorem ult_rem_nz_proof : ult_rem_nz_before ⊑ ult_rem_nz_after

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

theorem sdiv_shl_pair1_proof : sdiv_shl_pair1_before ⊑ sdiv_shl_pair1_after

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

omit rets var in
theorem Com.recAux'_eq :
    Com.recAux' (motive:=motive) = Com.rec' (motive:=motive)

theorem test3_proof : test3_before ⊑ test3_after

theorem e_271 :
    2 *  ~~~y + 5 *  ~~~(x ^^^ y) + 11 *  ~~~(x &&&  ~~~y) + 2 * (x ||| y) - 2 *  ~~~x - 16 *  ~~~(x ||| y) - 4 * (x &&&  ~~~y) = 18 * (x &&& y) + 11 *  ~~~(x |||  ~~~y)

theorem basic_com_add_proof : basic_com_add_before ⊑ basic_com_add_after

theorem logical_and_icmps1_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 → ofBool (-1#32 <ₛ x) = 1#1 → ofBool (x <ₛ 10086#32) = ofBool (x <ᵤ 10086#32)

theorem test18_proof : test18_before ⊑ test18_after

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

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_proof : negate_select_of_op_vs_negated_op_nsw_xyyx_before ⊑ negate_select_of_op_vs_negated_op_nsw_xyyx_after

theorem lshrult_02_00_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 2)) (const? 4 0) ⊑ const? 1 0

theorem foo1_and_commuted_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ¬(x_1 ≥ ↑32 ∨ x ≥ ↑32) →
    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_1 >>> x_1 ≠ 1#32 ∨ x_1 ≥ ↑32 ∨ True ∧ 1#32 <<< x >>> x ≠ 1#32 ∨ x ≥ ↑32 →
      False

theorem test12_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨ zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 (zeroExtend 128 x_1 >>> (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 >>> zeroExtend 64 (x &&& 31#32)

theorem sext_shl_trunc_smaller_thm.extracted_1._1 : ∀ (x : BitVec 32) (x_1 : BitVec 16),
  ¬x ≥ ↑32 → truncate 5 (signExtend 32 x_1 <<< x) = truncate 5 (zeroExtend 32 x_1 <<< x)

theorem PR2844_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) = 1#1 →
    True → 0#32 = zeroExtend 32 (ofBool (x != 0#32) &&& ofBool (BitVec.ofInt 32 (-638208502) <ₛ x))

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

theorem positive_biggerlshr_proof : positive_biggerlshr_before ⊑ positive_biggerlshr_after

@[simp] theorem denote_mk {lets : Lets d Γ_in eff Γ_out} {com : Com d Γ_out eff ty} :
    denote ⟨lets, com⟩ = fun V => (lets.denote V) >>= com.denote

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

theorem trunc_shl_1_i32_i64_proof : trunc_shl_1_i32_i64_before ⊑ trunc_shl_1_i32_i64_after

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

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

theorem ashr_and_proof : ashr_and_before ⊑ ashr_and_after

theorem sgt_smin3_thm (e e_1 : IntW 32) :
  icmp IntPred.slt (add e_1 (const? 32 3))
      (select (icmp IntPred.slt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    const? 1 0

theorem icmp_and_ashr_multiuse_proof : icmp_and_ashr_multiuse_before ⊑ icmp_and_ashr_multiuse_after

theorem fold_icmp_shl_nuw_c2_non_pow2_proof : fold_icmp_shl_nuw_c2_non_pow2_before ⊑ fold_icmp_shl_nuw_c2_non_pow2_after

theorem different_size_zext_zext_ugt_proof : different_size_zext_zext_ugt_before ⊑ different_size_zext_zext_ugt_after

theorem test10_proof : test10_before ⊑ test10_after

theorem badimm1_thm.extracted_1._4 : ∀ (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) →
          ¬ofBool (-1#16 <ₛ x) = 1#1 → truncate 8 (x.sshiftRight' 15#16) ^^^ 127#8 = BitVec.ofInt 8 (-128)

theorem scalar_i16_lshr_and_negC_eq_proof : scalar_i16_lshr_and_negC_eq_before ⊑ scalar_i16_lshr_and_negC_eq_after

theorem PR38139_proof : PR38139_before ⊑ PR38139_after

theorem or_ashr_not_commuted_thm (e e_1 e_2 : IntW 8) :
  LLVM.or (LLVM.xor (ashr e_2 e_1) (const? 8 (-1))) (ashr e e_1) ⊑
    ashr (LLVM.or e (LLVM.xor e_2 (const? 8 (-1)))) e_1

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 1), x ^^^ x = 0#1

theorem zext_nneg_redundant_and_proof : zext_nneg_redundant_and_before ⊑ zext_nneg_redundant_and_after

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

theorem ashr_exact_poison_constant_fold_thm (e : IntW 8) (e_1 : IntW 1) :
  ashr (select e_1 e (const? 8 42)) (const? 8 3) { «exact» := true } ⊑
    select e_1 (ashr e (const? 8 3)) (const? 8 5)

theorem x_thm (e : IntW 32) :
  icmp IntPred.slt (LLVM.sdiv e (const? 32 65536)) (const? 32 (-65536)) ⊑ const? 1 0

theorem neg_sgt_42_thm (e : IntW 32) :
  icmp IntPred.sgt (sub (const? 32 0) e) (const? 32 42) ⊑
    icmp IntPred.slt (add e (const? 32 (-1))) (const? 32 (-43))

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

theorem no_shift_xor_multiuse_cmp_or_thm.extracted_1._4 : ∀ (x x_1 x_2 x_3 : BitVec 32),
  ¬ofBool (0#32 != x_3 &&& 4096#32) = 1#1 →
    ¬ofBool (x_3 &&& 4096#32 == 0#32) = 1#1 →
      (x_2 ||| 4096#32) * x * (x_2 ||| 4096#32) = x_2 * x_1 * (x_2 ||| 4096#32)

theorem t0_thm.extracted_1._16 : ∀ (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 → ¬0#1 = 1#1 → False

theorem lshrult_01_00_exact_proof : lshrult_01_00_exact_before ⊑ lshrult_01_00_exact_after

theorem src3_proof : src3_before ⊑ src3_after

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

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

theorem c_0_1_0_thm (e e_1 : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e_1 e) (const? 4 (-2))) e_1 ⊑
    LLVM.or (LLVM.and e (const? 4 (-2))) (LLVM.and e_1 (const? 4 1)) { «disjoint» := true }

theorem test14_proof : test14_before ⊑ test14_after

theorem dec_mask_commute_neg_i32_proof : dec_mask_commute_neg_i32_before ⊑ dec_mask_commute_neg_i32_after

@[simp]
theorem extractLsb'_eq_setWidth {x : BitVec w} : x.extractLsb' 0 n = x.setWidth n

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

theorem uge_umin4_proof : uge_umin4_before ⊑ uge_umin4_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 ashr_xor_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬((42#32 == 0 || 32 != 1 && x_1 == intMin 32 && 42#32 == -1) = true ∨ 5#32 ≥ ↑32 ∨ 7#32 ≥ ↑32) →
    ¬(12#32 ≥ ↑32 ∨ (42#32 == 0 || 32 != 1 && x_1 == intMin 32 && 42#32 == -1) = true ∨ 7#32 ≥ ↑32) →
      (x_1.srem 42#32 ^^^ x.sshiftRight' 5#32).sshiftRight' 7#32 =
        x.sshiftRight' 12#32 ^^^ (x_1.srem 42#32).sshiftRight' 7#32

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

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

theorem e_393 :
    4 *  ~~~(x &&& y) + 3 * (x ||| y) + 4 *  ~~~(x &&&  ~~~y) + 2 * (x |||  ~~~y) - 8 *  ~~~(x ||| y) - 9 *  ~~~(x |||  ~~~y) - 9 * (x &&&  ~~~y) - 9 * (x &&& y) = 2 *  ~~~x

theorem positive_samevar_shlnuwnsw_ashrexact_proof : positive_samevar_shlnuwnsw_ashrexact_before ⊑ positive_samevar_shlnuwnsw_ashrexact_after

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

theorem udiv_i80_proof : udiv_i80_before ⊑ udiv_i80_after

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

theorem sge_swap_or_not_max_logical_proof : sge_swap_or_not_max_logical_before ⊑ sge_swap_or_not_max_logical_after

theorem or_xor_tree_0111_proof : or_xor_tree_0111_before ⊑ or_xor_tree_0111_after

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

theorem test5 (x y : BitVec w) : (x + y) = (y + x)

theorem and_min_7_7_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x <ᵤ BitVec.ofInt 8 (-7)) = 1#1 → BitVec.ofInt 8 (-7) &&& BitVec.ofInt 8 (-8) = x &&& BitVec.ofInt 8 (-8)

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

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

theorem test_simplify_decrement_invalid_ne_thm (e : IntW 8) :
  select (icmp IntPred.ne e (const? 8 0)) (const? 8 0) (sub e (const? 8 1)) ⊑
    sext 8 (icmp IntPred.eq e (const? 8 0))

theorem main7f_logical_proof : main7f_logical_before ⊑ main7f_logical_after

theorem test11d_proof : test11d_before ⊑ test11d_after

theorem trunc_sandwich_big_sum_shift1_thm (e : IntW 32) : lshr (trunc 12 (lshr e (const? 32 21))) (const? 12 11) ⊑ const? 12 0

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

theorem icmp_slt_0_and_icmp_sge_neg1_i64_fail_thm (e : IntW 64) :
  LLVM.and (lshr e (const? 64 62)) (zext 64 (icmp IntPred.sge e (const? 64 (-1)))) ⊑
    select (icmp IntPred.sgt e (const? 64 (-2))) (LLVM.and (lshr e (const? 64 62)) (const? 64 1))
      (const? 64 0)

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

theorem append_valid {Γ₁ Γ₂ Γ₃  : Ctxt Ty} {d₁ d₂ : Nat} :
  Diff.Valid Γ₁ Γ₂ d₁ →  Diff.Valid Γ₂ Γ₃ d₂ → Diff.Valid Γ₁ Γ₃ (d₁ + d₂)

theorem slt_swap_or_not_max_commute_proof : slt_swap_or_not_max_commute_before ⊑ slt_swap_or_not_max_commute_after

theorem lshrugt_01_00_exact_proof : lshrugt_01_00_exact_before ⊑ lshrugt_01_00_exact_after

theorem e_845 :
     - 1 * t - 6 * (z ^^^ t) - 1 *  ~~~(z ^^^ t) + 1 *  ~~~(z ||| t) + 12 *  ~~~(z |||  ~~~t) + 7 * (z &&& t) =  - 11 * (z &&&  ~~~t) + 5 * (z ||| t)

theorem R.trimTensor_getD_0 (tensor: List Int) :
  tensor.getD i 0 = (trimTensor tensor).getD i 0

theorem ashrsgt_03_04_exact_proof : ashrsgt_03_04_exact_before ⊑ ashrsgt_03_04_exact_after

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

theorem test_zext_nneg_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32) (x_2 : BitVec 64),
  ¬(True ∧ (x_1 ^^^ -1#32).msb = true) →
    x_2 + BitVec.ofInt 64 (-5) - (zeroExtend 64 (x_1 ^^^ -1#32) + x) =
      x_2 + BitVec.ofInt 64 (-4) + (signExtend 64 x_1 - x)

theorem test82_proof : test82_before ⊑ test82_after

theorem test44_proof : test44_before ⊑ test44_after

theorem e_2304 :
     - 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 * (f ^^^ (d &&& (e ||| f))) + 1 * ((d &&& e) ^^^ (e ||| f)) - 2 * (f &&& (d |||  ~~~e)) + 2 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 2 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 5 * (d ||| (e ^^^ f)) - 1 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 7 * (e ^^^  ~~~(d ||| (e &&& f))) - 2 * (e ^^^ (d &&& ( ~~~e ||| f))) - 1 * (f ^^^ (d ||| ( ~~~e &&& f))) + 11 * (e &&&  ~~~f) + 3 * (e &&&  ~~~(d &&& f)) - 2 * (e ||| (d &&&  ~~~f)) - 1 *  ~~~(d &&&  ~~~f) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 2 * ( ~~~d ||| (e ||| f)) - 11 * (f ^^^ (d &&&  ~~~e)) - 1 * (e |||  ~~~(d |||  ~~~f)) + 4 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 2 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 *  ~~~(d ||| (e ^^^ f)) + 11 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) - 11 * (f ^^^  ~~~(d &&&  ~~~e)) + 5 * ((d |||  ~~~e) &&& (e ^^^ f)) - 6 * (f ^^^  ~~~(d ||| (e &&& f))) + 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 1 * (e ^^^ ( ~~~d ||| (e ||| f))) + 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 3 * ( ~~~d &&& (e ^^^ f)) - 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 * (f ^^^ (d ||| (e ||| f))) + 11 *  ~~~(d |||  ~~~e) - 5 * (d &&& e) - 3 *  ~~~(d ||| (e &&& f)) - 3 * ((d &&& e) |||  ~~~(e ||| f)) + 7 * ( ~~~e |||  ~~~(d ^^^ f)) - 1 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * (d ^^^ ( ~~~e ||| f)) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 3 *  ~~~(d ^^^ ( ~~~e ||| f)) - 1 * (e ^^^ f) - 1 * (d &&& ( ~~~e ||| f)) - 1 * (e |||  ~~~(d ||| f)) - 6 * (d &&& (e ||| f)) + 2 * (e ||| (d ^^^ f)) + 26 *  ~~~(d ||| (e ||| f)) - 5 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) + 15 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ( ~~~d &&& ( ~~~e &&& f)) + 41 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 35 * (d &&& (e &&& f)) = 2 * (e ^^^  ~~~(d &&& f)) - 11 * (f ^^^  ~~~(d ||| ( ~~~e &&& f)))

@[simp] theorem not_eq :    (~~~x) i = !(x i)

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

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

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

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

theorem urem_constant_dividend_select_of_constants_divisor_proof : urem_constant_dividend_select_of_constants_divisor_before ⊑ urem_constant_dividend_select_of_constants_divisor_after

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

theorem ne_rem_zero_nonuw_thm (e : IntW 8) :
  icmp IntPred.ne (mul e (const? 8 5)) (const? 8 30) ⊑ icmp IntPred.ne e (const? 8 6)

theorem neg_sgt_n1_proof : neg_sgt_n1_before ⊑ neg_sgt_n1_after

theorem n7_wrong_pred2_proof : n7_wrong_pred2_before ⊑ n7_wrong_pred2_after

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

theorem substitute_constant_and_eq_eq_commute_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 == x) &&& ofBool (x_1 == 42#8) = ofBool (x_1 == 42#8) &&& ofBool (x == 42#8)

theorem sgt_positive_multip_rem_zero_proof : sgt_positive_multip_rem_zero_before ⊑ sgt_positive_multip_rem_zero_after

theorem test3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), x_1 &&& (x &&& x_1) = x &&& x_1

theorem factorize4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬1#32 ≥ ↑32 → x_1 <<< 1#32 * x - x * x_1 = x_1 * x

theorem bitwise_and_logical_and_icmps_comm3_thm.extracted_1._1 : ∀ (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 test14_thm (e e_1 : IntW 32) :
  add (add e_1 (const? 32 1) { «nsw» := true, «nuw» := false })
      (LLVM.xor (LLVM.or e (const? 32 (-1431655767))) (const? 32 1431655766)) { «nsw» := true, «nuw» := false } ⊑
    sub e_1 (LLVM.and e (const? 32 1431655766))

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

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

private theorem not_not_xor_not (a b : Bool) : ! ((!a).xor (!b)) = (a == b)

theorem ugt_sext_proof : ugt_sext_before ⊑ ugt_sext_after

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

theorem ult_and_max_commute_proof : ult_and_max_commute_before ⊑ ult_and_max_commute_after

theorem absdiff1_thm (e e_1 : IntW 64) :
  sub (LLVM.xor (sub e_1 e) (sext 64 (icmp IntPred.ult e_1 e))) (sext 64 (icmp IntPred.ult e_1 e)) ⊑
    select (icmp IntPred.ult e_1 e) (sub (const? 64 0) (sub e_1 e)) (sub e_1 e)

theorem lshrugt_03_00_exact_proof : lshrugt_03_00_exact_before ⊑ lshrugt_03_00_exact_after

theorem and_signbit_lshr_thm (e : IntW 32) :
  lshr (LLVM.and e (const? 32 (-65536))) (const? 32 8) ⊑ LLVM.and (lshr e (const? 32 8)) (const? 32 16776960)

theorem test43_proof : test43_before ⊑ test43_after

theorem lshr_xor_or_good_mask_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(4#8 ≥ ↑8 ∨ 4#8 ≥ ↑8) →
    ¬(4#8 ≥ ↑8 ∨ True ∧ ((x ||| x_1) >>> 4#8 &&& 48#8 != 0) = true) →
      x_1 >>> 4#8 ||

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

theorem and1 (w : Nat) (a b : BitVec w) : (a + b = b + a) ∧ (a + a = a <<< 1)

theorem n15_wrong_comparison_predicate_and_constant_thm.extracted_1._3 : ∀ (x : BitVec 8),
  ¬ofBool (x &&& 15#8 <ᵤ 2#8) = 1#1 →
    ¬ofBool (x &&& 14#8 == 0#8) = 1#1 → x + 16#8 &&& BitVec.ofInt 8 (-16) = (x &&& BitVec.ofInt 8 (-16)) + 16#8

@[simp] theorem pure_inf_eq      : min pure e = pure

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

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

theorem bv0 (a b : BitVec 0) : a = b

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_190 :
    1 * (x ||| y) + 2 * y + 7 *  ~~~(x ^^^ y) - 6 *  ~~~(x ||| y) - 3 *  ~~~(x |||  ~~~y) - 9 * (x &&& y) = 1 * (x |||  ~~~y)

theorem lshrugt_02_12_exact_proof : lshrugt_02_12_exact_before ⊑ lshrugt_02_12_exact_after

theorem test12_proof : test12_before ⊑ test12_after

theorem test3_proof : test3_before ⊑ test3_after

theorem t4_ugt_slt_65536_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬ofBool (65535#32 <ᵤ x) = 1#1 → ofBool (65535#32 <ₛ x) = 1#1 ∨ ofBool (x <ₛ 0#32) = 1#1 → False

theorem exact_lshr_eq_both_equal_proof : exact_lshr_eq_both_equal_before ⊑ exact_lshr_eq_both_equal_after

theorem ne_21_comm_ne2_proof : ne_21_comm_ne2_before ⊑ ne_21_comm_ne2_after

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

theorem main13_thm (e : IntW 32) :
  select (LLVM.and (icmp IntPred.slt (trunc 16 e) (const? 16 0)) (icmp IntPred.slt (trunc 8 e) (const? 8 0)))
      (const? 32 2) (const? 32 1) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 32 32896)) (const? 32 32896)) (const? 32 2) (const? 32 1)

theorem ashrslt_03_06_exact_proof : ashrslt_03_06_exact_before ⊑ ashrslt_03_06_exact_after

theorem e_1079 :
    3 *  ~~~z - 5 * (z ^^^ t) + 5 *  ~~~t - 6 * (z ||| t) - 3 *  ~~~(z &&&  ~~~t) - 8 *  ~~~(z ||| t) + 11 *  ~~~(z |||  ~~~t) + 6 * (z &&& t) =  - 3 * (z &&&  ~~~t) - 3 * (z |||  ~~~t)

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

theorem e_2170 :
     - 2 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 3 * (d &&& e) + 1 * (f &&& (d ^^^ e)) - 11 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 2 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 5 *  ~~~(d |||  ~~~e) + 4 * ((d &&& e) ^^^ (e |||  ~~~f)) - 3 * (f ^^^ (d ||| ( ~~~e &&& f))) - 2 *  ~~~d - 5 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (d ||| ( ~~~e ||| f)) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 7 * (e ^^^  ~~~(d &&& (e ||| f))) - 7 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 11 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 4 * (f ^^^ (d ||| e)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * (f ^^^ (d ||| (e ||| f))) - 11 * (f ^^^ (d &&& e)) + 11 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) + 2 * (f ^^^ (d &&& ( ~~~e ||| f))) + 5 *  ~~~( ~~~d &&& (e &&& f)) - 11 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 4 * (d &&& (e ||| f)) - 11 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 1 * e + 7 *  ~~~(d ^^^ (e &&& f)) + 1 * (f |||  ~~~(d ^^^ e)) + 5 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 2 * (d |||  ~~~e) - 6 * (d &&& (e ^^^ f)) - 2 * ((d &&& f) ||| (e &&&  ~~~f)) - 3 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&&  ~~~e) + 11 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 2 *  ~~~(d &&& ( ~~~e ||| f)) - 3 *  ~~~(d |||  ~~~f) - 3 *  ~~~(d ||| (e ||| f)) - 16 *  ~~~(d ||| ( ~~~e ||| f)) + 24 *  ~~~( ~~~d ||| (e ||| f)) - 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 1 * ( ~~~d &&& ( ~~~e &&& f)) - 3 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) = 27 * (d &&& (e &&& f)) + 1 * ((d &&& e) |||  ~~~(e ||| f))

theorem select_icmp_ne_0_and_1073741824_or_8_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ofBool (0#32 != x_1 &&& 1073741824#32) = 1#1 → ofBool (x_1 &&& 1073741824#32 == 0#32) = 1#1 → x = x ||

theorem e_1240 :
     - 1 * z + 11 *  ~~~(z &&&  ~~~t) + 7 * (z |||  ~~~t) - 1 * (z ^^^ t) - 7 *  ~~~z - 9 *  ~~~(z ||| t) - 3 *  ~~~(z |||  ~~~t) - 5 * (z &&&  ~~~t) - 15 * (z &&& t) = 2 *  ~~~(z ^^^ t)

theorem t5_thm.extracted_1._7 : ∀ (x x_1 : BitVec 1) (x_2 : BitVec 32),
  x_1 = 1#1 → ¬x = 1#1 → ¬64#32 = 0 → ¬6#32 ≥ ↑32 → x_2 / 64#32 = x_2 >>> 6#32

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

theorem mul_of_sdiv_fail_ub_proof : mul_of_sdiv_fail_ub_before ⊑ mul_of_sdiv_fail_ub_after

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

theorem ashrslt_01_14_proof : ashrslt_01_14_before ⊑ ashrslt_01_14_after

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

theorem e_901 :
     - 2 * (z ^^^ t) + 11 *  ~~~t - 12 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) - 9 * (z &&&  ~~~t) - 5 * (z &&& t) =  - 5 * t - 1 *  ~~~z

theorem lshrugt_01_01_proof : lshrugt_01_01_before ⊑ lshrugt_01_01_after

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

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

@[simp]
theorem Term.denoteFin_width_zero  (t : Term) (env : EnvFin 0 t.numVars) :
    t.denoteFin env = 0

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

theorem imp_eq (p q : Prop) : (p → q) = (¬ p ∨ q)

theorem Id.map_eq' (x : Id α) (f : α → β) : f <$> x = f x

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

theorem sle_or_min_logical_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 ≤ₛ x) = 1#1 → ofBool (x_1 == BitVec.ofInt 8 (-128)) = ofBool (x_1 ≤ₛ x)

theorem shl_lshr_demand3_proof : shl_lshr_demand3_before ⊑ shl_lshr_demand3_after

theorem shl_and_thm (e : IntW 8) :
  LLVM.and (shl (const? 8 48) e) (shl (const? 8 8) (add e (const? 8 1))) ⊑ shl (const? 8 16) e

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 sub_to_xor_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), (x_1 &&& x) - (x_1 ||| x) = 0#32 - (x_1 ^^^ x)

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

theorem testi16i8_com_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(8#16 ≥ ↑16 ∨ 7#8 ≥ ↑8) →
    ofBool (truncate 8 (x >>> 8#16) == (truncate 8 x).sshiftRight' 7#8) = ofBool (x + 128#16 <ᵤ 256#16)

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

@[simp] theorem Com.castPureToEff_var {com : Com d _ .pure ty} {e : Expr d Γ _ eTy} :
    (var e com).castPureToEff eff = var (e.castPureToEff eff) (com.castPureToEff eff)

theorem neg_or_lshr_i32_commute_thm (e : IntW 32) :
  lshr (LLVM.or (LLVM.sdiv (const? 32 42) e) (sub (const? 32 0) (LLVM.sdiv (const? 32 42) e))) (const? 32 31) ⊑
    zext 32 (icmp IntPred.ne (LLVM.sdiv (const? 32 42) e) (const? 32 0))

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

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

theorem mul128_low_proof : mul128_low_before ⊑ mul128_low_after

theorem logic_or_logic_and_3_thm.extracted_1._8 : ∀ (x x_1 x_2 : BitVec 1),
  ¬x_2 = 1#1 → ¬x = 1#1 → ¬x_1 = 1#1 → ¬0#1 = 1#1 → 0#1 = x_1

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

theorem e_517 :
     - 11 *  ~~~(x &&& y) - 11 * (x ^^^ y) + 1 * x + 2 *  ~~~(x &&&  ~~~x) - 3 * (x ||| y) + 2 *  ~~~(x ^^^ y) + 3 *  ~~~y + 4 *  ~~~(x ||| y) + 23 *  ~~~(x |||  ~~~y) =  - 19 * (x &&&  ~~~y) + 2 * (x &&& y)

theorem ashrsgt_01_14_proof : ashrsgt_01_14_before ⊑ ashrsgt_01_14_after

theorem neg_not_signbit3_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬7#8 ≥ ↑8 → 7#8 ≥ ↑8 ∨ True ∧ (0#32).ssubOverflow (zeroExtend 32 (x.sshiftRight' 7#8)) = true → False

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

theorem test54_thm (e : IntW 64) :
  sext 32 (LLVM.and (LLVM.or (trunc 16 e) (const? 16 (-32574))) (const? 16 (-25350))) ⊑
    sext 32 (LLVM.or (LLVM.and (trunc 16 e) (const? 16 7224)) (const? 16 (-32574)) { «disjoint» := true })

theorem e_2439 :
     - 3 * (e ^^^  ~~~(d &&& f)) + 2 * (e &&&  ~~~(d &&&  ~~~f)) + 3 * (e ^^^ (d ||| (e ||| f))) + 11 * (f ||| (d &&& e)) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) - 11 *  ~~~( ~~~d &&& (e &&& f)) + 11 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 5 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 3 * (d ^^^ f) - 3 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * ((d &&& e) ||| (e ^^^ f)) - 1 * (f ^^^  ~~~(d ||| e)) + 2 *  ~~~(d &&& e) + 3 * (f ^^^ (d &&& ( ~~~e ||| f))) - 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 2 * (d ||| ( ~~~e ||| f)) + 4 * ( ~~~d &&& ( ~~~e ||| f)) - 6 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * (f ^^^ (d &&& (e ||| f))) - 1 * (e ^^^ (d |||  ~~~f)) + 1 * (f |||  ~~~(d ||| e)) - 1 * (e ^^^  ~~~(d ||| f)) - 2 *  ~~~(d ||| (e ^^^ f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 2 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) + 3 * (e ^^^  ~~~(d ||| (e &&& f))) - 7 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 3 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 5 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 3 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 2 * (f &&&  ~~~(d &&& e)) + 11 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 2 * (f &&& (d |||  ~~~e)) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) + 7 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 5 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 1 * (e ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 5 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 7 * (d ^^^ (e ||| f)) - 1 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) - 2 *  ~~~(d &&& ( ~~~e &&& f)) - 7 * ((e &&& f) ||| (d &&& (e ||| f))) + 2 *  ~~~(d ||| f) - 2 *  ~~~(d ^^^ (e ^^^ f)) - 5 * ( ~~~f &&& (d ^^^ e)) - 11 * (e ||| (d &&& f)) + 4 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 11 * (d ||| e) - 2 * (f &&&  ~~~(d &&&  ~~~e)) + 2 * (e ^^^ (d &&& (e ||| f))) + 1 * ((d &&& f) ||| (e &&&  ~~~f)) - 2 * (e &&& (d ||| f)) - 1 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 2 *  ~~~( ~~~d &&& (e ||| f)) + 7 * (f ^^^ (d &&& e)) + 7 * (f ^^^  ~~~(d &&& e)) - 11 *  ~~~(d &&&  ~~~e) + 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 1 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 3 * (f ^^^  ~~~(d &&& (e &&& f))) + 1 * (f ^^^ (d ||| ( ~~~e &&& f))) - 6 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 7 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 2 * (e &&& (d ^^^ f)) + 6 *  ~~~(d ||| (e ||| f)) + 67 *  ~~~(d ||| ( ~~~e ||| f)) + 21 *  ~~~( ~~~d ||| (e ||| f)) + 32 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 4 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) + 10 * (d &&& ( ~~~e &&& f)) + 39 * (d &&& (e &&& f)) = 1 * ( ~~~d ||| (e &&& f)) + 5 * (e |||  ~~~f)

theorem e_624 :
    7 *  ~~~(x ^^^ y) + 2 * (x ||| y) - 2 * (x |||  ~~~y) - 11 * (x ^^^ y) - 11 *  ~~~x + 2 *  ~~~(x &&&  ~~~y) + 5 *  ~~~(x ||| y) + 25 *  ~~~(x |||  ~~~y) + 12 * (x &&&  ~~~y) - 2 * (x &&& y) = 1 *  ~~~(x &&&  ~~~x) + 6 * y

theorem positive_biggershl_shlnsw_proof : positive_biggershl_shlnsw_before ⊑ positive_biggershl_shlnsw_after

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

theorem sext_diff_i1_xor_sub_1_thm (e e_1 : IntW 1) :
  sub (sext 64 e_1) (sext 64 e) ⊑ add (zext 64 e) (sext 64 e_1) { «nsw» := true, «nuw» := false }

theorem eq_smax2_proof : eq_smax2_before ⊑ eq_smax2_after

theorem e_1178 :
     - 5 * (z ||| t) - 6 * z + 1 * (z |||  ~~~t) - 1 *  ~~~(z &&& t) + 8 *  ~~~(z ||| t) + 12 *  ~~~(z |||  ~~~t) + 13 * (z &&&  ~~~t) + 10 * (z &&& t) = 6 *  ~~~z + 2 *  ~~~t

theorem src_is_mask_and_proof : src_is_mask_and_before ⊑ src_is_mask_and_after

theorem or_not_and_commute9_proof : or_not_and_commute9_before ⊑ or_not_and_commute9_after

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

theorem mul32_low_proof : mul32_low_before ⊑ mul32_low_after

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

theorem scalar_zext_slt_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ofBool (zeroExtend 32 x <ₛ 500#32) = ofBool (x <ᵤ 500#16)

theorem test_sub_255_Y_eq_255_proof : test_sub_255_Y_eq_255_before ⊑ test_sub_255_Y_eq_255_after

theorem icmp_slt_0_and_icmp_ne_neg2_i32_fail_proof : icmp_slt_0_and_icmp_ne_neg2_i32_fail_before ⊑ icmp_slt_0_and_icmp_ne_neg2_i32_fail_after

theorem sub_sel_op1_thm.extracted_1._2 : ∀ (x : BitVec 1),
  ¬x = 1#1 → ¬(True ∧ (42#32).ssubOverflow 41#32 = true) → 42#32 - 41#32 = zeroExtend 32 (x ^^^ 1#1)

theorem rawspeed_signbit_thm.extracted_1._1 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬(True ∧ x_1.saddOverflow (-1#32) = true ∨
        x_1 + -1#32 ≥ ↑32 ∨ True ∧ (64#32).ssubOverflow x_1 = true ∨ zeroExtend 64 (64#32 - x_1) ≥ ↑64) →
    ofBool (1#32 <<< (x_1 + -1#32) &&& truncate 32 (x >>> zeroExtend 64 (64#32 - x_1)) == 0#32) = ofBool (-1#64 <ₛ x)

theorem negative_not_next_power_of_two_proof : negative_not_next_power_of_two_before ⊑ negative_not_next_power_of_two_after

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

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

theorem foo1_proof : foo1_before ⊑ foo1_after

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

theorem icmp_ne_and_pow2_minus1_shl1_thm (e : IntW 32) :
  zext 32 (icmp IntPred.ne (LLVM.and (shl (const? 32 1) e) (const? 32 15)) (const? 32 0)) ⊑
    zext 32 (icmp IntPred.ult e (const? 32 4))

theorem ult_swap_or_not_max_logical_proof : ult_swap_or_not_max_logical_before ⊑ ult_swap_or_not_max_logical_after

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

theorem ashrslt_03_07_exact_proof : ashrslt_03_07_exact_before ⊑ ashrslt_03_07_exact_after

theorem select_shl_icmp_bad_proof : select_shl_icmp_bad_before ⊑ select_shl_icmp_bad_after

theorem positive_samevar_lshrexact_thm (e e_1 : IntW 8) : shl (lshr e_1 e { «exact» := true }) e ⊑ e_1

theorem exact_ashr_eq_both_equal_thm (e : IntW 8) :
  icmp IntPred.eq (ashr (const? 8 (-128)) e { «exact» := true }) (const? 8 (-128)) ⊑
    icmp IntPred.eq e (const? 8 0)

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_7b_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 6#32 == 0#32) ||

@[simp] theorem head_corec : head (corec b f) = (f b).fst

theorem mul_constant_eq_nsw_proof : mul_constant_eq_nsw_before ⊑ mul_constant_eq_nsw_after

theorem sub_select_not_zext_thm.extracted_1._1 : ∀ (x : BitVec 1),
  ¬x = 1#1 → 64#64 - zeroExtend 64 (x ^^^ 1#1) = 63#64

theorem test24_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt e (const? 32 1)) (icmp IntPred.ne e (const? 32 2)) (const? 1 0) ⊑
    icmp IntPred.sgt e (const? 32 2)

omit [Fintype S] in
lemma processOneElem_spec {st : worklist.St A S} (s : State) (sa : S) (k : ℕ) :
    ∀ a sa', (f sa)[k]? = some (a, sa') →
    processOneElem_mot inits final f s sa k st →
    processOneElem_mot inits final f s sa (k+1) (processOneElem A S final s st (a, sa'))

theorem lshrult_01_05_thm (e : IntW 4) :
  icmp IntPred.ult (lshr e (const? 4 1)) (const? 4 5) ⊑ icmp IntPred.ult e (const? 4 (-6))

theorem fold_sext_to_and_wrong2_proof : fold_sext_to_and_wrong2_before ⊑ fold_sext_to_and_wrong2_after

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

theorem e_1721 :
     - 1 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 2 * (a ^^^ c) - 3 * ((a ^^^ b) ||| (a ^^^ c)) - 5 * ((a |||  ~~~b) &&& (b ^^^ c)) - 1 * (c ^^^ (a &&& ( ~~~b ||| c))) + 5 * ( ~~~a ||| (b ^^^ c)) - 7 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 2 * (a ^^^ ( ~~~b &&& c)) + 2 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 7 * (c |||  ~~~(a ||| b)) + 7 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 6 * (b ^^^ ( ~~~a ||| (b &&& c))) + 11 * (c &&&  ~~~(a ^^^ b)) + 1 * (a ^^^ ( ~~~b ||| c)) - 1 * (a ||| (b ^^^ c)) - 5 * (b ^^^ (a &&& c)) - 6 * (b |||  ~~~(a |||  ~~~c)) + 5 * ((a &&&  ~~~b) ||| (a ^^^ (b ^^^ c))) + 2 * (a &&& (b ||| c)) - 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 3 * (a |||  ~~~c) - 7 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 11 * (c ||| (a &&& b)) + 16 *  ~~~(a ||| (b ||| c)) + 16 *  ~~~(a ||| ( ~~~b ||| c)) + 13 *  ~~~( ~~~a ||| (b ||| c)) + 41 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 25 * ( ~~~a &&& ( ~~~b &&& c)) + 28 * ( ~~~a &&& (b &&& c)) + 20 * (a &&& ( ~~~b &&& c)) + 10 * (a &&& (b &&& c)) = 3 * (a &&& ( ~~~b ||| c))

theorem widget_proof : widget_before ⊑ widget_after

theorem test56_proof : test56_before ⊑ test56_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_after

theorem bitwise_or_bitwise_or_icmps_comm3_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 n1_proof : n1_before ⊑ n1_after

theorem test26_proof : test26_before ⊑ test26_after

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

@[simp] theorem Hom.appendCodomain_apply (f : Γ.Hom Δ) (v : Γ.Var t) :
    (f.appendCodomain (ts := ts)) v = (f v).appendInr

theorem nonexact_ashr_ne_proof : nonexact_ashr_ne_before ⊑ nonexact_ashr_ne_after

theorem ashr_ult_9_thm (e : IntW 4) :
  icmp IntPred.ult (ashr e (const? 4 1)) (const? 4 (-7)) ⊑ icmp IntPred.sgt e (const? 4 (-1))

theorem lshrult_01_13_exact_proof : lshrult_01_13_exact_before ⊑ lshrult_01_13_exact_after

theorem alive_Select_740 : forall (w : Nat) (A : 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 (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  w %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v1 %v7;
  %v9 := op:select w %v8;
  %v10 := op:const (-1) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  w %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub w %v14;
  %v16 := triple:%v12 %v9 %v15;
  %v17 := op:select w %v16
  dsl_ret %v17
  ]  ⊑
  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 (0) %v0;
  %v3 := pair:%v1 %v2;
  %v4 := op:icmp sgt  1 %v3;
  %v5 := op:const (0) %v0;
  %v6 := pair:%v5 %v1;
  %v7 := op:sub 1 %v6;
  %v8 := triple:%v4 %v1 %v7;
  %v9 := op:select 1 %v8;
  %v10 := op:const (-1) %v0;
  %v11 := pair:%v9 %v10;
  %v12 := op:icmp sgt  1 %v11;
  %v13 := op:const (0) %v0;
  %v14 := pair:%v13 %v9;
  %v15 := op:sub 1 %v14;
  %v16 := triple:%v4 %v1 %v7;
  %v17 := op:select 1 %v16
  dsl_ret %v17
  ]

theorem ashrslt_02_09_proof : ashrslt_02_09_before ⊑ ashrslt_02_09_after

theorem uge_or_max_logical_proof : uge_or_max_logical_before ⊑ uge_or_max_logical_after

theorem udiv_i32_multiuse_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬zeroExtend 32 x = 0 →
    zeroExtend 32 x = 0 ∨
        True ∧ (zeroExtend 32 x_1).saddOverflow (zeroExtend 32 x) = true ∨
          True ∧ (zeroExtend 32 x_1).uaddOverflow (zeroExtend 32 x) = true ∨
            True ∧ (zeroExtend 32 x_1 / zeroExtend 32 x).smulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true ∨
              True ∧ (zeroExtend 32 x_1 / zeroExtend 32 x).umulOverflow (zeroExtend 32 x_1 + zeroExtend 32 x) = true →
      False

theorem ne_umin2_proof : ne_umin2_before ⊑ ne_umin2_after

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

theorem icmp_eq_sext_eq_allones_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (signExtend 32 (ofBool (x == -1#32)) == x) = ofBool (x + 1#32 <ᵤ 2#32)

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem src_is_notmask_lshr_shl_fail_mismatch_shifts_proof : src_is_notmask_lshr_shl_fail_mismatch_shifts_before ⊑ src_is_notmask_lshr_shl_fail_mismatch_shifts_after

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

theorem and_or1_wrong_operand_proof : and_or1_wrong_operand_before ⊑ and_or1_wrong_operand_after

theorem or_sext_to_sel_proof : or_sext_to_sel_before ⊑ or_sext_to_sel_after

theorem alive_275   : alive_275_src ⊑ alive_275_tgt

theorem lshr_exact_add_negative_shift_positive_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ 2#32 >>> (x + -1#32) <<< (x + -1#32) ≠ 2#32 ∨ x + -1#32 ≥ ↑32) →
    True ∧ 4#32 >>> x <<< x ≠ 4#32 ∨ x ≥ ↑32 → False

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

theorem src_srem_shl_demand_max_signbit_mask_hit_first_demand_proof : src_srem_shl_demand_max_signbit_mask_hit_first_demand_before ⊑ src_srem_shl_demand_max_signbit_mask_hit_first_demand_after

theorem t0_thm (e e_1 : IntW 8) :
  ashr (LLVM.xor e_1 (const? 8 (-1))) e ⊑ LLVM.xor (ashr e_1 e) (const? 8 (-1))

theorem invert_both_cmp_operands_complex_proof : invert_both_cmp_operands_complex_before ⊑ invert_both_cmp_operands_complex_after

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

theorem lshr_16_add_zext_basic_thm (e e_1 : IntW 16) :
  lshr (add (zext 32 e_1) (zext 32 e)) (const? 32 16) ⊑
    zext 32 (icmp IntPred.ugt e (LLVM.xor e_1 (const? 16 (-1))))

theorem test_lshr_exact__exact_is_safe_proof : test_lshr_exact__exact_is_safe_before ⊑ test_lshr_exact__exact_is_safe_after

theorem lshr_exact_proof : lshr_exact_before ⊑ lshr_exact_after

@[simp] lemma eval_fsmCarry' (x : Bool → BitStream) :
    (fsmCarry' initCarry).eval x =
      (BitStream.carry initCarry (x true) (x false))

theorem test2_proof : test2_before ⊑ test2_after

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

theorem test4_proof : test4_before ⊑ test4_after

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

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

theorem test_lshr_exact__exact_is_safe_proof : test_lshr_exact__exact_is_safe_before ⊑ test_lshr_exact__exact_is_safe_after

theorem icmp_ne_sext_slt_allones_nofold_proof : icmp_ne_sext_slt_allones_nofold_before ⊑ icmp_ne_sext_slt_allones_nofold_after

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

theorem e_306 :
     - 2 *  ~~~x - 3 *  ~~~(x ^^^ y) - 2 * (x ||| y) - 6 * x + 5 *  ~~~(x ||| y) + 4 *  ~~~(x |||  ~~~y) + 11 * (x &&& y) =  - 8 * (x &&&  ~~~y)

theorem src_is_mask_shl_lshr_fail_not_allones_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬x ≥ ↑8 →
      ofBool (0#8 != (x_1 ^^^ 123#8) &&& (BitVec.ofInt 8 (-2) <<< x >>> x ^^^ -1#8)) =
        ofBool (x_1 ^^^ BitVec.ofInt 8 (-124) ||| (-1#8) >>> x &&& BitVec.ofInt 8 (-2) != -1#8)

theorem trunc_sel_equal_sext_thm.extracted_1._3 : ∀ (x : BitVec 32) (x_1 : BitVec 1),
  x_1 = 1#1 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ x <<< 16#32 >>> 16#32 <<< 16#32 ≠ x <<< 16#32 ∨ 16#32 ≥ ↑32) →
      signExtend 32 (truncate 16 x) = (x <<< 16#32).sshiftRight' 16#32

theorem alive_constant_fold_10: forall (w : Nat), TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v0 := unit: ;
  %v1 := op:const (Bitvec.ofInt w (0)) %v0
  dsl_ret %v1
  ]  ⊑
  TSSA.eval
  (Op := Op) (e := e)
  (i := TSSAIndex.STMT (UserType.base (BaseType.bitvec w)))
  [dsl_bb|
  ^bb
  %v000 := unit: ;
  %v001 := op:const (Bitvec.ofInt w (0)) %v000;
  %v100 := pair:%v001 %v001;
  %v101 := op:add w %v100;
  %v110 := pair:%v101 %v001;
  %v111 := op:add w %v110;
  %v120 := pair:%v111 %v001;
  %v121 := op:add w %v120;
  %v130 := pair:%v121 %v001;
  %v131 := op:add w %v130;
  %v140 := pair:%v131 %v001;
  %v141 := op:add w %v140;
  %v150 := pair:%v141 %v001;
  %v151 := op:add w %v150;
  %v160 := pair:%v151 %v001;
  %v161 := op:add w %v160;
  %v170 := pair:%v161 %v001;
  %v171 := op:add w %v170;
  %v180 := pair:%v171 %v001;
  %v181 := op:add w %v180;
  %v190 := pair:%v181 %v001;
  %v191 := op:add w %v190
  dsl_ret %v191
  ]

theorem e_1998 :
     - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(b ^^^ c)) - 7 * ( ~~~a ||| (b &&& c)) + 2 * (c |||  ~~~(a |||  ~~~b)) + 7 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 4 * (a &&&  ~~~c) - 2 *  ~~~( ~~~a ||| (b ^^^ c)) - 7 * (c &&& (a ||| b)) + 3 * (b &&&  ~~~c) - 5 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 5 * (b ^^^ (a &&& c)) + 2 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 5 * ((a &&& b) ||| (a ^^^ (b ^^^ c))) - 11 *  ~~~(a ^^^ b) + 2 * (c ^^^ (a &&&  ~~~b)) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) - 6 * ((a &&& b) ^^^ (a ^^^ ( ~~~b ||| c))) + 11 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 1 *  ~~~(a ^^^ (b &&& c)) - 6 * (b ^^^ (a ||| ( ~~~b ||| c))) + 1 * (a ||| ( ~~~b ||| c)) - 2 *  ~~~(b &&&  ~~~c) + 1 * ((a |||  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) + 3 *  ~~~(a ||| (b ^^^ c)) - 1 * b - 7 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 11 *  ~~~(a ^^^ c) - 1 *  ~~~(a ^^^ ( ~~~b &&& c)) - 1 *  ~~~(b &&& c) + 7 * (b ^^^ (a ||| ( ~~~b &&& c))) + 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 2 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) - 5 * (a &&& (b ^^^ c)) - 3 * (b ^^^ ( ~~~a &&& (b ^^^ c))) + 4 * ((a &&& b) |||  ~~~(b ||| c)) + 7 * (b ^^^ ( ~~~a ||| (b &&& c))) + 3 * (c ||| (a &&& b)) + 2 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) - 1 * (b ^^^ ( ~~~a ||| (b ^^^ c))) + 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 2 * ( ~~~(a ^^^ b) &&& (a ^^^ c)) + 5 * a - 6 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 2 * ((a |||  ~~~b) &&& (a ^^^ (b ^^^ c))) + 4 * ((a &&& c) ||| (b &&&  ~~~c)) - 1 * (b ^^^ (a &&& (b ||| c))) - 6 * (b ^^^ (a ||| (b ^^^ c))) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) - 5 * ((a |||  ~~~b) &&& (b ^^^ c)) + 1 * (b ^^^ ( ~~~a &&& (b ||| c))) - 18 *  ~~~(a ||| (b ||| c)) - 26 *  ~~~(a ||| ( ~~~b ||| c)) - 16 *  ~~~( ~~~a ||| (b ||| c)) - 12 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 15 * ( ~~~a &&& ( ~~~b &&& c)) + 25 * ( ~~~a &&& (b &&& c)) - 23 * (a &&& ( ~~~b &&& c)) + 4 * (a &&& (b &&& c)) =  - 11 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 1 * (c ^^^  ~~~(a &&& (b &&& c)))

theorem icmp_slt_0_or_icmp_sgt_0_i32_thm (e : IntW 32) :
  LLVM.or (zext 32 (icmp IntPred.slt e (const? 32 0))) (zext 32 (icmp IntPred.sgt e (const? 32 0))) ⊑
    zext 32 (icmp IntPred.ne e (const? 32 0))

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

theorem t2_commutative_proof : t2_commutative_before ⊑ t2_commutative_after

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

theorem extractLsb_setWidth_of_lt (x : BitVec w) (hi lo v : Nat) (hilo : lo < hi) (hhi : hi < v):
    BitVec.extractLsb hi lo (BitVec.setWidth v x) = BitVec.extractLsb hi lo x

theorem trunc_shl_16_i32_i64_proof : trunc_shl_16_i32_i64_before ⊑ trunc_shl_16_i32_i64_after

theorem ashrslt_03_02_exact_proof : ashrslt_03_02_exact_before ⊑ ashrslt_03_02_exact_after

theorem demorgan_nor_use2a_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬((x_1 ^^^ -1#8) * 23#8 == 0 || 8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && (x_1 ^^^ -1#8) * 23#8 == -1) =
        true →
    ((x_1 ^^^ -1#8) * 23#8 == 0 || 8 != 1 && x_1 &&& (x ^^^ -1#8) == intMin 8 && (x_1 ^^^ -1#8) * 23#8 == -1) = true →
      False

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

theorem ashrslt_03_13_exact_proof : ashrslt_03_13_exact_before ⊑ ashrslt_03_13_exact_after

theorem positive_samevar_shlnsw_proof : positive_samevar_shlnsw_before ⊑ positive_samevar_shlnsw_after

theorem bools_thm (e e_1 e_2 : IntW 1) :
  LLVM.or (LLVM.and (LLVM.xor e_2 (const? 1 1)) e_1) (LLVM.and e_2 e) ⊑ select e_2 e e_1

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

theorem PR75692_1_proof : PR75692_1_before ⊑ PR75692_1_after

theorem e_325 :
     - 1 *  ~~~(x &&&  ~~~y) - 2 *  ~~~(x &&& y) + 11 * (x ||| y) + 3 *  ~~~(x ||| y) - 8 *  ~~~(x |||  ~~~y) - 16 * (x &&&  ~~~y) - 17 * (x &&& y) =  - 7 * x

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

theorem e_2115 :
    5 * (e |||  ~~~(d ^^^ f)) - 6 * (e ^^^  ~~~(d &&& f)) + 2 * (e &&&  ~~~f) + 3 * (d &&& e) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 11 * (f ^^^  ~~~(d &&& (e &&& f))) + 11 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 2 *  ~~~f - 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 2 * (d ^^^ (e &&& f)) - 3 * (f ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 7 * (d ||| ( ~~~e ||| f)) - 1 *  ~~~(d ^^^ (e &&& f)) + 5 *  ~~~(d &&& (e ^^^ f)) + 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) + 5 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 3 * (e ^^^  ~~~(d ||| f)) + 1 * ((d &&& e) |||  ~~~(e ^^^ f)) + 7 * (f &&& (d |||  ~~~e)) + 1 * (e |||  ~~~f) + 1 * (d &&& (e ^^^ f)) + 3 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 5 * ( ~~~d ||| (e &&& f)) + 7 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 * (f &&&  ~~~(d ^^^ e)) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&& ( ~~~e &&& f)) - 6 * (f |||  ~~~(d |||  ~~~e)) - 11 * e - 6 * (d ||| (e &&& f)) + 5 * (f ^^^ (d &&& (e ||| f))) + 1 * (e ^^^ (d &&& (e ^^^ f))) + 2 *  ~~~( ~~~d ||| (e ^^^ f)) - 2 *  ~~~(e ||| f) - 17 *  ~~~(d ||| (e ||| f)) + 8 *  ~~~(d ||| ( ~~~e ||| f)) + 7 *  ~~~( ~~~d ||| (e ||| f)) + 2 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 3 * ( ~~~d &&& ( ~~~e &&& f)) + 9 * ( ~~~d &&& (e &&& f)) - 13 * (d &&& ( ~~~e &&& f)) + 2 * (d &&& (e &&& f)) =  - 11 *  ~~~(e &&&  ~~~f)

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

@[grind =, simp, aesop 50% unsafe]
lemma newState_finals (m : RawCNFA A) :
    m.newState.2.finals = m.finals

theorem c0_thm (e : IntW 8) :
  icmp IntPred.sle (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.sgt e (const? 8 (-1))

theorem test11_proof : test11_before ⊑ test11_after

theorem main5_like_proof : main5_like_before ⊑ main5_like_after

theorem a_true_implies_b_false2_comm_thm.extracted_1._2 : ∀ (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) = 0#1

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

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

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

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

lemma reduce_stepSet' {M : NFA α σ} (q : M.Reachable) (S1 : Set M.Reachable) (S2 : Set σ) :
    (∀ q, (∃ hq, S1 ⟨q, hq⟩) ↔ S2 q) →
    (q ∈ M.reduce.stepSet S1 a → q.val ∈ M.stepSet S2 a)

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

theorem lshr_lshr_thm (e : IntW 232) : lshr (lshr e (const? 232 231)) (const? 232 1) ⊑ const? 232 0

theorem e_236 :
     - 7 * (x ||| y) - 6 * x - 1 *  ~~~(x &&&  ~~~x) - 2 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) + 11 * (x &&&  ~~~y) + 11 * (x &&& y) =  - 3 * (x |||  ~~~y)
</all_available_lemmas>

<local_ctx>
import Batteries.Data.Fin.Basic

import Batteries.Data.Fin.Lemmas

import Blase.SingleWidth.Defs

import Blase.AutoStructs.Constructions

import Blase.AutoStructs.Defs

import Blase.AutoStructs.FiniteStateMachine

import Mathlib.Tactic.Ring

import Mathlib.Data.Nat.Size -- TODO: remove and get rid of shiftLeft_eq_mul_pow use

import Mathlib.Data.BitVec

import Mathlib.Tactic.FinCases

open Fin.NatCast

open Mathlib

section fsm

variable {arity : Type} [FinEnum arity]

open BitStream in

end fsm

section nfas_relations

inductive NFA.msbState : Type where
| i | f
deriving DecidableEq, Fintype

end nfas_relations

def liftUnop n : Fin (n + 1) → Fin (n + 2) :=
  fun k =>
    if k = n then Fin.last (n+1) else k.castLE (by admit /- proof elided -/
    )

inductive TermBinop where
| and | or | xor | add | sub

def TermBinop.subst (op : TermBinop) (t₁ t₂ : Term) : Term :=
  match op with
  | .and => .and t₁ t₂
  | .or => .or t₁ t₂
  | .xor => .xor t₁ t₂
  | .add => .add t₁ t₂
  | .sub => .sub t₁ t₂

def TermBinop.openTerm (op : TermBinop) : Term := op.subst (.var 0) (.var 1)

inductive TermUnop where
| neg | not | shiftL (k : Nat)

def TermUnop.openTerm (op : TermUnop) : Term :=
  match op with
  | .neg => .neg (.var 0)
  | .not => .not (.var 0)
  | .shiftL k => .shiftL (.var 0) k

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

def TermUnop.subst (op : TermUnop) (t : Term) : Term :=
  match op with
  | .neg => .neg t
  | .not => .not t
  | .shiftL k => .shiftL t k

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

<target_theorem>
lemma TermUnop.alt_lang {t : Term} (op : TermUnop) :
  (op.subst_arity' ▸ (op.subst t).language) =
    let lop : Set (BitVecs 2) :=
</target_theorem>

