[LLVMdev] Handling of pointer difference in llvm-gcc and clang
Stephan Falke
falke at iti.uka.de
Wed Aug 10 07:37:50 PDT 2011
Hi,
We are developing a bounded model checker for C/C++ programs
(http://baldur.iti.kit.edu/llbmc/) that operates on LLVM's intermediate
representation. While checking a C++ program that uses STL containers
we noticed that llvm-gcc and clang handle pointer differences in
disagreeing ways.
Consider the following C function:
int f(int *p, int *q)
{
return q - p;
}
Here's the LLVM code generated by llvm-gcc (2.9):
define i32 @f(i32* %p, i32* %q) nounwind readnone {
entry:
%0 = ptrtoint i32* %q to i32
%1 = ptrtoint i32* %p to i32
%2 = sub nsw i32 %0, %1
%3 = ashr exact i32 %2, 2
ret i32 %3
}
And here is what clang (2.9) produces:
define i32 @f(i32* %p, i32* %q) nounwind readnone {
%1 = ptrtoint i32* %q to i32
%2 = ptrtoint i32* %p to i32
%3 = sub i32 %1, %2
%4 = ashr exact i32 %3, 2
ret i32 %4
}
Thus, llvm-gcc added the nsw flag to the sub, whereas clang didn't.
We think that clang is right and llvm-gcc is wrong: it could be the
case that p and q point into the same array, that q is 0x80000000, and
that p is 0x7FFFFFFE. Then the sub results in a signed overflow, i.e.,
sub with nsw is a trap value.
Is this a bug in llvm-gcc?
--Stephan
More information about the llvm-dev
mailing list