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>
Bool in Init.Prelude
Nat in Init.Prelude
Int.xor in Mathlib.Data.Int.Bitwise
List in Init.Prelude
Nat.testBit in Init.Data.Nat.Bitwise.Basic
BitVec in Init.Prelude
BitVec.ofNat in Init.Prelude
List.map in Init.Prelude
BitVec.ult in Init.Data.BitVec.Basic
BitVec.carry in Init.Data.BitVec.Bitblast
BitVec.sle in Init.Data.BitVec.Basic
BitVec.slt in Init.Data.BitVec.Basic
BitVec.ule in Init.Data.BitVec.Basic
BitVec.adcb in Init.Data.BitVec.Bitblast
Prod in Init.Prelude

syntax "slt" : MLIR.Pretty.uniform_op

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

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

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

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

def BitStream : Type := Nat → Bool

def borrow (x y : BitStream) : BitStream :=
  fun n => (subAux x y n).2

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 nxor (a b : BitStream) : BitStream := fun i => a i == b i

def scanAnd (s : BitStream) : BitStream := scanl true Bool.and s

abbrev scanl (init : Bool) (f : Bool → Bool → Bool) (s : BitStream) : BitStream :=
  fun n => match n with
    | 0 => f init (s 0)
    | n+1 => f (scanl init f s n) (s (n + 1))

def scanOr (s : BitStream) : BitStream := scanl false Bool.or s

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

abbrev falseIffLt (n : Nat) : BitStream := fun i => decide (i ≥ n)

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

abbrev falseIffEq (n : Nat) : BitStream := fun i => decide (i != n)

abbrev falseIffGt (n : Nat) : BitStream := fun i => decide (i ≤ n)

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

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

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

abbrev negOne : BitStream := fun _ => true

def shiftLeft (x : BitStream) (k : Nat) : BitStream :=
  fun i => if i < k then false else x (i - k)

def ofNat (x : Nat) : BitStream :=
  Nat.testBit x

abbrev one    : BitStream := (· == 0)

abbrev zero   : BitStream := fun _ => false

inductive Predicate : Type where
 
| width (wp : WidthPredicate) (n : Nat) : Predicate
| binary (p : BinaryPredicate) (t₁ t₂ : Term)
| land  (p q : Predicate) : Predicate
| lor (p q : Predicate) : Predicate
deriving Repr, Inhabited, Lean.ToExpr

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)

abbrev map (f : Bool → Bool) : BitStream → BitStream :=
  fun x i => f (x i)

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

def Term.denote (w : Nat) (t : Term) (vars : List (BitVec w)) : BitVec w :=
  match t with
  | ofNat n => BitVec.ofNat w n
  | var n => vars.getD n default
  | zero => 0#w
  | negOne => -1#w
  | one  => 1#w
  | and a b => (a.denote w vars) &&& (b.denote w vars)
  | or a b => (a.denote w vars) ||| (b.denote w vars)
  | xor a b => (a.denote w vars) ^^^ (b.denote w vars)
  | not a => ~~~ (a.denote w vars)
  | add a b => (a.denote w vars) + (b.denote w vars)
  | sub a b => (a.denote w vars) - (b.denote w vars)
  | neg a => - (a.denote w vars)
  
  
  | shiftL a n => (a.denote w vars) <<< n

def Predicate.denote (p : Predicate) (w : Nat) (vars : List (BitVec w)) : Prop :=
  match p with
  | .width .ge k => k ≤ w 
  | .width .gt k => k < w 
  | .width .le k => w ≤ k
  | .width .lt k => w < k
  | .width .neq k => w ≠ k
  | .width .eq k => w = k
  | .binary .eq t₁ t₂ => t₁.denote w vars = t₂.denote w vars
  | .binary .neq t₁ t₂ => t₁.denote w vars ≠ t₂.denote w vars
  | .binary .sle  t₁ t₂ => ((t₁.denote w vars).sle (t₂.denote w vars)) = true
  | .binary .slt  t₁ t₂ => ((t₁.denote w vars).slt (t₂.denote w vars)) = true
  | .binary .ule  t₁ t₂ => ((t₁.denote w vars).ule (t₂.denote w vars)) = true
  | .binary .ult  t₁ t₂ => (t₁.denote w vars).ult (t₂.denote w vars) = true
  | .land  p q => p.denote w vars ∧ q.denote w vars
  | .lor  p q => p.denote w vars ∨ q.denote w vars

inductive WidthPredicate
| eq
| neq
| lt
| le
| gt
| ge
deriving Repr, Inhabited, Lean.ToExpr

