-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Open
Labels
Description
Clang 20.1.0 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