1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // Check that we use memcpy() instead of bzero to initialize this struct
3 // RUN: %cheri128_purecap_cc1 -mllvm -cheri-cap-table-abi=pcrel -emit-llvm %s -o - -O0 | FileCheck %s -check-prefix PCREL
4
5 typedef int (*nss_method)(void *_retval, void *_mdata, __builtin_va_list _ap);
6 #define NULL ((void *)0)
7 typedef struct _ns_dtab {
8 const char *src; /* Source this entry implements */
9 nss_method method; /* Method to be called */
10 void *mdata; /* Data passed to method */
11 } ns_dtab;
12
13 int nis_passwd(void *_retval, void *_mdata, __builtin_va_list _ap);
14 void do_stuff(ns_dtab *tab);
15
16 // PCREL-LABEL: @test(
17 // PCREL-NEXT: entry:
18 // PCREL-NEXT: [[MDATA_ADDR:%.*]] = alloca i8 addrspace(200)*, align 16, addrspace(200)
19 // PCREL-NEXT: [[DTAB:%.*]] = alloca [2 x %struct._ns_dtab], align 16, addrspace(200)
20 // PCREL-NEXT: [[I:%.*]] = alloca i32, align 4, addrspace(200)
21 // PCREL-NEXT: store i8 addrspace(200)* [[MDATA:%.*]], i8 addrspace(200)* addrspace(200)* [[MDATA_ADDR]], align 16
22 // PCREL-NEXT: [[TMP0:%.*]] = bitcast [2 x %struct._ns_dtab] addrspace(200)* [[DTAB]] to i8 addrspace(200)*
23 // PCREL-NEXT: call void @llvm.memcpy.p200i8.p200i8.i64(i8 addrspace(200)* align 16 [[TMP0]], i8 addrspace(200)* align 16 bitcast ([2 x %struct._ns_dtab] addrspace(200)* @__const.test.dtab to i8 addrspace(200)*), i64 96, i1 false)
24 // PCREL-NEXT: store i32 0, i32 addrspace(200)* [[I]], align 4
25 // PCREL-NEXT: br label [[FOR_COND:%.*]]
26 // PCREL: for.cond:
27 // PCREL-NEXT: [[TMP1:%.*]] = load i32, i32 addrspace(200)* [[I]], align 4
28 // PCREL-NEXT: [[CONV:%.*]] = sext i32 [[TMP1]] to i64
29 // PCREL-NEXT: [[CMP:%.*]] = icmp ult i64 [[CONV]], 1
30 // PCREL-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
31 // PCREL: for.body:
32 // PCREL-NEXT: [[TMP2:%.*]] = load i8 addrspace(200)*, i8 addrspace(200)* addrspace(200)* [[MDATA_ADDR]], align 16
33 // PCREL-NEXT: [[TMP3:%.*]] = load i32, i32 addrspace(200)* [[I]], align 4
34 // PCREL-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP3]] to i64
35 // PCREL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x %struct._ns_dtab], [2 x %struct._ns_dtab] addrspace(200)* [[DTAB]], i64 0, i64 [[IDXPROM]]
36 // PCREL-NEXT: [[MDATA2:%.*]] = getelementptr inbounds [[STRUCT__NS_DTAB:%.*]], [[STRUCT__NS_DTAB]] addrspace(200)* [[ARRAYIDX]], i32 0, i32 2
37 // PCREL-NEXT: store i8 addrspace(200)* [[TMP2]], i8 addrspace(200)* addrspace(200)* [[MDATA2]], align 16
38 // PCREL-NEXT: br label [[FOR_INC:%.*]]
39 // PCREL: for.inc:
40 // PCREL-NEXT: [[TMP4:%.*]] = load i32, i32 addrspace(200)* [[I]], align 4
41 // PCREL-NEXT: [[INC:%.*]] = add nsw i32 [[TMP4]], 1
42 // PCREL-NEXT: store i32 [[INC]], i32 addrspace(200)* [[I]], align 4
43 // PCREL-NEXT: br label [[FOR_COND]]
44 // PCREL: for.end:
45 // PCREL-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [2 x %struct._ns_dtab], [2 x %struct._ns_dtab] addrspace(200)* [[DTAB]], i64 0, i64 0
46 // PCREL-NEXT: call void @do_stuff(%struct._ns_dtab addrspace(200)* [[ARRAYDECAY]])
47 // PCREL-NEXT: ret void
48 //
test(void * mdata)49 void test(void *mdata) {
50 ns_dtab dtab[] = {
51 {"nis", nis_passwd, NULL},
52 {NULL, NULL, NULL}};
53 for (int i = 0; i < (sizeof(dtab) / sizeof(dtab[0])) - 1; i++) {
54 dtab[i].mdata = mdata;
55 }
56 do_stuff(dtab);
57 }
58