Andrew Kelley via llvm-dev
2017-Feb-15 21:22 UTC
[llvm-dev] Unsupported expression in static initializer?
Why is this not allowed? LLVM ERROR: Unsupported expression in static initializer: zext (i64 ptrtoint (i32* @an_integer to i64) to i72) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170215/d27345ac/attachment.html>
Tim Northover via llvm-dev
2017-Feb-15 21:40 UTC
[llvm-dev] Unsupported expression in static initializer?
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/
Andrew Kelley via llvm-dev
2017-Feb-15 21:51 UTC
[llvm-dev] Unsupported expression in static initializer?
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>
Reasonably Related Threads
- write.table call
- Replacement in an expression - can't use parse()
- Symbolic derivation using D in package stats - how do I properly convert the returned call into a character string?
- Trouble (?) reformatting flash drive to include former U3 partition
- loop in R