-
Notifications
You must be signed in to change notification settings - Fork 119
Description
procedure unsound() {
var x: int;
assume(x == 0);
if (true) {
goto Inside;
}
while (x < 10000) {
Inside: x := x + 1;
}
assert(x == -1);
}$ boogie unsound.bpl /extractLoops
Boogie program verifier finished with 1 verified, 0 errorsHistory of commits
- d8b239c @shazqadeer
added code to handle irreducible graphs - 28d46f8 @shazqadeer reverted it on the same day
- 64b57a0 @akashlal
Support for irreducible graphs (with extractLoops) - b6796ce @shazqadeer finally purged his initial code away from repo
So now the only surviving support for irreducible flow graphs I found is undocumented /extractLoops option
Problem with /extractLoops
Let's say, we have the canonical nonreducible flow graph
graph LR
A --> B & C
B --> C
C --> B
procedure nonreducible() {
A: goto B, C;
B: goto C;
C: goto B;
}According to the Dragon Book (9.7.6 Handling Nonreducible Flow Graphs) this flow graph should be transformed into one of
graph LR
A --> B' & C
B & B' --> C
C --> B
graph LR
A --> B & C'
B --> C
C & C' --> B
procedure reducible1() {
A: goto B', C;
B': goto C;
B: goto C;
C: goto B;
}
procedure reducible2() {
A: goto B, C';
C': goto B;
B: goto C;
C: goto B;
}Meanwhile /extractLoops just unrolls loop and produces control flow which is not equivalent to original
graph LR
A --> B & C
B --> C
C --> B'1
B'1 --> C'1
C'1 --> B'2
B'2 --> ...
procedure reducible() {
A: goto B, C;
B: goto C;
C: goto B'1;
B'1: goto C'1;
C'1: goto B'2;
B'2: goto C'2;
...
}Real-world example
https://github.com/open-s4c/libvsync/blob/main/include/vsync/atomic/internal/arm64.h#L551-L564
graph TB
A[ldx oldv, a
cmp oldv, cmpv]
B[b.eq oldv]
W[wfe]
C[ldx oldv, a
cmp oldv, cmpv]
D[b.neq oldv]
E[add new, oldv, v
stx tmp, new, a]
F[cbnz tmp]
A --> B
B --> W & E
W --> C
C --> D
D --> W & E
E --> F
F --> C
procedure await_eq_add() {
A: goto B;
B: goto W, E;
W: goto C;
C: goto D;
D: goto W, E;
E: goto F;
F: goto C, G;
G: return;
}Conclusions
Are there any unsolvable problems with properly handling irreducible flow graphs, that it was removed by @shazqadeer 28d46f8? Can it be brought back or are there other ways of dealing with this issue in Boogie?
Quotes
We use the standard techniques for converting an irreducible graph into an equivalent, although possibly far larger, reducible graph. We are looking into ways to deal with irreducible graphs that avoid this problem, but so far it has not been an issue.
Barnett, M., Leino, K.R.M. (2005). Weakest-precondition of unstructured programs.
if (!g.Reducible) { throw new VCGenException("Irreducible flow graphs are unsupported."); }