[llvm-dev] Unsupported expression in static initializer?
Andrew Kelley via llvm-dev
llvm-dev at lists.llvm.org
Wed Feb 15 13:51:46 PST 2017
Hmm I'm not sure that workaround will work. Here's the example code I'm
trying to compile (zig language):
// create 2-bit and 3-bit unsigned integer types
const u2 = @intType(false, 2);
const u3 = @intType(false, 3);
// define a packed struct with bitfields. the third field `c` is a pointer
which starts at 6 bits.
const Data = packed struct {
a: u3,
b: u3,
c: &i32,
d: u2,
};
var an_integer: i32 = 1234;
const data = Data {
.a = 1,
.b = 2,
.c = &an_integer,
.d = 3,
};
This generates the LLVM IR:
%Data = type <{ i72 }>
@an_integer = internal unnamed_addr global i32 1234, align 4
@data = internal unnamed_addr constant %Data <{ i72 or (i72 shl (i72 or
(i72 zext (i64 ptrtoint (i32* @an_integer to i64) to i72), i72
184467440737095516160), i72 2), i72 3) }>, align 8
It's an i72 because 3 + 3 + 64 + 2 = 72. The static initializer is trying
to initialize the packed struct with bit fields correctly.
I did notice that this is not possible with clang. Equivalent C:
struct Foo {
unsigned a : 3;
unsigned b : 3;
unsigned long c : 64;
unsigned d : 2;
} __attribute__ ((__packed__));
static int an_integer = 1234;
struct Foo foo = {1, 2, (unsigned long)&an_integer, 3};
unsigned long f(void) {
return foo.c;
}
Gives this compile error:
test.c:12:25: error: initializer element is not a compile-time constant
struct Foo foo = {1, 2, (unsigned long)&an_integer, 3};
^~~~~~~~~~~~~~~~~~~~~~~~~~
Is this simply not possible to determine? Is this because the target does
not support non-byte-aligned relocations at link time? Doesn't the linker
have a way to specify expressions such that this static initializer could
work?
On Wed, Feb 15, 2017 at 4:40 PM, Tim Northover <t.p.northover at gmail.com>
wrote:
> On 15 February 2017 at 13:22, Andrew Kelley via llvm-dev
> <llvm-dev at lists.llvm.org> wrote:
> > LLVM ERROR: Unsupported expression in static initializer: zext (i64
> ptrtoint
> > (i32* @an_integer to i64) to i72)
>
> It's the zext to a really weird type. Generally static initializers
> are only supported if they map neatly to a target's relocation (or an
> expression not needing any relocation).
>
> You could probably emulate it with something (depending on endianness) like
>
> @var = global [i32*, i8] [i32* @an_integer, i8 0]
>
> cast that to an i72* before each use and you probably can't tell the
> difference.
>
> Tim/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/ba96f6d5/attachment.html>
More information about the llvm-dev
mailing list