aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CodeGenCXX/alloc-token-builtin.cpp
blob: adadf7bbe4174d11c5b0defa30d0bde4f281e1a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// 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 <typename T>
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<int>();
}

// 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<int *>();
}

// 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]] = !{}