Skip to content

Commit 26e58d7

Browse files
zhixing-xutautschnig
authored andcommitted
Loop shrinking
Enables proving properties in selected loops without having to unwind them. Based on "Property Checking Array Programs Using Loop Shrinking" by Shrawan Kumar, Amitabha Sanyal, Venkatesh R and Punit Shah, TACAS 2018.
1 parent 673e247 commit 26e58d7

File tree

24 files changed

+1059
-4
lines changed

24 files changed

+1059
-4
lines changed

jbmc/unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ CPROVER_LIBS =../src/java_bytecode/java_bytecode$(LIBEXT) \
126126
$(CPROVER_DIR)/src/goto-instrument/reachability_slicer$(OBJEXT) \
127127
$(CPROVER_DIR)/src/goto-instrument/nondet_static$(OBJEXT) \
128128
$(CPROVER_DIR)/src/goto-instrument/full_slicer$(OBJEXT) \
129+
$(CPROVER_DIR)/src/goto-instrument/abstract_loops$(OBJEXT) \
129130
$(CPROVER_DIR)/src/goto-instrument/unwindset$(OBJEXT) \
130131
$(CPROVER_DIR)/src/pointer-analysis/pointer-analysis$(LIBEXT) \
131132
$(CPROVER_DIR)/src/langapi/langapi$(LIBEXT) \
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#define ROW 10
2+
#define COL 10
3+
4+
void main()
5+
{
6+
int sum;
7+
int image[ROW][COL];
8+
9+
// shrinkable
10+
for(int j = 0; j < COL; j++)
11+
image[0][j] = 0;
12+
13+
sum = 0;
14+
// outer loop unshrinkable
15+
// inner loop shrinkable
16+
for(int i = 0; i < ROW; i++)
17+
{
18+
image[i][0] = 0;
19+
sum = sum + i;
20+
for(int j = 0; j < COL; j++)
21+
image[sum][j] = 0;
22+
}
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
main.c
3+
--bounds-check --pointer-check --abstract-loops --show-goto-functions
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
ASSUME j < 10
7+
ASSUME j >= 0
8+
--
9+
ASSUME i < 10
10+
ASSUME i >= 0
11+
^warning: ignoring
12+
--
13+
This test ensures that the loop with loop variable i is not shrunk (so it
14+
appears in unwinding). Loops with loop variable j are shrunk. The test also
15+
checks the constraints to the loop variable are correctly applied.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#define ROW 3
2+
#define COL 10
3+
4+
void boo(int r)
5+
{
6+
int val = 0;
7+
int image[ROW][COL];
8+
;
9+
// shrinkable, and set as shrink target
10+
for(int j = 0; j < COL; j++)
11+
{
12+
int c = j + val;
13+
image[r][c] = val;
14+
}
15+
}
16+
17+
void main()
18+
{
19+
int r;
20+
int buffer[ROW];
21+
// not shrinkable since r is used in mem-safe assertion in boo()
22+
// and r update itself in loop
23+
for(int i = 0; i < ROW; i++)
24+
{
25+
r = r + i;
26+
boo(r);
27+
buffer[i];
28+
}
29+
30+
// shrinkable
31+
for(int i = 0; i < ROW; i++)
32+
{
33+
boo(i);
34+
buffer[i];
35+
}
36+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
main.c
3+
--bounds-check --pointer-check --abstract-loops --abstractset boo.0,main.0 --show-goto-functions
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
ASSUME j < 10
7+
ASSUME j >= 0
8+
--
9+
ASSUME i < 10
10+
ASSUME i >= 0
11+
^warning: ignoring
12+
--
13+
This test ensures that the loops with loop variable i are not shrunk (so they
14+
appear in unwinding). Although the second loop in main is shrinkable, it is not
15+
in the target loop set provided by --abstractset, thus it shouldn't be shrunk.
16+
The test also ensures the loop in boo() with loop variable j is shrunk and the
17+
constraints are correctly applied.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdlib.h>
2+
#define ROW 10
3+
4+
void boo(int *x)
5+
{
6+
*x = *x + 1;
7+
}
8+
9+
void main()
10+
{
11+
int *x = (int *)malloc(sizeof(int));
12+
int buffer[ROW];
13+
*x = 2;
14+
// not shrinkable since x has a self-update in boo()
15+
for(int i = 0; i < ROW; i++)
16+
{
17+
boo(x);
18+
buffer[*x] = 1;
19+
}
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
KNOWNBUG
2+
main.c
3+
--bounds-check --pointer-check --abstract-loops --abstractset main.0
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
main\.0
8+
--
9+
ASSUME i < 10
10+
ASSUME i >= 0
11+
^warning: ignoring
12+
--
13+
This test ensures that the loops with loop variable i are not shrunk (so they
14+
appear in unwinding), even when the instruction that makes the loop unshrinkable
15+
is in another function.
16+
17+
Requires #2646, #2694 to work.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#define ROW 10
2+
#define COL 10
3+
4+
void main()
5+
{
6+
int sum;
7+
int image[ROW][COL];
8+
9+
// shrinkable
10+
for(int j = 0; j < COL; j++)
11+
image[0][j] = 0;
12+
13+
sum = 0;
14+
// outer loop unshrinkable
15+
// inner loop shrinkable
16+
for(int i = 0; i < ROW; i++)
17+
{
18+
image[i][0] = 0;
19+
sum = sum + i;
20+
for(int j = 0; j < COL; j++)
21+
image[sum][j] = 0;
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
CORE
2+
main.c
3+
--bounds-check --pointer-check --abstract-loops
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
main\.0
8+
ASSUME j < 10
9+
ASSUME j >= 0
10+
--
11+
main\.1
12+
main\.2
13+
ASSUME i < 10
14+
ASSUME i >= 0
15+
^warning: ignoring
16+
--
17+
This test ensures that the loop with loop variable i is not shrunk (so it
18+
appears in unwinding). Loops with loop variable j are shrunk. The test also
19+
checks the constraints to the loop variable are correctly applied.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#define ROW 3
2+
#define COL 10
3+
4+
void boo(int r)
5+
{
6+
int val = 0;
7+
int image[ROW][COL];
8+
;
9+
// shrinkable, and set as shrink target
10+
for(int j = 0; j < COL; j++)
11+
{
12+
int c = j + val;
13+
image[r][c] = val;
14+
}
15+
}
16+
17+
void main()
18+
{
19+
int r;
20+
int buffer[ROW];
21+
// not shrinkable since r is used in mem-safe assertion in boo()
22+
// and r update itself in loop
23+
for(int i = 0; i < ROW; i++)
24+
{
25+
r = r + i;
26+
boo(r);
27+
buffer[i];
28+
}
29+
30+
// shrinkable
31+
for(int i = 0; i < ROW; i++)
32+
{
33+
boo(i);
34+
buffer[i];
35+
}
36+
}

0 commit comments

Comments
 (0)