<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/150437>150437</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Missed moving load after if.end block in memory_grow ()
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
BreadTom
</td>
</tr>
</table>
<pre>
[Clang 20.1.0](https://godbolt.org/z/GMf5bdbj4) computes new_m = *m at entry block even though this value isn't needed until after if condition.
C code
```
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
uint32_t memory_grow(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {
uint8_t *new_m = *m;
uint32_t r = *p;
uint32_t new_p = r + n;
if (new_p > UINT32_C(0xFFFF)) return UINT32_C(0xFFFFFFFF);
uint32_t new_c = *c;
if (new_c < new_p) {
do new_c += new_c / 2 + 8; while (new_c < new_p);
if (new_c > UINT32_C(0xFFFF)) new_c = UINT32_C(0xFFFF);
new_m = realloc(new_m, new_c << 16);
if (new_m == NULL) return UINT32_C(0xFFFFFFFF);
*m = new_m;
*c = new_c;
}
*p = new_p;
memset(&new_m[r << 16], 0, n << 16);
return r;
}
uint32_t memory_grow_new(uint8_t **m, uint32_t *p, uint32_t *c, uint32_t n) {
uint32_t r = *p;
uint32_t new_p = r + n;
if (new_p > UINT32_C(0xFFFF)) return UINT32_C(0xFFFFFFFF);
uint8_t *new_m = *m;
uint32_t new_c = *c;
if (new_c < new_p) {
do new_c += new_c / 2 + 8; while (new_c < new_p);
if (new_c > UINT32_C(0xFFFF)) new_c = UINT32_C(0xFFFF);
new_m = realloc(new_m, new_c << 16);
if (new_m == NULL) return UINT32_C(0xFFFFFFFF);
*m = new_m;
*c = new_c;
}
*p = new_p;
memset(&new_m[r << 16], 0, n << 16);
return r;
}
```
LLVM IR
```
define dso_local i32 @memory_grow(ptr nocapture noundef %m, ptr nocapture noundef %p, ptr nocapture noundef %c, i32 noundef %n) local_unnamed_addr {
entry:
%0 = load ptr, ptr %m, align 8
%1 = load i32, ptr %p, align 4
%add = add i32 %1, %n
%cmp = icmp ugt i32 %add, 65535
br i1 %cmp, label %cleanup17, label %if.end
if.end:
%2 = load i32, ptr %c, align 4
%cmp1 = icmp ult i32 %2, %add
br i1 %cmp1, label %do.body, label %if.end13
do.body:
%new_c.0 = phi i32 [ %add4, %do.body ], [ %2, %if.end ]
%div38 = lshr i32 %new_c.0, 1
%add3 = add i32 %new_c.0, 8
%add4 = add i32 %add3, %div38
%cmp5 = icmp ult i32 %add4, %add
br i1 %cmp5, label %do.body, label %do.end
do.end:
%spec.store.select = tail call i32 @llvm.umin.i32(i32 %add4, i32 65535)
%shl = shl nuw i32 %spec.store.select, 16
%conv = zext i32 %shl to i64
%call = tail call ptr @realloc(ptr noundef %0, i64 noundef %conv) #4
%cmp9 = icmp eq ptr %call, null
br i1 %cmp9, label %cleanup17, label %if.end12
if.end12:
store ptr %call, ptr %m, align 8
store i32 %spec.store.select, ptr %c, align 4
br label %if.end13
if.end13:
%new_m.0 = phi ptr [ %call, %if.end12 ], [ %0, %if.end ]
store i32 %add, ptr %p, align 4
%shl14 = shl i32 %1, 16
%idxprom = zext i32 %shl14 to i64
%arrayidx = getelementptr inbounds nuw i8, ptr %new_m.0, i64 %idxprom
%shl15 = shl i32 %n, 16
%conv16 = zext i32 %shl15 to i64
tail call void @llvm.memset.p0.i64(ptr align 1 %arrayidx, i8 0, i64 %conv16, i1 false)
br label %cleanup17
cleanup17:
%retval.1 = phi i32 [ -1, %entry ], [ %1, %if.end13 ], [ -1, %do.end ]
ret i32 %retval.1
}
declare noalias noundef ptr @realloc(ptr allocptr nocapture noundef, i64 noundef) local_unnamed_addr #1
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #2
define dso_local i32 @memory_grow_new(ptr nocapture noundef %m, ptr nocapture noundef %p, ptr nocapture noundef %c, i32 noundef %n) local_unnamed_addr {
entry:
%0 = load i32, ptr %p, align 4
%add = add i32 %0, %n
%cmp = icmp ugt i32 %add, 65535
br i1 %cmp, label %cleanup18, label %if.end
if.end:
%1 = load ptr, ptr %m, align 8
%2 = load i32, ptr %c, align 4
%cmp1 = icmp ult i32 %2, %add
br i1 %cmp1, label %do.body, label %if.end13
do.body:
%new_c.0 = phi i32 [ %add4, %do.body ], [ %2, %if.end ]
%div38 = lshr i32 %new_c.0, 1
%add3 = add i32 %new_c.0, 8
%add4 = add i32 %add3, %div38
%cmp5 = icmp ult i32 %add4, %add
br i1 %cmp5, label %do.body, label %do.end
do.end:
%spec.store.select = tail call i32 @llvm.umin.i32(i32 %add4, i32 65535)
%shl = shl nuw i32 %spec.store.select, 16
%conv = zext i32 %shl to i64
%call = tail call ptr @realloc(ptr noundef %1, i64 noundef %conv) #4
%cmp9 = icmp eq ptr %call, null
br i1 %cmp9, label %cleanup18, label %if.end12
if.end12:
store ptr %call, ptr %m, align 8
store i32 %spec.store.select, ptr %c, align 4
br label %if.end13
if.end13:
%new_m.0 = phi ptr [ %call, %if.end12 ], [ %1, %if.end ]
store i32 %add, ptr %p, align 4
%shl14 = shl i32 %0, 16
%idxprom = zext i32 %shl14 to i64
%arrayidx = getelementptr inbounds nuw i8, ptr %new_m.0, i64 %idxprom
%shl15 = shl i32 %n, 16
%conv16 = zext i32 %shl15 to i64
tail call void @llvm.memset.p0.i64(ptr align 1 %arrayidx, i8 0, i64 %conv16, i1 false)
br label %cleanup18
cleanup18:
%retval.1 = phi i32 [ -1, %entry ], [ %0, %if.end13 ], [ -1, %do.end ]
ret i32 %retval.1
}
declare i32 @llvm.umin.i32(i32, i32) #3
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWU9v2zoS_zT0haggUpYtH3ywk3pRIO1h0e7VoETaZpcitRTlJP30C1KURDlyUjTNe8FDgwCSOMOZ3_zlWCJ1zY-SsTVItyC9nZHGnJRebzUj9KsqZ7mij5Z2I4g8QhxHKIpBegtwdjKmqkGyAXgH8O6oaK6EiZQ-Arz7AfDuX58PaU7z73OAV7BQZdUYVkPJ7vclBMktBHhTQmIgk0Y_wlyo4r-QnZmE5qSa4wmaE6_hmYiGQV5LgJcGSsYoo7CRhgtIDoZpyA-wUJJyw5WMQLy5gYWiDMQbsIj9f7wBOOGyEA1lECQ3taFcmugEko8TNM3l8RqNCp73tHjTcGkSvDewZKXSj_ujVvcAZ3Y52xtroLUR4BvYcwK8qS4XitGCtO4Cyy2INxBCGAgbuw4kIYvbqjtiNUG0uyvHoCHAWygHHn6AAGcdw0f47dOXrwne3wCcxQ-73W4H8Mqi0sw0Wj4ldyzTSosOVTGl0VJvWnCB4VR1W_HW7u4edhA78BlItvD-xAWbljNoeqrtun0D2kmOkcwhGJoRIVThNbhw94AsJrR4BpATYaV8-XZ39_M-drXTOaYcC7ee7mmBz8HytrvDm6rn6HKlZGXNDMAZwItWarrVgQ225m9g7My7YprHrtuVVt-VMtlL9ntL5X0WwXOV--oi8X9_auXFUPik_90lA-Grq2ayZIKT6-7uP5_hp39frFJ24JJBWqu9UAURkCcYgnk8Pocqo6FUBalMoxmUqpGUWWemzu9XqdWzVFeBVl2w5urQAdk3UpKS0T2hVPs8dee7nROsxwBOY-dHoQi1WjplHSwi-FHCrG1yKRp4eYID3mrgnXeCCaWO3V6dQ3CKLJtD6HmKsg0jtzfN0XSMhFLLukjTJHW8uYYc-R2WIkjOhHsWjMimQsvRKj9ETNK23_n71mKAU3zNiGLCiKKsUIBQ9AixN8UivQSIRlioiuzUNoEPJS3CjmMIikv8qA1NdeKt0nTrFc69br8P-rT2DB2yVocjeqmUn5Ostb4-6c4Sr8vuQkHsksvgBXxZwDe_5LN7O4BWYeDKdNKVgUVT3kxf9CZVQ7T9fR_tumJFVBulWVQzwQrjIBjCBSyI6EtViHMZNSWXkcuJ7AKafWyTEa86wSfhRNmrbO47Y57oc35d9E5Q8uy2_WAPvQOsCKMgX8y9bIdsjNPl6DweOnbbEvqid3Hhi_moOSh5dgcUTsKEXg1RYP_rk58I4dpiI8STEKx-uuQQDosO4S6nnUcudV1pNJ75OYdeq9hcX6ux_qnPDHc-BDXmZLYl1AEMzLoosni6yEbIfRN7pkXWJ4HmfRaFTXLIGE4fKq3KqaRB8yBtnEatySOnD475yAwTrGTSWARc5jYx6jZXswCY90OXP4PKEGV6iVI-zWu0mASZBiCHfD4rTvvCa4_tqIojy9fmdusqFJrlIGYwhNrqdQsIHoioma_QUSoMGetyYXgcOq5m5kxEhJ603A_dodX-MB6nARpnSRKS-41tS-pzRLPePZ3ScDynrBDEHfJEcFL39TzZANz95HBw0Q6ujQQ4QWO1L8Zl0HSvuWFKisc2Ll6jjwUvS6KPvvvgTseLc5L_IfL-Z6Vfmn_it5t_sp-bfy6muOcnvj_T0u-blt7_sPR209Kbjku_OC-hv35emirRK_PSexuXXj0vobebl-J_8Lz0dw9M2Xhgyl49MMVvNzBd702-J_nSTsK3NzO6TugqWZEZW6NlmiTLOFvFs9OasBVitDgsEopZjAhKaY5SlscYL3Kc4Rlf4xin8RLPUYozFEeLxXwVZ6tltkKLguAlmMesJFxEDpHSxxmv64atURrPk-XM-bp233kwluweOirAGKS3M722mz7kzbG2JvHa1IMYw41g68-8rhmFpTpzeWwP6O4TjPNe-wWHy_A1L3RvxlazRov1xfcibk5NHhWqBHhnNfnLh0qr766L7By-GuCdN-C8xv8PAAD__317f4E">