Skip to content
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

LLVM optimization breaking Gazer with --math-int #47

Open
radl97 opened this issue Sep 21, 2020 · 0 comments
Open

LLVM optimization breaking Gazer with --math-int #47

radl97 opened this issue Sep 21, 2020 · 0 comments
Labels
bug Something isn't working

Comments

@radl97
Copy link
Contributor

radl97 commented Sep 21, 2020

Describe the bug

a < 0 || b < 0 becomes BvSlt (BvOr(a,b), 0) (in C it would be (a|b) < 0), which --math-int cannot handle too well...

Haven't tested Theta, but BMC gives a bad result.

To Reproduce

tools/gazer-bmc/gazer-bmc gcd1.c --memory=havoc --math-int --trace --print-final-module=output

#include <assert.h>
int gcd(int a, int b) {
        while (b != 0) {
                int t = b;
                b = a%b;
                a = t;
        }
        return a;
}

int __VERIFIER_nondet_int(void);

int main(void) {
        int a = __VERIFIER_nondet_int();
        int b = __VERIFIER_nondet_int();
        if (a < 0) {
                return 0;
        }
        if (b < 0) {
                return 0;
        }
        assert(gcd(a,b) == gcd(b,a));
}

module output:

define dso_local i32 @main() local_unnamed_addr #0 !dbg !27 {
bb:
  call void @gazer.function.entry(metadata !27)
  %tmp = call i32 @__VERIFIER_nondet_int() #4
  call void @llvm.dbg.value(metadata i32 %tmp, metadata !31, metadata !DIExpression())
  %tmp3 = call i32 @__VERIFIER_nondet_int() #4
  call void @llvm.dbg.value(metadata i32 %tmp3, metadata !32, metadata !DIExpression())
  %tmp4 = or i32 %tmp, %tmp3, !dbg !36 ; !!!
  %tmp5 = icmp slt i32 %tmp4, 0, !dbg !36
  br i1 %tmp5, label %bb10, label %bb6, !dbg !36

bb6:
  %tmp7 = call fastcc i32 @gcd(i32 %tmp, i32 %tmp3)
  call void @gazer.function.call_returned(metadata !27)
  %tmp8 = call fastcc i32 @gcd(i32 %tmp3, i32 %tmp)
  call void @gazer.function.call_returned(metadata !27)
  %tmp9 = icmp eq i32 %tmp7, %tmp8
  br i1 %tmp9, label %bb10, label %error

bb10:
  call void @gazer.function.return_value.i32(metadata !27, i32 0)
  ret i32 0

error:
  %error_phi = phi i16 [ 2, %bb6 ]
  call void @gazer.error_code(i16 %error_phi)
  unreachable
}

BMC sets a=-1 and b=1, which should have meant a successful result (a<0, so return).

This happens only without the --no-optimize flag.

Expected behavior

LLVM shouldn't merge the two if's... a<0 || b<0 is equivalent to (a|b) < 0, but with mathematical integers, the latter does not make sense...

Version (please complete the following information):

  • Tested on Gazer master branch
@radl97 radl97 added the bug Something isn't working label Sep 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant