|  | 
|  | 1 | +// To test IR generation of the builtin without evaluating the LLVM intrinsic, | 
|  | 2 | +// we set the mode to a stateful mode, which prohibits constant evaluation. | 
|  | 3 | +// RUN: %clang_cc1 -triple x86_64-linux-gnu -Werror -std=c++20 -emit-llvm -falloc-token-mode=random -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-CODEGEN | 
|  | 4 | +// RUN: %clang_cc1 -triple x86_64-linux-gnu -Werror -std=c++20 -emit-llvm -falloc-token-max=2 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-LOWER | 
|  | 5 | + | 
|  | 6 | +extern "C" void *my_malloc(unsigned long, unsigned long); | 
|  | 7 | + | 
|  | 8 | +struct NoPtr { | 
|  | 9 | +  int x; | 
|  | 10 | +  long y; | 
|  | 11 | +}; | 
|  | 12 | + | 
|  | 13 | +struct WithPtr { | 
|  | 14 | +  int a; | 
|  | 15 | +  char *buf; | 
|  | 16 | +}; | 
|  | 17 | + | 
|  | 18 | +int unevaluated_fn(); | 
|  | 19 | + | 
|  | 20 | +// CHECK-LABEL: @_Z16test_builtin_intv( | 
|  | 21 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT:[0-9]+]]) | 
|  | 22 | +// CHECK-LOWER: ret i64 0 | 
|  | 23 | +unsigned long test_builtin_int() { | 
|  | 24 | +  return __builtin_infer_alloc_token(sizeof(1)); | 
|  | 25 | +} | 
|  | 26 | + | 
|  | 27 | +// CHECK-LABEL: @_Z16test_builtin_ptrv( | 
|  | 28 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_PTR:[0-9]+]]) | 
|  | 29 | +// CHECK-LOWER: ret i64 1 | 
|  | 30 | +unsigned long test_builtin_ptr() { | 
|  | 31 | +  return __builtin_infer_alloc_token(sizeof(int *)); | 
|  | 32 | +} | 
|  | 33 | + | 
|  | 34 | +// CHECK-LABEL: @_Z25test_builtin_struct_noptrv( | 
|  | 35 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_NOPTR:[0-9]+]]) | 
|  | 36 | +// CHECK-LOWER: ret i64 0 | 
|  | 37 | +unsigned long test_builtin_struct_noptr() { | 
|  | 38 | +  return __builtin_infer_alloc_token(sizeof(NoPtr)); | 
|  | 39 | +} | 
|  | 40 | + | 
|  | 41 | +// CHECK-LABEL: @_Z25test_builtin_struct_w_ptrv( | 
|  | 42 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_WITHPTR:[0-9]+]]) | 
|  | 43 | +// CHECK-LOWER: ret i64 1 | 
|  | 44 | +unsigned long test_builtin_struct_w_ptr() { | 
|  | 45 | +  return __builtin_infer_alloc_token(sizeof(WithPtr), 123); | 
|  | 46 | +} | 
|  | 47 | + | 
|  | 48 | +// CHECK-LABEL: @_Z24test_builtin_unevaluatedv( | 
|  | 49 | +// CHECK-NOT: call{{.*}}unevaluated_fn | 
|  | 50 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT:[0-9]+]]) | 
|  | 51 | +// CHECK-LOWER: ret i64 0 | 
|  | 52 | +unsigned long test_builtin_unevaluated() { | 
|  | 53 | +	return __builtin_infer_alloc_token(sizeof(int) * unevaluated_fn()); | 
|  | 54 | +} | 
|  | 55 | + | 
|  | 56 | +// CHECK-LABEL: @_Z36test_builtin_unsequenced_unevaluatedi( | 
|  | 57 | +// CHECK:     add nsw | 
|  | 58 | +// CHECK-NOT: add nsw | 
|  | 59 | +// CHECK-CODEGEN: %[[REG:[0-9]+]] = call i64 @llvm.alloc.token.id.i64(metadata ![[META_UNKNOWN:[0-9]+]]) | 
|  | 60 | +// CHECK-CODEGEN: call{{.*}}@my_malloc({{.*}}, i64 noundef %[[REG]]) | 
|  | 61 | +// CHECK-LOWER: call{{.*}}@my_malloc({{.*}}, i64 noundef 0) | 
|  | 62 | +void test_builtin_unsequenced_unevaluated(int x) { | 
|  | 63 | +  my_malloc(++x, __builtin_infer_alloc_token(++x)); | 
|  | 64 | +} | 
|  | 65 | + | 
|  | 66 | +// CHECK-LABEL: @_Z20test_builtin_unknownv( | 
|  | 67 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_UNKNOWN:[0-9]+]]) | 
|  | 68 | +// CHECK-LOWER: ret i64 0 | 
|  | 69 | +unsigned long test_builtin_unknown() { | 
|  | 70 | +  return __builtin_infer_alloc_token(4096); | 
|  | 71 | +} | 
|  | 72 | + | 
|  | 73 | +// Test template instantiation. | 
|  | 74 | +template <typename T> | 
|  | 75 | +constexpr unsigned long get_token() { | 
|  | 76 | +  return __builtin_infer_alloc_token(sizeof(T)); | 
|  | 77 | +} | 
|  | 78 | + | 
|  | 79 | +// CHECK-LABEL: @_Z13get_token_intv() | 
|  | 80 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT]]) | 
|  | 81 | +// CHECK-LOWER: ret i64 0 | 
|  | 82 | +unsigned long get_token_int() { | 
|  | 83 | +  return get_token<int>(); | 
|  | 84 | +} | 
|  | 85 | + | 
|  | 86 | +// CHECK-LABEL: @_Z13get_token_ptrv() | 
|  | 87 | +// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_PTR]]) | 
|  | 88 | +// CHECK-LOWER: ret i64 1 | 
|  | 89 | +unsigned long get_token_ptr() { | 
|  | 90 | +  return get_token<int *>(); | 
|  | 91 | +} | 
|  | 92 | + | 
|  | 93 | +// CHECK-CODEGEN: ![[META_INT]] = !{!"int", i1 false} | 
|  | 94 | +// CHECK-CODEGEN: ![[META_PTR]] = !{!"int *", i1 true} | 
|  | 95 | +// CHECK-CODEGEN: ![[META_NOPTR]] = !{!"NoPtr", i1 false} | 
|  | 96 | +// CHECK-CODEGEN: ![[META_WITHPTR]] = !{!"WithPtr", i1 true} | 
|  | 97 | +// CHECK-CODEGEN: ![[META_UNKNOWN]] = !{} | 
0 commit comments