Антон Кочков via llvm-dev
2017-Jun-01 07:23 UTC
[llvm-dev] Prevent anonymous union optimization
Good time of the day! I'm trying to make some transformations on generated LLVM IR and met a case, which stops me from properly loading the used types. Basically, I have some C code, that compiled into IR using clang -c -emit-llvm and want to process the resulting file. So, the problem is, that I have 2 nested (via anonymous union) structures: typedef struct struct1 { unsigned int a; unsigned int b; int32_t c; } struct1; typedef struct struct2 { int q; int p; int d; union { unsigned int f; int64_t i; double v; struct1 m; int z; int x; int y; }; } It generates: struct.struct2 = type { i32, i32, i32, %union.anon } union.anon = type { i64, [8 x i8] } struct.struct1 = type { i32, i32, i32 } And then performs bitcasts all the time it accesses that structure in the union. If I change struct1 to typedef struct struct1 { unsigned int a; unsigned int b; int32_t c; int64_t some_stupid_alignment; } struct1; Then it generates desired output of struct.struct2 = type { i32, i32, i32, %union.anon } union.anon = type { %struct.struct1 } struct.struct1 = type { i32, i32, i32, i64 } How to force it generate union.anon = type { %struct.struct1 } without changing the struct1 (it's an external API so better to avoid the changes here)? Best regards, Anton Kochkov.
Tim Northover via llvm-dev
2017-Jun-01 14:47 UTC
[llvm-dev] Prevent anonymous union optimization
On 1 June 2017 at 00:23, Антон Кочков via llvm-dev <llvm-dev at lists.llvm.org> wrote:> And then performs bitcasts all the time it accesses that structure in the union.Are these bitcasts actually causing problems? There may be edge cases where the extra IR-instruction causes an analysis to decide it's done as much as it can, but in general I'd expect them to be free (i.e. generate no code at runtime).> How to force it generate union.anon = type { %struct.struct1 } without > changing the struct1 (it's an external API so better to avoid the > changes here)?There's no way to do this without modifying Clang. And even then you're arbitrarily choosing one member of the union to have precedence, which seems pretty sketchy to me. You're just moving the bitcasts from the struct1 accesses to all the other members. Cheers. Tim.