[LLVMdev] getelementptr on static const struct
Katsuhiro Ueno
katsu at riec.tohoku.ac.jp
Wed Jan 29 07:42:40 PST 2014
Hi,
I found a mysterious behavior of LLVM optimizer.
I compiled the following code by clang -emit-llvm -S:
#include <stddef.h>
static const struct t {char t[4]; char s;} p = {{}, 'a'};
char f() {
return ((char*)&p)[offsetof(struct t, s)];
}
then I obtained the following LLVM IR:
%struct.t = type { [4 x i8], i8 }
@p = constant %struct.t { [4 x i8] zeroinitializer, i8 97 }, align 1
define signext i8 @f() nounwind ssp uwtable {
%1 = load i8* getelementptr inbounds (%struct.t* @p, i32 0, i32 0,
i64 4), align 1
ret i8 %1
}
By applying the above code to opt -O1 of LLVM 3.4, I obtained:
%struct.t = type { [4 x i8], i8 }
@p = constant %struct.t { [4 x i8] zeroinitializer, i8 97 }, align 1
define signext i8 @f() nounwind readnone ssp uwtable {
ret i8 0
}
The function "f" is eventually compiled into a function that always
returns 0, while I expect "f" returns 'a' (97).
Is this an intended behavior, or a bug?
By replacing the getelementptr expression in the clang output
getelementptr inbounds (%struct.t* @p, i32 0, i32 0, i64 4)
with
getelementptr inbounds (i8* bitcast (%struct.t* @p to i8*), i64 4)
opt -O1 generates the following code that is what I expected:
define signext i8 @f() nounwind readnone ssp uwtable {
ret i8 97
}
I carefully read LLVM Language Reference Manual but I could not
understand the difference of these two getelementptr expressions.
Are these two getelementptr equivalent in the semantics of LLVM IR?
Thanks,
--
UENO, Katsuhiro
More information about the llvm-dev
mailing list