Issue 146742
Summary Missed optimization of strdup to malloc + memcpy if argument is known at compile time
Labels new issue
Assignees
Reporter BreadTom
    [Clang godbolt](https://godbolt.org/z/5GM85jT3G)
[GCC godbolt](https://godbolt.org/z/afqarMj9n)

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
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to