Skip to content

Commit a85297d

Browse files
[CIR][CodeGen][Builtin] Implement bcopy and __builtin_bcopy (#1855)
Closes #1816
1 parent 4e092b2 commit a85297d

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,8 +1716,19 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
17161716
llvm_unreachable("BIbzero like NYI");
17171717

17181718
case Builtin::BIbcopy:
1719-
case Builtin::BI__builtin_bcopy:
1720-
llvm_unreachable("BIbcopy like NYI");
1719+
case Builtin::BI__builtin_bcopy: {
1720+
Address src = emitPointerWithAlignment(E->getArg(0));
1721+
Address dest = emitPointerWithAlignment(E->getArg(1));
1722+
mlir::Value sizeVal = emitScalarExpr(E->getArg(2));
1723+
emitNonNullArgCheck(RValue::get(src.getPointer()), E->getArg(0)->getType(),
1724+
E->getArg(0)->getExprLoc(), FD, 0);
1725+
emitNonNullArgCheck(RValue::get(dest.getPointer()), E->getArg(1)->getType(),
1726+
E->getArg(1)->getExprLoc(), FD, 0);
1727+
builder.createMemMove(getLoc(E->getSourceRange()), dest.getPointer(),
1728+
src.getPointer(), sizeVal);
1729+
1730+
return RValue::get(nullptr);
1731+
}
17211732

17221733
case Builtin::BImemcpy:
17231734
case Builtin::BI__builtin_memcpy:
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
void foo(void) {
7+
// CIR-LABEL: cir.func dso_local @_Z3foov()
8+
// CIR: %[[V0:.*]] = cir.alloca !cir.array<!cir.float x 4>, !cir.ptr<!cir.array<!cir.float x 4>>, ["f4"] {alignment = 16 : i64}
9+
// CIR: %[[V1:.*]] = cir.alloca !cir.array<!cir.float x 8>, !cir.ptr<!cir.array<!cir.float x 8>>, ["f8"] {alignment = 16 : i64}
10+
// CIR: %[[V2:.*]] = cir.cast(array_to_ptrdecay, %[[V0]] : !cir.ptr<!cir.array<!cir.float x 4>>), !cir.ptr<!cir.float>
11+
// CIR: %[[V3:.*]] = cir.cast(bitcast, %[[V2]] : !cir.ptr<!cir.float>), !cir.ptr<!void>
12+
// CIR: %[[V4:.*]] = cir.cast(array_to_ptrdecay, %[[V1]] : !cir.ptr<!cir.array<!cir.float x 8>>), !cir.ptr<!cir.float>
13+
// CIR: %[[V5:.*]] = cir.cast(bitcast, %[[V4]] : !cir.ptr<!cir.float>), !cir.ptr<!void>
14+
// CIR: %[[V6:.*]] = cir.const #cir.int<4> : !u64i
15+
// CIR: %[[V7:.*]] = cir.const #cir.int<4> : !s32i
16+
// CIR: %[[V8:.*]] = cir.cast(integral, %[[V7]] : !s32i), !u64i
17+
// CIR: %[[V9:.*]] = cir.binop(mul, %[[V6]], %[[V8]]) : !u64i
18+
// CIR: cir.libc.memmove %[[V9]] bytes from %[[V3]] to %[[V5]] : !cir.ptr<!void>, !u64i
19+
// CIR: cir.return
20+
21+
// LLVM-LABEL: define dso_local void @_Z3foov()
22+
// LLVM: %[[V1:.*]] = alloca [4 x float], i64 1, align 16
23+
// LLVM: %[[V2:.*]] = alloca [8 x float], i64 1, align 16
24+
// LLVM: %[[V3:.*]] = getelementptr float, ptr %[[V1]], i32 0
25+
// LLVM: %[[V4:.*]] = getelementptr float, ptr %[[V2]], i32 0
26+
// LLVM: call void @llvm.memmove.p0.p0.i64(ptr %[[V4]], ptr %[[V3]], i64 16, i1 false)
27+
// LLVM: ret void
28+
29+
float f4[4];
30+
float f8[8];
31+
__builtin_bcopy(f4, f8, sizeof(float) * 4);
32+
}
33+
34+
void test_conditional_bcopy(void) {
35+
// CIR-LABEL: cir.func dso_local @_Z22test_conditional_bcopyv()
36+
// CIR: cir.libc.memmove {{.*}} bytes from {{.*}} to {{.*}} : !cir.ptr<!void>, !u64i
37+
// CIR: cir.libc.memmove {{.*}} bytes from {{.*}} to {{.*}} : !cir.ptr<!void>, !u64i
38+
39+
// LLVM-LABEL: define{{.*}} void @_Z22test_conditional_bcopyv
40+
// LLVM: call void @llvm.memmove
41+
// LLVM: call void @llvm.memmove
42+
// LLVM-NOT: phi
43+
44+
char dst[20];
45+
char src[20];
46+
int _sz = 20, len = 20;
47+
return (_sz ? ((_sz >= len) ? __builtin_bcopy(src, dst, len) : foo())
48+
: __builtin_bcopy(src, dst, len));
49+
}
50+
51+
void another_conditional_bcopy(char *dst, char *src, int sz, int len) {
52+
// CIR-LABEL: cir.func dso_local @_Z25another_conditional_bcopyPcS_ii
53+
// CIR: cir.libc.memmove {{.*}} bytes from {{.*}} to {{.*}} : !cir.ptr<!void>, !u64i
54+
// CIR: cir.libc.memmove {{.*}} bytes from {{.*}} to {{.*}} : !cir.ptr<!void>, !u64i
55+
56+
// LLVM-LABEL: define{{.*}} void @_Z25another_conditional_bcopyPcS_ii
57+
// LLVM: call void @llvm.memmove
58+
// LLVM: call void @llvm.memmove
59+
// LLVM-NOT: phi
60+
61+
if (sz >= len)
62+
__builtin_bcopy(src, dst, len);
63+
else
64+
__builtin_bcopy(src, dst, len * 2);
65+
}
66+
67+
#define size_t __SIZE_TYPE__
68+
69+
extern "C" void bcopy(const void *__src, void *__dest, size_t __n);
70+
71+
// LLVM: @_Z9testbcopyPKvPvm(
72+
// LLVM: call void @llvm.memmove.p0.p0.i64(ptr {{.*}}, ptr {{.*}}, i64 {{.*}}, i1 false)
73+
// LLVM: ret void
74+
75+
void testbcopy(const void *src, void *dest, size_t n) {
76+
bcopy(src, dest, n);
77+
}

0 commit comments

Comments
 (0)