-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Annotations take forever to check - hang up in Z3 #944
Comments
Diving a bit deeper, if I look at the spec for (if rd.0 = 19 { old_cpu.1.1 } else { if rd.0 = 13 { if old_cpu.7.0 = 0 ∨ ¬old_cpu.2.1 { old_cpu.1.0 } else { old_cpu.1.1 } } else { if rd.0 = 14 { old_cpu.3 } else { if rd.0 = 15 { old_cpu.4 } else { if rd.0 = 16 { if old_cpu.2.0 ∧ old_cpu.2.1 { BV32 { bv_int_to_bv32(3) } } else { if old_cpu.2.0 { BV32 { bv_int_to_bv32(1) } } else { if old_cpu.2.1 { BV32 { bv_int_to_bv32(2) } } else { BV32 { bv_int_to_bv32(0) } } } } } else { if rd.0 = 17 { old_cpu.5 } else { BV32 { bv_and(old_cpu.5.0, bv_int_to_bv32(255)) } } } } } } }.0 And if I look at the SMT query, I see it 210 times. (if (= reftgen$rd$2 19) (tuple2$1 (tuple8$1 reftgen$old_cpu$1)) (if (= reftgen$rd$2 13) (if (or (= (tuple8$7 reftgen$old_cpu$1) 0) (not (tuple2$1 (tuple8$2 reftgen$old_cpu$1)))) (tuple2$0 (tuple8$1 reftgen$old_cpu$1)) (tuple2$1 (tuple8$1 reftgen$old_cpu$1))) (if (= reftgen$rd$2 14) (tuple8$3 reftgen$old_cpu$1) (if (= reftgen$rd$2 15) (tuple8$4 reftgen$old_cpu$1) (if (= reftgen$rd$2 16) (if (and (tuple2$0 (tuple8$2 reftgen$old_cpu$1)) (tuple2$1 (tuple8$2 reftgen$old_cpu$1))) (int_to_bv32 3) (if (tuple2$0 (tuple8$2 reftgen$old_cpu$1)) (int_to_bv32 1) (if (tuple2$1 (tuple8$2 reftgen$old_cpu$1)) (int_to_bv32 2) (int_to_bv32 0)))) (if (= reftgen$rd$2 17) (tuple8$5 reftgen$old_cpu$1) (bvand (tuple8$5 reftgen$old_cpu$1) (int_to_bv32 255)))))))) I'm not sure if this is relevant - but it seems like it may be something to poke at? |
I'm now thinking that this might not matter: Z3Prover/z3#6732 "within z3, there are no "let" term constructors. Let expressions are expanded. The reason why this works is that terms within z3 use shared pointers. So you can write let x = y + y let z = x + x in let u = z + z in u and the term named u has only 5 subterms. |
Hopefully this example helps narrow things down... I have two functions that do something fairly similar.
lmdia_w
updates multiple general purpose register (which is refined by a map) with memory values (another map) at a given address. This address comes from a general purpose register.ldmia_w_special
does the exact same thing, except that it's address comes from a special purpose register.ldmia_w
checks in around 1 second, whileldmia_w_special
hangs and hangs. I'm almost 100% sure that the hang up is in z3 because if I runFLUX_CHECK_DEF=ldmia_w_special cargo flux
and usetop
I see fixpoint spin it's wheels for maybe a few seconds before z3 takes over and goes on and on.The postcondition for
ldmia_w
iswhere
gprs_post_ldmia_w
looks like:The spec for
ldmia_w_special
looks like:where
gprs_post_ldmia_w_special
looks like:The only difference between these two is
get_special_reg
andget_gpr
. Here is the definition for both:I'm pretty convinced that the hang up is in
get_special_reg
. One thing I noticed looking at the constraints and spec etc. is thatget_special_reg
is unfolded multiple times in all the array updates. I'm not very knowledgeable in all things SMT solving but I'm wondering if this complex subexpression showing up many many times is slowing things down? Maybe thelet (var expr)
available in smtlib could help?The text was updated successfully, but these errors were encountered: