<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/57842>57842</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Unions's and parameters's lowering ln Clang
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          sidtver
      </td>
    </tr>
</table>

<pre>
    Lets consider simple example in C-language.

 ``
#include <stdint.h>
typedef struct { uint64_t a; uint32_t b; uint64_t c; } S1;
typedef struct { uint32_t a; uint64_t b; uint32_t c; } S2;
typedef union { S1 x; S2 y; } S3;
 
extern void g( S3);
extern S3 A, B;
 
void f() {
    S3 v;
    B = A;
    v.x.a = 3;
    v.y.b = 5LL << 32LL;
    v.x.c = 7;
    g( v);
}
``

There are two circumstances.
(1) The llvm-IR hasn’t unions in its type system. It has only structs.
(2) Load and store operations for structs copy only struct’s fields, not whole memory area of struct as in C/C++.

So lets see llvm-IR of the example for x86.
 
``
%union.S3 = type { %struct.S1 }
%struct.S1 = type { i64, i32, i64 }
``
Clang transforms union S3 into the struct with name %union.S3. Only the first field S3.x was saved, and the second field S3.y was deleted.

``
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(24) bitcast (%union.S3* @B to i8*), i8* noundef nonnull align 8 dereferenceable(24) bitcast (%union.S3* @A to i8*), i64 24, i1 false), !tbaa.struct !3
`` 
Copy operation from B to A was made as a call of intrinsic @llvm.memcpy.* It is an imposible to load value of B and store the loaded value to A. Because in this case (in x86-backend) the field S3.x.b will be copied as 32-bit value. So high 32 bits of S3.y.b will be lost. It is easy to check.

The x86-ABI says to pass struct’s values by reference:
``
  tail call void @g(%union.S3* nonnull byval(%union.S3) align 8 %1) #4
``
That is why there is no copy operation in IR for formal parameters’s values in call of function g.

Now lets see llvm-IR for MIPS (mips64el).
``
; Function Attrs: nounwind
define void @f() local_unnamed_addr #0 {
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(24) bitcast (%union.S3* @B to i8*), i8* noundef nonnull align 8 dereferenceable(24) bitcast (%union.S3* @A to i8*), i64 24, i1 false), !tbaa.struct !3
  tail call void @g(i64 inreg 3, i64 inreg 21474836480, i64 inreg 7) #3
  ret void
}

declare void @g(i64 inreg, i64 inreg, i64 inreg) local_unnamed_addr #2
``
The Clang frontend split struct S3 into three i64 values. It was made for parameters of functions g. Also access operations to struct fields are transformed to bit-operations.


All together (1) and (2) force to apply very low-level target dependent (stack and registers layer) transformation in Clang frontend. It causes unnatural transformation in IR for targets with direct transport of struct values. It causes premature optimization in single frontend (Clang) when targets backends are possible to make parameters’s transportation in valid way. And a uniform optimization (MachineInstruction or llvm-IR stage) is needed for all frontends. Not only for Clang.

As an alternative I see a possible change of union’s lowering as follows. It may be a llvm first-time pass or internal clang-AST to llvm-IR functionality. Suppose for all structures with indirect paddings was made an embeding of additional fields. For example lets substitute
``
%struct.S1 = type { i64, i32, i64 }
``
into
``
%struct.S1 = type { i64, i32, i32, i64 }
                               ^
                               |
                    inserted field
``

