Skip to content

Commit bec5b92

Browse files
authored
[CIR] Added codegen support for builtin_mempcpy (#1844)
1 parent f601904 commit bec5b92

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,10 +1687,15 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
16871687
builder.createMemCpy(getLoc(E->getSourceRange()), Dest.getPointer(),
16881688
Src.getPointer(), SizeVal);
16891689
if (BuiltinID == Builtin::BImempcpy ||
1690-
BuiltinID == Builtin::BI__builtin_mempcpy)
1691-
llvm_unreachable("mempcpy is NYI");
1692-
else
1693-
return RValue::get(Dest.getPointer());
1690+
BuiltinID == Builtin::BI__builtin_mempcpy) {
1691+
auto ppTy = builder.getPointerTo(builder.getUInt8PtrTy());
1692+
auto castBuf = builder.createBitcast(Dest.getPointer(), ppTy);
1693+
auto loc = getLoc(E->getSourceRange());
1694+
auto gep = cir::PtrStrideOp::create(builder, loc, ppTy, castBuf, SizeVal);
1695+
assert(!cir::MissingFeatures::emitCheckedInBoundsGEP());
1696+
return RValue::get(gep);
1697+
}
1698+
return RValue::get(Dest.getPointer());
16941699
}
16951700

16961701
case Builtin::BI__builtin_memcpy_inline: {

clang/test/CIR/CodeGen/builtins-memory.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - \
44
// RUN: | opt -S -passes=instcombine,mem2reg,simplifycfg -o %t.ll
55
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
6+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - \
7+
// RUN: | opt -S -passes=instcombine,mem2reg,simplifycfg -o %t.ll
8+
// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
69

710
typedef __SIZE_TYPE__ size_t;
811
void test_memcpy_chk(void *dest, const void *src, size_t n) {
@@ -230,3 +233,28 @@ void test_memset_inline(void *dst, int val) {
230233
// LLVM: call void @llvm.memset.inline.p0.i64(ptr {{%.*}}, i8 {{%.*}}, i64 4, i1 false)
231234
__builtin_memset_inline(dst, val, 4);
232235
}
236+
237+
void* test_builtin_mempcpy(void *dest, void *src, size_t n) {
238+
// CIR-LABEL: test_builtin_mempcpy
239+
// CIR: [[ALLOCA:%.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["__retval"]
240+
// CIR: cir.libc.memcpy [[NUM:%.*]] bytes from [[S:.*]] to [[DST:.*]] :
241+
// CIR: [[CAST2:%.*]] = cir.cast(bitcast, [[DST]] : !cir.ptr<!void>), !cir.ptr<!cir.ptr<!u8i>>
242+
// CIR: [[GEP:%.*]] = cir.ptr_stride([[CAST2]] : !cir.ptr<!cir.ptr<!u8i>>, [[NUM]] : !u64i)
243+
// CIR: [[CAST3:%.*]] = cir.cast(bitcast, [[ALLOCA]]
244+
// CIR: cir.store [[GEP]], [[CAST3:%.*]]
245+
// CIR-NEXT: [[LD:%.*]] = cir.load [[ALLOCA]]
246+
// CIR-NEXT: cir.return [[LD]]
247+
248+
// LLVM-LABEL: test_builtin_mempcpy
249+
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr [[DST:%.*]], ptr {{%.*}}, i64 [[NUM:%.*]], i1 false)
250+
// LLVM-NEXT: [[GEP:%.*]] = getelementptr ptr, ptr [[DST]], i64 [[NUM]]
251+
// LLVM-NEXT: store ptr [[GEP]], ptr [[P:%.*]]
252+
// LLVM-NEXT: [[LD:%.*]] = load ptr, ptr [[P]]
253+
// LLVM-NEXT: ret ptr [[LD]]
254+
255+
// OGCG-LABEL: test_builtin_mempcpy
256+
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[DST:%.*]], ptr align 1 {{%.*}}, i64 [[NUM:%.*]], i1 false)
257+
// OGCG-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[NUM]]
258+
// OGCG-NEXT: ret ptr [[GEP]]
259+
return __builtin_mempcpy(dest, src, n);
260+
}

0 commit comments

Comments
 (0)