def toBitVec (w : Nat) (x : BitStream) : BitVec w :=
  match w with
  | 0   => 0#0
  | w+1 => (x.toBitVec w).cons (x w)

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 concat (b : Bool) (x : BitStream) : BitStream
  | 0   => b
  | i+1 => x i

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

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 test6_before := [llvm|
{
^0(%arg103 : i64):
  %0 = llvm.mlir.constant(32 : i128) : i128
  %1 = llvm.zext %arg103 : i64 to i128
  %2 = llvm.lshr %1, %0 : i128
  %3 = llvm.trunc %2 : i128 to i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

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

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

def 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 test21_after := [llvm|
{
^0(%arg174 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.and %arg174, %0 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

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

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

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

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

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

def ult_rem_zero_before := [llvm|
{
^0(%arg174 : i8):
  %0 = llvm.mlir.constant(7 : i8) : i8
  %1 = llvm.mlir.constant(21 : i8) : i8
  %2 = llvm.mul %arg174, %0 overflow<nuw> : i8
  %3 = llvm.icmp "ult" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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 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 Reflect.Map.get (ix : ℕ) (_ : BitVec w)  (m : List (BitVec w)) : BitVec w := m[ix]!

Qq.synthInstanceQ in Qq.MetaM

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

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

def srli_i32_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := srli_llvm_i64
  rhs := srli_riscv_i64

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

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

def src_srem_shl_demand_max_mask_hit_demand_after := [llvm|
{
^0(%arg18 : i32):
  %0 = llvm.mlir.constant(4 : i32) : i32
  %1 = llvm.mlir.constant(1 : i32) : i32
  %2 = llvm.mlir.constant(-4 : i32) : i32
  %3 = llvm.srem %arg18, %0 : i32
  %4 = llvm.shl %3, %1 overflow<nsw> : i32
  %5 = llvm.and %4, %2 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

structure GenConfig where
  specialize : Bool := false

declare_config_elab elabGenConfig GenConfig

def lowmask_xor_zext_commute_before := [llvm|
{
^0(%arg219 : i8, %arg220 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mul %arg220, %arg220 : i32
  %2 = llvm.zext %arg219 : i8 to i32
  %3 = llvm.xor %1, %2 : i32
  %4 = llvm.and %3, %0 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

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

inductive ISLOp
  | regConst (r : RegIndex)
  | regRead
  | regWrite
  | bitsConst {w : Nat} (x : BitVec w)
  | bitsAdd (w : Nat)
  deriving DecidableEq, ToExpr, Repr

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 binop_left_to_zero_ashr : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      %0 = llvm.ashr %c, %x : i64
      llvm.return %0 : i64
  }]
  rhs := [LV| {
    ^entry (%x: i64):
      %c = llvm.mlir.constant (0) : i64
      llvm.return %c : 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 and_not_or_wrong_c_before := [llvm|
{
^0(%arg432 : i32, %arg433 : i32, %arg434 : i32, %arg435 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg432, %arg433 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.or %2, %arg434 : i32
  %4 = llvm.and %arg432, %arg435 : i32
  %5 = llvm.xor %4, %0 : i32
  %6 = llvm.or %5, %arg433 : i32
  %7 = llvm.and %3, %6 : i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

def bitwise_and_bitwise_and_icmps_comm3_before := [llvm|
{
^0(%arg235 : i8, %arg236 : i8, %arg237 : 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" %arg236, %0 : i8
  %4 = llvm.and %arg235, %1 : i8
  %5 = llvm.shl %1, %arg237 : i8
  %6 = llvm.and %arg235, %5 : i8
  %7 = llvm.icmp "ne" %4, %2 : i8
  %8 = llvm.icmp "ne" %6, %2 : i8
  %9 = llvm.and %7, %3 : i1
  %10 = llvm.and %8, %9 : i1
  "llvm.return"(%10) : (i1) -> ()
}
]

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

structure Item where
 name : String
 tac : Syntax

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

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

def shl_sub_lshr_reverse_no_nsw_after := [llvm|
{
^0(%arg133 : i32, %arg134 : i32, %arg135 : i32):
  %0 = llvm.lshr exact %arg135, %arg134 : i32
  %1 = llvm.sub %0, %arg133 overflow<nuw> : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def add_2_after := [llvm|
{
^0(%arg121 : i8, %arg122 : i1, %arg123 : i8, %arg124 : i8):
  %0 = llvm.mlir.constant(-124 : i8) : i8
  %1 = llvm.xor %arg124, %0 : i8
  %2 = "llvm.select"(%arg122, %arg123, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %3 = llvm.sub %2, %arg121 : i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

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

def test9_after := [llvm|
{
^0(%arg111 : i32, %arg112 : i32):
  %0 = llvm.or %arg111, %arg112 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_1_logical_after := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(9 : i32) : i32
  %2 = llvm.and %arg27, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (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 eq_21_comm_and_before := [llvm|
{
^0(%arg122 : i32, %arg123 : i32):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.mlir.constant(16 : i32) : i32
  %2 = llvm.lshr %arg122, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  %4 = llvm.lshr %arg122, %1 : i32
  %5 = llvm.trunc %4 : i32 to i8
  %6 = llvm.lshr %arg123, %0 : i32
  %7 = llvm.trunc %6 : i32 to i8
  %8 = llvm.lshr %arg123, %1 : i32
  %9 = llvm.trunc %8 : i32 to i8
  %10 = llvm.icmp "eq" %3, %7 : i8
  %11 = llvm.icmp "eq" %5, %9 : i8
  %12 = llvm.and %10, %11 : i1
  "llvm.return"(%12) : (i1) -> ()
}
]

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

partial def collectTerm (state : CollectState) (e : Expr) :
     SolverM (MultiWidth.Nondep.Term × CollectState) := do
  match_expr e with
  | BitVec.ofBool bExpr =>
      let (b, state) ← collectBoolTerm state bExpr
      return (.bvOfBool b, state)
  | BitVec.ofNat wExpr nExpr =>
    let (w, state) ← collectWidthExpr state wExpr
    if let some n ← getNatValue? nExpr then
      return (.ofNat w n, state)
    else
      mkAtom
  | HAdd.hAdd _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.add w ta tb, state)
    | _ => mkAtom
  | BitVec.zeroExtend _w v x =>
      let (v, state) ← collectWidthExpr state v
      let (x, state) ← collectTerm state x
      return (.zext x v, state)
  | BitVec.setWidth _w v x =>
      let (v, state) ← collectWidthExpr state v
      let (x, state) ← collectTerm state x
      return (.setWidth x v, state)
  | BitVec.signExtend _w v x =>
      let (v, state) ← collectWidthExpr state v
      let (x, state) ← collectTerm state x
      return (.sext x v, state)
  | HXor.hXor _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.bxor w ta tb, state)
    | _ => mkAtom
  | HAnd.hAnd _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.band w ta tb, state)
    | _ => mkAtom
  | HOr.hOr _bv _bv _bv _inst a b =>
    match_expr _bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      let (tb, state) ← collectTerm state b
      return (.bor w ta tb, state)
    | _ => mkAtom
  | Complement.complement bv _inst a =>
    match_expr bv with
    | BitVec w =>
      let (w, state) ← collectWidthExpr state w
      let (ta, state) ← collectTerm state a
      return (.bnot w ta, state)
    | _ => mkAtom
  | HShiftLeft.hShiftLeft _bv _nat _bv _inst a n =>
    match_expr _bv with
    | BitVec w =>
      match_expr _nat with
      | Nat =>
        let (w, state) ← collectWidthExpr state w
        let (ta, state) ← collectTerm state a
        if let some nn ← getNatValue? n then
          return (.shiftl w ta nn, state)
        else
          mkAtom
      | _ => mkAtom
    | _ => mkAtom
  | _ => mkAtom
  where
    mkAtom := do
      let (t, state) ← collectBVAtom state e
      return (t, state)

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

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

setOf in Mathlib.Data.Set.Defs

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

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

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

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

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

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

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

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

Lean.Elab.Term.withDeclName in Lean.Elab.Term.TermElabM

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

def test6_after := [llvm|
{
^0(%arg48 : i55):
  %0 = llvm.mlir.constant(6 : i55) : i55
  %1 = llvm.mul %arg48, %0 : i55
  "llvm.return"(%1) : (i55) -> ()
}
]

def p0_scalar_urem_by_const_before := [llvm|
{
^0(%arg20 : i32, %arg21 : i32):
  %0 = llvm.mlir.constant(128 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.mlir.constant(0 : i32) : i32
  %3 = llvm.and %arg20, %0 : i32
  %4 = llvm.urem %3, %1 : i32
  %5 = llvm.icmp "eq" %4, %2 : i32
  "llvm.return"(%5) : (i1) -> ()
}
]

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

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

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

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

def udiv_eq_big_after := [llvm|
{
^0(%arg38 : i8, %arg39 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.icmp "eq" %arg38, %0 : i8
  %3 = llvm.icmp "eq" %arg39, %1 : i8
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (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 sgt_swap_and_not_min_logical_before := [llvm|
{
^0(%arg84 : i8, %arg85 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.mlir.constant(false) : i1
  %2 = llvm.icmp "slt" %arg85, %arg84 : i8
  %3 = llvm.icmp "ne" %arg84, %0 : i8
  %4 = "llvm.select"(%2, %3, %1) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%4) : (i1) -> ()
}
]

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

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

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

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

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

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

def scalar_i32_signbit_shl_and_slt_before := [llvm|
{
^0(%arg2 : i32, %arg3 : i32):
  %0 = llvm.mlir.constant(-2147483648 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.shl %0, %arg3 : i32
  %3 = llvm.and %2, %arg2 : i32
  %4 = llvm.icmp "slt" %3, %1 : i32
  "llvm.return"(%4) : (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 test1_after := [llvm|
{
^0(%arg209 : i32):
  "llvm.return"(%arg209) : (i32) -> ()
}
]

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

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

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

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

def 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 select_sub_before := [llvm|
{
^0(%arg9 : i1, %arg10 : i17, %arg11 : i17):
  %0 = llvm.sub %arg10, %arg11 : i17
  %1 = "llvm.select"(%arg9, %0, %arg10) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i17, i17) -> i17
  "llvm.return"(%1) : (i17) -> ()
}
]

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

def parity (x : BitVec w) : BitVec 1 :=
  BitVec.ofBool ((BitVec.umod x 2#w) == 1)

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

def add_and_or_commutative_after := [llvm|
{
^0(%arg13 : i32, %arg14 : i32):
  %0 = llvm.add %arg13, %arg14 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

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

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

def lowmask_mul_zext_before := [llvm|
{
^0(%arg221 : i8, %arg222 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.zext %arg221 : i8 to i32
  %2 = llvm.mul %1, %arg222 : i32
  %3 = llvm.and %2, %0 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

def llvm_const_lower_riscv_li_46 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_46, rhs:= liRiscv_46,
   correct := by admit /- proof elided -/

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

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

private def op1 : Op φ :=
  [mlir_op| "foo"(%x, %y) : (i32, i32) -> () ]

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

Std.Format.line in Init.Data.Format.Basic

RV64.sltiu in RISCV.Instructions

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 zext_sext_add_icmp_ult_minus1_after := [llvm|
{
^0(%arg78 : i1, %arg79 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg79, %0 : i1
  %2 = llvm.or %arg78, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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

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

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

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

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

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

def and_sext_multiuse_before := [llvm|
{
^0(%arg0 : i32, %arg1 : i32, %arg2 : i32, %arg3 : i32):
  %0 = llvm.icmp "sgt" %arg0, %arg1 : i32
  %1 = llvm.sext %0 : i1 to i32
  %2 = llvm.and %1, %arg2 : i32
  %3 = llvm.and %1, %arg3 : i32
  %4 = llvm.add %2, %3 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

def MatchVar.IsMonotone (f : MatchVar Δ Γ) : Prop :=
    ∀ mapIn, ∀ mapOut ∈ f mapIn,
      mapIn.entries ⊆ mapOut.2.entries

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

def n2_after := [llvm|
{
^0(%arg0 : i8, %arg1 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.mlir.constant(-2 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.shl %0, %arg1 overflow<nsw> : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.and %arg0, %4 : i8
  %6 = llvm.icmp "eq" %5, %2 : i8
  "llvm.return"(%6) : (i1) -> ()
}
]

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

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

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

def xor_lshr_multiuse_after := [llvm|
{
^0(%arg596 : i8, %arg597 : i8, %arg598 : i8, %arg599 : i8):
  %0 = llvm.lshr %arg596, %arg599 : i8
  %1 = llvm.xor %0, %arg598 : i8
  %2 = llvm.xor %arg596, %arg597 : i8
  %3 = llvm.lshr %2, %arg599 : i8
  %4 = llvm.xor %3, %arg598 : i8
  %5 = llvm.sdiv %1, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

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

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

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

def bools2_logical_commute1_and1_and2_after := [llvm|
{
^0(%arg43 : i1, %arg44 : i1, %arg45 : i1):
  %0 = "llvm.select"(%arg45, %arg43, %arg44) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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 mkStateUniqueCircuitN {arity : Type _}
  [DecidableEq arity] [Fintype arity] [Hashable arity]
  (p : FSM arity) (n : Nat) : Circuit (Vars p.α arity n) :=
  let sn : p.α → Circuit (Vars p.α arity n) := fun s =>
    Circuit.var true (Vars.stateN s n)
  let circs := (List.range n).attach |>.map fun ⟨i, hi⟩ =>
    let si : p.α → Circuit (Vars p.α arity n) := fun s =>
      Circuit.var true (Vars.stateN s i (by admit /- proof elided -/
      ))
    (mkStateNeqCircuit p si sn)
  Circuit.bigOr circs

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

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

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

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

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

ZMod.finEquiv in Mathlib.Data.ZMod.Basic

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

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

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

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

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

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

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

structure Inputs (ι : Type) (n : Nat) : Type  where
  ix : Fin n
  input : ι
deriving DecidableEq, Hashable

def Lets.WellTyped (Γ_in : Context Ty) : UnTyped.Lets Op VarName → Context Ty → Prop
  | ⟨[]⟩, Γ_out       => Γ_out = Γ_in 
  | ⟨e :: es⟩, Γ_out  =>
      let eTy := (signature e.op).returnType
      Expr.WellTyped Γ_in e eTy ∧ Lets.WellTyped (Γ_in.push e.varName eTy) ⟨es⟩ Γ_out

instance : ToString Ty where
  toString t := repr t |>.pretty

def_signature for Comb where
  | .add w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  | .and w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  
  | .divs w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .divu w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .extract w n => (Ty.bitvec w) → (Ty.bitvec (w - n))
  | .icmp _ w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec 1)
  | .mods w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .modu w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .mul w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  | .mux w => (Ty.bitvec w, Ty.bitvec w, Ty.bitvec 1) → (Ty.bitvec w)
  | .or w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)
  | .parity w => (Ty.bitvec w) → (Ty.bitvec 1)
  | .replicate w n => (Ty.bitvec w) → (Ty.bitvec (w * n))
  | .shl w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .shlPar w _ => (Ty.bitvec w) → (Ty.bitvec w)
  | .shrs w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .shru w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .sub w => (Ty.bitvec w, Ty.bitvec w) → (Ty.bitvec w)
  | .xor w n => ${List.replicate n (Ty.bitvec w)} → (Ty.bitvec w)

def t0_after := [llvm|
{
^0(%arg30 : i1, %arg31 : i8, %arg32 : i8, %arg33 : i8, %arg34 : i8):
  %0 = llvm.icmp "ne" %arg31, %arg32 : i8
  %1 = llvm.or %0, %arg30 : i1
  %2 = "llvm.select"(%1, %arg34, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

def alive_AndOrXor_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 lshrult_01_06_after := [llvm|
{
^0(%arg361 : i4):
  %0 = llvm.mlir.constant(-4 : i4) : i4
  %1 = llvm.icmp "ult" %arg361, %0 : i4
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

@[simp_denote]
def freeze_riscv_32 := [LV| {
  ^entry (%r1: i32):
    %toRISCV = "builtin.unrealized_conversion_cast" (%r1) : (i32) -> (!i64)
    %toLLVM = "builtin.unrealized_conversion_cast" (%toRISCV) : (!i64) -> (i32)
    llvm.return %toLLVM : i32
  }]

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

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

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

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

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

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

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

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

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

def Relation.autOfRelation : Relation → CNFA 2
| .eq => CNFA.autEq
| .signed ord => CNFA.autSignedCmp ord
| .unsigned ord => CNFA.autUnsignedCmp ord

def shl_nsw_add_negative_invalid_constant3_after := [llvm|
{
^0(%arg39 : i4):
  %0 = llvm.mlir.constant(-8 : i4) : i4
  %1 = llvm.mlir.constant(2 : i4) : i4
  %2 = llvm.xor %arg39, %0 : i4
  %3 = llvm.shl %1, %2 overflow<nsw> : i4
  "llvm.return"(%3) : (i4) -> ()
}
]

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

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

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

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 positive_sameconst_shlnuwnsw_after := [llvm|
{
^0(%arg46 : i8):
  %0 = llvm.mlir.constant(-8 : i8) : i8
  %1 = llvm.and %arg46, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

def lshrugt_01_11_exact_before := [llvm|
{
^0(%arg210 : i4):
  %0 = llvm.mlir.constant(1 : i4) : i4
  %1 = llvm.mlir.constant(-5 : i4) : i4
  %2 = llvm.lshr exact %arg210, %0 : i4
  %3 = llvm.icmp "ugt" %2, %1 : i4
  "llvm.return"(%3) : (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 test3_after := [llvm|
{
^0(%arg26 : i32, %arg27 : i32):
  %0 = llvm.and %arg26, %arg27 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

@[simp_llvm_option]
def sub {w : Nat} (x y : IntW w) (flags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w := do
  let x' ← x
  let y' ← y
  if flags.nsw ∧ BitVec.ssubOverflow x' y' then
    .poison
  else if flags.nuw ∧ BitVec.usubOverflow x' y' then
    .poison
  else
    sub? x' y'

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 bools2_logical_commute0_after := [llvm|
{
^0(%arg64 : i1, %arg65 : i1, %arg66 : i1):
  %0 = "llvm.select"(%arg66, %arg64, %arg65) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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

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

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

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

def not_sub_before := [llvm|
{
^0(%arg133 : i32):
  %0 = llvm.mlir.constant(123 : i32) : i32
  %1 = llvm.mlir.constant(-1 : i32) : i32
  %2 = llvm.sub %0, %arg133 : i32
  %3 = llvm.xor %2, %1 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

    |

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

Lean.Parser.Tactic.unknown in Lean.Parser.Tactic

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

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

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

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

def Body.return : (body : Body Op Γ ty) → Var body.returnContext ty
  | ⟨⟨_, ret⟩, h⟩ => ⟨ret, by admit /- proof elided -/
  ⟩

instance : ToFormat (MLIRType φ) := ⟨repr⟩

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

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

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 test6_before := [llvm|
{
^0(%arg27 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(-1073741824) : i64
  %2 = llvm.ashr %arg27, %0 : i32
  %3 = llvm.sext %2 : i32 to i64
  %4 = llvm.add %3, %1 : i64
  "llvm.return"(%4) : (i64) -> ()
}
]

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 and_xor_or2_before := [llvm|
{
^0(%arg670 : i64, %arg671 : i64, %arg672 : i64):
  %0 = llvm.mlir.constant(42) : i64
  %1 = llvm.udiv %0, %arg670 : i64
  %2 = llvm.udiv %0, %arg671 : i64
  %3 = llvm.udiv %0, %arg672 : i64
  %4 = llvm.and %2, %1 : i64
  %5 = llvm.xor %4, %3 : i64
  %6 = llvm.or %5, %2 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

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

def trunc {w: Nat} (w': Nat) (x: IntW w) (noWrapFlags : NoWrapFlags := {nsw := false , nuw := false}) : IntW w' := do
  let x' <- x
  if noWrapFlags.nsw ∧ ((x'.truncate w').signExtend w ≠ x') then
    .poison
  else if noWrapFlags.nuw ∧ ((x'.truncate w').zeroExtend w ≠ x') then
    .poison
  else
    trunc? w' x'

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

def or_eq_notY_eq_0_before := [llvm|
{
^0(%arg45 : i8, %arg46 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.xor %arg46, %0 : i8
  %2 = llvm.or %arg45, %1 : i8
  %3 = llvm.icmp "eq" %2, %1 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

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

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

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

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

NatCast.natCast in Init.Data.Cast

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

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

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

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

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

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

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

def mkWidthFSM (wcard : Nat) (tcard : Nat) (bcard : Nat) (ncard icard : Nat) (pcard : Nat) (w : Nondep.WidthExpr) :
    (NatFSM wcard tcard bcard ncard icard pcard w) :=
  match w with
  | .const nat => {
      toFsm := (FSM.trueUptoExcluding nat).map Fin.elim0
    }
  | .var wnat =>
    if h : wnat < wcard then
      { toFsm :=
        composeUnaryAux FSM.scanAnd (FSM.var' (StateSpace.widthVar ⟨wnat, h⟩))
        
      }
    else
      { toFsm := FSM.zero' } 
  | .min v w =>
      { toFsm :=
        (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm &&& (mkWidthFSM wcard tcard bcard ncard icard pcard w).toFsm
      }
  | .max v w =>
        { toFsm :=
        (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm ||| (mkWidthFSM wcard tcard bcard ncard icard pcard w).toFsm
      }
  | .addK v k =>
    { toFsm :=
        composeUnaryAux (FSM.repeatN true k)  (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm
    }
  | .kadd k v =>
    { toFsm :=
        composeUnaryAux (FSM.repeatN true k)  (mkWidthFSM wcard tcard bcard ncard icard pcard v).toFsm
    }

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

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

def fold_add_udiv_urem_after := [llvm|
{
^0(%arg10 : i32):
  %0 = llvm.mlir.constant(10 : i32) : i32
  %1 = llvm.mlir.constant(6 : i32) : i32
  %2 = llvm.udiv %arg10, %0 : i32
  %3 = llvm.mul %2, %1 overflow<nuw> : i32
  %4 = llvm.add %3, %arg10 : 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 "ne" %2, %arg14 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

instance : MLIR.AST.TransformExpr (FHE q n) 0 where
  mkExpr := mkExpr

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

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

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

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

Sub.sub in Init.Prelude

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 sle_and_min_commute_logical_after := [llvm|
{
^0(%arg216 : i8, %arg217 : i8):
  %0 = llvm.mlir.constant(-128 : i8) : i8
  %1 = llvm.icmp "eq" %arg216, %0 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

inductive ExTy
  | nat
  | bool
  deriving DecidableEq, Repr

partial def reflectPredicateAux (exprToIx : ReflectMap) (e : Expr) (wExpected : Expr) : MetaM (ReflectResult Predicate) := do
  match_expr e with
  | Eq α a b =>
    match_expr α with
    | Nat =>
       
      
      if wExpected != a then
        throwError m!"Only Nat expressions allowed are '{wExpected} ≠ <concrete value>'. Found {indentD e}."
      let some natVal ← Lean.Meta.getNatValue? b
        | throwError m!"Expected '{wExpected} ≠ <concrete width>', found symbolic width {indentD b}."
      let out := Predicate.width .eq natVal
      return { exprToIx := exprToIx, e := out }

    | BitVec w =>
      let a ←  reflectTermUnchecked exprToIx w a
      let b ← reflectTermUnchecked a.exprToIx w b
      return { exprToIx := b.exprToIx, e := Predicate.binary .eq a.e b.e }
    | Bool =>
      
      
      
      
      let_expr true := b
        | throwError m!"only boolean conditionals allowed are 'bv.\{u,s}l\{t,e} bv = true'. Found {indentD e}."
      match_expr a with
      | BitVec.slt w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .slt a.e b.e }
      | BitVec.sle w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .sle a.e b.e }
      | BitVec.ult w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .ult a.e b.e }
      | BitVec.ule w a b =>
        let a ← reflectTermUnchecked exprToIx w a
        let b ← reflectTermUnchecked a.exprToIx w b
        return { exprToIx := b.exprToIx, e := Predicate.binary .ule a.e b.e }
      | _ =>
        throwError m!"unknown boolean conditional, expected 'bv.slt bv = true' or 'bv.sle bv = true'. Found {indentD e}"
    | _ =>
      throwError m!"unknown equality kind, expected 'bv = bv' or 'bv.slt bv = true' or 'bv.sle bv = true'. Found {indentD e}"
  | Ne α a b =>
     
    match_expr α with
    | Nat => do
      
      if wExpected != a then
        throwError m!"Only Nat expressions allowed are '{wExpected} ≠ <concrete value>'. Found {indentD e}."
      let some natVal ← Lean.Meta.getNatValue? b
        | throwError m!"Expected '{wExpected} ≠ <concrete width>', found symbolic width {indentD b}."
      let out := Predicate.width .neq natVal
      return { exprToIx := exprToIx, e := out }
    | BitVec w =>
      let a ← reflectTermUnchecked exprToIx w a
      let b ← reflectTermUnchecked a.exprToIx w b
      return { exprToIx := b.exprToIx, e := Predicate.binary .neq a.e b.e }
    | _ =>
      throwError m!"Expected typeclass to be 'BitVec w' / 'Nat', found '{indentD α}' in {e} when matching against 'Ne'"
  | LT.lt α _inst a b =>
    let_expr BitVec w := α | throwError m!"Expected typeclass to be BitVec w, found '{indentD α}' in {indentD e} when matching against 'LT.lt'"
    let a ← reflectTermUnchecked exprToIx w a
    let b ← reflectTermUnchecked a.exprToIx w b
    return { exprToIx := b.exprToIx, e := Predicate.binary .ult a.e b.e }
  | LE.le α _inst a b =>
    let_expr BitVec w := α | throwError m!"Expected typeclass to be BitVec w, found '{indentD α}' in {indentD e} when matching against 'LE.le'"
    let a ← reflectTermUnchecked exprToIx w a
    let b ← reflectTermUnchecked a.exprToIx w b
    return { exprToIx := b.exprToIx, e := Predicate.binary .ule a.e b.e }
  | Or p q =>
    let p ← reflectPredicateAux exprToIx p wExpected
    let q ← reflectPredicateAux p.exprToIx q wExpected
    let out := Predicate.lor p.e q.e
    return { q with e := out }
  | And p q =>
    let p ← reflectPredicateAux exprToIx p wExpected
    let q ← reflectPredicateAux p.exprToIx q wExpected
    let out := Predicate.land p.e q.e
    return { q with e := out }
  | _ =>
     throwError m!"expected predicate over bitvectors (no quantification), found:  {indentD e}"

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 narrow_zext_and_after := [llvm|
{
^0(%arg54 : i16, %arg55 : i32):
  %0 = llvm.trunc %arg55 : i32 to i16
  %1 = llvm.and %arg54, %0 : i16
  "llvm.return"(%1) : (i16) -> ()
}
]

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

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

Lean.Parser.Term.leading_parser in Lean.Parser.Term

def t3_before := [llvm|
{
^0(%arg40 : i32, %arg41 : i32):
  %0 = llvm.mlir.constant(32 : i32) : i32
  %1 = llvm.mlir.constant(-16 : i32) : i32
  %2 = llvm.mlir.constant(131071) : i64
  %3 = llvm.mlir.constant(0 : i32) : i32
  %4 = llvm.sub %0, %arg41 : i32
  %5 = llvm.shl %arg40, %4 : i32
  %6 = llvm.add %arg41, %1 : i32
  %7 = llvm.zext %6 : i32 to i64
  %8 = llvm.lshr %2, %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 ult_umin3_before := [llvm|
{
^0(%arg32 : i32, %arg33 : i32):
  %0 = llvm.mlir.constant(3 : i32) : i32
  %1 = llvm.add %arg32, %0 : i32
  %2 = llvm.icmp "ult" %1, %arg33 : i32
  %3 = "llvm.select"(%2, %1, %arg33) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i32, i32) -> i32
  %4 = llvm.icmp "ugt" %1, %3 : i32
  "llvm.return"(%4) : (i1) -> ()
}
]

def srl_match : List (Σ Γ, Σ ty, PeepholeRewrite LLVMPlusRiscV Γ ty) := [
  
  
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_srl_lower_riscv_exact_64),
  mkRewrite (LLVMToRiscvPeepholeRewriteRefine.toPeepholeUNSOUND llvm_srl_lower_riscv_64),
]

Lean.mkMVar in Lean.Expr

def or_simplify_ule_after := [llvm|
{
^0(%arg18 : i8, %arg19 : i8, %arg20 : i1):
  %0 = llvm.mlir.constant(-2 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.and %arg19, %0 : i8
  %3 = llvm.or %arg18, %arg19 : i8
  %4 = llvm.or %3, %1 : i8
  %5 = llvm.icmp "ule" %4, %2 : i8
  "llvm.return"(%5) : (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 rewritePeepholeRecursively (fuel : ℕ)
    (pr : PeepholeRewrite d Γ t) (target : Com d Γ₂ eff t₂) :
    { out : Com d Γ₂ eff t₂ // out.denote = target.denote } :=
  match fuel with
  | 0 => ⟨target, rfl⟩
  | fuel + 1 =>
    let target' := rewritePeephole fuel pr target
    have htarget'_denote_eq_htarget : target'.denote = target.denote := by admit /- proof elided -/

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 or_xor_commute3_before := [llvm|
{
^0(%arg162 : i32, %arg163 : i32):
  %0 = llvm.mlir.constant(42 : i32) : i32
  %1 = llvm.udiv %0, %arg162 : i32
  %2 = llvm.udiv %0, %arg163 : i32
  %3 = llvm.or %2, %1 : i32
  %4 = llvm.xor %3, %2 : i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def uge_zext_before := [llvm|
{
^0(%arg170 : i1, %arg171 : i8):
  %0 = llvm.zext %arg170 : i1 to i8
  %1 = llvm.icmp "uge" %0, %arg171 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

def test23_before := [llvm|
{
^0(%arg185 : i32, %arg186 : i32):
  %0 = llvm.xor %arg186, %arg185 : i32
  %1 = llvm.icmp "eq" %0, %arg185 : i32
  "llvm.return"(%1) : (i1) -> ()
}
]

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

def reduce_xor_common_op_commute0_before := [llvm|
{
^0(%arg10 : i4, %arg11 : i4, %arg12 : i4):
  %0 = llvm.xor %arg10, %arg11 : i4
  %1 = llvm.xor %0, %arg12 : i4
  %2 = llvm.or %1, %arg10 : i4
  "llvm.return"(%2) : (i4) -> ()
}
]

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

List.lookup in Init.Data.List.Basic

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 RawCNFA.addFinal (m : RawCNFA A) (s : State) : RawCNFA A :=
  { m with finals := m.finals.insert s }

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

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

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

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

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

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

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

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

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

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

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

def or_and_or_pat8_after := [llvm|
{
^0(%arg10 : i8, %arg11 : i8, %arg12 : i8, %arg13 : i8):
  %0 = llvm.or %arg13, %arg10 : i8
  %1 = llvm.and %0, %arg11 : i8
  %2 = llvm.or %1, %arg12 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

def shl_sub_lshr_reverse_no_nsw_before := [llvm|
{
^0(%arg133 : i32, %arg134 : i32, %arg135 : i32):
  %0 = llvm.shl %arg133, %arg134 overflow<nuw> : i32
  %1 = llvm.sub %arg135, %0 overflow<nuw> : i32
  %2 = llvm.lshr exact %1, %arg134 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

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

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

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

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

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

def CombEg4 := [Comb_com| {
  ^entry(%0: i4, %1 : i4):
    %2 = "Comb.icmp_eq" (%0, %1) : (i4, i4) -> i1
    "return" (%2) : (i1) -> ()
  }]

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

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

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

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

def toHom (d : Diff Γ₁ Γ₂) : Hom Γ₁ Γ₂ :=
  fun _ v => ⟨v.val + d.val, d.property v.property⟩

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

def Com.outContextHom (com : Com d Γ eff t) : Γ.Hom com.outContext :=
  com.outContextDiff.toHom

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

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

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

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

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

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

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

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

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

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

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

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

def bAnd : ∀ (_s : List α) (_f : α → Circuit β), Circuit β
| [], _ => tru
| a::l, f => l.foldl (λ c x => c &&& (f x)) (f a)

@[simp_denote]
def sext_llvm_i1_to_i8 := [LV| {
  ^entry (%arg: i1):
    %0 = llvm.sext %arg: i1 to i8
    llvm.return %0: i8
  }]

instance : Inhabited (Ty q n) := ⟨Ty.index⟩

RV64.sextb in RISCV.Instructions

def test19_after := [llvm|
{
^0(%arg7 : i10):
  %0 = llvm.mlir.constant(1 : i3) : i3
  %1 = llvm.mlir.constant(0 : i3) : i3
  %2 = llvm.trunc %arg7 : i10 to i3
  %3 = llvm.and %2, %0 : i3
  %4 = llvm.sub %1, %3 overflow<nsw> : i3
  %5 = llvm.sext %4 : i3 to i10
  "llvm.return"(%5) : (i10) -> ()
}
]

def one_sdiv { w : Nat} {a : BitVec w} (ha0 : a ≠ 0) (ha1 : a ≠ 1)
    (hao : a ≠ allOnes w) :
    BitVec.sdiv (1#w) a = 0#w :=

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

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

def 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 trunc_lshr_sext_wide_input_before := [llvm|
{
^0(%arg33 : i16):
  %0 = llvm.mlir.constant(9 : i32) : i32
  %1 = llvm.sext %arg33 : i16 to i32
  %2 = llvm.lshr %1, %0 : i32
  %3 = llvm.trunc %2 : i32 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

Function.Injective in Init.Data.Function

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

def Expr.changeVars (varsMap : Γ.Hom Γ') {ty} (e : Expr d Γ eff ty) :
    Expr d Γ' eff ty :=
  ⟨e.op, e.ty_eq, e.eff_le, e.args.map varsMap, e.regArgs⟩

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

def masked_icmps_mask_notallzeros_bmask_mixed_negated_swapped_6_after := [llvm|
{
^0(%arg14 : i32):
  %0 = llvm.mlir.constant(15 : i32) : i32
  %1 = llvm.mlir.constant(8 : i32) : i32
  %2 = llvm.and %arg14, %0 : i32
  %3 = llvm.icmp "ne" %2, %1 : i32
  "llvm.return"(%3) : (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 test_ne_0_and_15_add_3_before := [llvm|
{
^0(%arg2 : i8):
  %0 = llvm.mlir.constant(3 : i8) : i8
  %1 = llvm.mlir.constant(15 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.add %arg2, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.icmp "ne" %4, %2 : i8
  "llvm.return"(%5) : (i1) -> ()
}
]

Lean.ToExpr.toExpr in Lean.ToExpr

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

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

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

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

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

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

def xor_to_xor2_after := [llvm|
{
^0(%arg83 : i32, %arg84 : i32):
  %0 = llvm.xor %arg83, %arg84 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def sub_select_not_sext_before := [llvm|
{
^0(%arg20 : i1, %arg21 : i64):
  %0 = llvm.mlir.constant(64) : i64
  %1 = llvm.mlir.constant(true) : i1
  %2 = "llvm.select"(%arg20, %arg21, %0) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i64, i64) -> i64
  %3 = llvm.xor %arg20, %1 : i1
  %4 = llvm.sext %3 : i1 to i64
  %5 = llvm.sub %2, %4 : i64
  "llvm.return"(%5) : (i64) -> ()
}
]

def corec {α} {β} (s0 : β) (f : β → (Option α × β)) : Stream α :=
  Stream'.corec (f · |>.fst) (f · |>.snd) s0

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

instance : Coe (String × MLIRType φ) (AttrEntry φ) where
  coe v := AttrEntry.mk v.fst (AttrValue.type v.snd)

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

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

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

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 alive_Select_1100_src  (w : Nat)   :=
[llvm( w )| {
^bb0(%Y : _, %X : _):
  %v1 = llvm.mlir.constant 1 :  i1
  %v2 = llvm.select %v1, %X, %Y
  llvm.return %v2
}]

def icmp_ult_riscv_eq_icmp_ult_llvm_64 : LLVMPeepholeRewriteRefine 1 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64)] :=
  {lhs:= icmp_ult_llvm_64, rhs:= icmp_ult_riscv_64}

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

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

instance fpHydrableParseAndGeneralize : HydrableParseAndGeneralize ParsedFpExpr FpPredicate FpExpr where

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

List in Init.Prelude

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

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

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

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

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

RV64.mulhu in RISCV.Instructions

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

def factorize3_before := [llvm|
{
^0(%arg5 : i32, %arg6 : i32, %arg7 : i32):
  %0 = llvm.or %arg6, %arg7 : i32
  %1 = llvm.or %arg5, %0 : i32
  %2 = llvm.or %arg5, %arg7 : i32
  %3 = llvm.and %1, %2 : i32
  "llvm.return"(%3) : (i32) -> ()
}
]

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

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

def r3 : Com (.ofList [.nat, .nat]) .nat :=
  .var (cst 0) <|
  .var (add ⟨0, by admit /- proof elided -/
  ⟩ ⟨1, by admit /- proof elided -/
  ⟩) <|
  .var (add ⟨0, by admit /- proof elided -/
  ⟩ ⟨3, by admit /- proof elided -/
  ⟩) <|
  .ret ⟨0, by admit /- proof elided -/
  ⟩

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 negate_sdiv_after := [llvm|
{
^0(%arg116 : i8, %arg117 : i8):
  %0 = llvm.mlir.constant(-42 : i8) : i8
  %1 = llvm.sdiv %arg117, %0 : i8
  %2 = llvm.add %1, %arg116 : i8
  "llvm.return"(%2) : (i8) -> ()
}
]

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

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

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

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

def fold_xor_zext_icmp_after := [llvm|
{
^0(%arg91 : i64, %arg92 : i64, %arg93 : i64):
  %0 = llvm.icmp "sgt" %arg91, %arg92 : i64
  %1 = llvm.icmp "slt" %arg91, %arg93 : i64
  %2 = llvm.xor %0, %1 : i1
  %3 = llvm.zext %2 : i1 to i8
  "llvm.return"(%3) : (i8) -> ()
}
]

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

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

instance : BEq BVExpr.PackedBitVec where
  beq a b := if h : a.w = b.w then
                let b' := h ▸ b.bv
                a.bv == b'
              else
                false

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

def reduce_xor_common_op_commute0_after := [llvm|
{
^0(%arg10 : i4, %arg11 : i4, %arg12 : i4):
  %0 = llvm.xor %arg11, %arg12 : i4
  %1 = llvm.or %0, %arg10 : i4
  "llvm.return"(%1) : (i4) -> ()
}
]

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

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 shrMax (a : BitVec v) (b : BitVec w) : BitVec (max v w) :=
    a.signExtend (max v w) >>> b.signExtend (max v w)

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

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

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

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

def ashr_C1_add_A_C2_i32_before := [llvm|
{
^0(%arg77 : i32):
  %0 = llvm.mlir.constant(65535 : i32) : i32
  %1 = llvm.mlir.constant(5 : i32) : i32
  %2 = llvm.mlir.constant(6 : i32) : i32
  %3 = llvm.and %arg77, %0 : i32
  %4 = llvm.add %3, %1 : i32
  %5 = llvm.ashr %2, %4 : i32
  "llvm.return"(%5) : (i32) -> ()
}
]

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

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

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

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

def merge {Γ : Ctxt _} (a b : Var Γ (.stream r)) : Expr (Handshake) Γ .pure (.stream r)  :=
  Expr.mk
    (op := .merge r)
    (ty_eq := rfl)
    (eff_le := by admit /- proof elided -/
    )
    (args := .cons a <| .cons b <| .nil)
    (regArgs := .nil)

Sum.elim in Init.Data.Sum.Basic

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

def ugt_sext_before := [llvm|
{
^0(%arg130 : i1, %arg131 : i8):
  %0 = llvm.sext %arg130 : i1 to i8
  %1 = llvm.icmp "ugt" %0, %arg131 : i8
  "llvm.return"(%1) : (i1) -> ()
}
]

private def initialGeneralizerState (startTime timeout widthId targetWidth: Nat) (parsedLogicalExpr : ParsedFpLogicalExpr)
            : FpGeneralizerState := { startTime := startTime
                                    , widthId := widthId
                                    , timeout := timeout
                                    , processingWidth           := targetWidth
                                    , targetWidth               := targetWidth
                                    , parsedLogicalExpr       := parsedLogicalExpr
                                    , needsPreconditionsExprs   := []
                                    , visitedSubstitutions      := Std.HashSet.emptyWithCapacity
                                    }

def xori_i64_test : LLVMPeepholeRewriteRefine 64 [Ty.llvm (.bitvec 64)] where
  lhs := xori_llvm_i64
  rhs := xori_riscv_i64

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

def different_size_sext_sext_sgt_after := [llvm|
{
^0(%arg14 : i7, %arg15 : i4):
  %0 = llvm.sext %arg15 : i4 to i7
  %1 = llvm.icmp "sgt" %arg14, %0 : i7
  "llvm.return"(%1) : (i1) -> ()
}
]

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

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

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

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

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 map (f : Ty₁ → Ty₂) : Ctxt Ty₁ → Ctxt Ty₂ :=
  ofList ∘ (List.map f) ∘ toList

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 llvm_const_lower_riscv_li_23 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_23, rhs:= liRiscv_23,
   correct := by admit /- proof elided -/

instance : HydrableExistsForall ParsedBVExpr GenBVPred GenBVExpr where

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

def Term.denote {w : Nat} (t : Term) (xs : Env w) : Int :=
  t.c * t.f.denote xs

def src_is_notmask_sext_before := [llvm|
{
^0(%arg75 : i16, %arg76 : i8):
  %0 = llvm.mlir.constant(123 : i16) : i16
  %1 = llvm.mlir.constant(-8 : i8) : i8
  %2 = llvm.mlir.constant(-1 : i16) : i16
  %3 = llvm.xor %arg75, %0 : i16
  %4 = llvm.shl %1, %arg76 : i8
  %5 = llvm.sext %4 : i8 to i16
  %6 = llvm.xor %5, %2 : i16
  %7 = llvm.and %6, %3 : i16
  %8 = llvm.icmp "ule" %3, %7 : i16
  "llvm.return"(%8) : (i1) -> ()
}
]

def test4_after := [llvm|
{
^0(%arg8 : i49):
  %0 = llvm.mlir.constant(1 : i49) : i49
  %1 = llvm.or %arg8, %0 : i49
  "llvm.return"(%1) : (i49) -> ()
}
]

structure Term where
  c : Int
  f : Factor
deriving Repr

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

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

def RISCV_identity_combines: List (Σ Γ, RISCVPeepholeRewrite Γ) :=
  right_identity_zero ++ binop_same_val ++ right_identity_one ++ add_sub_reg_frags

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

def bitwise_and_logical_and_icmps_comm3_before := [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(0 : i8) : i8
  %3 = llvm.mlir.constant(false) : i1
  %4 = llvm.icmp "eq" %arg224, %0 : i8
  %5 = llvm.and %arg223, %1 : i8
  %6 = llvm.shl %1, %arg225 : i8
  %7 = llvm.and %arg223, %6 : i8
  %8 = llvm.icmp "ne" %5, %2 : i8
  %9 = llvm.icmp "ne" %7, %2 : i8
  %10 = "llvm.select"(%8, %4, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = llvm.and %9, %10 : i1
  "llvm.return"(%11) : (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 andn_or_cmp_1_logical_before := [llvm|
{
^0(%arg173 : i37, %arg174 : i37, %arg175 : i37):
  %0 = llvm.mlir.constant(42 : i37) : i37
  %1 = llvm.mlir.constant(true) : i1
  %2 = llvm.mlir.constant(false) : i1
  %3 = llvm.icmp "sgt" %arg173, %arg174 : i37
  %4 = llvm.icmp "sle" %arg173, %arg174 : i37
  %5 = llvm.icmp "ugt" %arg175, %0 : i37
  %6 = "llvm.select"(%5, %1, %3) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %7 = "llvm.select"(%4, %6, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%7) : (i1) -> ()
}
]

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

def select_icmp_x_and_8_eq_0_y_xor_8_after := [llvm|
{
^0(%arg179 : i32, %arg180 : i64):
  %0 = llvm.mlir.constant(8 : i32) : i32
  %1 = llvm.and %arg179, %0 : i32
  %2 = llvm.zext nneg %1 : i32 to i64
  %3 = llvm.xor %arg180, %2 : i64
  "llvm.return"(%3) : (i64) -> ()
}
]

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

def SimplePathOfPath.hEvalWith (this : SimplePathOfPath fsm s0 (K + 1) env) :
    fsm.evalWith s0 env (K + 1) =
    fsm.evalWith s0
      (envBitstream_set this.simplePath (this.k) (fun a => env a (K + 1))) this.k :=

def packedBitVecToSubstitutionValue (map: Std.HashMap Nat BVExpr.PackedBitVec) : Std.HashMap Nat (SubstitutionValue GenBVExpr) :=
  Std.HashMap.ofList (List.map (fun item => (item.fst, SubstitutionValue.packedBV item.snd)) map.toList)

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

def bitwise_or_logical_or_icmps_comm3_before := [llvm|
{
^0(%arg175 : i8, %arg176 : i8, %arg177 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.mlir.constant(1 : i8) : i8
  %2 = llvm.mlir.constant(0 : i8) : i8
  %3 = llvm.mlir.constant(true) : i1
  %4 = llvm.icmp "eq" %arg176, %0 : i8
  %5 = llvm.and %arg175, %1 : i8
  %6 = llvm.shl %1, %arg177 : i8
  %7 = llvm.and %arg175, %6 : i8
  %8 = llvm.icmp "eq" %5, %2 : i8
  %9 = llvm.icmp "eq" %7, %2 : i8
  %10 = "llvm.select"(%8, %3, %4) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  %11 = llvm.or %9, %10 : i1
  "llvm.return"(%11) : (i1) -> ()
}
]

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

@[simp_llvm]
def udiv? {w : Nat} (x y : BitVec w) : IntW w :=
  if y = 0 then
    .poison
  else
    .value <| x / y

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

def main7b_logical_after := [llvm|
{
^0(%arg75 : i32, %arg76 : i32, %arg77 : i32):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.and %arg75, %arg76 : i32
  %2 = llvm.icmp "ne" %arg76, %1 : i32
  %3 = llvm.and %arg75, %arg77 : i32
  %4 = llvm.icmp "ne" %arg77, %3 : 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) -> ()
}
]

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

instance [ToString α] : ToString (PoisonOr α) where
  toString
  | .poison  => "poison"
  | .value a => "(value " ++ addParenHeuristic (toString a) ++ ")"

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

Language.instMembershipList in Mathlib.Computability.Language

def test_invert_demorgan_or2_after := [llvm|
{
^0(%arg15 : i64, %arg16 : i64, %arg17 : i64):
  %0 = llvm.mlir.constant(24) : i64
  %1 = llvm.mlir.constant(60) : i64
  %2 = llvm.icmp "ult" %arg15, %0 : i64
  %3 = llvm.icmp "ult" %arg16, %1 : i64
  %4 = llvm.and %2, %3 : i1
  %5 = llvm.icmp "ult" %arg17, %1 : i64
  %6 = llvm.and %4, %5 : i1
  "llvm.return"(%6) : (i1) -> ()
}
]

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

instance : ToString FVarId where
  toString f := s! "{f.name}"

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 add_and_or_after := [llvm|
{
^0(%arg15 : i32, %arg16 : i32):
  %0 = llvm.add %arg15, %arg16 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def add_shl_same_amount_before := [llvm|
{
^0(%arg59 : i6, %arg60 : i6, %arg61 : i6):
  %0 = llvm.shl %arg59, %arg61 : i6
  %1 = llvm.shl %arg60, %arg61 : i6
  %2 = llvm.add %0, %1 : i6
  "llvm.return"(%2) : (i6) -> ()
}
]

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

def getSimpData (simpsetName : Name) : MetaM (SimpTheorems × Simprocs) := do
  let some ext ← (getSimpExtension? simpsetName)
    | throwError m!"'{simpsetName}' simp attribute not found!"
  let theorems ← ext.getTheorems
  let some ext ← (Simp.getSimprocExtension? simpsetName)
    | throwError m!"'{simpsetName}' simp attribute not found!"
  let simprocs ← ext.getSimprocs
  return (theorems, simprocs)

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

IO.userError in Init.System.IOError

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

Lean.Meta.isDefEq in Lean.Meta.Basic

def shl_and_and_before := [llvm|
{
^0(%arg172 : i8, %arg173 : i8):
  %0 = llvm.mlir.constant(4 : i8) : i8
  %1 = llvm.mlir.constant(88 : i8) : i8
  %2 = llvm.shl %arg172, %0 : i8
  %3 = llvm.shl %arg173, %0 : i8
  %4 = llvm.and %3, %1 : i8
  %5 = llvm.and %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

def bools_logical_commute3_and2_after := [llvm|
{
^0(%arg69 : i1, %arg70 : i1, %arg71 : i1):
  %0 = "llvm.select"(%arg71, %arg70, %arg69) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i1, i1) -> i1
  "llvm.return"(%0) : (i1) -> ()
}
]

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

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 select_of_truncate_rw : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 64), Ty.llvm (.bitvec 1)] where
  lhs := [LV| {
    ^entry (%cond: i1, %true_val: i64, %false_val: i64):
      %0 = llvm.select %cond, %true_val, %false_val : i64
      %1 = llvm.trunc %0 : i64 to i32
      llvm.return %1 : i32
  }]
  rhs := [LV| {
    ^entry (%cond: i1, %true_val: i64, %false_val: i64):
      %0 = llvm.trunc %true_val : i64 to i32
      %1 = llvm.trunc %false_val : i64 to i32
      %2 = llvm.select %cond, %0, %1 : i32
      llvm.return %2 : i32
  }]

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

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

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

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

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

@[match_pattern] abbrev Ty.ptr : SLLVM.Ty := .ptr

def t7_before := [llvm|
{
^0(%arg181 : i8, %arg182 : i1, %arg183 : i8):
  %0 = llvm.mlir.constant(1 : i8) : i8
  %1 = llvm.mlir.constant(0 : i8) : i8
  %2 = llvm.shl %0, %arg183 : i8
  %3 = "llvm.select"(%arg182, %1, %2) <{"fastmathFlags" = #llvm.fastmath<none>}> : (i1, i8, i8) -> i8
  %4 = llvm.sub %arg181, %3 : i8
  "llvm.return"(%4) : (i8) -> ()
}
]

def elabRegion (env : Lean.Environment) (stx : Lean.Syntax) :
    EIO ParseError (MLIR.AST.Region 0) := do
  let reg ← unsafe elabIntoEIO (α := MLIR.AST.Region 0) env region0Expr stx
  return reg

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

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

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

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

def ult_to_sgt_before := [llvm|
{
^0(%arg24 : i8, %arg25 : i8):
  %0 = llvm.mlir.constant(127 : i8) : i8
  %1 = llvm.xor %arg24, %0 : i8
  %2 = llvm.xor %arg25, %0 : i8
  %3 = llvm.icmp "ult" %1, %2 : i8
  "llvm.return"(%3) : (i1) -> ()
}
]

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

def or_and_or_pat2_before := [llvm|
{
^0(%arg34 : i8, %arg35 : i8, %arg36 : i8, %arg37 : i8):
  %0 = llvm.mlir.constant(42 : i8) : i8
  %1 = llvm.udiv %0, %arg36 : i8
  %2 = llvm.and %arg34, %arg35 : i8
  %3 = llvm.and %arg37, %arg34 : i8
  %4 = llvm.or %1, %3 : i8
  %5 = llvm.or %2, %4 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

instance [IsTrans α (· ⊑ ·)] : IsTrans (PoisonOr α) (· ⊑ ·) where
  trans a? b? c? := by admit /- proof elided -/

def uge_swap_or_max_before := [llvm|
{
^0(%arg166 : i8, %arg167 : i8):
  %0 = llvm.mlir.constant(-1 : i8) : i8
  %1 = llvm.icmp "ule" %arg167, %arg166 : i8
  %2 = llvm.icmp "eq" %arg166, %0 : i8
  %3 = llvm.or %1, %2 : i1
  "llvm.return"(%3) : (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 test_shl_nuw__nsw_is_safe_after := [llvm|
{
^0(%arg74 : i32):
  %0 = llvm.mlir.constant(0 : i32) : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

def trunc_lshr_exact_mask_before := [llvm|
{
^0(%arg9 : i8):
  %0 = llvm.mlir.constant(2 : i8) : i8
  %1 = llvm.mlir.constant(15 : i6) : i6
  %2 = llvm.lshr %arg9, %0 : i8
  %3 = llvm.trunc %2 : i8 to i6
  %4 = llvm.and %3, %1 : i6
  "llvm.return"(%4) : (i6) -> ()
}
]

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

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

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

def pb_after := [llvm|
{
^0(%arg13 : i65):
  %0 = llvm.mlir.constant(9223372036854775808 : i65) : i65
  %1 = llvm.mlir.constant(-1 : i65) : i65
  %2 = llvm.add %arg13, %0 : i65
  %3 = llvm.icmp "sgt" %2, %1 : i65
  "llvm.return"(%3) : (i1) -> ()
}
]

@[simp_denote]
def sltu_riscv :=
  [LV| {
    ^entry (%arg0: i16, %arg1: i16):
    %a0 = "builtin.unrealized_conversion_cast" (%arg0) : (i16) -> (!i64)
    %a1 = "builtin.unrealized_conversion_cast" (%arg1) : (i16) -> (!i64)
    %0 = li (149595403036) : !i64 
    %1 = "lui" (%0) {imm = 16 : !i64} : (!i64) -> (!i64)
    %2 = "addi" (%1) {imm = -1 : !i64} : (!i64) -> (!i64)
    %3 = and %2, %a1 : !i64
    %4 = and %2, %a0 : !i64
    %5 = sltu %4, %3 : !i64
    %6 = "builtin.unrealized_conversion_cast" (%5) : (!i64) -> (i16)
    llvm.return %6 :i16
  }]

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

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

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

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

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

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

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

def test5_before := [llvm|
{
^0(%arg4 : i32):
  %0 = llvm.mlir.constant(16 : i32) : i32
  %1 = llvm.shl %arg4, %0 : i32
  %2 = llvm.ashr %1, %0 : i32
  "llvm.return"(%2) : (i32) -> ()
}
]

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

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

def test11_before := [llvm|
{
^0(%arg30 : i23):
  %0 = llvm.mlir.constant(3 : i23) : i23
  %1 = llvm.mlir.constant(11 : i23) : i23
  %2 = llvm.mlir.constant(12 : i23) : i23
  %3 = llvm.mul %arg30, %0 : i23
  %4 = llvm.lshr %3, %1 : i23
  %5 = llvm.shl %4, %2 : i23
  "llvm.return"(%5) : (i23) -> ()
}
]

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

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

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

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

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

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

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

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

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

Union in Init.Core

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

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

def llvm_const_lower_riscv_li_31 : LLVMPeepholeRewriteRefine 64 [] :=
  {lhs := constLLVM_31, rhs:= liRiscv_31,
   correct := by admit /- proof elided -/

def changeBVExprWidth (bvExpr: GenBVExpr w) (target: Nat) : GenBVExpr target := Id.run do
  if h : w = target then
    return (h ▸ bvExpr)

  match bvExpr with
  | .var idx => (GenBVExpr.var idx : GenBVExpr target)
  | .const val => GenBVExpr.const (val.signExtend target)
  | .extract start len expr => GenBVExpr.extract start target (changeBVExprWidth expr (start + target))
  | .bin lhs op rhs => GenBVExpr.bin (changeBVExprWidth lhs target) op (changeBVExprWidth rhs target)
  | .un op operand => GenBVExpr.un op (changeBVExprWidth operand target)
  | .shiftLeft lhs rhs =>  GenBVExpr.shiftLeft (changeBVExprWidth lhs target)  (changeBVExprWidth rhs target)
  | .shiftRight lhs rhs =>  GenBVExpr.shiftRight (changeBVExprWidth lhs target) (changeBVExprWidth rhs target)
  | .arithShiftRight lhs rhs => GenBVExpr.arithShiftRight (changeBVExprWidth lhs target) (changeBVExprWidth rhs target)
  | .signExtend v expr => GenBVExpr.signExtend target (changeBVExprWidth expr target)
  | .zeroExtend v expr => GenBVExpr.zeroExtend target (changeBVExprWidth expr target)
  | .truncate v expr => GenBVExpr.truncate target (changeBVExprWidth expr target)
  | _ => GenBVExpr.const (BitVec.zero target)

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 foo1_and_signbit_lshr_without_shifting_signbit_before := [llvm|
{
^0(%arg118 : i32, %arg119 : i32, %arg120 : i32):
  %0 = llvm.mlir.constant(1 : i32) : i32
  %1 = llvm.mlir.constant(0 : i32) : i32
  %2 = llvm.mlir.constant(-1 : i32) : i32
  %3 = llvm.shl %0, %arg119 : i32
  %4 = llvm.and %3, %arg118 : i32
  %5 = llvm.icmp "eq" %4, %1 : i32
  %6 = llvm.shl %arg118, %arg120 : i32
  %7 = llvm.icmp "sgt" %6, %2 : i32
  %8 = llvm.or %5, %7 : i1
  "llvm.return"(%8) : (i1) -> ()
}
]

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

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

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

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

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

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

def test19_after := [llvm|
{
^0(%arg13 : i1, %arg14 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg13, %arg14 : i1
  %2 = llvm.xor %1, %0 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

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 shl_lshr_pow2_not_const_case2_before := [llvm|
{
^0(%arg71 : i16):
  %0 = llvm.mlir.constant(16 : i16) : i16
  %1 = llvm.mlir.constant(3 : i16) : i16
  %2 = llvm.mlir.constant(8 : i16) : i16
  %3 = llvm.shl %0, %arg71 : i16
  %4 = llvm.lshr %3, %1 : i16
  %5 = llvm.and %4, %2 : i16
  %6 = llvm.xor %5, %2 : i16
  "llvm.return"(%6) : (i16) -> ()
}
]

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

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

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

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

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

inductive AffineMap
  | mk: AffineTuple -> AffineTuple -> AffineMap
  deriving DecidableEq, Repr

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

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

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

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

@[inline]
def CNFA.proj (m: CNFA n2) (f : Fin n1 → Fin n2) : CNFA n1 :=
  ⟨m.m.proj f, m.m.proj_wf m.wf⟩

def lshr_shl_eq_amt_multi_use_before := [llvm|
{
^0(%arg5 : i43):
  %0 = llvm.mlir.constant(23 : i43) : i43
  %1 = llvm.lshr %arg5, %0 : i43
  %2 = llvm.shl %1, %0 : i43
  %3 = llvm.mul %1, %2 : i43
  "llvm.return"(%3) : (i43) -> ()
}
]

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

def test25_before := [llvm|
{
^0(%arg271 : i32):
  %0 = llvm.mlir.constant(50 : i32) : i32
  %1 = llvm.mlir.constant(100 : i32) : i32
  %2 = llvm.icmp "sge" %arg271, %0 : i32
  %3 = llvm.icmp "slt" %arg271, %1 : i32
  %4 = llvm.and %2, %3 : i1
  "llvm.return"(%4) : (i1) -> ()
}
]

def sub_sext_mask1_trunc_lshr_after := [llvm|
{
^0(%arg16 : i64):
  %0 = llvm.mlir.constant(48) : i64
  %1 = llvm.mlir.constant(63) : i64
  %2 = llvm.mlir.constant(10 : i8) : i8
  %3 = llvm.shl %arg16, %0 : i64
  %4 = llvm.ashr %3, %1 : i64
  %5 = llvm.trunc %4 overflow<nsw> : i64 to i8
  %6 = llvm.add %5, %2 overflow<nsw> : i8
  %7 = llvm.zext %6 : i8 to i32
  "llvm.return"(%7) : (i32) -> ()
}
]

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

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

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

@[reducible]
instance : DialectSignature Tensor2D where
  signature op := { sig := op.sig, regSig := op.regSig, returnTypes := [op.outTy] }

Fin.instOfNat in Init.Data.Fin.Basic

Std.HashSet.ofList in Std.Data.HashSet.Basic

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

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

def Vars.format (fσ : σ → Format) (fι : ι → Format) {n : Nat} (v : Vars σ ι n) : Format :=
  match v with
  | .state ss => ss.format fσ
  | .inputs is => is.format fι
  | .outputs os => f!"{os}"

def zext_sext_add_icmp_eq_1_after := [llvm|
{
^0(%arg72 : i1, %arg73 : i1):
  %0 = llvm.mlir.constant(true) : i1
  %1 = llvm.xor %arg73, %0 : i1
  %2 = llvm.and %arg72, %1 : i1
  "llvm.return"(%2) : (i1) -> ()
}
]

def or_not_xor_common_op_commute3_after := [llvm|
{
^0(%arg98 : i8, %arg99 : i8, %arg100 : i8):
  %0 = llvm.mlir.constant(0 : i8) : i8
  %1 = llvm.mlir.constant(-1 : i8) : i8
  %2 = llvm.sub %0, %arg100 : i8
  %3 = llvm.and %arg98, %arg99 : i8
  %4 = llvm.xor %3, %1 : i8
  %5 = llvm.or %4, %2 : i8
  "llvm.return"(%5) : (i8) -> ()
}
]

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

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

def llvm_sub_nsw_nuw_lower_riscv_16: LLVMPeepholeRewriteRefine 16 [Ty.llvm (.bitvec 16), Ty.llvm (.bitvec 16)] where
  lhs := llvm_sub_nsw_nuw_16
  rhs := sub_riscv_16

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 pruneEquivalentBVLogicalExprs(expressions : List (BoolExpr GenBVPred)) :
    GeneralizerStateM ParsedBVExpr GenBVPred (List (BoolExpr GenBVPred)) := do
  withTraceNode `Generalize (fun _ => return "Pruned equivalent bvLogicalExprs") do
    let mut pruned: List (BoolExpr GenBVPred) := []
    
    for expr in expressions do
      if pruned.isEmpty then
        pruned := expr :: pruned
        continue
      let newConstraints := pruned.map (fun f =>  BoolExpr.not (BoolExpr.gate Gate.beq f expr))
      let subsumeCheckExpr :=  bigAnd newConstraints

      if let some _ ← solve subsumeCheckExpr then
        pruned := expr :: pruned

    logInfo m! "Removed {expressions.length - pruned.length} expressions after pruning"
    pure pruned

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

def llvm_add_lower_riscv_nuw_nsw_flag_32 : LLVMPeepholeRewriteRefine 32 [Ty.llvm (.bitvec 32), Ty.llvm (.bitvec 32)]
where
  lhs:= add_llvm_nsw_nuw_flags_32
  rhs:= add_riscv_32

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

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

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

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

def shl_lshr_and_exact_after := [llvm|
{
^0(%arg88 : i32, %arg89 : i32, %arg90 : i32):
  %0 = llvm.lshr %arg90, %arg89 : i32
  %1 = llvm.and %0, %arg88 : i32
  "llvm.return"(%1) : (i32) -> ()
}
]

def not_signbit_zext_before := [llvm|
{
^0(%arg17 : i16):
  %0 = llvm.mlir.constant(-1 : i16) : i16
  %1 = llvm.mlir.constant(15 : i16) : i16
  %2 = llvm.xor %arg17, %0 : i16
  %3 = llvm.lshr %2, %1 : i16
  %4 = llvm.zext %3 : i16 to i32
  "llvm.return"(%4) : (i32) -> ()
}
]

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

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

def shl_mul_mask_after := [llvm|
{
^0(%arg1 : i32):
  %0 = llvm.mlir.constant(255 : i32) : i32
  %1 = llvm.mlir.constant(65537 : i32) : i32
  %2 = llvm.mlir.constant(8 : i32) : i32
  %3 = llvm.and %arg1, %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 not_or_or_and_no_and_commute1_before := [llvm|
{
^0(%arg112 : i32, %arg113 : i32, %arg114 : i32):
  %0 = llvm.mlir.constant(-1 : i32) : i32
  %1 = llvm.and %arg112, %arg113 : i32
  %2 = llvm.xor %1, %0 : i32
  %3 = llvm.xor %arg112, %0 : i32
  %4 = llvm.or %3, %arg113 : i32
  %5 = llvm.or %4, %arg114 : i32
  %6 = llvm.and %5, %2 : i32
  "llvm.return"(%6) : (i32) -> ()
}
]

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

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

def and_to_xor1_after := [llvm|
{
^0(%arg119 : i32, %arg120 : i32):
  %0 = llvm.xor %arg119, %arg120 : i32
  "llvm.return"(%0) : (i32) -> ()
}
]

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

def hasType (Γ : Context Ty) (v : VarName) (ty : Ty) : Prop :=
  Γ.lookup v = some ty

def lshr_32_add_not_known_32_leading_zeroes_before := [llvm|
{
^0(%arg13 : i64, %arg14 : i64):
  %0 = llvm.mlir.constant(8589934591) : i64
  %1 = llvm.mlir.constant(4294967295) : i64
  %2 = llvm.mlir.constant(32) : i64
  %3 = llvm.and %arg13, %0 : i64
  %4 = llvm.and %arg14, %1 : i64
  %5 = llvm.add %3, %4 : i64
  %6 = llvm.lshr %5, %2 : i64
  "llvm.return"(%6) : (i64) -> ()
}
]

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

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

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

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

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

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

def test2_before := [llvm|
{
^0(%arg11 : i47):
  %0 = llvm.mlir.constant(-70368744177664 : i47) : i47
  %1 = llvm.xor %arg11, %0 : i47
  %2 = llvm.add %1, %0 : i47
  "llvm.return"(%2) : (i47) -> ()
}
]

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

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

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

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

def printException : Except Exception α → IO String
  | Except.ok _ => throw <| IO.userError "printException called on Except.ok"
  | Except.error e => e.toMessageData.toString

abbrev DC : Dialect where
  Op := Op
  Ty := Ty

def_signature for DC where
  | .fst => (Ty.tokenstream2) → (Ty.tokenstream)
  | .fstVal t => (Ty.valuetokenstream t) → Ty.valuestream t
  | .fstVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .snd => (Ty.tokenstream2) → (Ty.tokenstream)
  | .pair w => (Ty.valuestream w, Ty.valuestream w) → Ty.valuestream2 w
  | .sndVal t => (Ty.valuetokenstream t) → Ty.tokenstream
  | .sndVal' t => (Ty.variadicvaluetokenstream t) → Ty.valuestream t
  | .tokVal' t => (Ty.variadicvaluetokenstream t) → Ty.tokenstream
  | .merge => (Ty.tokenstream, Ty.tokenstream) → Ty.valuestream 1
  | .branch => (Ty.valuestream 1) → Ty.tokenstream2
  | .fork => (Ty.tokenstream) → Ty.tokenstream2
  | .join => (Ty.tokenstream, Ty.tokenstream) → Ty.tokenstream
  | .select => (Ty.tokenstream, Ty.tokenstream, Ty.valuestream 1) → Ty.tokenstream
  | .sink => (Ty.tokenstream) → Ty.tokenstream
  | .source => () → Ty.tokenstream
  | .pack t => (Ty.valuestream t, Ty.tokenstream) → Ty.valuestream t
  | .pack2 t => (Ty.variadicvaluetokenstream t) → Ty.valuestream2 t
  | .unpack t => (Ty.valuestream t) → Ty.valuetokenstream t
  | .unpack2 t => (Ty.valuestream t, Ty.valuestream t) → Ty.variadicvaluetokenstream t

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

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

def t1_flags_nuw_nsw_second_after := [llvm|
{
^0(%arg30 : i8, %arg31 : i8, %arg32 : i8):
  %0 = llvm.add %arg31, %arg32 : i8
  %1 = llvm.sub %arg30, %0 : i8
  "llvm.return"(%1) : (i8) -> ()
}
]

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

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

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

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

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

def test20_before := [llvm|
{
^0(%arg2 : i33, %arg3 : i33):
  %0 = llvm.sub %arg2, %arg3 : i33
  %1 = llvm.icmp "ne" %0, %arg2 : i33
  "llvm.return"(%1) : (i1) -> ()
}
]

inductive NatPredicate (wcard : Nat) : Type
| eq : WidthExpr wcard → WidthExpr wcard → NatPredicate wcard

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

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

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

structure RawCNFA.SimulFun (m : RawCNFA A) (M : NFA A Q) (f : m.states ≃ Q)  where
  accept {q} : ((f.invFun q).val ∈ m.finals ↔ q ∈ M.accept)
  initial {q} : q ∈ M.start ↔ (f.invFun q).val ∈ m.initials
  trans_match {a q q'} : q' ∈ M.step q a ↔ (f.invFun q').val ∈ m.tr (f.invFun q) a

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

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

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

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

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

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

def tail : Stream α → Stream α := Stream'.tail
</all_available_defs>

<all_available_lemmas>
BitVec.lt_def in Init.Data.BitVec.Lemmas
BitVec.of_length_zero in Init.Data.BitVec.Lemmas
BitVec.ult_eq_not_carry in Init.Data.BitVec.Bitblast
BitVec.eq_of_getLsbD_eq in Init.Data.BitVec.Bootstrap
Bool.not_eq_false in Init.SimpLemmas
BitVec.eq_of_toInt_eq in Init.Data.BitVec.Lemmas
Bool.false_eq_true in Init.Data.Bool
Bool.not_eq_true in Init.SimpLemmas
Bool.not_false in Init.SimpLemmas
Bool.not_true in Init.SimpLemmas
decide_false in Init.Core
decide_true in Init.Core
true_and in Init.SimpLemmas
BitVec.neg_one_eq_allOnes in Init.Data.BitVec.Lemmas
Bool.true_and in Init.SimpLemmas
BitVec.msb_eq_getLsbD_last in Init.Data.BitVec.Lemmas
BitVec.le_def in Init.Data.BitVec.Lemmas
BitVec.slt_eq_ult in Init.Data.BitVec.Lemmas

@[simp] theorem subAux_eq_BitVec_carry (a b : BitStream) (w i : Nat) (hi : i < w) :
    (a.subAux b i).2 = !(BitVec.carry (i + 1) (a.toBitVec w) ((~~~b).toBitVec w) true)

theorem scanOr_true_iff (s : BitStream) (n : Nat)
    : s.scanOr n = true ↔ ∃ (i : Nat), (i ≤ n) ∧ s i = true

theorem scanOr_false_iff (s : BitStream) (n : Nat) : s.scanOr n = false ↔ ∀ (i : Nat), (hi : i ≤ n) → s i = false

@[simp]
theorem scanOr_succ (s : BitStream) : scanOr s (n+1) = ((s.scanOr n) || s (n + 1))

theorem scanAnd_true_iff (s : BitStream) (n : Nat) :
    s.scanAnd n = true ↔ ∀ (i : Nat), (hi : i ≤ n) → s i = true

@[simp] theorem scanAnd_succ (s : BitStream) : scanAnd s (n+1) = ((s.scanAnd n) && s (n + 1))

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

@[simp] theorem and_eq : (x &&& y) i = (x i && y i)

@[simp] theorem getLsbD_toBitVec (w : Nat) (x : BitStream) :
    (x.toBitVec w).getLsbD i = ((decide (i < w)) && x i)

@[simp] theorem xor_eq : (x ^^^ y) i = (xor (x i) (y i))

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

theorem lshrugt_01_09_proof : lshrugt_01_09_before ⊑ lshrugt_01_09_after

theorem lshr_pow2_sgt_thm (e : IntW 8) :
  icmp IntPred.sgt (lshr (const? 8 (-128)) e) (const? 8 3) ⊑
    icmp IntPred.sgt (lshr (const? 8 (-128)) e { «exact» := true }) (const? 8 3)

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

theorem uadd_sat_via_add_nonstrict_proof : uadd_sat_via_add_nonstrict_before ⊑ uadd_sat_via_add_nonstrict_after

theorem lshr_16_add_not_known_16_leading_zeroes_proof : lshr_16_add_not_known_16_leading_zeroes_before ⊑ lshr_16_add_not_known_16_leading_zeroes_after

theorem logical_or_bitwise_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 → True ∧ 1#8 <<< x_1 >>> x_1 ≠ 1#8 ∨ x_1 ≥ ↑8 → False

theorem test_proof : test_before ⊑ test_after

theorem trunc_shl_shl_var_proof : trunc_shl_shl_var_before ⊑ trunc_shl_shl_var_after

theorem p0_proof : p0_before ⊑ p0_after

theorem test12_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x &&& BitVec.ofInt 32 (-4) == intMin 32 && 2#32 == -1) = true →
    (x &&& BitVec.ofInt 32 (-4)).srem 2#32 = 0#32

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

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 land_bor_left1_thm (e e_1 : IntW 1) : LLVM.or (select e_1 e (const? 1 0)) e_1 ⊑ e_1

theorem not_invert_signbit_splat_mask1_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (zext 16 (LLVM.xor (ashr e_1 (const? 8 7)) (const? 8 (-1)))) e ⊑
    LLVM.and e (zext 16 (sext 8 (icmp IntPred.sgt e_1 (const? 8 (-1)))))

theorem ashr_xor_proof : ashr_xor_before ⊑ ashr_xor_after

theorem evalWith_succ_eq_evalWith_delta' (p : FSM arity) (carryState : p.α → Bool)
      (x : arity → BitStream) :
  p.evalWith carryState x (n + 1) =
  p.evalWith (p.delta' carryState (fun s => x s 0)) (fun s i => x s (i + 1)) n

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

theorem zext_sext_eq_known_nonneg_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬1#8 ≥ ↑8 → ofBool (zeroExtend 32 (x_1 >>> 1#8) == signExtend 32 x) = ofBool (x_1 >>> 1#8 == x)

theorem shl_nsw_nuw_add_proof : shl_nsw_nuw_add_before ⊑ shl_nsw_nuw_add_after

theorem e_2142 :
     - 2 * (d &&& (e ^^^ f)) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) - 6 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 2 * ( ~~~d &&& ( ~~~e ||| f)) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) - 1 *  ~~~( ~~~d &&& (e &&& f)) - 2 * ( ~~~e &&& (d ^^^ f)) - 2 *  ~~~(d ||| (e &&& f)) - 11 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 2 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) - 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 11 * ( ~~~e |||  ~~~(d ^^^ f)) + 4 * (e &&&  ~~~(d &&&  ~~~f)) - 1 *  ~~~(d &&& (e ||| f)) + 3 * (f ^^^  ~~~(d &&& (e &&& f))) + 2 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 *  ~~~f - 5 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 7 * (e ^^^ (d &&& f)) + 3 * ( ~~~d ||| ( ~~~e ||| f)) + 3 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) - 11 *  ~~~(e ^^^ f) + 4 * (e ^^^  ~~~(d &&&  ~~~f)) + 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * ((d &&& e) ^^^ (e |||  ~~~f)) - 2 *  ~~~d - 6 * (d &&& f) + 1 * ((d &&& f) ^^^ (e ||| f)) + 2 * ( ~~~(d &&& e) &&& (d ^^^ (e ^^^ f))) + 3 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 2 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 4 * (f ^^^  ~~~(d |||  ~~~e)) + 1 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 3 * ((d &&& e) ^^^ (e ||| f)) + 5 * ( ~~~d ||| (e ||| f)) - 11 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) + 2 * (e |||  ~~~(d |||  ~~~f)) + 24 *  ~~~(d ||| (e ||| f)) - 17 *  ~~~(d ||| ( ~~~e ||| f)) + 37 *  ~~~( ~~~d ||| (e ||| f)) + 26 * ( ~~~d &&& ( ~~~e &&& f)) - 8 * ( ~~~d &&& (e &&& f)) + 7 * (d &&& ( ~~~e &&& f)) + 18 * (d &&& (e &&& f)) =  - 7 * (f |||  ~~~(d |||  ~~~e)) - 1 * (e |||  ~~~(d ||| f))

theorem icmp_eq_or_z_or_pow2orz_fail_logic_or_proof : icmp_eq_or_z_or_pow2orz_fail_logic_or_before ⊑ icmp_eq_or_z_or_pow2orz_fail_logic_or_after

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

theorem eq1 : ∀ (w : Nat) (a : BitVec w), a = a

theorem sdiv_icmp3_thm (e : IntW 64) :
  icmp IntPred.eq (LLVM.sdiv e (const? 64 5) { «exact» := true }) (const? 64 (-1)) ⊑
    icmp IntPred.eq e (const? 64 (-5))

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

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

theorem select_replace_nested_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ¬ofBool (x_1 == 0#32) = 1#1 → x = x + 0#32

theorem ashrsgt_03_13_exact_proof : ashrsgt_03_13_exact_before ⊑ ashrsgt_03_13_exact_after

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

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

theorem shl_xor_xor_bad_mask_distribute_thm (e e_1 : IntW 8) :
  LLVM.xor (shl e_1 (const? 8 1)) (LLVM.xor (shl e (const? 8 1)) (const? 8 (-68))) ⊑
    LLVM.xor (shl (LLVM.xor e e_1) (const? 8 1)) (const? 8 (-68))

theorem main7f_logical_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 32),
  ¬ofBool (x_2 &&& x_1 == x &&& (x_2 &&& x_1)) = 1#1 →
    ¬ofBool (x_2 &&& x_1 != x &&& (x_2 &&& x_1)) = 1#1 → ¬0#1 = 1#1 → False

theorem e_2271 :
    3 *  ~~~(d ||| ( ~~~e &&& f)) - 1 * ((d ^^^ e) &&& (d ^^^ f)) - 2 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 6 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 1 * (f ^^^ (d &&& e)) - 11 *  ~~~(d ||| e) - 6 * (e ||| (d &&&  ~~~f)) + 7 * (d ^^^ e) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 7 * (f ^^^ (d ||| (e ||| f))) - 5 * ( ~~~(d ^^^ e) &&& (d ^^^ f)) + 2 * ( ~~~d ||| (e &&& f)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 2 * ((d &&& e) |||  ~~~(e |||  ~~~f)) + 4 * (f ^^^ (d ||| (e &&& f))) + 5 * (d &&& (e ^^^ f)) - 3 *  ~~~( ~~~d ||| (e &&& f)) - 1 * (e ^^^  ~~~(d ||| f)) - 2 * ((e &&& f) ||| (d &&& (e ||| f))) + 4 * ((d &&& e) ||| (e ^^^ f)) - 5 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^  ~~~(d &&& (e ||| f))) - 11 *  ~~~(d &&&  ~~~d) + 11 * (f ^^^ (d &&&  ~~~e)) - 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 7 * (d ||| (e ||| f)) + 1 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * ( ~~~e ||| (d ^^^ f)) + 2 * (e ^^^ (d ||| f)) - 2 * (f ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 1 * (e |||  ~~~f) + 7 *  ~~~( ~~~d ||| (e ^^^ f)) - 6 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) - 5 * ((d &&& e) ^^^ (e ||| f)) - 7 * (e |||  ~~~(d ^^^ f)) - 3 * (f ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * ((d ^^^ e) ||| (d ^^^ f)) + 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 7 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) + 1 *  ~~~(d |||  ~~~f) + 5 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 5 * (e &&& f) - 1 *  ~~~( ~~~d &&& (e ^^^ f)) - 6 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 7 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 *  ~~~(d ||| (e &&& f)) - 2 * (d &&& e) + 1 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 4 * (f &&& (d ||| e)) + 2 * (e |||  ~~~(d |||  ~~~f)) + 28 *  ~~~(d ||| (e ||| f)) + 14 *  ~~~( ~~~d ||| (e ||| f)) + 43 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 35 * ( ~~~d &&& ( ~~~e &&& f)) + 39 * ( ~~~d &&& (e &&& f)) + 43 * (d &&& ( ~~~e &&& f)) + 40 * (d &&& (e &&& f)) =  - 25 *  ~~~(d ||| ( ~~~e ||| f)) + 5 * (d &&& ( ~~~e ||| f))

theorem lshrult_01_13_proof : lshrult_01_13_before ⊑ lshrult_01_13_after

theorem udiv_icmp2_proof : udiv_icmp2_before ⊑ udiv_icmp2_after

theorem e_967 :
     - 1 *  ~~~(z ^^^ t) - 5 * (z ||| t) - 6 *  ~~~t + 2 *  ~~~(z &&&  ~~~z) + 3 *  ~~~(z ||| t) + 1 *  ~~~(z |||  ~~~t) + 4 * (z &&& t) =  - 2 *  ~~~z - 9 * (z &&&  ~~~t)

theorem alive_AndOrXor_2430 : alive_AndOrXor_2430_src ⊑ alive_AndOrXor_2430_tgt

theorem e_939 :
    7 *  ~~~(z &&&  ~~~z) + 2 *  ~~~(z ^^^ t) - 1 * (z ||| t) - 9 *  ~~~(z ||| t) - 6 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) = 8 * (z &&& t)

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

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

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

theorem lshrult_03_12_thm (e : IntW 4) : icmp IntPred.ult (lshr e (const? 4 3)) (const? 4 (-4)) ⊑ const? 1 1

theorem add_smin_simplify_proof : add_smin_simplify_before ⊑ add_smin_simplify_after

theorem add_select_sext_proof : add_select_sext_before ⊑ add_select_sext_after

theorem ofBitVecSext_add_eq_ofBitVecSext_add_ofBitVecSext
    (x y : BitVec w) (i : Nat) (hi : i < w):
    (ofBitVecSext (x + y)) i =
    ((ofBitVecSext x) + (ofBitVecSext y)) i

theorem shl1_nsw_not_exact_thm (e e_1 : IntW 8) :
  LLVM.sdiv e_1 (shl (const? 8 1) e { «nsw» := true, «nuw» := false }) ⊑
    LLVM.sdiv e_1 (shl (const? 8 1) e { «nsw» := true, «nuw» := true })

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

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

theorem t0_exact_proof : t0_exact_before ⊑ t0_exact_after

theorem icmp_eq_mul_nsw_nonequal_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(True ∧ x_1.smulOverflow x = true ∨ True ∧ (x_1 + 1#8).smulOverflow x = true) →
    ofBool (x_1 * x == (x_1 + 1#8) * x) = ofBool (x == 0#8)

theorem neg_slt_0_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (0#8 - x <ₛ 0#8) = ofBool (-1#8 <ₛ x + -1#8)

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

theorem foo1_proof : foo1_before ⊑ foo1_after

theorem t1_flags_nuw_second_proof : t1_flags_nuw_second_before ⊑ t1_flags_nuw_second_after

theorem test16_thm.extracted_1._1 : ∀ (x : BitVec 32), ¬x = 0 → ofBool (4#32 / x <ᵤ -1#32) = 1#1

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 xor_icmp_true_unsigned_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (5#32 <ᵤ x) ^^^ ofBool (x <ᵤ 6#32) = 1#1

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

theorem t0_proof : t0_before ⊑ t0_after

theorem bv_AndOrXor_1705 :
    ∀ (e e_1 : LLVM.IntW w),
      LLVM.or (LLVM.icmp LLVM.IntPred.eq e_1 (LLVM.const? w 0)) (LLVM.icmp LLVM.IntPred.ugt e_1 e) ⊑
        LLVM.icmp LLVM.IntPred.uge (LLVM.add e_1 (LLVM.const? w (-1))) e

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

theorem sge_to_ult_proof : sge_to_ult_before ⊑ sge_to_ult_after

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

theorem src_is_mask_shl_lshr_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬x ≥ ↑8 →
      ofBool (0#8 != (x_1 ^^^ 123#8) &&& ((-1#8) <<< x >>> x ^^^ -1#8)) = ofBool ((-1#8) >>> x <ᵤ x_1 ^^^ 122#8)

theorem bool_eq0_logical_thm (e : IntW 64) :
  select (icmp IntPred.sgt e (const? 64 0))
      (icmp IntPred.eq (icmp IntPred.eq e (const? 64 1)) (const? 1 0)) (const? 1 0) ⊑
    icmp IntPred.sgt e (const? 64 1)

theorem demorgan_nor_use2b_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x * 23#8 == 0 || 8 != 1 && (x_1 ^^^ -1#8 ||| x) ^^^ -1#8 == intMin 8 && x * 23#8 == -1) = true →
    (x * 23#8 == 0 || 8 != 1 && x_1 &&& (x ^^^ -1#8) == intMin 8 && x * 23#8 == -1) = true → False

theorem ashrsgt_01_04_proof : ashrsgt_01_04_before ⊑ ashrsgt_01_04_after

theorem xor_of_icmps_to_ne_proof : xor_of_icmps_to_ne_before ⊑ xor_of_icmps_to_ne_after

theorem signed_sign_bit_extract_trunc_proof : signed_sign_bit_extract_trunc_before ⊑ signed_sign_bit_extract_trunc_after

theorem test7_thm (e : IntW 47) : LLVM.and (ashr e (const? 47 39)) (const? 47 255) ⊑ lshr e (const? 47 39)

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

theorem or_logic_or_logic_and_2_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ||

theorem ashrslt_01_10_proof : ashrslt_01_10_before ⊑ ashrslt_01_10_after

@[simp] theorem le_refl (e : EffectKind) : e ≤ e

theorem subAux_inductive_lemma (i : Nat) :
    a.subAux b i = ⟨(a.addAux b.neg i).1, subCarries? a b i⟩

theorem OrZextOr_thm.extracted_1._1 : ∀ (x : BitVec 3), zeroExtend 5 (x ||| 3#3) ||

theorem test_sub_4_Y_ne_4_thm.extracted_1._1 : ∀ (x : BitVec 8), ofBool (4#8 - x != 4#8) = ofBool (x != 0#8)

theorem reassoc_x2_add_nuw_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ x_1.uaddOverflow 4#32 = true ∨
        True ∧ x.uaddOverflow 8#32 = true ∨ True ∧ (x_1 + 4#32).uaddOverflow (x + 8#32) = true) →
    ¬(True ∧ x_1.uaddOverflow x = true ∨ True ∧ (x_1 + x).uaddOverflow 12#32 = true) →
      x_1 + 4#32 + (x + 8#32) = x_1 + x + 12#32

theorem tryFactorization_add_nuw_mul_nuw_proof : tryFactorization_add_nuw_mul_nuw_before ⊑ tryFactorization_add_nuw_mul_nuw_after

theorem test37_proof : test37_before ⊑ test37_after

theorem sdiv4_proof : sdiv4_before ⊑ sdiv4_after

theorem substitute_constant_or_ne_uge_commute_proof : substitute_constant_or_ne_uge_commute_before ⊑ substitute_constant_or_ne_uge_commute_after

theorem ashrslt_01_08_proof : ashrslt_01_08_before ⊑ ashrslt_01_08_after

theorem shl1_trunc_sgt4_proof : shl1_trunc_sgt4_before ⊑ shl1_trunc_sgt4_after

theorem nonexact_ashr_ne_exactdiv_proof : nonexact_ashr_ne_exactdiv_before ⊑ nonexact_ashr_ne_exactdiv_after

theorem udiv_x_by_const_cmp_x_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬123#32 = 0 → ofBool (x / 123#32 <ₛ x) = ofBool (0#32 <ₛ x)

theorem sub_congr (e1 : a ≈ʷ b) (e2 : c ≈ʷ d) : (a - c) ≈ʷ (b - d)

theorem ashr_can_be_lshr_2_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(34#64 ≥ ↑64 ∨
        True ∧
            (zeroExtend 64 x ||| 4278190080#64) <<< 34#64 >>> 32#64 <<< 32#64 ≠
              (zeroExtend 64 x ||| 4278190080#64) <<< 34#64 ∨
          32#64 ≥ ↑64 ∨
            True ∧
              signExtend 64 (truncate 32 (((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64)) ≠
                ((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64) →
    ¬2#32 ≥ ↑32 →
      truncate 32 (((zeroExtend 64 x ||| 4278190080#64) <<< 34#64).sshiftRight' 32#64) =
        x <<< 2#32 ||

theorem logical_or_logical_or_icmps_comm1_proof : logical_or_logical_or_icmps_comm1_before ⊑ logical_or_logical_or_icmps_comm1_after

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

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

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

theorem test22_thm (e e_1 : IntW 32) :
  LLVM.or (icmp IntPred.ult (LLVM.and e_1 (const? 32 100663295)) (const? 32 268435456))
      (icmp IntPred.sgt (LLVM.and e (const? 32 7)) (const? 32 (-1))) ⊑
    const? 1 1

theorem e_1263 :
    4 * z + 3 * (z ||| t) - 1 *  ~~~(z &&&  ~~~z) + 5 *  ~~~(z &&&  ~~~t) - 11 * (z ^^^ t) + 3 *  ~~~(z ||| t) + 4 *  ~~~(z |||  ~~~t) + 12 * (z &&&  ~~~t) - 11 * (z &&& t) = 7 *  ~~~t

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

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 urem_i32_multiuse_thm (e e_1 : IntW 8) :
  mul (urem (zext 32 e_1) (zext 32 e)) (add (zext 32 e_1) (zext 32 e)) ⊑
    mul (urem (zext 32 e_1) (zext 32 e)) (add (zext 32 e_1) (zext 32 e) { «nsw» := true, «nuw» := true })
      { «nsw» := true, «nuw» := true }

theorem lshrult_03_12_exact_proof : lshrult_03_12_exact_before ⊑ lshrult_03_12_exact_after

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

theorem scalar_i16_lshr_and_signbit_eq_thm (e e_1 : IntW 16) :
  icmp IntPred.eq (LLVM.and (lshr e_1 e) (const? 16 (-32768))) (const? 16 0) ⊑
    icmp IntPred.sgt (lshr e_1 e) (const? 16 (-1))

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

theorem exact_lshr_eq_noexactdiv_proof : exact_lshr_eq_noexactdiv_before ⊑ exact_lshr_eq_noexactdiv_after

theorem trunc_shl_ashr_infloop_proof : trunc_shl_ashr_infloop_before ⊑ trunc_shl_ashr_infloop_after

theorem modulo4_proof : modulo4_before ⊑ modulo4_after

theorem e_1528 :
     - 1 * ((a &&& c) ||| (b &&&  ~~~c)) - 11 *  ~~~(a &&&  ~~~c) - 5 * ( ~~~(a ||| b) ||| (a ^^^ (b ^^^ c))) + 5 *  ~~~(a ||| (b ||| c)) + 19 *  ~~~(a ||| ( ~~~b ||| c)) - 4 *  ~~~( ~~~a ||| (b ||| c)) - 10 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 5 * ( ~~~a &&& ( ~~~b &&& c)) + 2 * ( ~~~a &&& (b &&& c)) + 12 * (a &&& ( ~~~b &&& c)) + 6 * (a &&& (b &&& c)) =  - 11 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 2 * (b ^^^  ~~~( ~~~a ||| ( ~~~b &&& c)))

theorem zext_sext_add_icmp_sgt_1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  ofBool (1#8 <ₛ zeroExtend 8 x_1 + signExtend 8 x) = 0#1

theorem slt_zero_ult_i1_fail1_proof : slt_zero_ult_i1_fail1_before ⊑ slt_zero_ult_i1_fail1_after

theorem and_signbit_select_lshr_proof : and_signbit_select_lshr_before ⊑ and_signbit_select_lshr_after

theorem test_mul__nuw_is_safe_thm (e : IntW 32) :
  select (icmp IntPred.eq (LLVM.and e (const? 32 268435457)) (const? 32 268435456)) (const? 32 (-1879048192))
      (mul (LLVM.and e (const? 32 268435457)) (const? 32 9)) ⊑
    mul (LLVM.and e (const? 32 268435457)) (const? 32 9) { «nsw» := false, «nuw» := true }

theorem n4_thm (e : IntW 16) :
  LLVM.and (shl (zext 32 e) (const? 32 16)) (const? 32 (-1073741824)) ⊑
    LLVM.and (shl (zext 32 e) (const? 32 16) { «nsw» := false, «nuw» := true }) (const? 32 (-1073741824))

theorem XorZextXor_thm (e : IntW 3) :
  LLVM.xor (zext 5 (LLVM.xor e (const? 3 3))) (const? 5 12) ⊑ LLVM.xor (zext 5 e) (const? 5 15)

theorem lshrult_02_06_exact_proof : lshrult_02_06_exact_before ⊑ lshrult_02_06_exact_after

theorem sge_and_max_logical_proof : sge_and_max_logical_before ⊑ sge_and_max_logical_after

theorem pr51551_2_proof : pr51551_2_before ⊑ pr51551_2_after

theorem test6_thm (e : IntW 32) :
  add (lshr (LLVM.xor e (const? 32 1234)) (const? 32 16)) (LLVM.xor e (const? 32 1234)) ⊑
    add (lshr e (const? 32 16)) (LLVM.xor e (const? 32 1234))

theorem main11_proof : main11_before ⊑ main11_after

theorem factorize_thm (e : IntW 32) : LLVM.and (LLVM.or e (const? 32 1)) (LLVM.or e (const? 32 2)) ⊑ e

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

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

theorem negative3_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 <ₛ x_1 &&& 2147483647#32) &&& ofBool (0#32 ≤ₛ x) =
    ofBool (x_2 <ₛ x_1 &&& 2147483647#32) &&& ofBool (-1#32 <ₛ x)

@[grind =, simp, aesop 50% unsafe]
lemma newState_initials (m : RawCNFA A) :
    m.newState.2.initials = m.initials

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 eq_smin3_proof : eq_smin3_before ⊑ eq_smin3_after

theorem lshrult_03_04_exact_proof : lshrult_03_04_exact_before ⊑ lshrult_03_04_exact_after

theorem no_masks_with_logical_or2_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 != -1#32) = 1#1 → ¬ofBool (x_1 &&& x != -1#32) = 1#1 → False

theorem or_not_and_and_not_and_xor_commute3_proof : or_not_and_and_not_and_xor_commute3_before ⊑ or_not_and_and_not_and_xor_commute3_after

theorem lshrugt_02_01_proof : lshrugt_02_01_before ⊑ lshrugt_02_01_after

theorem ashr_lshr_shift_amt_mismatch_proof : ashr_lshr_shift_amt_mismatch_before ⊑ ashr_lshr_shift_amt_mismatch_after

theorem and_lshr_and_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 1#32 == 0#32) = 1#1 → ¬1#32 ≥ ↑32 → x >>> 1#32 &&& 1#32 = zeroExtend 32 (ofBool (x &&& 3#32 != 0#32))

theorem prove_exact_with_high_mask_limit_thm (e : IntW 8) :
  LLVM.sdiv (LLVM.and e (const? 8 (-32))) (const? 8 (-32)) ⊑
    sub (const? 8 0) (ashr e (const? 8 5)) { «nsw» := true, «nuw» := false }

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

theorem test_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(12#32 ≥ ↑32 ∨ 12#32 ≥ ↑32) → ofBool (x <<< 12#32 >>> 12#32 != 0#32) = ofBool (x &&& 1048575#32 != 0#32)

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

theorem a_false_implies_b_false_thm.extracted_1._1 : ∀ (x : BitVec 1) (x_1 : BitVec 8),
  ¬ofBool (10#8 <ᵤ x_1) = 1#1 → ofBool (20#8 <ᵤ x_1) = 1#1 → False

theorem lshr_pow2_sgt_proof : lshr_pow2_sgt_before ⊑ lshr_pow2_sgt_after

theorem or_signbit_lshr_proof : or_signbit_lshr_before ⊑ or_signbit_lshr_after

theorem test20_proof : test20_before ⊑ test20_after

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

theorem eq_21_comm_eq2_proof : eq_21_comm_eq2_before ⊑ eq_21_comm_eq2_after

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

theorem test_sub_nuw_nsw__nsw_is_safe_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x ||| BitVec.ofInt 32 (-2147483648) == BitVec.ofInt 32 (-2147483647)) = 1#1 →
    ¬(True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true ∨
          True ∧ (BitVec.ofInt 32 (-2147483648)).usubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true) →
      True ∧ (BitVec.ofInt 32 (-2147483648)).ssubOverflow (x ||| BitVec.ofInt 32 (-2147483648)) = true → False

theorem negative_not_less_than_proof : negative_not_less_than_before ⊑ negative_not_less_than_after

theorem or_eq_with_diff_one_signed_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x == 0#32) = 1#1 → ofBool (x == -1#32) = ofBool (x + 1#32 <ᵤ 2#32)

theorem test11_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬zeroExtend 128 x &&& 31#128 ≥ ↑128 →
    ¬(True ∧ (x &&& 31#32).msb = true ∨
          True ∧
              (zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)).sshiftRight' (zeroExtend 64 (x &&& 31#32)) ≠
                zeroExtend 64 x_1 ∨
            True ∧
                zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32) >>> zeroExtend 64 (x &&& 31#32) ≠ zeroExtend 64 x_1 ∨
              zeroExtend 64 (x &&& 31#32) ≥ ↑64) →
      truncate 64 (zeroExtend 128 x_1 <<< (zeroExtend 128 x &&& 31#128)) =
        zeroExtend 64 x_1 <<< zeroExtend 64 (x &&& 31#32)

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

theorem c_1_1_0_proof : c_1_1_0_before ⊑ c_1_1_0_after

theorem or_signbit_select_lshr_proof : or_signbit_select_lshr_before ⊑ or_signbit_select_lshr_after

theorem add_nsw_mul_nsw_thm.extracted_1._1 : ∀ (x : BitVec 16),
  ¬(True ∧ x.saddOverflow x = true ∨ True ∧ (x + x).saddOverflow x = true) →
    True ∧ x.smulOverflow 3#16 = true → False

theorem e_281 :
     - 1 *  ~~~(x &&&  ~~~x) - 11 * (x ||| y) - 1 *  ~~~(x &&&  ~~~y) - 7 * (x ^^^ y) + 2 *  ~~~(x ||| y) + 20 * (x &&&  ~~~y) + 14 * (x &&& y) =  - 20 *  ~~~(x |||  ~~~y) + 1 * x

theorem shl_and_and_thm (e e_1 : IntW 8) :
  LLVM.and (shl e_1 (const? 8 4)) (LLVM.and (shl e (const? 8 4)) (const? 8 88)) ⊑
    LLVM.and (shl (LLVM.and e e_1) (const? 8 4)) (const? 8 80)

theorem e_1486 :
    3 *  ~~~t - 2 * z - 11 * (z |||  ~~~t) - 1 *  ~~~(z &&&  ~~~z) + 2 *  ~~~(z ^^^ t) + 1 *  ~~~(z &&& t) + 3 * (z ||| t) + 7 *  ~~~z - 1 *  ~~~(z ||| t) - 13 *  ~~~(z |||  ~~~t) + 7 * (z &&&  ~~~t) =  - 3 * t - 6 * (z &&& t)

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

theorem sge_or_not_max_logical_proof : sge_or_not_max_logical_before ⊑ sge_or_not_max_logical_after

theorem Tensor2d'.map_extract (δ₀ δ₁ sz₀ sz₁ : ℕ) (t : Tensor2d' α) (f : α → β) :
  (t.map f).extract δ₀ δ₁ sz₀ sz₁ = (t.extract δ₀ δ₁ sz₀ sz₁).map f

theorem tryFactorization_add_nuw_mul_nuw_int_max_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ x.umulOverflow 2147483647#32 = true ∨ True ∧ (x * 2147483647#32).uaddOverflow x = true) →
    True ∧ x <<< 31#32 >>> 31#32 ≠ x ∨ 31#32 ≥ ↑32 → False

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

theorem decideIfZerosAux_correct {arity : Type _} [DecidableEq arity]
    (p : FSM arity) (c : Circuit p.α)
    (hc : ∀ s, c.eval s = true →
      ∃ m y, (p.changeInitCarry s).eval y m = true)
    (hc₂ : ∀ (x : arity → Bool) (s : p.α → Bool),
      (FSM.nextBit p s x).snd = true → Circuit.eval c s = true) :
    decideIfZerosAux p c = true ↔ ∀ n x, p.eval x n = false

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

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 test7_thm (e : IntW 32) :
  add (zext 64 (lshr e (const? 32 1))) (const? 64 2147483647) ⊑
    zext 64 (add (lshr e (const? 32 1)) (const? 32 2147483647) { «nsw» := false, «nuw» := true })

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

theorem band_land_left1_proof : band_land_left1_before ⊑ band_land_left1_after

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

theorem test_shl__all_are_safe_thm.extracted_1._3 : ∀ (x : BitVec 64) (x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 15#32 == 0#32) = 1#1 →
    ¬(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 main13_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (truncate 16 x <ₛ 0#16) = 1#1 →
    ofBool (x &&& 32896#32 == 32896#32) = 1#1 → ¬ofBool (truncate 8 x <ₛ 0#8) = 1#1 → 1#32 = 2#32

theorem bools_logical_commute0_thm.extracted_1._4 : ∀ (x x_1 : BitVec 1),
  x_1 ^^^ 1#1 = 1#1 → x_1 = 1#1 → x = 1#1 → False

theorem urem_i1_is_zero_proof : urem_i1_is_zero_before ⊑ urem_i1_is_zero_after

theorem select2_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 1), x_1 = 1#1 → truncate 8 (zeroExtend 32 x) = x

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

theorem test5_thm (e : IntW 32) :
  sext 64 (urem e (const? 32 30000)) ⊑ zext 64 (urem e (const? 32 30000)) { «nneg» := true }

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

theorem test67_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬ofBool (x &&& 4#16 != 0#16) = 1#1 → ¬ofBool (x &&& 4#16 == 0#16) = 1#1 → 42#32 = 40#32

theorem ashr_ne_msb_low_second_zero_proof : ashr_ne_msb_low_second_zero_before ⊑ ashr_ne_msb_low_second_zero_after

theorem factorize4_thm (e e_1 : IntW 32) : sub (mul (shl e_1 (const? 32 1)) e) (mul e e_1) ⊑ mul e_1 e

theorem PR1817_1_logical_thm (e : IntW 32) :
  select (icmp IntPred.slt e (const? 32 10)) (icmp IntPred.ult e (const? 32 10)) (const? 1 0) ⊑
    icmp IntPred.ult e (const? 32 10)

theorem modulo2_proof : modulo2_before ⊑ modulo2_after

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

theorem sgt_negative_multip_rem_zero_proof : sgt_negative_multip_rem_zero_before ⊑ sgt_negative_multip_rem_zero_after

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

theorem ashrslt_03_14_exact_proof : ashrslt_03_14_exact_before ⊑ ashrslt_03_14_exact_after

@[simp]
lemma autMsbSet_accepts : NFA'.autMsbSet.accepts = langMsb

theorem negate_xor_thm (e : IntW 4) :
  sub (const? 4 0) (LLVM.xor e (const? 4 5)) ⊑ add (LLVM.xor e (const? 4 (-6))) (const? 4 1)

theorem ashr_lshr2_proof : ashr_lshr2_before ⊑ ashr_lshr2_after

theorem test_proof : test_before ⊑ test_after

theorem e_1849 :
     - 7 *  ~~~(a ^^^ b) + 5 * ( ~~~a ||| (b ||| c)) - 1 * ( ~~~c |||  ~~~(a ^^^ b)) + 3 *  ~~~(a ||| (b &&& c)) - 5 * (c ^^^ (a &&&  ~~~b)) + 1 * (a ^^^ (b &&& c)) + 1 * ( ~~~b |||  ~~~(a ^^^ c)) - 6 * (c ^^^ (a &&& b)) + 11 *  ~~~(a &&& b) - 2 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 2 * (a ^^^ (b ^^^ c)) - 11 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) + 7 *  ~~~(a &&& ( ~~~b ||| c)) - 11 *  ~~~( ~~~a ||| (b ^^^ c)) - 1 * (a ||| (b &&& c)) - 7 * (c ^^^  ~~~(a &&& (b ||| c))) + 7 * ((a &&& c) ^^^ (a ^^^ ( ~~~b &&& c))) + 2 * (b ^^^ ( ~~~a ||| ( ~~~b ||| c))) - 2 * (b ^^^  ~~~(a &&& (b ||| c))) + 11 * ((b &&&  ~~~c) ^^^ ( ~~~a ||| (b ^^^ c))) - 1 * (c ^^^ ( ~~~a ||| (b ||| c))) - 1 * (c |||  ~~~(a |||  ~~~b)) + 1 *  ~~~(a &&&  ~~~b) - 11 * (b ||| (a &&&  ~~~c)) + 1 * ((a &&& c) ||| (b &&&  ~~~c)) + 1 * ((b &&&  ~~~c) |||  ~~~(a ||| ( ~~~b &&& c))) + 2 *  ~~~(a &&&  ~~~a) + 5 * (b ^^^ (a |||  ~~~c)) - 3 * ((a &&& b) ^^^  ~~~(a ^^^ ( ~~~b ||| c))) + 3 * ( ~~~a &&& ( ~~~b ||| c)) + 7 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 4 * (c ^^^  ~~~(a ||| ( ~~~b &&& c))) + 2 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) - 2 * ( ~~~(a ^^^ b) |||  ~~~(a ^^^ c)) - 6 * (b ^^^  ~~~(a ||| (b &&& c))) + 3 * (b ^^^  ~~~(a |||  ~~~c)) - 6 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 12 *  ~~~(a ||| (b ||| c)) - 1 *  ~~~(a ||| ( ~~~b ||| c)) + 22 *  ~~~( ~~~a ||| (b ||| c)) + 18 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 39 * ( ~~~a &&& ( ~~~b &&& c)) - 6 * ( ~~~a &&& (b &&& c)) - 31 * (a &&& ( ~~~b &&& c)) + 38 * (a &&& (b &&& c)) = 1 * (c ^^^ ( ~~~a ||| ( ~~~b &&& c)))

theorem e_949 :
     - 2 * (z ^^^ t) - 1 *  ~~~(z &&&  ~~~t) - 6 *  ~~~(z ||| t) - 4 *  ~~~(z |||  ~~~t) + 2 * (z &&&  ~~~t) + 1 * (z &&& t) =  - 7 *  ~~~z

theorem test_sub_255_Y_eq_255_proof : test_sub_255_Y_eq_255_before ⊑ test_sub_255_Y_eq_255_after

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

theorem ashr_C1_add_A_C2_i32_proof : ashr_C1_add_A_C2_i32_before ⊑ ashr_C1_add_A_C2_i32_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_2_proof : masked_icmps_mask_notallzeros_bmask_mixed_2_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_2_after

theorem src_srem_shl_demand_eliminate_signbit_proof : src_srem_shl_demand_eliminate_signbit_before ⊑ src_srem_shl_demand_eliminate_signbit_after

private theorem BitVec.getLsbD_zeroExtend_eq_getLsbD (x : BitVec wold) (wnew : Nat) :
    (x.zeroExtend wnew).getLsbD i = ((x.getLsbD i) ∧ (i ≤ wnew - 1) ∧ (wnew ≠ 0))

theorem sub_sel_op1_proof : sub_sel_op1_before ⊑ sub_sel_op1_after

theorem zext_nneg_sext_sgt_thm (e e_1 : IntW 8) :
  icmp IntPred.sgt (zext 32 e_1 { «nneg» := true }) (sext 32 e) ⊑ icmp IntPred.sgt e_1 e

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

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

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

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

theorem sext_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ (zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8))).saddOverflow (BitVec.ofInt 7 (-8)) = true) →
    zeroExtend 7 (x ^^^ BitVec.ofInt 4 (-8)) + BitVec.ofInt 7 (-8) = signExtend 7 x

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

theorem lt_signed_to_large_unsigned_proof : lt_signed_to_large_unsigned_before ⊑ lt_signed_to_large_unsigned_after

theorem bitwise_or_bitwise_or_icmps_comm3_proof : bitwise_or_bitwise_or_icmps_comm3_before ⊑ bitwise_or_bitwise_or_icmps_comm3_after

theorem trunc_shl_7_i8_i64_proof : trunc_shl_7_i8_i64_before ⊑ trunc_shl_7_i8_i64_after

theorem negate_sdiv_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ¬(42#8 == 0 || 8 != 1 && x == intMin 8 && 42#8 == -1) = true →
    ¬(BitVec.ofInt 8 (-42) == 0 || 8 != 1 && x == intMin 8 && BitVec.ofInt 8 (-42) == -1) = true →
      x_1 - x.sdiv 42#8 = x.sdiv (BitVec.ofInt 8 (-42)) + x_1

theorem test59_proof : test59_before ⊑ test59_after

theorem test8_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬32#128 ≥ ↑128 →
    ¬(True ∧ zeroExtend 64 x_1 <<< 32#64 >>> 32#64 ≠ zeroExtend 64 x_1 ∨
          32#64 ≥ ↑64 ∨ True ∧ (zeroExtend 64 x_1 <<< 32#64 &&& zeroExtend 64 x != 0) = true) →
      truncate 64 (zeroExtend 128 x_1 <<< 32#128 ||| zeroExtend 128 x) =
        zeroExtend 64 x_1 <<< 32#64 ||

@[simp]
theorem MatchVar.isMonotone_bind {f : MatchVar Δ Γ} {g : Unit → MatchVar Δ Γ} :
    f.IsMonotone → (g ()).IsMonotone → IsMonotone (f >>= g)

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

theorem e_196 :
    4 *  ~~~(x &&& y) + 2 * y + 7 *  ~~~(x ||| y) - 6 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) + 9 * (x &&& y) = 11 *  ~~~(x ^^^ y)

theorem ule_or_not_min_commute_logical_proof : ule_or_not_min_commute_logical_before ⊑ ule_or_not_min_commute_logical_after

theorem test70_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 <ₛ 0#8) = 1#1 → ¬6#8 ≥ ↑8 → x ||

theorem or_test1_proof : or_test1_before ⊑ or_test1_after

theorem masked_icmps_mask_notallzeros_bmask_mixed_1b_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& 14#32 != 0#32) = 1#1 →
    ofBool (x &&& 3#32 == 1#32) = ofBool (x &&& 14#32 != 0#32) &&& ofBool (x &&& 3#32 == 1#32)

theorem test67_thm (e : IntW 16) :
  select (icmp IntPred.ne (LLVM.and e (const? 16 4)) (const? 16 0)) (const? 32 40) (const? 32 42) ⊑
    select (icmp IntPred.eq (LLVM.and e (const? 16 4)) (const? 16 0)) (const? 32 42) (const? 32 40)

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

theorem lowmask_add_zext_commute_proof : lowmask_add_zext_commute_before ⊑ lowmask_add_zext_commute_after

theorem test8_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(127#128 ≥ ↑128 ∨ 120#128 ≥ ↑128 ∨ 127#128 ≥ ↑128) →
    (x ^^^ (1#128 <<< 127#128).sshiftRight' 120#128) + 1#128 <<< 127#128 =
      x ^^^ 170141183460469231731687303715884105600#128

theorem tryFactorization_add_nuw_mul_nuw_mul_var_proof : tryFactorization_add_nuw_mul_nuw_mul_var_before ⊑ tryFactorization_add_nuw_mul_nuw_mul_var_after

theorem test1_proof : test1_before ⊑ test1_after

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

theorem icmp_shl_nsw_eq_proof : icmp_shl_nsw_eq_before ⊑ icmp_shl_nsw_eq_after

theorem select_replace_nested_proof : select_replace_nested_before ⊑ select_replace_nested_after

theorem ashrslt_01_10_proof : ashrslt_01_10_before ⊑ ashrslt_01_10_after

theorem test_proof : test_before ⊑ test_after

theorem select_and_icmp_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32), ofBool (x_1 == -1#32) = 1#1 → x_1 &&& x = x

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

theorem test34_thm.extracted_1._2 : ∀ (x : BitVec 16),
  ¬8#32 ≥ ↑32 → ¬8#16 ≥ ↑16 → truncate 16 (zeroExtend 32 x >>> 8#32) = x >>> 8#16

theorem srem_constant_dividend_select_of_constants_divisor_proof : srem_constant_dividend_select_of_constants_divisor_before ⊑ srem_constant_dividend_select_of_constants_divisor_after

@[simp] theorem Com.returnVars_castPureToEff (eff : _) (com : Com d Γ .pure tys) :
    (com.castPureToEff eff).returnVars = com.returnVars.map (fun _ v => v.castCtxt (by simp))

theorem ashr_sel_op1_proof : ashr_sel_op1_before ⊑ ashr_sel_op1_after

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

theorem PR42691_5_logical_proof : PR42691_5_logical_before ⊑ PR42691_5_logical_after

theorem p_commutative2_proof : p_commutative2_before ⊑ p_commutative2_after

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

theorem scalar_i8_shl_ult_const_2_proof : scalar_i8_shl_ult_const_2_before ⊑ scalar_i8_shl_ult_const_2_after

theorem or_min_31_30_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬ofBool (x <ᵤ BitVec.ofInt 8 (-30)) = 1#1 → BitVec.ofInt 8 (-30) ||

theorem shl_lshr_demand4_thm (e : IntW 8) :
  LLVM.or (lshr (shl (const? 8 44) e) (const? 8 3)) (const? 8 (-32)) ⊑
    LLVM.or (lshr (shl (const? 8 44) e) (const? 8 3)) (const? 8 (-32)) { «disjoint» := true }

@[simp] theorem inf_pure_eq      : min e pure = pure

theorem fold_icmp_shl_nuw_c2_precondition1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(True ∧ 0#32 <<< x >>> x ≠ 0#32 ∨ x ≥ ↑32) → ofBool (0#32 <<< x <ᵤ 63#32) = 1#1

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

theorem ne_basic_equal_5_thm (e e_1 : IntW 8) :
  LLVM.and (icmp IntPred.ne e_1 (const? 8 5)) (icmp IntPred.ule (add e_1 (const? 8 (-5))) e) ⊑
    icmp IntPred.ult (add e_1 (const? 8 (-6))) e

theorem or_simplify_uge_proof : or_simplify_uge_before ⊑ or_simplify_uge_after

theorem ult_to_sgt_thm (e e_1 : IntW 8) :
  icmp IntPred.ult (LLVM.xor e_1 (const? 8 127)) (LLVM.xor e (const? 8 127)) ⊑ icmp IntPred.sgt e_1 e

theorem list_perm_trick (x y a b c : List α) :
    y ~ b ++ x → x ~ a ++ c → y ~ a ++ b ++ c

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

theorem e_2385 :
    4 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 2 * (f ^^^  ~~~(d &&& (e ||| f))) - 2 * (e |||  ~~~(d ||| f)) - 1 *  ~~~( ~~~d ||| ( ~~~e &&& f)) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 6 * (e ^^^ (d &&& (e ^^^ f))) - 6 * (d ^^^ f) + 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) - 7 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 5 * (f ^^^  ~~~( ~~~d ||| (e &&& f))) + 3 * ((d ||| e) &&& (e ^^^ f)) - 11 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 3 * (f ^^^ (d ||| ( ~~~e &&& f))) - 7 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 4 * (f &&& (d ^^^ e)) - 5 * (e ^^^  ~~~(d &&&  ~~~f)) - 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 3 * (d &&& f) - 5 * ( ~~~d &&& (e ^^^ f)) + 1 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 7 *  ~~~(d &&&  ~~~d) - 7 * ((d &&& e) ^^^ (e |||  ~~~f)) - 6 * (e ^^^ (d ||| (e ^^^ f))) - 3 *  ~~~( ~~~d &&& (e ^^^ f)) + 7 * (e ^^^  ~~~(d &&& (e &&& f))) + 2 *  ~~~e + 4 *  ~~~(d ||| (e &&& f)) + 5 * (e ^^^ ( ~~~d ||| (e &&& f))) - 7 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 2 * ( ~~~d &&& ( ~~~e ||| f)) - 3 * ((d &&&  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~(d &&&  ~~~e) &&& (e ^^^ f)) + 3 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (d ||| (e &&& f)) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e ||| f))) - 11 * (e &&&  ~~~f) + 7 * (e ^^^ f) - 2 * (d ||| e) - 1 * (f ^^^ (d &&&  ~~~e)) + 3 * (e ^^^ ( ~~~d &&& (e ||| f))) - 11 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 4 * (f ^^^ (d ||| (e &&& f))) + 1 * (e ^^^ (d ||| (e ||| f))) + 5 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * (e ||| (d &&&  ~~~f)) + 3 *  ~~~(e ||| f) - 2 * ( ~~~d ||| (e ^^^ f)) + 1 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 * (d ||| (e ||| f)) - 6 * (d &&& (e ^^^ f)) + 11 *  ~~~(e &&&  ~~~f) + 11 * (e ^^^ ( ~~~d &&& (e ^^^ f))) + 11 * (e &&& (d ||| f)) + 3 *  ~~~(d ^^^ (e ^^^ f)) + 5 *  ~~~(d &&& (e ||| f)) - 5 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * (e ^^^ (d &&& ( ~~~e ||| f))) + 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) - 1 * (e ^^^ (d ||| (e &&& f))) - 11 *  ~~~(d ||| (e ||| f)) + 34 *  ~~~(d ||| ( ~~~e ||| f)) + 15 *  ~~~( ~~~d ||| (e ||| f)) + 19 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 26 * ( ~~~d &&& ( ~~~e &&& f)) - 24 * ( ~~~d &&& (e &&& f)) + 21 * (d &&& ( ~~~e &&& f)) - 33 * (d &&& (e &&& f)) = 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f)))

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

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

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

theorem add_select_zext_thm (e : IntW 1) :
  add (select e (const? 64 64) (const? 64 1)) (zext 64 e) ⊑ select e (const? 64 65) (const? 64 1)

theorem relabelNat_unsat_iff₂ {α : Type} [DecidableEq α] [Hashable α]
{entry : Entrypoint α} :
    (entry.relabelNat).Unsat ↔ entry.Unsat

theorem fold_mask_cmps_to_true_logical_thm (e : IntW 32) :
  select (icmp IntPred.ne e (const? 32 2147483647)) (const? 1 1)
      (icmp IntPred.ne (LLVM.and e (const? 32 2147483647)) (const? 32 0)) ⊑
    const? 1 1

theorem logic_and_logic_or_5_proof : logic_and_logic_or_5_before ⊑ logic_and_logic_or_5_after

theorem p3_sgt_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sgt e_1 (const? 32 65534)) e (const? 32 65535) ⊑
    select (icmp IntPred.slt e_1 (const? 32 65535)) (const? 32 65535) e

theorem wrongimm2_thm (e : IntW 16) :
  icmp IntPred.eq (ashr (trunc 8 e) (const? 8 6)) (trunc 8 (lshr e (const? 16 8))) ⊑
    icmp IntPred.eq (ashr (trunc 8 e) (const? 8 6))
      (trunc 8 (lshr e (const? 16 8)) { «nsw» := false, «nuw» := true })

theorem test2_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬3#32 ≥ ↑32 →
    True ∧ (zeroExtend 32 x).saddOverflow 7#32 = true ∨ True ∧ (zeroExtend 32 x).uaddOverflow 7#32 = true ∨ 3#32 ≥ ↑32 →
      False

theorem differentconsts_proof : differentconsts_before ⊑ differentconsts_after

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

theorem or_xor_common_op_commute7_proof : or_xor_common_op_commute7_before ⊑ or_xor_common_op_commute7_after

theorem PR24763_thm (e : IntW 8) : trunc 16 (lshr (sext 32 e) (const? 32 1)) ⊑ sext 16 (ashr e (const? 8 1))

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

theorem positive_samevar_proof : positive_samevar_before ⊑ positive_samevar_after

theorem test17_proof : test17_before ⊑ test17_after

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

theorem ult_to_slt_proof : ult_to_slt_before ⊑ ult_to_slt_after

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

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

theorem not_lshr_proof : not_lshr_before ⊑ not_lshr_after

theorem trunc_shl_7_i8_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬7#64 ≥ ↑64 → ¬7#8 ≥ ↑8 → truncate 8 (x <<< 7#64) = truncate 8 x <<< 7#8

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

theorem test_sext_proof : test_sext_before ⊑ test_sext_after

theorem alive_AndOrXor_827  (w : Nat)   : alive_AndOrXor_827_src w  ⊑ alive_AndOrXor_827_tgt w

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

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

private theorem BitVec.setWidth_le_setWidth_of_le {x y : BitVec w}
  {N : Nat} (hN : w ≤ N)
    (h : x ≤ y) : x.setWidth N ≤  y.setWidth N

theorem ugt_or_not_min_commute_proof : ugt_or_not_min_commute_before ⊑ ugt_or_not_min_commute_after

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

theorem p_commutative0_thm (e e_1 e_2 : IntW 32) :
  LLVM.or (LLVM.and e_2 e_1) (LLVM.and (LLVM.xor e_2 (const? 32 (-1))) e) ⊑
    LLVM.or (LLVM.and e_2 e_1) (LLVM.and e (LLVM.xor e_2 (const? 32 (-1)))) { «disjoint» := true }

theorem e_1781 :
    11 * ((a &&&  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 1 * ( ~~~(a |||  ~~~b) ||| (b ^^^ c)) - 5 * ((a &&& c) ^^^  ~~~(a ^^^ (b &&& c))) - 11 * ( ~~~(a &&&  ~~~b) &&&  ~~~(a ^^^ (b ^^^ c))) - 5 * (c |||  ~~~(a |||  ~~~b)) - 2 * (c ^^^ (a &&& (b ||| c))) - 2 *  ~~~( ~~~a ||| ( ~~~b &&& c)) - 3 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * ( ~~~a &&& (b ||| c)) + 3 *  ~~~(a |||  ~~~b) + 1 * ((a &&& c) ^^^ (a ^^^ (b &&& c))) + 11 * (b |||  ~~~(a ||| c)) + 7 * (b ^^^  ~~~( ~~~a ||| (b ^^^ c))) + 11 * (b ^^^  ~~~( ~~~a &&& ( ~~~b ||| c))) + 1 *  ~~~(a &&& (b ^^^ c)) - 2 * (a ^^^ ( ~~~b ||| c)) + 2 * (b ||| (a &&& c)) - 5 * (c &&&  ~~~(a &&&  ~~~b)) + 11 * (a ||| (b ^^^ c)) - 1 * (b ^^^  ~~~(a &&& (b ^^^ c))) + 7 * ( ~~~b |||  ~~~(a ^^^ c)) + 3 * ((a &&& b) |||  ~~~(b ||| c)) - 2 * (c ^^^ (a ||| ( ~~~b ||| c))) + 1 * ((a &&&  ~~~b) |||  ~~~(b ^^^ c)) + 5 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) - 11 * ( ~~~(a ^^^ b) &&&  ~~~(a ^^^ c)) + 4 * (b ^^^ ( ~~~a ||| ( ~~~b &&& c))) - 6 * ( ~~~b ||| (a ^^^ c)) + 2 * (a ||| (b &&& c)) - 5 *  ~~~(a ||| (b ||| c)) - 34 *  ~~~(a ||| ( ~~~b ||| c)) - 49 *  ~~~( ~~~a ||| (b ||| c)) - 30 *  ~~~( ~~~a ||| ( ~~~b ||| c)) - 3 * ( ~~~a &&& ( ~~~b &&& c)) - 28 * ( ~~~a &&& (b &&& c)) - 35 * (a &&& ( ~~~b &&& c)) - 23 * (a &&& (b &&& c)) =  - 2 * (b ^^^ (a |||  ~~~c)) - 1 * ((a ^^^ b) |||  ~~~(a ^^^ c))

theorem alive_AndOrXor_2453 : alive_AndOrXor_2453_src ⊑ alive_AndOrXor_2453_tgt

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

theorem pr33078_2_proof : pr33078_2_before ⊑ pr33078_2_after

theorem or_ashr_not_commuted_proof : or_ashr_not_commuted_before ⊑ or_ashr_not_commuted_after

theorem t0_thm (e e_1 e_2 e_3 : IntW 8) (e_4 : IntW 1) :
  select (select (LLVM.xor e_4 (const? 1 1)) (icmp IntPred.eq e_3 e_2) (const? 1 0)) e_1 e ⊑
    select (select e_4 (const? 1 1) (icmp IntPred.ne e_3 e_2)) e e_1

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

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

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

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

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

theorem p0_scalar_urem_by_const_thm (e : IntW 32) :
  icmp IntPred.eq (urem (LLVM.and e (const? 32 128)) (const? 32 6)) (const? 32 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 128)) (const? 32 0)

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

theorem sge_swap_or_not_max_commute_thm (e e_1 : IntW 8) :
  LLVM.or (icmp IntPred.ne e_1 (const? 8 127)) (icmp IntPred.sle e e_1) ⊑ const? 1 1

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

theorem test_sub_nuw_nsw__all_are_safe_proof : test_sub_nuw_nsw__all_are_safe_before ⊑ test_sub_nuw_nsw__all_are_safe_after

theorem n8_wrong_pred3_proof : n8_wrong_pred3_before ⊑ n8_wrong_pred3_after

theorem c0_thm (e : IntW 8) :
  icmp IntPred.sgt (LLVM.and e (const? 8 3)) e ⊑ icmp IntPred.slt e (const? 8 0)

theorem trunc_sandwich_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(28#32 ≥ ↑32 ∨ 2#12 ≥ ↑12) →
    30#32 ≥ ↑32 ∨
        True ∧ signExtend 32 (truncate 12 (x >>> 30#32)) ≠ x >>> 30#32 ∨
          True ∧ zeroExtend 32 (truncate 12 (x >>> 30#32)) ≠ x >>> 30#32 →
      False

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

theorem test_add_nuw_nsw__nsw_is_safe_proof : test_add_nuw_nsw__nsw_is_safe_before ⊑ test_add_nuw_nsw__nsw_is_safe_after

theorem n7_proof : n7_before ⊑ n7_after

theorem select_icmp_eq_pow2_flipped_proof : select_icmp_eq_pow2_flipped_before ⊑ select_icmp_eq_pow2_flipped_after

theorem test13_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 ((signExtend 128 x_1).sshiftRight' (zeroExtend 128 x &&& 31#128)) =
        (signExtend 64 x_1).sshiftRight' (zeroExtend 64 (x &&& 31#32))

theorem pr51551_neg1_thm.extracted_1._2 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-3) ||| 1#32).smulOverflow x = true) →
    ¬(True ∧ (x_1 &&& 4#32 &&& 1#32 != 0) = true) →
      ofBool ((x_1 &&& BitVec.ofInt 32 (-3) ||| 1#32) * x &&& 7#32 == 0#32) =
        ofBool ((x_1 &&& 4#32 ||| 1#32) * x &&& 7#32 == 0#32)

theorem set_shl_mask_proof : set_shl_mask_before ⊑ set_shl_mask_after

theorem icmp_ugt_16_thm (e : IntW 64) :
  icmp IntPred.ugt (shl e (const? 64 16) { «nsw» := false, «nuw» := true }) (const? 64 1048575) ⊑
    icmp IntPred.ugt e (const? 64 15)

theorem neg_mask2_lshr_thm (e : IntW 8) :
  sub (const? 8 0) (LLVM.and (lshr e (const? 8 3)) (const? 8 2)) ⊑
    sub (const? 8 0) (LLVM.and (lshr e (const? 8 3)) (const? 8 2)) { «nsw» := true, «nuw» := false }

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

theorem test_and4_logical_proof : test_and4_logical_before ⊑ test_and4_logical_after

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

theorem masked_icmps_bmask_notmixed_and_thm (e : IntW 32) :
  LLVM.and (icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 3))
      (icmp IntPred.ne (LLVM.and e (const? 32 255)) (const? 32 243)) ⊑
    icmp IntPred.ne (LLVM.and e (const? 32 15)) (const? 32 3)

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

theorem uge_to_slt_proof : uge_to_slt_before ⊑ uge_to_slt_after

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

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

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

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

theorem icmp_sgt10_proof : icmp_sgt10_before ⊑ icmp_sgt10_after

theorem test_with_neg_even_thm (e : IntW 32) : LLVM.and (shl (const? 32 (-4)) e) (const? 32 1) ⊑ const? 32 0

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

theorem sub_to_and_proof : sub_to_and_before ⊑ sub_to_and_after

theorem sext_sub_thm (e : IntW 1) (e_1 : IntW 8) : sub e_1 (sext 8 e) ⊑ add e_1 (zext 8 e)

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

theorem test53_proof : test53_before ⊑ test53_after

theorem CNFA.isUniversal_spec {m : CNFA n} {M : NFA' n} :
    m.Sim M → m.isUniversal → M.accepts = ⊤

theorem or_not_and_commute2_proof : or_not_and_commute2_before ⊑ or_not_and_commute2_after

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

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

theorem test24_thm (e : IntW 1) :
  icmp IntPred.ne (select e (const? 32 14) (const? 32 1234)) (const? 32 0) ⊑ const? 1 1

theorem select_icmp_and_2147483648_eq_0_xor_2147483648_proof : select_icmp_and_2147483648_eq_0_xor_2147483648_before ⊑ select_icmp_and_2147483648_eq_0_xor_2147483648_after

theorem and_logic_and_logic_or_8_thm.extracted_1._5 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x_1 = 1#1 → 1#1 = x_1 &&& 1#1

theorem trunc_equality_nuw_zext_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 32),
  ¬(True ∧ zeroExtend 32 (truncate 16 x_1) ≠ x_1) →
    ofBool (truncate 16 x_1 != zeroExtend 16 x) = ofBool (x_1 != zeroExtend 32 x)

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

theorem and_ne_with_one_bit_diff_constants2_proof : and_ne_with_one_bit_diff_constants2_before ⊑ and_ne_with_one_bit_diff_constants2_after

theorem and_not_or_commute1_proof : and_not_or_commute1_before ⊑ and_not_or_commute1_after

theorem ult_and_max_commute_logical_proof : ult_and_max_commute_logical_before ⊑ ult_and_max_commute_logical_after

theorem t_0_10_proof : t_0_10_before ⊑ t_0_10_after

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

theorem test15_thm (e e_1 : IntW 32) :
  urem (zext 64 e_1) (zext 64 (shl (const? 32 1) e)) ⊑
    zext 64 (LLVM.and e_1 (LLVM.xor (shl (const? 32 (-1)) e { «nsw» := true, «nuw» := false }) (const? 32 (-1))))
      { «nneg» := true }

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 ashrslt_02_10_proof : ashrslt_02_10_before ⊑ ashrslt_02_10_after

theorem canonicalize_logic_first_and0_nswnuw_proof : canonicalize_logic_first_and0_nswnuw_before ⊑ canonicalize_logic_first_and0_nswnuw_after

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

theorem max_sub_ult_c12_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 1#32) = 1#1 → ¬ofBool (x == 0#32) = 1#1 → x + BitVec.ofInt 32 (-2) = 0#32

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

theorem test3_thm.extracted_1._1 : ∀ (x : BitVec 64), zeroExtend 64 (truncate 8 x) = x &&& 255#64

theorem trunc_shl_15_i16_i64_proof : trunc_shl_15_i16_i64_before ⊑ trunc_shl_15_i16_i64_after

theorem shift_no_xor_multiuse_or_proof : shift_no_xor_multiuse_or_before ⊑ shift_no_xor_multiuse_or_after

theorem icmp_ult_8_thm (e : IntW 64) :
  icmp IntPred.ult (shl e (const? 64 8) { «nsw» := false, «nuw» := true }) (const? 64 4095) ⊑
    icmp IntPred.ult e (const? 64 16)

theorem ashrsgt_02_05_proof : ashrsgt_02_05_before ⊑ ashrsgt_02_05_after

theorem test71_proof : test71_before ⊑ test71_after

theorem ne_and_lshr_minval_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) → True ∧ BitVec.ofInt 8 (-128) >>> x <<< x ≠ BitVec.ofInt 8 (-128) ∨ x ≥ ↑8 → False

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

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

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

theorem test_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 sgt_swap_or_not_min_commute_logical_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != BitVec.ofInt 8 (-128)) = 1#1 → ofBool (x <ₛ x_1) = ofBool (x_1 != BitVec.ofInt 8 (-128))

theorem e_2496 :
    2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 3 * (f ||| (d &&&  ~~~e)) - 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) - 5 * ( ~~~d ||| (e ||| f)) + 11 * (e ^^^ (d &&& f)) - 2 * (f ^^^ ( ~~~d &&& (e ||| f))) - 11 * ( ~~~d ||| (e ^^^ f)) - 6 * ( ~~~f &&& (d ^^^ e)) - 2 * (e |||  ~~~f) - 5 * ( ~~~d ||| ( ~~~e &&& f)) + 3 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(d &&&  ~~~e) - 1 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 2 * (f &&&  ~~~(d ^^^ e)) + 1 * (e &&& (d ||| f)) - 1 * ( ~~~d ||| ( ~~~e ||| f)) - 1 * ( ~~~(d ||| e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f))) - 1 * (e ^^^ (d |||  ~~~f)) - 6 * (f &&& (d ||| e)) + 7 * (e ^^^ (d &&& ( ~~~e ||| f))) + 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 4 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 7 * (e ||| (d &&& f)) + 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 1 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 2 * (f ^^^ (d ||| (e &&& f))) + 5 * (e ^^^  ~~~(d &&& (e ||| f))) + 1 * (f ^^^ ( ~~~d ||| (e ||| f))) + 3 * (d ||| e) + 1 * (e &&&  ~~~f) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 7 * ((d ||| e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~d &&& (e ^^^ f)) - 1 * (d &&&  ~~~e) - 1 * (d ^^^ (e ^^^ f)) + 7 * (d ||| (e ||| f)) + 2 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) - 2 *  ~~~( ~~~d &&& ( ~~~e ||| f)) - 3 *  ~~~( ~~~d ||| (e ^^^ f)) + 3 * (f ||| (d &&& e)) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 7 * (d ^^^ f) - 1 * (e ^^^ ( ~~~d ||| (e &&& f))) - 5 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 1 * (e |||  ~~~(d |||  ~~~f)) + 5 *  ~~~(d ^^^ e) - 6 *  ~~~f + 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * (f ^^^  ~~~(d |||  ~~~e)) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) - 6 * (d ||| ( ~~~e &&& f)) + 7 * (d ^^^ (e ||| f)) + 2 * (e ^^^ (d ||| ( ~~~e ||| f))) - 5 * ((d &&& e) ||| (e ^^^ f)) + 7 * (e &&& f) + 1 * (f ^^^ (d &&& e)) + 3 * ((d ||| e) &&& (e ^^^ f)) + 4 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 7 *  ~~~(e ^^^ f) + 3 *  ~~~(d ||| (e ^^^ f)) - 6 * ((d ||| e) &&& (d ^^^ (e ^^^ f))) + 7 * ( ~~~d &&& ( ~~~e ||| f)) - 6 * (f ^^^ (d &&&  ~~~e)) - 3 * (f ^^^ ( ~~~d ||| (e &&& f))) + 2 * (d ||| ( ~~~e ||| f)) + 5 *  ~~~(d ||| e) - 2 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 * ((d &&& f) |||  ~~~(e ||| f)) + 1 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * (d ^^^ ( ~~~e ||| f)) - 11 * ((d |||  ~~~e) &&& (e ^^^ f)) - 2 * ( ~~~d &&& (e ||| f)) + 13 *  ~~~(d ||| (e ||| f)) + 2 *  ~~~(d ||| ( ~~~e ||| f)) + 20 *  ~~~( ~~~d ||| (e ||| f)) - 3 * ( ~~~d &&& ( ~~~e &&& f)) - 9 * ( ~~~d &&& (e &&& f)) + 18 * (d &&& ( ~~~e &&& f)) + 17 * (d &&& (e &&& f)) = 18 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 2 * ((d &&& f) ^^^ (e ||| f))

theorem lshrugt_01_15_proof : lshrugt_01_15_before ⊑ lshrugt_01_15_after

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

theorem icmp_slt_0_or_icmp_sgt_0_i64_fail3_thm (e : IntW 64) :
  LLVM.or (ashr e (const? 64 62)) (zext 64 (icmp IntPred.slt e (const? 64 0))) ⊑
    LLVM.or (ashr e (const? 64 62)) (lshr e (const? 64 63))

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

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

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

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 test_slt_nuw_thm (e : IntW 16) (e_1 : IntW 32) :
  icmp IntPred.slt (trunc 8 e_1 { «nsw» := true, «nuw» := true }) (trunc 8 e { «nsw» := true, «nuw» := true }) ⊑
    icmp IntPred.slt e_1 (zext 32 e)

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 is_rem4_neg_i16_proof : is_rem4_neg_i16_before ⊑ is_rem4_neg_i16_after

theorem xor_nosignbit_ashr_proof : xor_nosignbit_ashr_before ⊑ xor_nosignbit_ashr_after

theorem test73_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (-1#8 <ₛ truncate 8 x) = 1#1 → ofBool (x &&& 128#32 == 0#32) = 1#1 → 42#32 = 40#32

@[simp] theorem value_isRefinedBy_value :
    value a ⊑ value b ↔ a ⊑ b

theorem or_eq_with_diff_one_signed_proof : or_eq_with_diff_one_signed_before ⊑ or_eq_with_diff_one_signed_after

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

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

theorem lshrugt_03_02_proof : lshrugt_03_02_before ⊑ lshrugt_03_02_after

theorem sgt_smax3_proof : sgt_smax3_before ⊑ sgt_smax3_after

theorem bv_AndOrXor_2263 :
    ∀ (e e_1 : LLVM.IntW w), LLVM.or e_1 (LLVM.xor e_1 e) ⊑ LLVM.or e_1 e

theorem zext_sext_add_icmp_ne_minus1_proof : zext_sext_add_icmp_ne_minus1_before ⊑ zext_sext_add_icmp_ne_minus1_after

theorem pr33078_3_thm (e : IntW 8) :
  trunc 4 (lshr (sext 16 e) (const? 16 12)) ⊑
    trunc 4 (lshr (sext 16 e) (const? 16 12)) { «nsw» := false, «nuw» := true }

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

theorem lshrult_03_04_proof : lshrult_03_04_before ⊑ lshrult_03_04_after

theorem positive_trunc_base_logical_thm (e : IntW 32) :
  select (icmp IntPred.sgt (trunc 16 e) (const? 16 (-1)))
      (icmp IntPred.ult (add (trunc 16 e) (const? 16 128)) (const? 16 256)) (const? 1 0) ⊑
    icmp IntPred.eq (LLVM.and e (const? 32 65408)) (const? 32 0)

theorem e_1880 :
    11 *  ~~~(a &&&  ~~~a) - 6 * ( ~~~c &&&  ~~~(a ^^^ b)) - 2 * (b &&& (a ||| c)) - 7 * (b ||| (a ^^^ c)) + 4 * ((b &&& c) ||| ( ~~~a &&& (b ||| c))) - 11 * ((b &&& c) ^^^  ~~~( ~~~a &&& (b ^^^ c))) - 1 *  ~~~( ~~~a &&& ( ~~~b ||| c)) + 7 * (a ||| c) - 1 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) + 2 * (b ||| (a &&& c)) - 6 * ((a &&& b) |||  ~~~(a ^^^ (b ^^^ c))) + 2 * (a &&& (b ||| c)) - 5 * ((a &&& b) |||  ~~~(b ^^^ c)) + 1 * (a ||| (b ^^^ c)) + 1 * (b ^^^ (a &&&  ~~~c)) - 1 * (b &&&  ~~~(a &&&  ~~~c)) - 7 * (c ||| (a &&& b)) - 2 * ((b &&&  ~~~c) ^^^ (a ||| (b ^^^ c))) + 2 * ( ~~~a ||| (b ||| c)) + 2 *  ~~~(a &&&  ~~~b) - 6 * (b ^^^  ~~~(a ||| (b ^^^ c))) + 2 * ((a &&& c) ^^^  ~~~(b &&&  ~~~c)) + 2 * ( ~~~(a |||  ~~~b) ||| (a ^^^ (b ^^^ c))) - 6 * ( ~~~a &&& (b ^^^ c)) - 11 * (b ^^^  ~~~(a ||| (b &&& c))) + 1 * ( ~~~c ||| (a ^^^ b)) + 2 * (b ||| c) + 1 * ((a &&& b) ^^^ (b ||| c)) - 7 * (c ^^^ (a &&& b)) - 2 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) - 3 *  ~~~(a &&& (b ^^^ c)) - 2 * ((b &&& c) ||| (a &&& (b ||| c))) + 7 * (b ^^^  ~~~(a &&& ( ~~~b ||| c))) + 3 * (a ||| (b ||| c)) - 7 * (c ^^^  ~~~(a ||| b)) + 1 * (b ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 3 * (b ^^^  ~~~(a &&& c)) + 4 *  ~~~(a ||| b) - 1 * (b ^^^ (a &&& (b ||| c))) - 3 * ( ~~~(a |||  ~~~b) |||  ~~~(a ^^^ (b ^^^ c))) - 11 * (a |||  ~~~b) + 11 * (c |||  ~~~(a |||  ~~~b)) + 39 *  ~~~(a ||| (b ||| c)) - 13 *  ~~~(a ||| ( ~~~b ||| c)) + 9 *  ~~~( ~~~a ||| (b ||| c)) + 54 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 16 * (a &&& ( ~~~b &&& c)) + 14 * (a &&& (b &&& c)) = 8 * ( ~~~a &&& ( ~~~b &&& c)) - 11 * ( ~~~a &&& (b &&& c))

theorem icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823_proof : icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823_before ⊑ icmp_power2_and_icmp_shifted_mask_swapped_1073741824_1073741823_after

theorem scalar_i32_shl_and_signbit_eq_proof : scalar_i32_shl_and_signbit_eq_before ⊑ scalar_i32_shl_and_signbit_eq_after

theorem or_and_shifts1_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32) →
    3#32 ≥ ↑32 ∨ 5#32 ≥ ↑32 ∨ True ∧ (x <<< 3#32 &&& 8#32 &&& (x <<< 5#32 &&& 32#32) != 0) = true → False

theorem AvoidCollision_setWidth_setWidth_of_le (x : BitVec w) (h : k ≤ l) :
    (x.setWidth l).setWidth k = x.setWidth k

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 test9_proof : test9_before ⊑ test9_after

theorem t1_flags_nuw_first_proof : t1_flags_nuw_first_before ⊑ t1_flags_nuw_first_after

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

theorem lshr_shl_pow2_const_case2_thm (e : IntW 16) :
  LLVM.and (shl (lshr (const? 16 8192) e) (const? 16 4)) (const? 16 32) ⊑
    select (icmp IntPred.eq e (const? 16 12)) (const? 16 32) (const? 16 0)

theorem trunc_lshr_zext_thm (e : IntW 8) : trunc 8 (lshr (zext 32 e) (const? 32 6)) ⊑ lshr e (const? 8 6)

theorem or_xor_xor_normal_variant2_proof : or_xor_xor_normal_variant2_before ⊑ or_xor_xor_normal_variant2_after

theorem e_315 :
     - 6 *  ~~~x - 1 * x + 5 * (x ||| y) + 13 *  ~~~(x ||| y) + 8 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) + 3 * (x &&& y) = 7 *  ~~~(x &&&  ~~~y)

theorem scalar_i32_shl_and_signbit_slt_proof : scalar_i32_shl_and_signbit_slt_before ⊑ scalar_i32_shl_and_signbit_slt_after

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

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 lshrugt_01_07_exact_proof : lshrugt_01_07_exact_before ⊑ lshrugt_01_07_exact_after

theorem test2_proof : test2_before ⊑ test2_after

theorem and_consts_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (4#32 &&& x == 0#32) = 1#1 → ofBool (8#32 &&& x == 0#32) = ofBool (x &&& 12#32 != 12#32)

theorem n11_thm.extracted_1._1 : ∀ (x : BitVec 16) (x_1 : BitVec 32),
  ¬(zeroExtend 32 (30#16 - x) ≥ ↑32 ∨ x + BitVec.ofInt 16 (-31) ≥ ↑16) →
    True ∧ (30#16 - x).msb = true ∨ zeroExtend 32 (30#16 - x) ≥ ↑32 ∨ x + BitVec.ofInt 16 (-31) ≥ ↑16 → False

theorem rem_euclid_add_different_const_proof : rem_euclid_add_different_const_before ⊑ rem_euclid_add_different_const_after

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

theorem zext_zext_sgt_proof : zext_zext_sgt_before ⊑ zext_zext_sgt_after

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

theorem not_or_or_and_no_and_commute3_proof : not_or_or_and_no_and_commute3_before ⊑ not_or_or_and_no_and_commute3_after

@[simp] theorem toBitVec_negOne : BitStream.toBitVec w BitStream.negOne = BitVec.allOnes w

theorem zext_sext_add_icmp_slt_1_proof : zext_sext_add_icmp_slt_1_before ⊑ zext_sext_add_icmp_slt_1_after

theorem tryFactorization_xor_lshr_lshr_proof : tryFactorization_xor_lshr_lshr_before ⊑ tryFactorization_xor_lshr_lshr_after

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

theorem src_is_mask_zext_fail_not_mask_thm.extracted_1._1 : ∀ (x : BitVec 8) (x_1 : BitVec 16),
  ¬x ≥ ↑8 →
    ofBool ((x_1 ^^^ 123#16) &&& zeroExtend 16 (BitVec.ofInt 8 (-2) >>> x) == x_1 ^^^ 123#16) =
      ofBool (x_1 ^^^ BitVec.ofInt 16 (-124) ||| zeroExtend 16 (BitVec.ofInt 8 (-2) >>> x) == -1#16)

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

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

theorem n3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬x_1 ≥ ↑8 → True ∧ ((-1#8) <<< x_1).sshiftRight' x_1 ≠ -1#8 ∨ x_1 ≥ ↑8 → False

theorem test9_thm (e : IntW 32) :
  icmp IntPred.ne (LLVM.and e (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.slt e (const? 32 0)

theorem or_ranges_single_elem_right_thm (e : IntW 8) :
  LLVM.or (LLVM.and (icmp IntPred.uge e (const? 8 5)) (icmp IntPred.ule e (const? 8 10)))
      (icmp IntPred.eq e (const? 8 11)) ⊑
    icmp IntPred.ult (add e (const? 8 (-5))) (const? 8 7)

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

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

theorem smear_set_bit_different_dest_type_wider_dst_thm (e : IntW 32) :
  sext 64 (ashr (trunc 8 e) (const? 8 7)) ⊑ sext 64 (ashr (shl e (const? 32 24)) (const? 32 31))

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

theorem sub_eq_subAux (x y : BitStream) : (x - y) i = (subAux x y i).1

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

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 sle_or_min_logical_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ≤ₛ x) = 1#1 → 1#1 = ofBool (x_1 ≤ₛ x)

theorem test9_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x &&& BitVec.ofInt 32 (-2147483648) != 0#32) = ofBool (x <ₛ 0#32)

theorem test17_proof : test17_before ⊑ test17_after

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

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

theorem icmp_eq_zext_ne_non_boolean_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (zeroExtend 32 (ofBool (x != 2#32)) == x) = ofBool (x == 1#32)

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

theorem ashr_ult_7_proof : ashr_ult_7_before ⊑ ashr_ult_7_after

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

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

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

theorem masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical_proof : masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical_before ⊑ masked_icmps_mask_notallzeros_bmask_mixed_negated_2_logical_after

theorem and1_lshr1_is_cmp_eq_0_multiuse_proof : and1_lshr1_is_cmp_eq_0_multiuse_before ⊑ and1_lshr1_is_cmp_eq_0_multiuse_after

theorem smear_set_bit_thm (e : IntW 32) :
  sext 32 (ashr (trunc 8 e) (const? 8 7)) ⊑ ashr (shl e (const? 32 24)) (const? 32 31)

theorem eq_nsw_rem_zero_proof : eq_nsw_rem_zero_before ⊑ eq_nsw_rem_zero_after

theorem shl_nsw_slt_1_proof : shl_nsw_slt_1_before ⊑ shl_nsw_slt_1_after

lemma mem_varsFinset [DecidableEq α] {c : Circuit α} :
    ∀ {x : α}, x ∈ c.varsFinset ↔ x ∈ c.vars

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

theorem e_1292 :
     - 6 * (z |||  ~~~t) - 1 * (z ||| t) - 1 * z + 4 *  ~~~(z ^^^ t) - 2 *  ~~~(z &&&  ~~~z) - 7 *  ~~~(z ||| t) - 8 *  ~~~(z |||  ~~~t) + 10 * (z &&&  ~~~t) + 6 * (z &&& t) =  - 11 *  ~~~z

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

theorem test3_proof : test3_before ⊑ test3_after

theorem add_smin_simplify2_proof : add_smin_simplify2_before ⊑ add_smin_simplify2_after

theorem e_331 :
     - 6 *  ~~~x + 2 * (x |||  ~~~y) - 3 * x + 2 * (x ||| y) - 10 *  ~~~(x ||| y) - 10 *  ~~~(x |||  ~~~y) - 4 * (x &&&  ~~~y) - 15 * (x &&& y) =  - 3 *  ~~~(x &&&  ~~~x) - 11 *  ~~~(x &&&  ~~~y)

theorem e_2447 :
     - 1 * (e ^^^  ~~~(d &&& (e &&& f))) + 3 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) - 6 * (e |||  ~~~(d ||| f)) - 6 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& ( ~~~e &&& f)) + 2 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) + 3 * ((d &&& e) ^^^ (d ^^^ ( ~~~e ||| f))) - 2 * (e ||| (d &&&  ~~~f)) + 4 * (f ^^^ ( ~~~d ||| (e ||| f))) - 2 * (f ^^^ (d ||| (e &&& f))) + 5 * (f ^^^ (d &&& (e ||| f))) + 11 * (f ^^^  ~~~(d ||| e)) + 3 * (f ^^^  ~~~(d &&& e)) - 5 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) - 11 * ( ~~~(d &&&  ~~~e) &&& (d ^^^ (e ^^^ f))) + 2 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) - 1 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 1 *  ~~~(d ||| (e ^^^ f)) - 1 * (d ^^^ e) + 2 * (f ^^^ (d &&&  ~~~e)) - 11 * ( ~~~(d &&& e) &&&  ~~~(d ^^^ (e ^^^ f))) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) + 1 * (f &&& (d |||  ~~~e)) - 5 * ( ~~~(d ^^^ e) ||| (d ^^^ f)) + 2 * ( ~~~d &&& (e ^^^ f)) + 7 * (f ^^^ (d ||| ( ~~~e ||| f))) + 1 *  ~~~(d ^^^ (e &&& f)) - 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 2 * ((e &&&  ~~~f) ^^^ (d ||| (e ^^^ f))) + 11 * ((d &&& f) |||  ~~~(e ||| f)) - 5 * (f &&& (d ^^^ e)) + 1 * (e ^^^ (d ||| ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 3 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 3 *  ~~~(e |||  ~~~f) - 2 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 7 * ( ~~~d ||| (e ^^^ f)) - 2 * (f ^^^ (d ||| (e ||| f))) + 4 * ( ~~~d &&& (e ||| f)) + 1 * (e ^^^  ~~~(d &&& ( ~~~e &&& f))) - 6 * (d ||| f) - 2 * (e ^^^ (d ||| f)) + 1 * (f |||  ~~~(d ^^^ e)) + 3 * (e &&&  ~~~(d ^^^ f)) + 2 * (f ^^^  ~~~(d &&& (e ||| f))) - 5 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 4 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) - 6 * (d ^^^ ( ~~~e &&& f)) - 11 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * (e ^^^ (d &&& (e ^^^ f))) - 2 * ((d &&& e) ||| (d ^^^ (e ^^^ f))) - 1 * ((d |||  ~~~e) &&& (d ^^^ (e ^^^ f))) - 5 * (e ||| (d ^^^ f)) + 2 *  ~~~( ~~~d &&& (e ||| f)) + 7 * e - 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 11 *  ~~~(d ^^^ (e ||| f)) - 3 * (e ^^^  ~~~( ~~~d &&& (e ||| f))) - 3 * ( ~~~d &&& ( ~~~e ||| f)) + 3 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 *  ~~~(d ||| ( ~~~e &&& f)) + 11 * (d ||| ( ~~~e &&& f)) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * ((d &&& e) |||  ~~~(d ^^^ (e ^^^ f))) - 1 * (d &&& f) + 5 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 19 *  ~~~(d ||| (e ||| f)) - 2 *  ~~~(d ||| ( ~~~e ||| f)) + 4 *  ~~~( ~~~d ||| (e ||| f)) + 8 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 14 * ( ~~~d &&& ( ~~~e &&& f)) + 15 * ( ~~~d &&& (e &&& f)) - 20 * (d &&& ( ~~~e &&& f)) - 30 * (d &&& (e &&& f)) =  - 5 * (e &&&  ~~~(d &&& f))

theorem and1_lshr1_is_cmp_eq_0_multiuse_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) →
    ¬(x ≥ ↑8 ∨
          True ∧ (1#8 >>> x <<< 1#8).sshiftRight' 1#8 ≠ 1#8 >>> x ∨
            True ∧ 1#8 >>> x <<< 1#8 >>> 1#8 ≠ 1#8 >>> x ∨ 1#8 ≥ ↑8) →
      1#8 >>> x + (1#8 >>> x &&& 1#8) = 1#8 >>> x <<< 1#8

theorem masked_or_allzeroes_proof : masked_or_allzeroes_before ⊑ masked_or_allzeroes_after

theorem fold_icmp_shl_nuw_c1_proof : fold_icmp_shl_nuw_c1_before ⊑ fold_icmp_shl_nuw_c1_after

@[simp]
lemma CNFA.autWidth_states: s ∈ (autWidth wp n).m.states ↔ s < n+2

theorem scalar_i64_shl_and_signbit_eq_proof : scalar_i64_shl_and_signbit_eq_before ⊑ scalar_i64_shl_and_signbit_eq_after

theorem fold_select_trunc_nsw_true_thm.extracted_1._1 : ∀ (x : BitVec 128),
  ¬(True ∧ signExtend 128 (truncate 1 x) ≠ x) → truncate 1 x = 1#1 → x = -1#128

theorem e_2365 :
    1 * (f ^^^ (d &&& (e ||| f))) + 3 *  ~~~(d ^^^ (e ^^^ f)) + 1 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 2 * ( ~~~f ||| (d ^^^ e)) + 1 * (d ^^^ e) - 2 * (d ||| (e ||| f)) - 1 *  ~~~e + 1 * (e ||| (d ^^^ f)) + 11 *  ~~~(d &&&  ~~~e) - 6 *  ~~~(d &&&  ~~~d) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^ (d ||| ( ~~~e &&& f))) + 3 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 7 *  ~~~(e ||| f) + 1 * (e ^^^ (d ||| (e ^^^ f))) + 2 * ((d &&&  ~~~e) |||  ~~~(d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d &&&  ~~~e)) - 3 * ((d ^^^ e) &&& (d ^^^ f)) + 2 * (e ^^^ ( ~~~d &&& ( ~~~e ||| f))) - 7 *  ~~~(d &&& f) - 2 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) - 5 *  ~~~(d &&& e) - 1 * ((d &&&  ~~~e) ||| (e ^^^ f)) + 2 * ( ~~~(d ||| e) ||| (d ^^^ (e ^^^ f))) + 3 *  ~~~(d |||  ~~~e) + 2 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 7 * (f ^^^ (d &&& ( ~~~e ||| f))) + 3 * (f |||  ~~~(d ||| e)) - 1 * (e ^^^ (d ||| ( ~~~e ||| f))) - 1 * ( ~~~d ||| (e ^^^ f)) + 11 * ( ~~~(d |||  ~~~e) ||| (d ^^^ (e ^^^ f))) + 1 * (f ^^^ (d ||| ( ~~~e ||| f))) - 3 * (e ^^^  ~~~(d ||| (e ^^^ f))) - 1 *  ~~~(e ^^^ f) - 11 * (e ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 4 * (d ||| (e &&& f)) - 3 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 1 * ((d |||  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * (e |||  ~~~(d |||  ~~~f)) - 5 * (e ^^^ (d |||  ~~~f)) + 1 * (f |||  ~~~(d ^^^ e)) - 7 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 1 * (f &&&  ~~~(d &&&  ~~~e)) + 7 * (f ^^^  ~~~(d |||  ~~~e)) + 3 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 6 * ((d ||| e) &&& (e ^^^ f)) - 2 * (e ^^^  ~~~(d |||  ~~~f)) + 1 * (e ^^^  ~~~( ~~~d ||| (e ^^^ f))) - 5 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) + 5 * (d ^^^ ( ~~~e ||| f)) + 4 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) + 5 * (e &&& (d |||  ~~~f)) - 3 * (e ^^^  ~~~(d &&& (e ||| f))) + 7 * ( ~~~d ||| (e ||| f)) + 2 * ( ~~~d ||| ( ~~~e &&& f)) - 11 * ( ~~~d &&& (e ||| f)) - 3 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) - 1 * (d ||| e) + 7 * (d ^^^ (e ^^^ f)) + 7 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 7 * (d ||| f) + 10 *  ~~~(d ||| (e ||| f)) - 20 *  ~~~(d ||| ( ~~~e ||| f)) + 40 *  ~~~( ~~~d ||| (e ||| f)) + 7 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 7 * ( ~~~d &&& ( ~~~e &&& f)) - 15 * ( ~~~d &&& (e &&& f)) + 17 * (d &&& ( ~~~e &&& f)) - 34 * (d &&& (e &&& f)) =  - 3 * ((d &&& f) ^^^  ~~~(d ^^^ ( ~~~e &&& f)))

theorem test5_proof : test5_before ⊑ test5_after

theorem xor_with_or_disjoint_ba_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& x != 0) = true) → x_1 ^^^ (x_1 ||| x) = x

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

theorem ashrslt_02_01_exact_proof : ashrslt_02_01_exact_before ⊑ ashrslt_02_01_exact_after

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

theorem select_constants_and_icmp_eq0_thm.extracted_1._1 : ∀ (x x_1 : BitVec 1),
  x_1 = 1#1 → x = 1#1 → ofBool (2#8 &&& 2#8 == 0#8) = x_1 ^^^ x

theorem reused_mul_nuw_xy_z_selectnonzero_ugt_thm.extracted_1._3 : ∀ (x x_1 : BitVec 8),
  ¬ofBool (x_1 != 0#8) = 1#1 → ¬ofBool (x_1 == 0#8) = 1#1 → ¬(True ∧ x.umulOverflow x_1 = true) → False

theorem evalWith_congrEnv {p : FSM arity}
    {x y : arity → BitStream} {carryState : p.α → Bool} {n : Nat}
    (h : ∀ a i, i ≤ n → x a i = y a i) :
    p.evalWith carryState x n = p.evalWith carryState y n

theorem fold_add_udiv_urem_without_noundef_proof : fold_add_udiv_urem_without_noundef_before ⊑ fold_add_udiv_urem_without_noundef_after

theorem bitvec_AddSub_1309 :
  [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v1 = llvm.and %X, %Y
      %v2 = llvm.or %X, %Y
      %v3 = llvm.add %v1, %v2
      llvm.return %v3
  }] ⊑ [llvm(w)| {
    ^bb0(%X : _, %Y : _):
      %v3 = llvm.add %X, %Y
      llvm.return %v3
  }]

theorem ashr_add_fail_thm (e : IntW 8) :
  add (ashr (const? 8 (-128)) e) (ashr (const? 8 (-128)) (add e (const? 8 1))) ⊑
    add (ashr (const? 8 (-128)) e { «exact» := true })
      (ashr (const? 8 (-128)) (add e (const? 8 1)) { «exact» := true })

@[simp]
theorem flipAccept_eval {M : NFA α σ} : M.flipAccept.eval w = M.eval w

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

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

theorem Factor.denote_eq_toNat_reflect {w : Nat} (xs : Env w) (f : Factor) :
  f.denote xs = (f.reflect xs |>.toNat)

theorem sub_ashr_or_i8_proof : sub_ashr_or_i8_before ⊑ sub_ashr_or_i8_after

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

theorem exact_lshr_eq_thm (e : IntW 8) :
  icmp IntPred.eq (lshr (const? 8 4) e { «exact» := true }) (const? 8 1) ⊑
    icmp IntPred.eq e (const? 8 2)

theorem uadd_sat_via_add_swapped_cmp_nonstrict_proof : uadd_sat_via_add_swapped_cmp_nonstrict_before ⊑ uadd_sat_via_add_swapped_cmp_nonstrict_after

theorem test8_thm.extracted_1._2 : ∀ (x : BitVec 27), ¬3#27 ≥ ↑27 → 9#27 * x - x = x <<< 3#27

theorem scalar0_thm (e e_1 : IntW 4) :
  LLVM.xor (LLVM.and (LLVM.xor e_1 e) (const? 4 1)) e ⊑
    LLVM.or (LLVM.and e_1 (const? 4 1)) (LLVM.and e (const? 4 (-2))) { «disjoint» := true }

theorem or_and_not_not_commute6_proof : or_and_not_not_commute6_before ⊑ or_and_not_not_commute6_after

theorem add_or_sub_comb_i8_commuted2_nsw_proof : add_or_sub_comb_i8_commuted2_nsw_before ⊑ add_or_sub_comb_i8_commuted2_nsw_after

theorem const_sub_const_sub_thm.extracted_1._1 : ∀ (x : BitVec 32), 2#32 - (8#32 - x) = x + BitVec.ofInt 32 (-6)

theorem PR42691_1_proof : PR42691_1_before ⊑ PR42691_1_after

theorem ashr_or_proof : ashr_or_before ⊑ ashr_or_after

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

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

theorem ne_umin1_proof : ne_umin1_before ⊑ ne_umin1_after

theorem lshr_or_or_no_const_proof : lshr_or_or_no_const_before ⊑ lshr_or_or_no_const_after

theorem bitwise_or_bitwise_or_icmps_comm2_proof : bitwise_or_bitwise_or_icmps_comm2_before ⊑ bitwise_or_bitwise_or_icmps_comm2_after

theorem logical_and_logical_and_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 → ¬ofBool (x == 42#8) = 1#1 → ofBool (x_2 &&& 1#8 != 0#8) = 0#1

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

theorem lshrult_02_14_exact_proof : lshrult_02_14_exact_before ⊑ lshrult_02_14_exact_after

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

theorem t0_proof : t0_before ⊑ t0_after

theorem main5c_like_logical_thm.extracted_1._12 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x_1 &&& 7#32 != 7#32) = 1#1 →
    ¬ofBool (x_1 &&& 7#32 == 7#32) = 1#1 → ¬ofBool (x &&& 7#32 != 7#32) = 1#1 → 1#32 = zeroExtend 32 0#1

theorem PR23309v2_proof : PR23309v2_before ⊑ PR23309v2_after

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

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

theorem mul_select_sext_thm.extracted_1._2 : ∀ (x : BitVec 1), ¬x = 1#1 → 1#64 * signExtend 64 x = 0#64

theorem test9a_proof : test9a_before ⊑ test9a_after

theorem e_60 :
     - 2 *  ~~~y + 7 *  ~~~(x &&& y) + 5 * x - 5 *  ~~~(x ||| y) - 10 * (x &&&  ~~~y) = 7 *  ~~~(x |||  ~~~y) + 5 * (x &&& y)

theorem PR28476_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  zeroExtend 32 (ofBool (x_1 != 0#32) &&& ofBool (x != 0#32)) ^^^ 1#32 =
    zeroExtend 32 (ofBool (x_1 == 0#32) ||| ofBool (x == 0#32))

theorem zext_ashr_proof : zext_ashr_before ⊑ zext_ashr_after

theorem ashrsgt_02_04_exact_proof : ashrsgt_02_04_exact_before ⊑ ashrsgt_02_04_exact_after

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

theorem slt_and_max_proof : slt_and_max_before ⊑ slt_and_max_after

theorem test2_thm (e : IntW 8) : zext 64 (zext 32 (zext 16 e)) ⊑ zext 64 e

theorem cmpne_xor_cst1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 ^^^ 10#32 != x) = ofBool (x_1 ^^^ x != 10#32)

theorem test25 (x y : BitVec w) : (x &&& y) = (((~~~x) ||| y) - ~~~x)

theorem ashr_mul_thm (e e_1 : IntW 8) :
  trunc 16 (ashr (mul (sext 20 e_1) (sext 20 e)) (const? 20 8)) ⊑
    ashr (mul (sext 16 e_1) (sext 16 e) { «nsw» := true, «nuw» := false }) (const? 16 8)

theorem t1_ult_slt_0_proof : t1_ult_slt_0_before ⊑ t1_ult_slt_0_after

theorem e_797 :
     - 6 * (z ||| t) - 1 * t - 7 *  ~~~(z ||| t) + 7 * (z &&&  ~~~t) + 8 * (z &&& t) = 1 * z - 7 *  ~~~z

theorem missed_const_prop_2002h12h05_proof : missed_const_prop_2002h12h05_before ⊑ missed_const_prop_2002h12h05_after

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 ashrsgt_03_06_exact_thm.extracted_1._1 : ∀ (x : BitVec 4),
  ¬(True ∧ x >>> 3#4 <<< 3#4 ≠ x ∨ 3#4 ≥ ↑4) → ofBool (6#4 <ₛ x.sshiftRight' 3#4) = 0#1

theorem ashr_ugt_3_proof : ashr_ugt_3_before ⊑ ashr_ugt_3_after

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

theorem shiftLeft_eq' {x : BitVec w₁} {y : BitVec w₂} : x <<< y = x <<< y.toNat

theorem test_shl_nuw__all_are_safe_proof : test_shl_nuw__all_are_safe_before ⊑ test_shl_nuw__all_are_safe_after

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

theorem ashr_ult_12_proof : ashr_ult_12_before ⊑ ashr_ult_12_after

theorem test22_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬24#32 ≥ ↑32 → signExtend 32 (truncate 8 x) <<< 24#32 = x <<< 24#32

theorem slt_to_ugt_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ^^^ 127#8 <ₛ x ^^^ 127#8) = ofBool (x <ᵤ x_1)

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

theorem test_and_ne_a_b_commuted_proof : test_and_ne_a_b_commuted_before ⊑ test_and_ne_a_b_commuted_after

theorem carry_add_succ (x : Bool → BitStream) (n : ℕ) :
    add.carry x (n+1) =
      fun _ => (BitStream.addAux (x true) (x false) n).2

theorem test11_proof : test11_before ⊑ test11_after

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

theorem t2_thm (e : IntW 64) :
  sub (const? 32 0) (trunc 32 (ashr e (const? 64 63))) ⊑
    trunc 32 (lshr e (const? 64 63)) { «nsw» := true, «nuw» := true }

theorem scalar_i32_lshr_and_negC_eq_X_is_constant2_thm (e : IntW 32) :
  icmp IntPred.eq (LLVM.and (lshr (const? 32 (-2147483648)) e) (const? 32 (-2147483648))) (const? 32 0) ⊑
    icmp IntPred.ne e (const? 32 0)

theorem main4f_like_logical_thm.extracted_1._7 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 &&& x_1 != x_1) = 1#1 → ¬ofBool (x_2 &&& x_1 == x_1) = 1#1 → True → 0#32 = zeroExtend 32 0#1

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

lemma CNFA.autWidth_bv_language :
    (autWidth wp n).bv_recognizes { bv | wp.sat bv.w n }

theorem scalar_i32_shl_ult_const_proof : scalar_i32_shl_ult_const_before ⊑ scalar_i32_shl_ult_const_after

theorem select_bittest_to_sub_thm.extracted_1._3 : ∀ (x : BitVec 32),
  ¬ofBool (x &&& 1#32 == 0#32) = 1#1 →
    True ∧ (4#32).ssubOverflow (x &&& 1#32) = true ∨ True ∧ (4#32).usubOverflow (x &&& 1#32) = true → False

theorem e_1487 :
    11 * (z ^^^ t) + 3 *  ~~~(z ^^^ t) - 11 *  ~~~z - 1 * (z |||  ~~~t) + 3 *  ~~~(z &&&  ~~~t) + 3 * t - 1 *  ~~~(z &&& t) + 5 *  ~~~(z ||| t) - 5 *  ~~~(z |||  ~~~t) - 18 * (z &&&  ~~~t) - 15 * (z &&& t) =  - 7 * z - 2 *  ~~~t

theorem logical_and_not_cond_reuse_proof : logical_and_not_cond_reuse_before ⊑ logical_and_not_cond_reuse_after

theorem trunc_shl_1_i32_i64_proof : trunc_shl_1_i32_i64_before ⊑ trunc_shl_1_i32_i64_after

theorem no_shift_xor_multiuse_cmp_with_xor_thm.extracted_1._7 : ∀ (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_3 &&& 4096#32 ^^^ x_2 ^^^ 4096#32) * x

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

theorem xor_or_xor_common_op_commute2_proof : xor_or_xor_common_op_commute2_before ⊑ xor_or_xor_common_op_commute2_after

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

theorem ule_and_min_commute_logical_proof : ule_and_min_commute_logical_before ⊑ ule_and_min_commute_logical_after

theorem positive_biggershl_shlnuw_proof : positive_biggershl_shlnuw_before ⊑ positive_biggershl_shlnuw_after

theorem lshr_shl_demand4_proof : lshr_shl_demand4_before ⊑ lshr_shl_demand4_after

theorem slt_smin4_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (x <ₛ x_1 + 3#32) = 1#1 → ofBool (x_1 + 3#32 <ₛ x_1 + 3#32) = ofBool (x <ₛ x_1 + 3#32)

@[simp] theorem Valuation.append_inj_left {V V' : Γ.Valuation} {W : Δ.Valuation} :
    (V ++ W) = (V' ++ W) ↔ V = V'

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

theorem zext_sub_proof : zext_sub_before ⊑ zext_sub_after

theorem lowbitmask_casted_shift_thm (e : IntW 8) :
  LLVM.and (sext 32 (ashr e (const? 8 1))) (const? 32 2147483647) ⊑ lshr (sext 32 e) (const? 32 1)

theorem rem_euclid_pow2_false_arm_folded_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬(2#32 == 0 || 32 != 1 && x == intMin 32 && 2#32 == -1) = true →
    ofBool (0#32 ≤ₛ x.srem 2#32) = 1#1 → x.srem 2#32 = x &&& 1#32

theorem demorgan_and_apint4_proof : demorgan_and_apint4_before ⊑ demorgan_and_apint4_after

theorem sge_or_max_logical_thm (e e_1 : IntW 8) :
  select (icmp IntPred.sge e_1 e) (const? 1 1) (icmp IntPred.eq e_1 (const? 8 127)) ⊑
    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)

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

theorem and_or1_commuted_thm.extracted_1._6 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 ||

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

theorem pr33078_2_thm.extracted_1._1 : ∀ (x : BitVec 8), ¬4#16 ≥ ↑16 → 4#8 ≥ ↑8 → False

theorem negative_trunc_not_arg_logical_proof : negative_trunc_not_arg_logical_before ⊑ negative_trunc_not_arg_logical_after

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

theorem positive_samevar_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ¬(x ≥ ↑8 ∨ x ≥ ↑8) → True ∧ ((-1#8) <<< x).sshiftRight' x ≠ -1#8 ∨ x ≥ ↑8 → False

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

theorem select_2_thm.extracted_1._14 : ∀ (x x_1 x_2 : BitVec 8) (x_3 x_4 : BitVec 1),
  x_4 = 1#1 → x_3 = 1#1 → x_2 ^^^ -1#8 ^^^ -1#8 = x_2

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

theorem substitute_constant_and_eq_ugt_swap_proof : substitute_constant_and_eq_ugt_swap_before ⊑ substitute_constant_and_eq_ugt_swap_after

theorem scalar_i32_shl_and_negC_eq_nonzero_proof : scalar_i32_shl_and_negC_eq_nonzero_before ⊑ scalar_i32_shl_and_negC_eq_nonzero_after

theorem not_ashr_const_proof : not_ashr_const_before ⊑ not_ashr_const_after

theorem exact_ashr_eq_proof : exact_ashr_eq_before ⊑ exact_ashr_eq_after

theorem test5_proof : test5_before ⊑ test5_after

theorem e_1086 :
     - 6 *  ~~~(z ^^^ t) - 11 *  ~~~z - 6 * t + 7 *  ~~~(z &&&  ~~~z) - 1 * (z |||  ~~~t) + 11 *  ~~~(z ||| t) + 10 *  ~~~(z |||  ~~~t) - 6 * (z &&&  ~~~t) =  - 6 * (z &&& t)

theorem alive_constant_fold_100: 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;
  %v200 := pair:%v191 %v001;
  %v201 := op:add w %v200;
  %v210 := pair:%v201 %v001;
  %v211 := op:add w %v210;
  %v220 := pair:%v211 %v001;
  %v221 := op:add w %v220;
  %v230 := pair:%v221 %v001;
  %v231 := op:add w %v230;
  %v240 := pair:%v231 %v001;
  %v241 := op:add w %v240;
  %v250 := pair:%v241 %v001;
  %v251 := op:add w %v250;
  %v260 := pair:%v251 %v001;
  %v261 := op:add w %v260;
  %v270 := pair:%v261 %v001;
  %v271 := op:add w %v270;
  %v280 := pair:%v271 %v001;
  %v281 := op:add w %v280;
  %v290 := pair:%v281 %v001;
  %v291 := op:add w %v290;
  %v300 := pair:%v291 %v001;
  %v301 := op:add w %v300;
  %v310 := pair:%v301 %v001;
  %v311 := op:add w %v310;
  %v320 := pair:%v311 %v001;
  %v321 := op:add w %v320;
  %v330 := pair:%v321 %v001;
  %v331 := op:add w %v330;
  %v340 := pair:%v331 %v001;
  %v341 := op:add w %v340;
  %v350 := pair:%v341 %v001;
  %v351 := op:add w %v350;
  %v360 := pair:%v351 %v001;
  %v361 := op:add w %v360;
  %v370 := pair:%v361 %v001;
  %v371 := op:add w %v370;
  %v380 := pair:%v371 %v001;
  %v381 := op:add w %v380;
  %v390 := pair:%v381 %v001;
  %v391 := op:add w %v390;
  %v400 := pair:%v391 %v001;
  %v401 := op:add w %v400;
  %v410 := pair:%v401 %v001;
  %v411 := op:add w %v410;
  %v420 := pair:%v411 %v001;
  %v421 := op:add w %v420;
  %v430 := pair:%v421 %v001;
  %v431 := op:add w %v430;
  %v440 := pair:%v431 %v001;
  %v441 := op:add w %v440;
  %v450 := pair:%v441 %v001;
  %v451 := op:add w %v450;
  %v460 := pair:%v451 %v001;
  %v461 := op:add w %v460;
  %v470 := pair:%v461 %v001;
  %v471 := op:add w %v470;
  %v480 := pair:%v471 %v001;
  %v481 := op:add w %v480;
  %v490 := pair:%v481 %v001;
  %v491 := op:add w %v490;
  %v500 := pair:%v491 %v001;
  %v501 := op:add w %v500;
  %v510 := pair:%v501 %v001;
  %v511 := op:add w %v510;
  %v520 := pair:%v511 %v001;
  %v521 := op:add w %v520;
  %v530 := pair:%v521 %v001;
  %v531 := op:add w %v530;
  %v540 := pair:%v531 %v001;
  %v541 := op:add w %v540;
  %v550 := pair:%v541 %v001;
  %v551 := op:add w %v550;
  %v560 := pair:%v551 %v001;
  %v561 := op:add w %v560;
  %v570 := pair:%v561 %v001;
  %v571 := op:add w %v570;
  %v580 := pair:%v571 %v001;
  %v581 := op:add w %v580;
  %v590 := pair:%v581 %v001;
  %v591 := op:add w %v590;
  %v600 := pair:%v591 %v001;
  %v601 := op:add w %v600;
  %v610 := pair:%v601 %v001;
  %v611 := op:add w %v610;
  %v620 := pair:%v611 %v001;
  %v621 := op:add w %v620;
  %v630 := pair:%v621 %v001;
  %v631 := op:add w %v630;
  %v640 := pair:%v631 %v001;
  %v641 := op:add w %v640;
  %v650 := pair:%v641 %v001;
  %v651 := op:add w %v650;
  %v660 := pair:%v651 %v001;
  %v661 := op:add w %v660;
  %v670 := pair:%v661 %v001;
  %v671 := op:add w %v670;
  %v680 := pair:%v671 %v001;
  %v681 := op:add w %v680;
  %v690 := pair:%v681 %v001;
  %v691 := op:add w %v690;
  %v700 := pair:%v691 %v001;
  %v701 := op:add w %v700;
  %v710 := pair:%v701 %v001;
  %v711 := op:add w %v710;
  %v720 := pair:%v711 %v001;
  %v721 := op:add w %v720;
  %v730 := pair:%v721 %v001;
  %v731 := op:add w %v730;
  %v740 := pair:%v731 %v001;
  %v741 := op:add w %v740;
  %v750 := pair:%v741 %v001;
  %v751 := op:add w %v750;
  %v760 := pair:%v751 %v001;
  %v761 := op:add w %v760;
  %v770 := pair:%v761 %v001;
  %v771 := op:add w %v770;
  %v780 := pair:%v771 %v001;
  %v781 := op:add w %v780;
  %v790 := pair:%v781 %v001;
  %v791 := op:add w %v790;
  %v800 := pair:%v791 %v001;
  %v801 := op:add w %v800;
  %v810 := pair:%v801 %v001;
  %v811 := op:add w %v810;
  %v820 := pair:%v811 %v001;
  %v821 := op:add w %v820;
  %v830 := pair:%v821 %v001;
  %v831 := op:add w %v830;
  %v840 := pair:%v831 %v001;
  %v841 := op:add w %v840;
  %v850 := pair:%v841 %v001;
  %v851 := op:add w %v850;
  %v860 := pair:%v851 %v001;
  %v861 := op:add w %v860;
  %v870 := pair:%v861 %v001;
  %v871 := op:add w %v870;
  %v880 := pair:%v871 %v001;
  %v881 := op:add w %v880;
  %v890 := pair:%v881 %v001;
  %v891 := op:add w %v890;
  %v900 := pair:%v891 %v001;
  %v901 := op:add w %v900;
  %v910 := pair:%v901 %v001;
  %v911 := op:add w %v910;
  %v920 := pair:%v911 %v001;
  %v921 := op:add w %v920;
  %v930 := pair:%v921 %v001;
  %v931 := op:add w %v930;
  %v940 := pair:%v931 %v001;
  %v941 := op:add w %v940;
  %v950 := pair:%v941 %v001;
  %v951 := op:add w %v950;
  %v960 := pair:%v951 %v001;
  %v961 := op:add w %v960;
  %v970 := pair:%v961 %v001;
  %v971 := op:add w %v970;
  %v980 := pair:%v971 %v001;
  %v981 := op:add w %v980;
  %v990 := pair:%v981 %v001;
  %v991 := op:add w %v990
  dsl_ret %v991
  ]

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

theorem udiv_shl_mul_nuw_proof : udiv_shl_mul_nuw_before ⊑ udiv_shl_mul_nuw_after

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

theorem main7g_logical_thm.extracted_1._13 : ∀ (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 → 0#1 = 1#1 → 0#32 = zeroExtend 32 1#1

theorem lshrugt_01_03_proof : lshrugt_01_03_before ⊑ lshrugt_01_03_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 positive_biggerashr_thm (e : IntW 8) :
  shl (ashr e (const? 8 6)) (const? 8 3) ⊑ LLVM.and (ashr e (const? 8 3)) (const? 8 (-8))

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

theorem signExtend_eq (x : BitVec w) : x.signExtend w = x  := sorry

--

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

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

theorem lshrult_03_06_exact_proof : lshrult_03_06_exact_before ⊑ lshrult_03_06_exact_after

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

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

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

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

theorem add_nuw_nsw_or_and_proof : add_nuw_nsw_or_and_before ⊑ add_nuw_nsw_or_and_after

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

theorem test37_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬31#32 ≥ ↑32 → ofBool (truncate 8 (x >>> 31#32 ||| 512#32) == 11#8) = 0#1

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

theorem canonicalize_logic_first_or0_nsw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.saddOverflow 112#32 = true) →
    ¬(True ∧ (x ||| 15#32).saddOverflow 112#32 = true) → x + 112#32 ||

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

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

theorem a_true_implies_b_true2_proof : a_true_implies_b_true2_before ⊑ a_true_implies_b_true2_after

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

theorem neg_sgt_1_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ofBool (1#8 <ₛ 0#8 - x) = ofBool (x + -1#8 <ₛ BitVec.ofInt 8 (-2))

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

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

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

theorem xor_i8_to_i64_shl_save_and_ne_proof : xor_i8_to_i64_shl_save_and_ne_before ⊑ xor_i8_to_i64_shl_save_and_ne_after

theorem p0_ult_65536_proof : p0_ult_65536_before ⊑ p0_ult_65536_after

theorem invert_signbit_splat_mask_thm (e : IntW 16) (e_1 : IntW 8) :
  LLVM.and (sext 16 (LLVM.xor (ashr e_1 (const? 8 7)) (const? 8 (-1)))) e ⊑
    select (icmp IntPred.sgt e_1 (const? 8 (-1))) e (const? 16 0)

theorem p2_scalar_shifted_urem_by_const_proof : p2_scalar_shifted_urem_by_const_before ⊑ p2_scalar_shifted_urem_by_const_after

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

theorem lshrugt_02_02_thm (e : IntW 4) :
  icmp IntPred.ugt (lshr e (const? 4 2)) (const? 4 2) ⊑ icmp IntPred.ugt e (const? 4 (-5))

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

theorem src_thm (e : IntW 1) :
  shl (LLVM.and (LLVM.xor (shl (const? 32 (-1)) (zext 32 e)) (const? 32 (-1))) (zext 32 e)) (zext 32 e) ⊑
    shl
      (LLVM.and (LLVM.xor (shl (const? 32 (-1)) (zext 32 e) { «nsw» := true, «nuw» := false }) (const? 32 (-1)))
        (zext 32 e))
      (zext 32 e) { «nsw» := true, «nuw» := true }

theorem n4_proof : n4_before ⊑ n4_after

theorem positive_with_icmp_logical_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x <ᵤ 512#32) = 1#1 → ofBool (x + 128#32 <ᵤ 256#32) = ofBool (x <ᵤ 128#32)

theorem e_284 :
     - 3 *  ~~~y + 1 * (x ||| y) + 1 *  ~~~(x ^^^ y) - 2 *  ~~~(x &&&  ~~~y) + 4 *  ~~~(x ||| y) + 8 * (x &&&  ~~~y) + 7 * (x &&& y) = 7 * x - 1 * (x ^^^ y)

theorem trunc_lshr_zext_exact_proof : trunc_lshr_zext_exact_before ⊑ trunc_lshr_zext_exact_after

theorem slt_zero_ult_i1_fail2_proof : slt_zero_ult_i1_fail2_before ⊑ slt_zero_ult_i1_fail2_after

theorem icmp_shl_nsw_sge1_thm (e : IntW 32) :
  icmp IntPred.sge (shl e (const? 32 21) { «nsw» := true, «nuw» := false }) (const? 32 1) ⊑
    icmp IntPred.sgt e (const? 32 0)

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

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

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

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

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

theorem and1_shl1_is_cmp_eq_0_multiuse_proof : and1_shl1_is_cmp_eq_0_multiuse_before ⊑ and1_shl1_is_cmp_eq_0_multiuse_after

theorem bools2_logical_commute2_and1_thm.extracted_1._4 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 &&& x_1 = 1#1 → ¬x_2 = 1#1 → 1#1 = x

theorem sge_or_not_max_proof : sge_or_not_max_before ⊑ sge_or_not_max_after

theorem test1_thm (e e_1 : IntW 47) :
  LLVM.xor (LLVM.and e_1 (const? 47 (-70368744177664))) (LLVM.and e (const? 47 70368744177661)) ⊑
    LLVM.or (LLVM.and e_1 (const? 47 (-70368744177664))) (LLVM.and e (const? 47 70368744177661))
      { «disjoint» := true }

theorem p1_ugt_thm.extracted_1._3 : ∀ (x x_1 : BitVec 32),
  ¬ofBool (65534#32 <ᵤ x_1) = 1#1 → ¬ofBool (x_1 <ᵤ 65535#32) = 1#1 → 65535#32 = x

theorem src_is_mask_const_sgt_proof : src_is_mask_const_sgt_before ⊑ src_is_mask_const_sgt_after

theorem l_thm.extracted_1._1 : ∀ (x x_1 x_2 : BitVec 32), 0#32 - x_2 + (0#32 - x_1) + x = x - (x_2 + x_1)

theorem scalar_i32_signbit_lshr_and_eq_X_is_constant2_proof : scalar_i32_signbit_lshr_and_eq_X_is_constant2_before ⊑ scalar_i32_signbit_lshr_and_eq_X_is_constant2_after

theorem negate_xor_thm (e : IntW 4) :
  sub (const? 4 0) (LLVM.xor e (const? 4 5)) ⊑ add (LLVM.xor e (const? 4 (-6))) (const? 4 1)

theorem main6_logical_thm (e : IntW 32) :
  select
      (select (icmp IntPred.eq (LLVM.and e (const? 32 7)) (const? 32 3))
        (icmp IntPred.eq (LLVM.and e (const? 32 48)) (const? 32 16)) (const? 1 0))
      (const? 32 0) (const? 32 1) ⊑
    zext 32 (icmp IntPred.ne (LLVM.and e (const? 32 55)) (const? 32 19))

theorem canonicalize_logic_first_or0_nswnuw_proof : canonicalize_logic_first_or0_nswnuw_before ⊑ canonicalize_logic_first_or0_nswnuw_after

@[simp]
theorem state0_eq_stateN_zero {σ : Type} {ι : Type} {n : Nat} (s : σ) :
    (Vars.state0 s : Vars σ ι n) = Vars.stateN s 0

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

theorem lshr_mul_proof : lshr_mul_before ⊑ lshr_mul_after

theorem or_and_not_not_commute3_proof : or_and_not_not_commute3_before ⊑ or_and_not_not_commute3_after

theorem icmp_eq_and_pow2_minus1_shl_pow2_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ¬x ≥ ↑32 → zeroExtend 32 (ofBool (2#32 <<< x &&& 15#32 == 0#32)) = zeroExtend 32 (ofBool (2#32 <ᵤ x))

theorem test_invert_demorgan_logical_or_thm.extracted_1._3 : ∀ (x x_1 : BitVec 64),
  ofBool (x_1 == 27#64) = 1#1 →
    ofBool (x_1 != 27#64) = 1#1 →
      (ofBool (x_1 == 0#64) ||| 1#1) ^^^ 1#1 = ofBool (x_1 != 0#64) &&& ofBool (x != 0#64)

theorem test16_thm (e : IntW 8) : LLVM.and (shl e (const? 8 2)) (const? 8 3) ⊑ const? 8 0

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

theorem main4f_like_logical_thm.extracted_1._4 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 &&& x != x) = 1#1 → ¬ofBool (x_1 &&& x == x) = 1#1 → ¬True → 0#32 = zeroExtend 32 0#1

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

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

theorem uadd_sat_flipped_wrong_bounds7_proof : uadd_sat_flipped_wrong_bounds7_before ⊑ uadd_sat_flipped_wrong_bounds7_after

theorem add_shl_same_amount_partial_nuw2_proof : add_shl_same_amount_partial_nuw2_before ⊑ add_shl_same_amount_partial_nuw2_after

theorem trunc_shl_1_i32_i64_thm.extracted_1._2 : ∀ (x : BitVec 64),
  ¬1#64 ≥ ↑64 → ¬1#32 ≥ ↑32 → truncate 32 (x <<< 1#64) = truncate 32 x <<< 1#32

theorem mul_selectp2_x_non_const_thm.extracted_1._4 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1),
  x_2 = 1#1 → ¬1#8 ≥ ↑8 → 2#8 * x = x <<< 1#8

theorem pr51551_neg1_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬(True ∧ (x_1 &&& BitVec.ofInt 32 (-3) ||| 1#32).smulOverflow x = true) →
    True ∧ (x_1 &&& 4#32 &&& 1#32 != 0) = true → False

theorem t0_commutative_thm.extracted_1._14 : ∀ (x x_1 x_2 x_3 : BitVec 8),
  ofBool (x_3 == x_2) = 1#1 → ofBool (x_3 != x_2) = 1#1 → ¬True → False

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

theorem logic_or_logic_and_1_proof : logic_or_logic_and_1_before ⊑ logic_or_logic_and_1_after

theorem ashr_lshr_cst2_proof : ashr_lshr_cst2_before ⊑ ashr_lshr_cst2_after

theorem ne_smin3_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ofBool (x_1 + 3#32 <ₛ x) = 1#1 → ofBool (x_1 + 3#32 != x_1 + 3#32) = ofBool (x <ₛ x_1 + 3#32)

theorem shl_add_lshr_comm_proof : shl_add_lshr_comm_before ⊑ shl_add_lshr_comm_after

theorem bisimul_accepts :
    Bisimul R M₁ M₂ → M₁.accepts = M₂.accepts

theorem test8_proof : test8_before ⊑ test8_after

theorem e_631 :
    2 *  ~~~(x ^^^ y) - 1 *  ~~~x + 1 * (x ^^^ y) - 7 *  ~~~(x &&& y) + 5 *  ~~~y + 2 * (x |||  ~~~y) - 2 *  ~~~(x ||| y) - 5 *  ~~~(x |||  ~~~y) - 12 * (x &&&  ~~~y) - 16 * (x &&& y) =  - 1 *  ~~~(x &&&  ~~~y) - 11 * (x ||| y)

theorem alive_Select_1100 : alive_Select_1100_src ⊑ alive_Select_1100_tgt

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

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

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

@[simp]
theorem EnvFin.getLsbD_getNonLsbs {w : Nat} (env : EnvFin (w + 1) n) (bit : Nat) :
    (env.getNonLsbs i).getLsbD bit = (decide (bit < w) && (env i).getLsbD (bit + 1))

theorem sext_proof : sext_before ⊑ sext_after

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

theorem test2_proof : test2_before ⊑ test2_after

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

theorem t9_ashr_exact_flag_preservation_proof : t9_ashr_exact_flag_preservation_before ⊑ t9_ashr_exact_flag_preservation_after

@[bv_multi_width_normalize] theorem BitVec.lt_eq_ult {x y : BitVec w} :
    (x < y) = ((x.ult y) = true)

theorem ashr_exact_add_negative_shift_negative_proof : ashr_exact_add_negative_shift_negative_before ⊑ ashr_exact_add_negative_shift_negative_after

theorem lt_signed_to_small_negative_proof : lt_signed_to_small_negative_before ⊑ lt_signed_to_small_negative_after

theorem positive_with_icmp_logical_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬ofBool (x <ᵤ 512#32) = 1#1 → 0#1 = ofBool (x <ᵤ 128#32)

theorem ashr_lshr_no_lshr_thm (e e_1 : IntW 32) :
  select (icmp IntPred.sge e_1 (const? 32 0)) (add e_1 e) (ashr e_1 e) ⊑
    select (icmp IntPred.slt e_1 (const? 32 0)) (ashr e_1 e) (add e_1 e)

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

theorem e_2482 :
    1 * (e ^^^  ~~~(d &&& (e ||| f))) + 7 *  ~~~( ~~~d &&& ( ~~~e &&& f)) + 1 * (e |||  ~~~(d ||| f)) + 11 * ((d &&& e) |||  ~~~(e ^^^ f)) - 5 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 3 * (e &&& (d ||| f)) + 1 * (e ^^^  ~~~(d ||| ( ~~~e &&& f))) + 3 * (d ^^^ (e ||| f)) - 1 * (e ^^^ ( ~~~d &&& (e ^^^ f))) - 1 * ( ~~~d &&& (e ^^^ f)) + 2 * (e ^^^  ~~~(d &&& f)) + 2 *  ~~~(d &&& (e ^^^ f)) + 5 * (f |||  ~~~(d |||  ~~~e)) + 2 * (d ||| (e ^^^ f)) - 1 * (e ^^^ ( ~~~d &&& (e ||| f))) + 7 * ((d &&& f) ||| (e &&&  ~~~f)) - 2 * ( ~~~(d &&& e) &&&  ~~~(e ^^^ f)) + 1 * ( ~~~d ||| (e ||| f)) - 1 * ((d &&& f) ^^^  ~~~(d ^^^ (e &&& f))) + 7 *  ~~~( ~~~d &&& (e ||| f)) + 2 * (d ||| (e ||| f)) - 1 * ( ~~~e &&& (d ^^^ f)) + 2 *  ~~~(d &&&  ~~~d) + 1 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 11 * ((d &&& e) ^^^ (e ||| f)) - 1 * (e &&&  ~~~f) - 2 * ((d &&& e) ^^^  ~~~(d ^^^ (e &&& f))) + 5 * (f &&&  ~~~(d &&& e)) - 3 * ((d &&& e) |||  ~~~(e ||| f)) - 3 * ((d &&& f) ^^^  ~~~(e &&&  ~~~f)) + 4 * (f ^^^  ~~~( ~~~d &&& (e ||| f))) - 1 * (f ^^^ (d &&& e)) - 7 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 6 *  ~~~(d &&& f) + 2 * ((d &&& f) ^^^ (d ^^^ (e &&& f))) + 5 * (d &&&  ~~~e) - 5 * (e ^^^ (d &&& (e ||| f))) - 7 * (e &&&  ~~~(d &&&  ~~~f)) + 1 * (f ^^^  ~~~(d &&& ( ~~~e &&& f))) - 1 * (e ^^^ ( ~~~d ||| (e ||| f))) - 2 * ( ~~~(d &&&  ~~~e) &&&  ~~~(e ^^^ f)) + 5 *  ~~~(d ^^^ (e ^^^ f)) + 1 * ((d &&& e) ^^^  ~~~(d ^^^ ( ~~~e ||| f))) + 3 * (d &&& (e ||| f)) - 11 *  ~~~(d ^^^ (e &&& f)) - 3 * (e ^^^  ~~~(d ||| (e &&& f))) + 11 * (e ^^^ f) - 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) - 7 * ( ~~~(d ||| e) |||  ~~~(e ^^^ f)) + 1 * (d ||| f) + 4 * (e |||  ~~~(d ^^^ f)) - 2 * (f ^^^ ( ~~~d ||| (e &&& f))) - 2 * (e ^^^ ( ~~~d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& (e &&& f))) - 5 * (e &&& f) + 1 * (f ^^^ (d ||| e)) + 1 * (e ^^^  ~~~( ~~~d ||| ( ~~~e &&& f))) + 5 *  ~~~(d ||| ( ~~~e &&& f)) + 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) + 7 * (e ^^^  ~~~(d |||  ~~~f)) - 7 * f + 2 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 6 * ( ~~~f |||  ~~~(d ^^^ e)) + 4 * ( ~~~d ||| ( ~~~e &&& f)) - 3 * ((d &&& e) ||| (e ^^^ f)) + 4 * (e ^^^ (d ||| ( ~~~e &&& f))) + 1 *  ~~~(d &&& ( ~~~e ||| f)) - 7 * (d |||  ~~~f) - 1 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 * (e ||| f) + 1 * ( ~~~(d |||  ~~~e) ||| (e ^^^ f)) - 2 *  ~~~( ~~~d &&& (e ^^^ f)) - 3 *  ~~~(d ||| (e ||| f)) - 24 *  ~~~(d ||| ( ~~~e ||| f)) - 23 *  ~~~( ~~~d ||| (e ||| f)) - 66 *  ~~~( ~~~d ||| ( ~~~e ||| f)) - 15 * ( ~~~d &&& ( ~~~e &&& f)) - 29 * ( ~~~d &&& (e &&& f)) - 67 * (d &&& ( ~~~e &&& f)) - 3 * (d &&& (e &&& f)) =  - 4 * ((e &&&  ~~~f) ^^^ ( ~~~d ||| (e ^^^ f))) - 11 * ( ~~~d ||| (e ^^^ f))

theorem smear_sign_and_widen_proof : smear_sign_and_widen_before ⊑ smear_sign_and_widen_after

theorem sdiv_mul_shl_nsw_proof : sdiv_mul_shl_nsw_before ⊑ sdiv_mul_shl_nsw_after

theorem sdiv_common_divisor_defined_cond_proof : sdiv_common_divisor_defined_cond_before ⊑ sdiv_common_divisor_defined_cond_after

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

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

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

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

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

theorem alive_AndOrXor_2595 : alive_AndOrXor_2595_src ⊑ alive_AndOrXor_2595_tgt

@[grind =, simp]
lemma RawCNFA.empty_stateMax : empty (A := A).stateMax = 0

theorem lshr_31_i32_add_zext_basic_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32),
  ¬31#64 ≥ ↑64 →
    True ∧ (zeroExtend 64 x_1).saddOverflow (zeroExtend 64 x) = true ∨
        True ∧ (zeroExtend 64 x_1).uaddOverflow (zeroExtend 64 x) = true ∨ 31#64 ≥ ↑64 →
      False

theorem ule_swap_or_not_min_logical_proof : ule_swap_or_not_min_logical_before ⊑ ule_swap_or_not_min_logical_after

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

@[simp]
lemma formula_predicate_term_match {t : Term} :
    t.denote w vars = t.evalNat (vars[·]!)

theorem test_thm.extracted_1._1' : ∀ (x : BitVec 64),
  ¬(-1#32 == 0 || 32 != 1 && truncate 32 (x ||| 4294967294#64) == intMin 32 && -1#32 == -1) = true →
    (truncate 32 (x ||| 4294967294#64)).srem (-1#32) = 0#32

theorem or_nosignbit_select_lshr_thm (e : IntW 32) (e_1 : IntW 1) :
  lshr (select e_1 (LLVM.or e (const? 32 2147418112)) e) (const? 32 8) ⊑
    select e_1 (LLVM.or (lshr e (const? 32 8)) (const? 32 8388352)) (lshr e (const? 32 8))

@[grind =, simp]
lemma RawCNFA.addFinal_finals {m : RawCNFA A} : (m.addFinal s).finals = m.finals.insert s

theorem n14_trunc_of_lshr_thm.extracted_1._1 : ∀ (x x_1 : BitVec 32) (x_2 : BitVec 64),
  ¬(zeroExtend 64 (32#32 - x_1) ≥ ↑64 ∨ x_1 + -1#32 ≥ ↑32) →
    x_1 + -1#32 ≥ ↑32 ∨ True ∧ (32#32 - x_1).msb = true ∨ zeroExtend 64 (32#32 - x_1) ≥ ↑64 → False

theorem select_add_icmp_bad_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 32),
  ofBool (x_2 == 1#32) = 1#1 → x_2 + x_1 = x_1 + 1#32

theorem e_2033 :
    1 *  ~~~(d &&& f) - 1 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 5 * (e ^^^ ( ~~~d ||| (e ||| f))) - 5 * (e ^^^  ~~~(d &&& (e ^^^ f))) + 2 * (f ^^^  ~~~(d &&& e)) - 3 * (e &&& (d ^^^ f)) + 2 * (e &&&  ~~~f) - 2 * ( ~~~d ||| (e &&& f)) + 11 * (d ^^^ f) + 2 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) + 11 * (e ||| (d &&& f)) - 11 * ((e &&& f) ||| ( ~~~d &&& (e ||| f))) + 2 * (f ^^^  ~~~( ~~~d &&& (e &&& f))) - 3 * (d |||  ~~~e) - 2 * ((d &&& f) ^^^ (e ||| f)) + 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 1 * (d &&&  ~~~f) + 5 * (d ||| (e &&& f)) - 5 * (e ^^^  ~~~(d ||| f)) + 4 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) + 1 * ((d &&& e) |||  ~~~(e ||| f)) + 1 * ((e &&& f) ^^^  ~~~(d &&& (e ^^^ f))) + 1 *  ~~~(d &&& ( ~~~e ||| f)) - 6 * (d ^^^ (e ^^^ f)) - 1 * (f ^^^  ~~~(d ||| ( ~~~e &&& f))) - 1 * (e ^^^  ~~~(d &&& ( ~~~e ||| f))) - 1 * (e &&& f) + 4 * ((e &&&  ~~~f) |||  ~~~(d ||| ( ~~~e &&& f))) - 4 *  ~~~(d ||| (e ||| f)) - 16 *  ~~~( ~~~d ||| (e ||| f)) - 21 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 12 * ( ~~~d &&& ( ~~~e &&& f)) - 17 * ( ~~~d &&& (e &&& f)) - 18 * (d &&& ( ~~~e &&& f)) + 4 * (d &&& (e &&& f)) = 8 *  ~~~(d ||| ( ~~~e ||| f))

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

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

theorem ashrsgt_03_06_exact_proof : ashrsgt_03_06_exact_before ⊑ ashrsgt_03_06_exact_after

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

theorem lshr_xor_or_good_mask_proof : lshr_xor_or_good_mask_before ⊑ lshr_xor_or_good_mask_after

theorem ashrsgt_01_08_exact_proof : ashrsgt_01_08_exact_before ⊑ ashrsgt_01_08_exact_after

theorem test9_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬16#32 ≥ ↑32 →
    ¬(16#32 ≥ ↑32 ∨ True ∧ (x.sshiftRight' 16#32).smulOverflow (BitVec.ofInt 32 (-32767)) = true) →
      signExtend 64 (x.sshiftRight' 16#32) * BitVec.ofInt 64 (-32767) =
        signExtend 64 (x.sshiftRight' 16#32 * BitVec.ofInt 32 (-32767))

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

theorem test10_thm (e : IntW 32) :
  icmp IntPred.ugt (LLVM.udiv (const? 32 4) e) (const? 32 1) ⊑ icmp IntPred.ult e (const? 32 3)

theorem p14_commutativity1_proof : p14_commutativity1_before ⊑ p14_commutativity1_after

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

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

theorem mul_splat_fold_no_nuw_thm (e : IntW 32) :
  lshr (mul e (const? 32 65537) { «nsw» := true, «nuw» := false }) (const? 32 16) ⊑
    add e (lshr e (const? 32 16)) { «nsw» := true, «nuw» := false }

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

theorem test55_thm (e : IntW 32) :
  sext 64 (LLVM.and (LLVM.or (trunc 16 e) (const? 16 (-32574))) (const? 16 (-25350))) ⊑
    sext 64 (LLVM.or (LLVM.and (trunc 16 e) (const? 16 7224)) (const? 16 (-32574)) { «disjoint» := true })

theorem not_cmp_constant_proof : not_cmp_constant_before ⊑ not_cmp_constant_after

theorem e_1915 :
     - 2 * ( ~~~(a &&&  ~~~b) &&& (b ^^^ c)) - 2 *  ~~~(a &&& (b ^^^ c)) + 4 * (a ^^^ ( ~~~b ||| c)) + 3 *  ~~~(b &&& c) + 1 * ( ~~~(a |||  ~~~b) |||  ~~~(b ^^^ c)) - 5 * (a ||| (b ||| c)) + 2 * ((a ||| b) &&&  ~~~(a ^^^ (b ^^^ c))) - 1 *  ~~~a - 7 *  ~~~(a ^^^ b) + 4 * (b ^^^ (a ||| ( ~~~b ||| c))) - 6 * (b ^^^ ( ~~~a &&& (b ^^^ c))) - 1 * (a ||| b) - 1 * ( ~~~(a &&& b) &&& (b ^^^ c)) - 3 * (c ^^^ ( ~~~a &&& (b ||| c))) - 1 * ( ~~~(a &&& b) &&& (a ^^^ (b ^^^ c))) - 5 * (c ^^^  ~~~(a &&& ( ~~~b ||| c))) + 4 *  ~~~( ~~~a &&& ( ~~~b ||| c)) - 6 * a - 1 * (c ^^^  ~~~( ~~~a &&& ( ~~~b &&& c))) + 5 * (b |||  ~~~c) + 2 * (c ||| (a &&& b)) - 1 *  ~~~(a ^^^ c) - 11 * (a &&& c) - 2 * (c ^^^ ( ~~~a &&& ( ~~~b ||| c))) - 1 * ( ~~~(a &&& b) &&&  ~~~(a ^^^ (b ^^^ c))) - 6 * (b &&& (a |||  ~~~c)) - 3 * ((a ^^^ b) &&&  ~~~(a ^^^ c)) - 7 *  ~~~(a ||| ( ~~~b &&& c)) + 11 *  ~~~(a |||  ~~~c) + 4 * (b &&&  ~~~(a ^^^ c)) + 1 * (c |||  ~~~(a |||  ~~~b)) - 1 *  ~~~( ~~~a &&& (b ^^^ c)) + 1 * (c &&& (a |||  ~~~b)) - 3 * (a |||  ~~~c) - 1 * (c &&&  ~~~(a ^^^ b)) + 11 * ( ~~~(a &&&  ~~~b) &&& (a ^^^ (b ^^^ c))) + 2 * (b ^^^  ~~~(a &&& ( ~~~b &&& c))) - 1 * ( ~~~(a ^^^ b) ||| (a ^^^ c)) + 4 * ( ~~~c &&&  ~~~(a ^^^ b)) + 2 *  ~~~(a &&& (b &&& c)) + 7 * (c ^^^ ( ~~~a ||| (b ||| c))) - 5 * (c ^^^ (a ||| (b &&& c))) - 7 * ((a |||  ~~~b) &&&  ~~~(b ^^^ c)) - 11 * ( ~~~b ||| (a ^^^ c)) + 18 *  ~~~(a ||| (b ||| c)) + 23 *  ~~~( ~~~a ||| (b ||| c)) + 27 *  ~~~( ~~~a ||| ( ~~~b ||| c)) + 3 * ( ~~~a &&& ( ~~~b &&& c)) + 8 * ( ~~~a &&& (b &&& c)) + 39 * (a &&& (b &&& c)) =  - 35 * (a &&& ( ~~~b &&& c))

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

theorem trunc_sel_smaller_zext_proof : trunc_sel_smaller_zext_before ⊑ trunc_sel_smaller_zext_after

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

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

theorem neg_not_signbit2_proof : neg_not_signbit2_before ⊑ neg_not_signbit2_after

theorem sge_swap_and_max_thm.extracted_1._1 : ∀ (x x_1 : BitVec 8),
  ofBool (x_1 ≤ₛ x) &&& ofBool (x == 127#8) = ofBool (x == 127#8)

theorem ashrslt_02_04_proof : ashrslt_02_04_before ⊑ ashrslt_02_04_after

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

theorem PR44545_thm.extracted_1._1 : ∀ (x : BitVec 32),
  ofBool (x == 0#32) = 1#1 →
    ¬(True ∧ (truncate 16 0#32).saddOverflow (-1#16) = true) → truncate 16 0#32 + -1#16 = -1#16

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

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

theorem icmp_slt_0_and_icmp_sgt_neg1_i64_proof : icmp_slt_0_and_icmp_sgt_neg1_i64_before ⊑ icmp_slt_0_and_icmp_sgt_neg1_i64_after

theorem trunc_lshr_zext_thm.extracted_1._2 : ∀ (x : BitVec 8),
  ¬6#32 ≥ ↑32 → ¬6#8 ≥ ↑8 → truncate 8 (zeroExtend 32 x >>> 6#32) = x >>> 6#8

theorem ashrslt_01_00_exact_proof : ashrslt_01_00_exact_before ⊑ ashrslt_01_00_exact_after

theorem badimm4_thm (e : IntW 16) :
  select (icmp IntPred.eq (ashr (trunc 8 e) (const? 8 7)) (trunc 8 (lshr e (const? 16 8)))) (trunc 8 e)
      (LLVM.xor (trunc 8 (ashr e (const? 16 15))) (const? 8 126)) ⊑
    select (icmp IntPred.sgt e (const? 16 127)) (const? 8 126)
      (select (icmp IntPred.slt e (const? 16 (-128))) (const? 8 (-127)) (trunc 8 e))

theorem e_2464 :
    3 * ((d &&& f) ^^^ (d ^^^ ( ~~~e &&& f))) - 7 * ((d ||| e) &&&  ~~~(d ^^^ (e ^^^ f))) - 6 * (f ^^^ (d &&& e)) - 7 * (d ^^^ ( ~~~e &&& f)) - 1 * (e |||  ~~~f) + 11 * (f ^^^ (d &&& (e ||| f))) - 2 * (e ^^^  ~~~( ~~~d &&& ( ~~~e &&& f))) + 1 * ( ~~~e ||| (d ^^^ f)) - 3 * (e ^^^ f) - 2 * ( ~~~(d ||| e) ||| (e ^^^ f)) + 1 * (e ^^^  ~~~(d &&& (e ^^^ f))) - 1 * ((d &&& f) ||| (e &&&  ~~~f)) + 1 * ((d &&&  ~~~e) |||  ~~~(e ^^^ f)) - 5 * ( ~~~e &&& (d ^^^ f)) + 1 *  ~~~(d &&& ( ~~~e ||| f)) + 2 * (e &&&  ~~~f) + 1 * (e ^^^ (d ||| (e ^^^ f))) - 6 * (f ^^^ ( ~~~d ||| ( ~~~e &&& f))) - 6 * (e ^^^  ~~~(d ||| (e ^^^ f))) + 1 * (e |||  ~~~(d |||  ~~~f)) - 1 * ( ~~~d ||| ( ~~~e ||| f)) + 5 * ( ~~~f &&& (d ^^^ e)) - 1 * (e ^^^ (d ||| (e ||| f))) + 5 * (d ^^^ (e ||| f)) + 1 * (f ^^^ ( ~~~d &&& ( ~~~e ||| f))) + 3 * ((d ^^^ e) &&& (d ^^^ f)) - 1 * (e ^^^  ~~~( ~~~d &&& (e &&& f))) + 4 *  ~~~( ~~~d &&& (e ^^^ f)) + 4 * (e ^^^  ~~~( ~~~d ||| (e &&& f))) - 2 * (f ^^^ (d &&&  ~~~e)) + 3 * ((d &&& e) |||  ~~~(e ||| f)) + 2 * (f ^^^ (d ||| ( ~~~e &&& f))) + 1 * (e ^^^  ~~~(d &&& (e ||| f))) - 1 * (f ^^^ (d ||| (e ||| f))) + 2 * (f &&& (d ^^^ e)) - 11 * ( ~~~(d |||  ~~~e) |||  ~~~(e ^^^ f)) - 3 *  ~~~(d &&& (e ^^^ f)) - 11 * (f ^^^  ~~~(d &&& e)) - 1 * (d ^^^ e) - 7 * ((d &&&  ~~~e) ||| (e ^^^ f)) - 7 * (d &&& e) - 2 *  ~~~(d &&& (e ||| f)) + 5 * (f ^^^ ( ~~~d ||| (e ||| f))) + 7 * (d ||| e) - 2 * (f &&&  ~~~(d &&&  ~~~e)) - 1 * ((d |||  ~~~e) &&&  ~~~(e ^^^ f)) + 2 * (f ||| (d ^^^ e)) + 1 * (f ^^^ (d &&& ( ~~~e ||| f))) - 2 * (d ||| ( ~~~e &&& f)) + 2 * ((d ^^^ e) |||  ~~~(d ^^^ f)) + 11 * (d ^^^ f) + 5 *  ~~~( ~~~d &&& (e ||| f)) - 1 *  ~~~(d &&& f) - 3 * (f ||| (d &&&  ~~~e)) + 1 * (d &&& (e ||| f)) + 11 * (e ^^^ (d &&&  ~~~f)) - 1 * ( ~~~(d &&&  ~~~e) &&&  ~~~(d ^^^ (e ^^^ f))) - 5 * ((d &&& e) ^^^ (d ^^^ (e &&& f))) - 2 * (e ^^^ (d &&& (e ^^^ f))) + 4 * (f ^^^ ( ~~~d ||| ( ~~~e ||| f))) + 1 *  ~~~(d &&& e) - 5 * ( ~~~(d &&& e) &&& (e ^^^ f)) - 11 * ( ~~~d ||| (e ||| f)) + 2 * ( ~~~d ||| (e ^^^ f)) - 3 *  ~~~( ~~~d ||| (e &&& f)) + 2 * (f ^^^  ~~~(d ||| e)) + 4 * ((e &&& f) ||| (d &&& (e ||| f))) + 1 * ((e &&& f) ^^^  ~~~( ~~~d &&& (e ^^^ f))) + 3 * ((e &&&  ~~~f) |||  ~~~( ~~~d ||| ( ~~~e &&& f))) - 1 *  ~~~(e &&&  ~~~f) - 1 * ( ~~~(d ^^^ e) &&&  ~~~(d ^^^ f)) + 28 *  ~~~(d ||| (e ||| f)) + 14 *  ~~~(d ||| ( ~~~e ||| f)) - 10 *  ~~~( ~~~d ||| (e ||| f)) - 10 *  ~~~( ~~~d ||| ( ~~~e ||| f)) + 23 * ( ~~~d &&& ( ~~~e &&& f)) - 18 * ( ~~~d &&& (e &&& f)) + 14 * (d &&& ( ~~~e &&& f)) + 32 * (d &&& (e &&& f)) =  - 7 * ((d ||| e) &&& (e ^^^ f)) + 1 * (f ^^^ ( ~~~d ||| (e &&& f)))

theorem xor_logic_and_or1_thm.extracted_1._2 : ∀ (x x_1 x_2 : BitVec 1),
  x_2 = 1#1 → x_1 ^^^ (x ||| x_2) = x_1 ^^^ 1#1

theorem lshr_and_add_proof : lshr_and_add_before ⊑ lshr_and_add_after

theorem test48_thm.extracted_1._1 : ∀ (x : BitVec 8),
  ¬8#32 ≥ ↑32 →
    True ∧ (zeroExtend 32 x <<< 8#32).sshiftRight' 8#32 ≠ zeroExtend 32 x ∨
        True ∧ zeroExtend 32 x <<< 8#32 >>> 8#32 ≠ zeroExtend 32 x ∨
          8#32 ≥ ↑32 ∨
            True ∧ (zeroExtend 32 x <<< 8#32 &&& zeroExtend 32 x != 0) = true ∨
              True ∧ (zeroExtend 32 x <<< 8#32 ||| zeroExtend 32 x).msb = true →
      False

theorem shl_nuw_add_nuw_thm.extracted_1._2 : ∀ (x : BitVec 32),
  ¬(True ∧ x.uaddOverflow 1#32 = true ∨ True ∧ 1#32 <<< (x + 1#32) >>> (x + 1#32) ≠ 1#32 ∨ x + 1#32 ≥ ↑32) →
    ¬(True ∧ 2#32 <<< x >>> x ≠ 2#32 ∨ x ≥ ↑32) → 1#32 <<< (x + 1#32) = 2#32 <<< x

theorem not_add_proof : not_add_before ⊑ not_add_after

theorem xor_notand_to_or_not2_proof : xor_notand_to_or_not2_before ⊑ xor_notand_to_or_not2_after

theorem negate_select_of_op_vs_negated_op_nsw_xyyx_thm.extracted_1._2 : ∀ (x x_1 : BitVec 8) (x_2 : BitVec 1)
  (x_3 : BitVec 8), ¬x_2 = 1#1 → ¬(True ∧ x.ssubOverflow x_1 = true) → x_3 - (x - x_1) = x_1 - x + x_3

theorem factorize4_proof : factorize4_before ⊑ factorize4_after

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

theorem t17_nocse_mismatching_x_proof : t17_nocse_mismatching_x_before ⊑ t17_nocse_mismatching_x_after

theorem eq_smin3_thm (e e_1 : IntW 32) :
  icmp IntPred.eq (add e_1 (const? 32 3))
      (select (icmp IntPred.slt (add e_1 (const? 32 3)) e) (add e_1 (const? 32 3)) e) ⊑
    icmp IntPred.sle (add e_1 (const? 32 3)) e

theorem ashr_sge_noexact_proof : ashr_sge_noexact_before ⊑ ashr_sge_noexact_after

theorem eq_smin2_proof : eq_smin2_before ⊑ eq_smin2_after

theorem AvoidCollision_setWidth_or {x y : BitVec w} :
    (x ||| y).setWidth k = x.setWidth k ||
</all_available_lemmas>

<local_ctx>
import Mathlib.Data.Bool.Basic

import Mathlib.Data.Fin.Basic

import Blase.Fast.BitStream

import Blase.SingleWidth.Defs

open Term

open BitStream in

def Term.eval (t : Term) (vars : List BitStream) : BitStream :=
  match t with
  | var n       => vars.getD n default
  | zero        => BitStream.zero
  | one         => BitStream.one
  | negOne      => BitStream.negOne
  | ofNat n     => BitStream.ofNat n
  | and t₁ t₂   => (t₁.eval vars) &&& (t₂.eval vars)
  | or t₁ t₂    => (t₁.eval vars) ||| (t₂.eval vars)
  | xor t₁ t₂   => (t₁.eval vars) ^^^ (t₂.eval vars)
  | not t       => ~~~(t.eval vars)
  | add t₁ t₂   => (Term.eval t₁ vars) + (Term.eval t₂ vars)
  | sub t₁ t₂   => (Term.eval t₁ vars) - (Term.eval t₂ vars)
  | neg t       => -(Term.eval t vars)


  | shiftL t n  => BitStream.shiftLeft (Term.eval t vars) n

def Predicate.evalEq (t₁ t₂ : BitStream) : BitStream := (t₁ ^^^ t₂).concat false |>.scanOr

def Predicate.evalNeq (t₁ t₂ : BitStream) : BitStream := (t₁.nxor t₂).concat true |>.scanAnd

def Predicate.evalLor (t₁ t₂ : BitStream) : BitStream := (t₁ &&& t₂)

def Predicate.evalLand (t₁ t₂ : BitStream) : BitStream := (t₁ ||| t₂)

def Predicate.evalUlt (t₁ t₂ : BitStream) : BitStream := (~~~ (t₁.borrow t₂)).concat true

def Predicate.evalMsbEq (t₁ t₂ : BitStream) : BitStream :=
  (t₁ ^^^ t₂).concat false

def Predicate.evalSlt (t₁ t₂ : BitStream) : BitStream :=
    (((Predicate.evalUlt t₁ t₂)) ^^^ (Predicate.evalMsbEq t₁ t₂))

open BitStream in

def Predicate.eval (p : Predicate) (vars : List BitStream) : BitStream :=
  match p with
  | .width .eq n => BitStream.falseIffEq n
  | .width .neq n => BitStream.falseIffNeq n
  | .width .lt n => BitStream.falseIffLt n
  | .width .le n => BitStream.falseIffLe n
  | .width .gt n => BitStream.falseIffGt n
  | .width .ge n => BitStream.falseIffGe n
  | lor p q => Predicate.evalLor (p.eval vars) (q.eval vars)
  | land p q => Predicate.evalLand (p.eval vars) (q.eval vars)
  | binary .eq t₁ t₂ => Predicate.evalEq (t₁.eval vars) (t₂.eval vars)
   
  | binary .neq t1 t2 => Predicate.evalNeq (t1.eval vars) (t2.eval vars)
  | binary .ult t₁ t₂ => Predicate.evalUlt (t₁.eval vars) (t₂.eval vars)
  | binary .ule t₁ t₂ =>
     Predicate.evalLor
       (Predicate.evalEq (t₁.eval vars) (t₂.eval vars))
       (Predicate.evalUlt (t₁.eval vars) (t₂.eval vars))
  | binary .slt t₁ t₂ => Predicate.evalSlt (t₁.eval vars) (t₂.eval vars)
  | binary .sle t₁ t₂ => Predicate.evalLor
       (Predicate.evalEq (t₁.eval vars) (t₂.eval vars))
       (Predicate.evalSlt (t₁.eval vars) (t₂.eval vars))

section Predicate

end Predicate
</local_ctx>

<target_theorem>
theorem Predicate.eval_eq_denote (w : Nat) (p : Predicate) (vars : List (BitVec w)) :
    (p.eval (vars.map .ofBitVecSext) w = false) ↔ p.denote w vars :=
</target_theorem>

