[llvm-dev] Is it ok to allocate > half of address space?
Nuno Lopes via llvm-dev
llvm-dev at lists.llvm.org
Wed Nov 8 09:24:19 PST 2017
Hi,
I was looking into the semantics of GEP inbounds and some BasicAA
rules and I'm wondering if it's valid in LLVM IR to allocate more than
half of the address space with a global variable or an alloca.
If that's a scenario want to consider, then we have problems :)
Consider this C code (32 bits):
#include <string.h>
char obj[0x80000008];
char f() {
char *p = obj + 0x79999999;
char *q = obj + 0x80000000;
*q = 1;
memcpy(p, "abcd", 4);
return *q;
}
Clearly the stores alias, and the memcpy should override the value
written by "*q = 1".
I dunno if this is legal in C or not, but the IR produced by clang
looks like (32 bits):
@obj = common global [2147483656 x i8] zeroinitializer, align 1
define signext i8 @f() {
store i8 1, i8* getelementptr inbounds (i8, i8* getelementptr
inbounds ([2147483656 x i8], [2147483656 x i8]* @obj, i32 0, i32 0),
i32 -2147483648), align 1
call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds
([2147483656 x i8], [2147483656 x i8]* @obj, i32 0, i32 2040109465),
i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0),
i32 4, i32 1, i1 false)
%1 = load i8, i8* getelementptr inbounds (i8, i8* getelementptr
inbounds ([2147483656 x i8], [2147483656 x i8]* @obj, i32 0, i32 0),
i32 -2147483648), align 1
ret i8 %1
}
With -O2, the store to q gets forwarded, and so we get "ret i8 1".
So, BasicAA concluded that p and q don't alias. The culprit is an
overflow in BasicAAResult::isGEPBaseAtNegativeOffset().
So my question is do we care about this use case where a single
allocation can take more than half of the address space?
Thanks,
Nuno
More information about the llvm-dev
mailing list