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 | |