I’m recently learning the attribute system of llvm. But sometimes it doesn’t works as I expected. For example:
#include <stdio.h>
#include <malloc.h>
__attribute__((noinline)) void print(int *p) {
printf("%d\n", *p);
}
int main() {
int *p = (int *)malloc(sizeof(int));
print(p);
return *p;
}
and the corresponding IR is:
; Function Attrs: nofree noinline nounwind uwtable
define dso_local void @print(i32* nocapture readonly %0) local_unnamed_addr #0 {
%2 = load i32, i32* %0, align 4, !tbaa !2
%3 = tail call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %2)
ret void
}
; Function Attrs: nofree nounwind
declare dso_local noundef i32 @printf(i8* nocapture noundef readonly, ...) local_unnamed_addr #1
; Function Attrs: nofree nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #2 {
%1 = tail call noalias dereferenceable_or_null(4) i8* @malloc(i64 4) #4
%2 = bitcast i8* %1 to i32*
tail call void @print(i32* %2)
ret i32 undef
}
I think the parameter of function print
should has a “nofree” attribute, but it actually only has “nocapture” and “readonly”. Is there any pass that can infer the “nofree” parameter attribute?