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.

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.