// To test IR generation of the builtin without evaluating the LLVM intrinsic, // we set the mode to a stateful mode, which prohibits constant evaluation. // 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 // 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 extern "C" void *my_malloc(unsigned long, unsigned long); struct NoPtr { int x; long y; }; struct WithPtr { int a; char *buf; }; int unevaluated_fn(); // CHECK-LABEL: @_Z16test_builtin_intv( // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT:[0-9]+]]) // CHECK-LOWER: ret i64 0 unsigned long test_builtin_int() { return __builtin_infer_alloc_token(sizeof(1)); } // CHECK-LABEL: @_Z16test_builtin_ptrv( // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_PTR:[0-9]+]]) // CHECK-LOWER: ret i64 1 unsigned long test_builtin_ptr() { return __builtin_infer_alloc_token(sizeof(int *)); } // CHECK-LABEL: @_Z25test_builtin_struct_noptrv( // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_NOPTR:[0-9]+]]) // CHECK-LOWER: ret i64 0 unsigned long test_builtin_struct_noptr() { return __builtin_infer_alloc_token(sizeof(NoPtr)); } // CHECK-LABEL: @_Z25test_builtin_struct_w_ptrv( // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_WITHPTR:[0-9]+]]) // CHECK-LOWER: ret i64 1 unsigned long test_builtin_struct_w_ptr() { return __builtin_infer_alloc_token(sizeof(WithPtr), 123); } // CHECK-LABEL: @_Z24test_builtin_unevaluatedv( // CHECK-NOT: call{{.*}}unevaluated_fn // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT:[0-9]+]]) // CHECK-LOWER: ret i64 0 unsigned long test_builtin_unevaluated() { return __builtin_infer_alloc_token(sizeof(int) * unevaluated_fn()); } // CHECK-LABEL: @_Z36test_builtin_unsequenced_unevaluatedi( // CHECK: add nsw // CHECK-NOT: add nsw // CHECK-CODEGEN: %[[REG:[0-9]+]] = call i64 @llvm.alloc.token.id.i64(metadata ![[META_UNKNOWN:[0-9]+]]) // CHECK-CODEGEN: call{{.*}}@my_malloc({{.*}}, i64 noundef %[[REG]]) // CHECK-LOWER: call{{.*}}@my_malloc({{.*}}, i64 noundef 0) void test_builtin_unsequenced_unevaluated(int x) { my_malloc(++x, __builtin_infer_alloc_token(++x)); } // CHECK-LABEL: @_Z20test_builtin_unknownv( // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_UNKNOWN:[0-9]+]]) // CHECK-LOWER: ret i64 0 unsigned long test_builtin_unknown() { return __builtin_infer_alloc_token(4096); } // Test template instantiation. template constexpr unsigned long get_token() { return __builtin_infer_alloc_token(sizeof(T)); } // CHECK-LABEL: @_Z13get_token_intv() // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_INT]]) // CHECK-LOWER: ret i64 0 unsigned long get_token_int() { return get_token(); } // CHECK-LABEL: @_Z13get_token_ptrv() // CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[META_PTR]]) // CHECK-LOWER: ret i64 1 unsigned long get_token_ptr() { return get_token(); } // CHECK-CODEGEN: ![[META_INT]] = !{!"int", i1 false} // CHECK-CODEGEN: ![[META_PTR]] = !{!"int *", i1 true} // CHECK-CODEGEN: ![[META_NOPTR]] = !{!"NoPtr", i1 false} // CHECK-CODEGEN: ![[META_WITHPTR]] = !{!"WithPtr", i1 true} // CHECK-CODEGEN: ![[META_UNKNOWN]] = !{}