1 // RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
2 
3 __INT32_TYPE__*m1(__INT32_TYPE__ i) __attribute__((alloc_align(1)));
4 
5 // Condition where parameter to m1 is not size_t.
6 __INT32_TYPE__ test1(__INT32_TYPE__ a) {
7 // CHECK: define i32 @test1
8   return *m1(a);
9 // CHECK: call i32* @m1(i32 [[PARAM1:%[^\)]+]])
10 // CHECK: [[ALIGNCAST1:%.+]] = zext i32 [[PARAM1]] to i64
11 // CHECK: [[MASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1
12 // CHECK: [[PTRINT1:%.+]] = ptrtoint
13 // CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], [[MASK1]]
14 // CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0
15 // CHECK: call void @llvm.assume(i1 [[MASKCOND1]])
16 }
17 // Condition where test2 param needs casting.
18 __INT32_TYPE__ test2(__SIZE_TYPE__ a) {
19 // CHECK: define i32 @test2
20   return *m1(a);
21 // CHECK: [[CONV2:%.+]] = trunc i64 %{{.+}} to i32
22 // CHECK: call i32* @m1(i32 [[CONV2]])
23 // CHECK: [[ALIGNCAST2:%.+]] = zext i32 [[CONV2]] to i64
24 // CHECK: [[MASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1
25 // CHECK: [[PTRINT2:%.+]] = ptrtoint
26 // CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], [[MASK2]]
27 // CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0
28 // CHECK: call void @llvm.assume(i1 [[MASKCOND2]])
29 }
30 __INT32_TYPE__ *m2(__SIZE_TYPE__ i) __attribute__((alloc_align(1)));
31 
32 // test3 param needs casting, but 'm2' is correct.
33 __INT32_TYPE__ test3(__INT32_TYPE__ a) {
34 // CHECK: define i32 @test3
35   return *m2(a);
36 // CHECK: [[CONV3:%.+]] = sext i32 %{{.+}} to i64
37 // CHECK: call i32* @m2(i64 [[CONV3]])
38 // CHECK: [[MASK3:%.+]] = sub i64 [[CONV3]], 1
39 // CHECK: [[PTRINT3:%.+]] = ptrtoint
40 // CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], [[MASK3]]
41 // CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0
42 // CHECK: call void @llvm.assume(i1 [[MASKCOND3]])
43 }
44 
45 // Every type matches, canonical example.
46 __INT32_TYPE__ test4(__SIZE_TYPE__ a) {
47 // CHECK: define i32 @test4
48   return *m2(a);
49 // CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]])
50 // CHECK: [[MASK4:%.+]] = sub i64 [[PARAM4]], 1
51 // CHECK: [[PTRINT4:%.+]] = ptrtoint
52 // CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], [[MASK4]]
53 // CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0
54 // CHECK: call void @llvm.assume(i1 [[MASKCOND4]])
55 }
56 
57 
58 struct Empty {};
59 struct MultiArgs { __INT64_TYPE__ a, b;};
60 // Struct parameter doesn't take up an IR parameter, 'i' takes up 2.
61 // Truncation to i64 is permissible, since alignments of greater than 2^64 are insane.
62 __INT32_TYPE__ *m3(struct Empty s, __int128_t i) __attribute__((alloc_align(2)));
63 __INT32_TYPE__ test5(__int128_t a) {
64 // CHECK: define i32 @test5
65   struct Empty e;
66   return *m3(e, a);
67 // CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}})
68 // CHECK: [[ALIGNCAST5:%.+]] = trunc i128 %{{.*}} to i64
69 // CHECK: [[MASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1
70 // CHECK: [[PTRINT5:%.+]] = ptrtoint
71 // CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], [[MASK5]]
72 // CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0
73 // CHECK: call void @llvm.assume(i1 [[MASKCOND5]])
74 }
75 // Struct parameter takes up 2 parameters, 'i' takes up 2.
76 __INT32_TYPE__ *m4(struct MultiArgs s, __int128_t i) __attribute__((alloc_align(2)));
77 __INT32_TYPE__ test6(__int128_t a) {
78 // CHECK: define i32 @test6
79   struct MultiArgs e;
80   return *m4(e, a);
81 // CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
82 // CHECK: [[ALIGNCAST6:%.+]] = trunc i128 %{{.*}} to i64
83 // CHECK: [[MASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1
84 // CHECK: [[PTRINT6:%.+]] = ptrtoint
85 // CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], [[MASK6]]
86 // CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0
87 // CHECK: call void @llvm.assume(i1 [[MASKCOND6]])
88 }
89 
90