blob: b7cfcf76d4510f81f4004a2d48f035f86c7eef93 [file] [log] [blame]
Erich Keane623efd82017-03-30 21:48:55 +00001// 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:%.+]] = sext i32 [[PARAM1]] to i64
11// CHECK: [[ISPOS1:%.+]] = icmp sgt i64 [[ALIGNCAST1]], 0
12// CHECK: [[POSMASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1
13// CHECK: [[MASK1:%.+]] = select i1 [[ISPOS1]], i64 [[POSMASK1]], i64 0
14// CHECK: [[PTRINT1:%.+]] = ptrtoint
15// CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], [[MASK1]]
16// CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0
17// CHECK: call void @llvm.assume(i1 [[MASKCOND1]])
18}
19// Condition where test2 param needs casting.
20__INT32_TYPE__ test2(__SIZE_TYPE__ a) {
21// CHECK: define i32 @test2
22 return *m1(a);
23// CHECK: [[CONV2:%.+]] = trunc i64 %{{.+}} to i32
24// CHECK: call i32* @m1(i32 [[CONV2]])
25// CHECK: [[ALIGNCAST2:%.+]] = sext i32 [[CONV2]] to i64
26// CHECK: [[ISPOS2:%.+]] = icmp sgt i64 [[ALIGNCAST2]], 0
27// CHECK: [[POSMASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1
28// CHECK: [[MASK2:%.+]] = select i1 [[ISPOS2]], i64 [[POSMASK2]], i64 0
29// CHECK: [[PTRINT2:%.+]] = ptrtoint
30// CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], [[MASK2]]
31// CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0
32// CHECK: call void @llvm.assume(i1 [[MASKCOND2]])
33}
34__INT32_TYPE__ *m2(__SIZE_TYPE__ i) __attribute__((alloc_align(1)));
35
36// test3 param needs casting, but 'm2' is correct.
37__INT32_TYPE__ test3(__INT32_TYPE__ a) {
38// CHECK: define i32 @test3
39 return *m2(a);
40// CHECK: [[CONV3:%.+]] = sext i32 %{{.+}} to i64
41// CHECK: call i32* @m2(i64 [[CONV3]])
42// CHECK: [[ISPOS3:%.+]] = icmp sgt i64 [[CONV3]], 0
43// CHECK: [[POSMASK3:%.+]] = sub i64 [[CONV3]], 1
44// CHECK: [[MASK3:%.+]] = select i1 [[ISPOS3]], i64 [[POSMASK3]], i64 0
45// CHECK: [[PTRINT3:%.+]] = ptrtoint
46// CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], [[MASK3]]
47// CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0
48// CHECK: call void @llvm.assume(i1 [[MASKCOND3]])
49}
50
51// Every type matches, canonical example.
52__INT32_TYPE__ test4(__SIZE_TYPE__ a) {
53// CHECK: define i32 @test4
54 return *m2(a);
55// CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]])
56// CHECK: [[ISPOS4:%.+]] = icmp sgt i64 [[PARAM4]], 0
57// CHECK: [[POSMASK4:%.+]] = sub i64 [[PARAM4]], 1
58// CHECK: [[MASK4:%.+]] = select i1 [[ISPOS4]], i64 [[POSMASK4]], i64 0
59// CHECK: [[PTRINT4:%.+]] = ptrtoint
60// CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], [[MASK4]]
61// CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0
62// CHECK: call void @llvm.assume(i1 [[MASKCOND4]])
63}
64
65
66struct Empty {};
67struct MultiArgs { __INT64_TYPE__ a, b;};
68// Struct parameter doesn't take up an IR parameter, 'i' takes up 2.
69// Truncation to i64 is permissible, since alignments of greater than 2^64 are insane.
70__INT32_TYPE__ *m3(struct Empty s, __int128_t i) __attribute__((alloc_align(2)));
71__INT32_TYPE__ test5(__int128_t a) {
72// CHECK: define i32 @test5
73 struct Empty e;
74 return *m3(e, a);
75// CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}})
76// CHECK: [[ALIGNCAST5:%.+]] = trunc i128 %{{.*}} to i64
77// CHECK: [[ISPOS5:%.+]] = icmp sgt i64 [[ALIGNCAST5]], 0
78// CHECK: [[POSMASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1
79// CHECK: [[MASK5:%.+]] = select i1 [[ISPOS5]], i64 [[POSMASK5]], i64 0
80// CHECK: [[PTRINT5:%.+]] = ptrtoint
81// CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], [[MASK5]]
82// CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0
83// CHECK: call void @llvm.assume(i1 [[MASKCOND5]])
84}
85// Struct parameter takes up 2 parameters, 'i' takes up 2.
86__INT32_TYPE__ *m4(struct MultiArgs s, __int128_t i) __attribute__((alloc_align(2)));
87__INT32_TYPE__ test6(__int128_t a) {
88// CHECK: define i32 @test6
89 struct MultiArgs e;
90 return *m4(e, a);
91// CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}})
92// CHECK: [[ALIGNCAST6:%.+]] = trunc i128 %{{.*}} to i64
93// CHECK: [[ISPOS6:%.+]] = icmp sgt i64 [[ALIGNCAST6]], 0
94// CHECK: [[POSMASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1
95// CHECK: [[MASK6:%.+]] = select i1 [[ISPOS6]], i64 [[POSMASK6]], i64 0
96// CHECK: [[PTRINT6:%.+]] = ptrtoint
97// CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], [[MASK6]]
98// CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0
99// CHECK: call void @llvm.assume(i1 [[MASKCOND6]])
100}
101