[klee-dev] Can klee generate a combined path expression to reach a particular statement?
Dan Liew
dan at su-root.co.uk
Sat Jan 28 09:30:47 GMT 2017
Hi,
On 27 January 2017 at 22:20, Cong Yan <congyan.apply at gmail.com> wrote:
> Hi,
>
> Is klee able to generate an expression combining different paths? For
> example,
>
> if (a)
> stmt1;
> else
> stmt2;
> stmt3;
The answer is yes and no. It is all dependent on how the C program
above is translated into LLVM IR
For Clang if the code is not optimized these would be broken into
basic blocks with a branch instruction. It that case KLEE
will fork and generate two paths that reach `stmt3`.
To see this
run
clang -S -emit-llvm x.c -o -
on
```
#include <stdio.h>
int main() {
int a = 0;
if (a) {
a = 1;
}
else {
a = 2;
}
printf("done %d\n", a);
return 0;
}
```
You'll see something like
```
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 0, i32* %2, align 4
%3 = load i32, i32* %2, align 4
%4 = icmp ne i32 %3, 0
br i1 %4, label %5, label %6
; <label>:5: ; preds = %0
store i32 1, i32* %2, align 4
br label %7
; <label>:6: ; preds = %0
store i32 2, i32* %2, align 4
br label %7
; <label>:7: ; preds = %6, %5
%8 = load i32, i32* %2, align 4
%9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x
i8], [9 x i8]* @.str, i32 0, i32 0), i32 %8)
ret i32 0
}
```
Note the branching (`br` instruction). KLEE will fork if more than one
path from the branch is feasible.
However if certain passes are run the branching can be removed.
clang -S -emit-llvm x.c -o - | opt -mem2reg -simplifycfg -S
You'll see output like this.
```
...
define i32 @main() #0 {
%1 = icmp ne i32 0, 0
%. = select i1 %1, i32 1, i32 2
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x
i8], [9 x i8]* @.str, i32 0, i32 0), i32 %.)
ret i32 0
}
...
```
You can see there are no branches here and there is a `select`
instruction instead.
This is a special case though. If you put code that has side effects
in the `if` or `else` blocks then LLVM will not
be able to simplify the control flow graph to remove the branches.
Instead you may want to experiment with the `klee_merge()` instrinsic
with I believe is supposed to do state merging.
Note that this instrinsic is experimental and I have no idea if it
still (did it ever?) works.
HTH,
Dan.
More information about the klee-dev
mailing list