xref: /llvm-project/clang/test/CodeGen/builtin-memfns.c (revision 12f78e740c5419f7d1fbcf8f2106e7a40cd1d6f7)
1 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm < %s| FileCheck %s
2 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -fexperimental-new-constant-interpreter < %s| FileCheck %s
3 
4 typedef __WCHAR_TYPE__ wchar_t;
5 typedef __SIZE_TYPE__ size_t;
6 
7 void *memcpy(void *, void const *, size_t);
8 void *memccpy(void *, void const *, int, size_t);
9 
10 // CHECK: @test1
11 // CHECK: call void @llvm.memset.p0.i32
12 // CHECK: call void @llvm.memset.p0.i32
13 // CHECK: call void @llvm.memcpy.p0.p0.i32
14 // CHECK: call void @llvm.memmove.p0.p0.i32
15 // CHECK-NOT: __builtin
16 // CHECK: ret
17 int test1(int argc, char **argv) {
18   unsigned char a = 0x11223344;
19   unsigned char b = 0x11223344;
20   __builtin_bzero(&a, sizeof(a));
21   __builtin_memset(&a, 0, sizeof(a));
22   __builtin_memcpy(&a, &b, sizeof(a));
23   __builtin_memmove(&a, &b, sizeof(a));
24   return 0;
25 }
26 
27 // CHECK: @test2
28 // CHECK: call void @llvm.memcpy.p0.p0.i32
29 char* test2(char* a, char* b) {
30   return __builtin_memcpy(a, b, 4);
31 }
32 
33 // CHECK: @test3
34 // CHECK: call void @llvm.memset
35 void test3(char *P) {
36   __builtin___memset_chk(P, 42, 128, 128);
37 }
38 
39 // CHECK: @test4
40 // CHECK: call void @llvm.memcpy
41 void test4(char *P, char *Q) {
42   __builtin___memcpy_chk(P, Q, 128, 128);
43 }
44 
45 // CHECK: @test5
46 // CHECK: call void @llvm.memmove
47 void test5(char *P, char *Q) {
48   __builtin___memmove_chk(P, Q, 128, 128);
49 }
50 
51 // CHECK: @test6
52 // CHECK: call void @llvm.memcpy
53 int test6(char *X) {
54   return __builtin___memcpy_chk(X, X, 42, 42) != 0;
55 }
56 
57 // CHECK: @test7
58 // PR12094
59 void test7(int *p) {
60   struct snd_pcm_hw_params_t* hwparams;  // incomplete type.
61 
62   // CHECK: call void @llvm.memset{{.*}} align 4 {{.*}}256, i1 false)
63   __builtin_memset(p, 0, 256);  // Should be alignment = 4
64 
65   // CHECK: call void @llvm.memset{{.*}} align 1 {{.*}}256, i1 false)
66   __builtin_memset((char*)p, 0, 256);  // Should be alignment = 1
67 
68   __builtin_memset(hwparams, 0, 256);  // No crash alignment = 1
69   // CHECK: call void @llvm.memset{{.*}} align 1{{.*}}256, i1 false)
70 }
71 
72 // Make sure we don't over-estimate the alignment of fields of
73 // packed structs.
74 struct PS {
75   int modes[4];
76 } __attribute__((packed));
77 struct PS ps;
78 void test8(int *arg) {
79   // CHECK: @test8
80   // CHECK: call void @llvm.memcpy{{.*}} align 4 {{.*}} align 1 {{.*}} 16, i1 false)
81   __builtin_memcpy(arg, ps.modes, sizeof(struct PS));
82 }
83 
84 __attribute((aligned(16))) int x[4], y[4];
85 void test9(void) {
86   // CHECK: @test9
87   // CHECK: call void @llvm.memcpy{{.*}} align 16 {{.*}} align 16 {{.*}} 16, i1 false)
88   __builtin_memcpy(x, y, sizeof(y));
89 }
90 
91 wchar_t dest;
92 wchar_t src;
93 
94 // CHECK-LABEL: @test10
95 // FIXME: Consider lowering these to llvm.memcpy / llvm.memmove.
96 void test10(void) {
97   // CHECK: call ptr @wmemcpy(ptr noundef @dest, ptr noundef @src, i32 noundef 4)
98   __builtin_wmemcpy(&dest, &src, 4);
99 
100   // CHECK: call ptr @wmemmove(ptr noundef @dest, ptr noundef @src, i32 noundef 4)
101   __builtin_wmemmove(&dest, &src, 4);
102 }
103 
104 // CHECK-LABEL: @test11
105 void test11(void) {
106   typedef struct { int a; } b;
107   int d;
108   b e;
109   // CHECK: call void @llvm.memcpy{{.*}}(
110   memcpy(&d, (char *)&e.a, sizeof(e));
111 }
112 
113 // CHECK-LABEL: @test12
114 extern char dest_array[];
115 extern char src_array[];
116 void test12(void) {
117   // CHECK: call void @llvm.memcpy{{.*}}(
118   memcpy(&dest_array, &dest_array, 2);
119 }
120 
121 // CHECK-LABEL: @test13
122 void test13(char *d, char *s, int c, size_t n) {
123   // CHECK: call ptr @memccpy
124   memccpy(d, s, c, n);
125 }
126