https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104600
Bug ID: 104600 Summary: VCE<integer_type>(vector){} should be converted (or expanded) into BIT_INSERT_EXPR Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: enhancement Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: pinskia at gcc dot gnu.org Target Milestone: --- When I looked at PR 104582, I Noticed that we had: _14 = {_1, _5}; _8 = VIEW_CONVERT_EXPR<__int128>(_14); Which can be converted into (with the ordering corrected for endianness): t1 = (__128)_1 _8 = BIT_INSERT_EXPR(t1, 64, _5); You can see this by taking the following testcases: #define vector __attribute__((vector_size(16))) __int128 f(long a, long b) { vector long t = {a, b}; return (__int128)t; } void f1(__int128 *t1, long a, long b) { vector long t = {a, b}; *t1 = (__int128)t; } void f2(__int128 *t1, long a, long b) { vector long t = {a, b}; *t1 = ((__int128)t) + 1; } f2 is really bad for x86_64 as GCC does a store to the stack and then loads back. Note if you use | instead of +, GCC does the right thing even.