1 // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm < %s| FileCheck %s
2 
3 typedef __WCHAR_TYPE__ wchar_t;
4 typedef __SIZE_TYPE__ size_t;
5 
6 void *memcpy(void *, void const *, size_t);
7 
8 // CHECK: @test1
9 // CHECK: call void @llvm.memset.p0i8.i32
10 // CHECK: call void @llvm.memset.p0i8.i32
11 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32
12 // CHECK: call void @llvm.memmove.p0i8.p0i8.i32
13 // CHECK-NOT: __builtin
14 // CHECK: ret
15 int test1(int argc, char **argv) {
16   unsigned char a = 0x11223344;
17   unsigned char b = 0x11223344;
18   __builtin_bzero(&a, sizeof(a));
19   __builtin_memset(&a, 0, sizeof(a));
20   __builtin_memcpy(&a, &b, sizeof(a));
21   __builtin_memmove(&a, &b, sizeof(a));
22   return 0;
23 }
24 
25 // rdar://9289468
26 
27 // CHECK: @test2
28 // CHECK: call void @llvm.memcpy.p0i8.p0i8.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 int 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 // <rdar://problem/11314941>
73 // Make sure we don't over-estimate the alignment of fields of
74 // packed structs.
75 struct PS {
76   int modes[4];
77 } __attribute__((packed));
78 struct PS ps;
79 void test8(int *arg) {
80   // CHECK: @test8
81   // CHECK: call void @llvm.memcpy{{.*}} align 4 {{.*}} align 1 {{.*}} 16, i1 false)
82   __builtin_memcpy(arg, ps.modes, sizeof(struct PS));
83 }
84 
85 __attribute((aligned(16))) int x[4], y[4];
86 void test9() {
87   // CHECK: @test9
88   // CHECK: call void @llvm.memcpy{{.*}} align 16 {{.*}} align 16 {{.*}} 16, i1 false)
89   __builtin_memcpy(x, y, sizeof(y));
90 }
91 
92 wchar_t dest;
93 wchar_t src;
94 
95 // CHECK-LABEL: @test10
96 // FIXME: Consider lowering these to llvm.memcpy / llvm.memmove.
97 void test10() {
98   // CHECK: call i32* @wmemcpy(i32* @dest, i32* @src, i32 4)
99   __builtin_wmemcpy(&dest, &src, 4);
100 
101   // CHECK: call i32* @wmemmove(i32* @dest, i32* @src, i32 4)
102   __builtin_wmemmove(&dest, &src, 4);
103 }
104 
105 // CHECK-LABEL: @test11
106 void test11() {
107   typedef struct { int a; } b;
108   int d;
109   b e;
110   // CHECK: call void @llvm.memcpy{{.*}}(
111   memcpy(&d, (char *)&e.a, sizeof(e));
112 }
113 
114 // CHECK-LABEL: @test12
115 extern char dest_array[];
116 extern char src_array[];
117 void test12() {
118   // CHECK: call void @llvm.memcpy{{.*}}(
119   memcpy(&dest_array, &dest_array, 2);
120 }
121