Erich Keane | 623efd8 | 2017-03-30 21:48:55 +0000 | [diff] [blame] | 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:%.+]] = 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 | |
| 66 | struct Empty {}; |
| 67 | struct 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 | |