Open
Description
Clang 20.1 and GCC 15.1 missed optimizing strdup("Hello") to malloc then memcpy "Hello" like f0_fast().
Maybe useful if the string came from -D:
#define HELLO_WORLD "Hello world"
char *f0_slow (void)
{
return __builtin_strdup (HELLO_WORLD);
}
C source code
char *f0_fast (void)
{
char *ret_val = __builtin_malloc (strlen ("Hello") + 1);
if (ret_val)
__builtin_memcpy (ret_val, "Hello", strlen ("Hello") + 1);
return ret_val;
}
char *f0_slow (void)
{
return __builtin_strdup ("Hello");
}
LLVM IR
@.str = private unnamed_addr constant [6 x i8] c"Hello\00", align 1
define dso_local noalias noundef ptr @f0_fast() local_unnamed_addr {
entry:
%call = tail call dereferenceable_or_null(6) ptr @malloc(i64 noundef 6) #5
%tobool.not = icmp eq ptr %call, null
br i1 %tobool.not, label %if.end, label %if.then
if.then:
tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(6) %call, ptr noundef nonnull align 1 dereferenceable(6) @.str, i64 6, i1 false)
br label %if.end
if.end:
ret ptr %call
}
declare noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr #1
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #2
define dso_local noalias noundef ptr @f0_slow() local_unnamed_addr {
entry:
%call = tail call dereferenceable_or_null(6) ptr @strdup(ptr noundef nonnull @.str) #5
ret ptr %call
}
declare noalias ptr @strdup(ptr nocapture noundef readonly) local_unnamed_addr #4