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 102