<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/122689>122689</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Unnecessary call to `memset` when initializing an array of structs with non zero member initialization.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
gchatelet
</td>
</tr>
</table>
<pre>
[godbolt link](https://godbolt.org/z/h39sa6fnv)
```
struct T {
int a = 1;
int b = 0;
};
template <int n>
struct S { T a[n]; };
S<75> F() { return {}; }
```
Compiled with `-O3 -std=c++20 -DNDEBUG -fno-exceptions -march=skylake` generates the following assembly
```
.LCPI0_0:
.long 1
.long 0
F():
pushq %rbx
movq %rdi, %rbx
movl $600, %edx
xorl %esi, %esi
callq memset@PLT
vbroadcastsd .LCPI0_0(%rip), %ymm0
vmovups %ymm0, 32(%rbx)
vmovups %ymm0, (%rbx)
vmovups %ymm0, 96(%rbx)
vmovups %ymm0, 64(%rbx)
vmovups %ymm0, 160(%rbx)
vmovups %ymm0, 128(%rbx)
vmovups %ymm0, 224(%rbx)
vmovups %ymm0, 192(%rbx)
vmovups %ymm0, 288(%rbx)
vmovups %ymm0, 256(%rbx)
vmovups %ymm0, 352(%rbx)
vmovups %ymm0, 320(%rbx)
vmovups %ymm0, 416(%rbx)
vmovups %ymm0, 384(%rbx)
vmovups %ymm0, 480(%rbx)
vmovups %ymm0, 448(%rbx)
vmovups %ymm0, 544(%rbx)
vmovups %ymm0, 512(%rbx)
vmovups %xmm0, 576(%rbx)
movq $1, 592(%rbx)
movq %rbx, %rax
popq %rbx
vzeroupper
retq
```
The compiler first clears `S<75>` content with a call to `memset` and then sets its content through an unrolled loop of YMM stores.
If using `S<74>` instead of `S<75>` the call to `memset` goes away.
Apparently the clearing part is created in the frontend (clang), here is the LLVM IR with `-O0`:
```
%struct.S = type { [75 x %struct.T] }
%struct.T = type { i32, i32 }
define dso_local void @F()(ptr dead_on_unwind noalias writable sret(%struct.S) align 4 %agg.result) {
entry:
call void @llvm.memset.p0.i64(ptr align 4 %agg.result, i8 0, i64 592, i1 false)
%a = getelementptr inbounds nuw %struct.S, ptr %agg.result, i32 0, i32 0
%arrayinit.end = getelementptr inbounds %struct.T, ptr %a, i64 75
br label %arrayinit.body
arrayinit.body:
%arrayinit.cur = phi ptr [ %a, %entry ], [ %arrayinit.next, %arrayinit.body ]
%a1 = getelementptr inbounds nuw %struct.T, ptr %arrayinit.cur, i32 0, i32 0
store i32 1, ptr %a1, align 4
%b = getelementptr inbounds nuw %struct.T, ptr %arrayinit.cur, i32 0, i32 1
store i32 0, ptr %b, align 4
%arrayinit.next = getelementptr inbounds %struct.T, ptr %arrayinit.cur, i64 1
%arrayinit.done = icmp eq ptr %arrayinit.next, %arrayinit.end
br i1 %arrayinit.done, label %arrayinit.end2, label %arrayinit.body
arrayinit.end2:
ret void
}
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0V12P4joS_TXmpQRynITAAw98DKuRenavdvqutE8tJykS7zh22nagmV-_spPQ0B_aZqWLkAj2qapTZftUzK0VlUJckXRD0t2Ed67WZlUVNXco0U1yXZ79ZKXLXEsHUqhfJN0Rtqiday2J14TtCdsP8zNtKsL2vwnb1_HS8vlBHQlbErr23zkdvnRtnekKB49Asg2hawChHHAg8Q4iEochP5KHEdqPkGw3PNC1w6aV3CGQeOuBisTfXt3-9G7hEThJN8rTjTdwbf2TxNssJfE32BO2IGwZ8AZdZ1RglF1MbmkTut7qphUSSzgJVwOZ0-k_YphaV5J4VxC2IWzDKEx3f9992_z5N5gelJ7iS4GtE1pZmDbcFDWJd_bXWfJfSOYUKlRouEMLrkY4aCn1SagKuLXY5PL8hsTsYfvHd_pEffHpGmZSqwoAolDH_jOOefiQ4oAePm1n62cAICw1-cvVRKOPz2G0FIRtP5yXEAyTOaUDBMtryIs2AyRFO3rxT3QNBZfSx22wsehIQv94eLwyPeZG87Lg1tky5DGm6lNIjWh9Ir3Dc9P47ODY6GPX2ssQ20LMBnz-0m--i_v32K8jl_OvY-fJ17HRnN4B9sivghm7h8byjqqxxT000jsqF6d30IjZHaVLontoLO4oXbK4h0ZyR-nS5A4aafSF0r2M4OyzagQF6E94FJCfboxXZD_XywUPWtDq9nruistvNLprWzRXgwbd83upfawRil5uDRyEsQ4KidxYL7sXDfcKWmjlULlek3lQGXDawwahmVPgqvT6qsCisyCcvVi52uiuqoEr6JTR0qu71LoFfYB___gB1mmDdkbo-vsBOuuleSSQDASEsg556S3ecvOa_iGhSqMFfuLnWZ_uum25QeXkubfxqfpYLTcOQFgoDHKHJQjVNwoT-JdewwrJVTWIY40GPdxjHh7-9QO-__OqWYXyxm_7MWFp3ztnP0PLdecWQ1Mk6SZL4QVeAY8k3Y2t8XXw1kp4Cd76nxFJ1yUehEIorX6SuuASjlqUQBI6Nii2aJ2BEnn5pNVTp05ClaA0l4JbOBnheC4RrEHX78eRsO_fXIpKQeJp8qqaGbSddENjJ3SNypnz2AHDYozBpTw2s35NZi2diaDcnscnHrcgFhBOkJgn_dnYgojgwKXF8Xh4m1CQCv1rVIPKeZdC5bpTpQXVneAmgS34-fehYjbECg-ja2P4WSjhZmHxPw9zvWZXIUbyWRo85gYkz1HeuvYvfv26vRkbingDLjoTeLS16KOkm0sk3_t99SG8Nm4vcxdjhS9uAN6GChZjrOjr9bxJ9prjJyUNxzv8j64tw59hF4w08r-CRfSGBb2yzD8gcVu6_2MDvGMzTwYSN7OlVhi8i6JpAZ_f23-4dKjKcV-J6L1Hj_9gv6Eq2SdTH23FAB-2okEXjvNwRRjEppDc4P8-5koXvHWdwaAwqJU894d8KMxwvEXTcH-1WQJhcXQtnpNyFZfLeMknuIqyeJ7NMxrHk3rFy_KwKBCzMqL5YrHMKac0ShgrDhHni2giVoyylEZRHEVRFsWzhC4w41mex_NDkuUpSSg2XMhZYK9NNRHWdriKGJsvlpNQKhuubowpPEGYJYz5m5xZeaNp3lXWpy-ss69unHASV38qhQVay8354wZ18t3Sl1twKX6HG4mCsAa-z_U7y_atRWkFvrH7F_sczasV99ee2aQzcvXmxihc3eWzQjeE7T2z4WfaGv0fLBxh-5CPJWw_JHxcsf8GAAD__wGVRV4">