- Lower to the memcpy intrinsic
- Raise warnings when size/bounds are known
Details
Details
Diff Detail
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
| clang/lib/CodeGen/CGBuiltin.cpp | ||
|---|---|---|
| 2518 | Is it an error here? It should be: if (BuiltinID == Builtin::BImempcpy ||
BuiltinID == Builtin::BI__builtin_mempcpy)
return RValue::get(Builder.CreateGEP(Dest.getPointer(), SizeVal));
else
return RValue::get(Dest.getPointer()); | |
Comment Actions
[[updated]]
Before, when compiling
#define _GNU_SOURCE
#include <string.h>
void* foo(void* to, void* from, unsigned n) {
return mempcpy(mempcpy(to, from, n), from, n);
}We get (clang -O3)
define dso_local i8* @foo(i8* %0, i8* nocapture readonly %1, i32 %2) local_unnamed_addr #0 {
%4 = zext i32 %2 to i64
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 %1, i64 %4, i1 false) #2
%5 = getelementptr inbounds i8, i8* %0, i64 %4
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %5, i8* align 1 %1, i64 %4, i1 false) #2
%6 = getelementptr inbounds i8, i8* %5, i64 %4
ret i8* %6
}And we now get
define dso_local i8* @foo(i8* %to, i8* nocapture readonly %from, i32 %n) local_unnamed_addr #0 {
entry:
%conv = zext i32 %n to i64
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %to, i8* align 1 %from, i64 %conv, i1 false)
%0 = getelementptr i8, i8* %to, i64 %conv
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %0, i8* align 1 %from, i64 %conv, i1 false)
%1 = getelementptr i8, i8* %0, i64 %conv
ret i8* %1
}So no real change apart from the inbound keyword that I forgot to add.
Comment Actions
Indeed, the clang version I was using as base reference was clang-9, and the mempcpy optimisation at IR level got introduced after that.
Nevertheless, this patch does much more than lowering mempcpy, it also triggers new warnings, so It's still useful that clang understands it.
@xbolva00 should I remove the lowering part and leave it to llvm?
Comment Actions
@xbolva00 should I remove the lowering part and leave it to llvm?
Probably okay to leave it + inbounds, but please add a test.
Is it an error here?
It should be:
if (BuiltinID == Builtin::BImempcpy || BuiltinID == Builtin::BI__builtin_mempcpy) return RValue::get(Builder.CreateGEP(Dest.getPointer(), SizeVal)); else return RValue::get(Dest.getPointer());