After such transformation it becames possible to use load/store operations for coping and using of direct parameters with struct type in IR.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztV0lv4zgT_TXyhbBgS95y8MFJdwMBMgu-9JwbFFW2OC1RgkjZ0fz67xW1WI7TgwZmjmN441as5dWrUlKm7f6FnBWqNFanVAuriyonQW_S_2ojnua5NKdGnigMFp-CxaH7FsFmwe9uKoq1UXmTkgjiJ-tSbVyYBfHnbtm1FaV0FNbVjXIi2D6KBjs2q29OyCDuRnGEUTKM_JriUbD9JF6X-Pe3svxpeXM6uZF8lRXdyWqMLo0X9boUb7zxNRLteCAeD4juh94c1UacS52KUxDteEv0MO7ql19jAcc8icf3x_25I87hEN_aL-KFI-frbrygQfwJYqZz5_AtlH4-fjffhomfX7-8cBzwFnH08nJ3Wvld25t5b8d5agZs7_9MI-2_v2ZUk5D4uEsplK5VU1gnjSI7gCTaLdk87BR5fi7mz_8TmbQm-BwFu0Xw8OA6r1uGmAYCORbCttZREYpnx5tFafK2D_REbsRyX0qZCmlSLJdQo6yols7LO5b1cAawrtqplPF2bNOUp5bjY0onLlkJtBdUlHXLdklRjhCTXsenIPqCzyPeN3nwWoqcM8jS1VCcddk1iVijt90mvAHBbfqsvTNCxJ8j433BcMRCp0QIYF7jcTM73a83K7ZIx5H_2azEh0F84owWrpbGQrfC9gmA25Etpde9t_2iXSaMLEhMdAzFb-xS3nbUtXWdL3E8fBMXeMvKM6WsAMfHCyPwS3rd1vptKcFxlN54c6qlEE7qXCiZ512qBasFezhEmFTVhtVC77ovb_ZOI58OiGZjOKdNaUyDkzLXJyN2uK2mIz7AqExyYhytGEiJdkrCBp-Oo4ksCdc9CrjDy-XEYJf--3cc7u5A2KIujktxlLmlfiGIli6RMhyoL1rGU6_1wHrymB_yQRzrshDejoP3eiFB0viVnWMBVcS81qB_9d7BrCAyUWMzcrSoSqthFYvKOfvOMm-IBTxOEpHDzas0rPPFoXgkJRvr64nLIBDuYEjtMEZmzBOpvpNJ2VcdqgY8gdAuGmomxLmsIRWqx9EcHu3khwIJmOlThln2s2WFGGKTk3lpXdhbQtK2rJPKSH0P33Ga1-Xw-AwEt5Z3VdLae-rwF1uRtGIMdxD_JIBP9xgYUJS0EPx--WEEF6Y9o6LWru7v-ppJb98l84mJSGBgyp4BRzTA3-AnJiROfJnDwhrZjXpl7w3E5gEjx8YoL-B047Nfy8s9-7H0X55_f-X4FrqymxXBrIfwA95Dhf0ySD44ByXiLrsuGmjwe5Bn2tDov6Fs5iVU-9YY5qb0m0zTmh2zmJbT_9jj59jjRzBlSdrUdEKf0QvuhtFytV3t4s0KcLlZ2Pb4HAXX5LzI9w1FH1mVcwvx4Z03gt8NfhT96KO0INFVO_CgccQ8VeUgj94L15JXA8F8R4d9TxcjXTKir4kyzQeLhBCH3JZCKjQ_dtqIQGx_S9drdP3SUHRBZdiA2M6vR25Lof8-ICiuPBHntBiaKqbboRGCLOVZVlYVivKZ0MDk5WWe05lwVNY4C2hVMJ2MBxEaNfXdy4A3tfUm5bKl2tPvoN_IF7fu847xXM5dg5GuqcEi96d6Hujut10fkeqa4A2_uSprN-mxJl7vhVc1FSydezunC_3XKNpqc-KuaggoTPI6svqXjMx4aV9VOsejeo3lq5Df6WPmG3Ubb4NmgOdFtogzLpPcK7Glt2pBh1-kysBUz6YziWfhgIEU4fQTZ6KnZSKuj-wfzrnBEJj_K1pR367ymjfqBhIHX4llzo8XuPdM4tkzr7xapzIc8lXZE8XENICCUOdPXEGPZY5h5-9CtlwkpVe1a-jmsIy64gc9kCB8HxiCFZofXr_6FmBg-z4T4CYHH702FXSh0bjOGQhjjwHweoeCClkLbeykKTGCioR4lvXn9U5wnz-h-AKhQ1PdlZ0msU67xtGHTfU_65KZGP6B2A-ki79_BevPP7dv-_TjfejkqHbUd9s_eoA7HB0_7Dcqu8tdPDijWSs4BScpw80b93V4CvrwiYu7M8YWUqSxfQTHSI_M6SHQp7z3m2eKHuMz2i83m3izjeJ1PEv3cfoQP8gZ4pvT_g__sBhEW-vvmCQvT43Yznu-mjV1vs-cq7ijgM54n3B3k4SqLDBg9PY_86ou_4SeGGprwUL4s97uVtEs229XR7k8qs1S7tRxtZMyWUdrtd0eiWK1Vskslwnldh-s8VwYGboILwL_g_Wnmd5HiyhaPESL5XKJqhiq4-64XqZyJxV-SKHogeR0HvrGpKxPs3rvVUqak-V-Bexsr4vIR3QKRP46yJeNy8p6b3XqQPszf_Xeq_5_eB-IKA">