-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[AllocToken, Clang] Implement __builtin_infer_alloc_token() and llvm.alloc.token.id #156842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/melver/spr/main.alloctoken-clang-implement-__builtin_alloc_token_infer-and-llvmalloctokenid
Are you sure you want to change the base?
Changes from all commits
a5dccd9
131332f
f2ca41f
48227c8
b7f4c7f
548eba5
3aa00d1
72f662e
7a33b73
ba5bb6e
3bad95e
5fb8572
80f47ce
5db2e34
28f29d9
a09fc1e
dacf09a
a2df6e7
ee0275d
ab980ba
e94eeee
d3e693f
00bf24a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1498,6 +1498,24 @@ static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall) { | |
TheCall->setType(S.Context.getPointerType(RT)); | ||
} | ||
|
||
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it have test like Sema/arithmetic-fence-builtin.c or Sema/builtin-allow-runtime-check.c? It would be easier to notice missing test coverage with smaller patches. |
||
if (S.checkArgCountAtLeast(TheCall, 1)) | ||
return true; | ||
|
||
for (Expr *Arg : TheCall->arguments()) { | ||
// If argument is dependent on a template parameter, we can't resolve now. | ||
if (Arg->isTypeDependent() || Arg->isValueDependent()) | ||
continue; | ||
// Reject void types. | ||
QualType ArgTy = Arg->IgnoreParenImpCasts()->getType(); | ||
if (ArgTy->isVoidType()) | ||
return S.Diag(Arg->getBeginLoc(), diag::err_param_with_void_type); | ||
} | ||
|
||
TheCall->setType(S.Context.UnsignedLongLongTy); | ||
return false; | ||
} | ||
|
||
namespace { | ||
enum PointerAuthOpKind { | ||
PAO_Strip, | ||
|
@@ -2779,6 +2797,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, | |
builtinAllocaAddrSpace(*this, TheCall); | ||
} | ||
break; | ||
case Builtin::BI__builtin_infer_alloc_token: | ||
if (checkBuiltinInferAllocToken(*this, TheCall)) | ||
return ExprError(); | ||
break; | ||
case Builtin::BI__arithmetic_fence: | ||
if (BuiltinArithmeticFence(TheCall)) | ||
return ExprError(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Test IR generation of the builtin without evaluating the LLVM intrinsic. | ||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -Werror -std=c++20 -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-CODEGEN | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. backendutils and CG* changes also seems unrelated |
||
// 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( | ||
unsigned long test_builtin_int() { | ||
// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[MD_INT:[0-9]+]]) | ||
// CHECK-LOWER: ret i64 0 | ||
return __builtin_infer_alloc_token(sizeof(1)); | ||
} | ||
|
||
// CHECK-LABEL: @_Z16test_builtin_ptrv( | ||
unsigned long test_builtin_ptr() { | ||
// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[MD_PTR:[0-9]+]]) | ||
// CHECK-LOWER: ret i64 1 | ||
return __builtin_infer_alloc_token(sizeof(int *)); | ||
} | ||
|
||
// CHECK-LABEL: @_Z25test_builtin_struct_noptrv( | ||
unsigned long test_builtin_struct_noptr() { | ||
// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[MD_NOPTR:[0-9]+]]) | ||
// CHECK-LOWER: ret i64 0 | ||
return __builtin_infer_alloc_token(sizeof(NoPtr)); | ||
} | ||
|
||
// CHECK-LABEL: @_Z25test_builtin_struct_w_ptrv( | ||
unsigned long test_builtin_struct_w_ptr() { | ||
// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[MD_WITHPTR:[0-9]+]]) | ||
// CHECK-LOWER: ret i64 1 | ||
return __builtin_infer_alloc_token(sizeof(WithPtr), 123); | ||
} | ||
|
||
// CHECK-LABEL: @_Z24test_builtin_unevaluatedv( | ||
unsigned long test_builtin_unevaluated() { | ||
// CHECK-NOT: call{{.*}}unevaluated_fn | ||
// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[MD_INT:[0-9]+]]) | ||
// CHECK-LOWER: ret i64 0 | ||
return __builtin_infer_alloc_token(sizeof(int) * unevaluated_fn()); | ||
} | ||
|
||
// CHECK-LABEL: @_Z36test_builtin_unsequenced_unevaluatedi( | ||
void test_builtin_unsequenced_unevaluated(int x) { | ||
// CHECK: add nsw | ||
// CHECK-NOT: add nsw | ||
// CHECK-CODEGEN: %[[REG:[0-9]+]] = call i64 @llvm.alloc.token.id.i64(metadata ![[MD_UNKNOWN:[0-9]+]]) | ||
// CHECK-CODEGEN: call{{.*}}@my_malloc({{.*}}, i64 noundef %[[REG]]) | ||
// CHECK-LOWER: call{{.*}}@my_malloc({{.*}}, i64 noundef 0) | ||
my_malloc(++x, __builtin_infer_alloc_token(++x)); | ||
} | ||
|
||
// CHECK-LABEL: @_Z20test_builtin_unknownv( | ||
unsigned long test_builtin_unknown() { | ||
// CHECK-CODEGEN: call i64 @llvm.alloc.token.id.i64(metadata ![[MD_UNKNOWN:[0-9]+]]) | ||
// CHECK-LOWER: ret i64 0 | ||
return __builtin_infer_alloc_token(4096); | ||
} | ||
|
||
// CHECK-CODEGEN: ![[MD_INT]] = !{!"int", i1 false} | ||
// CHECK-CODEGEN: ![[MD_PTR]] = !{!"int *", i1 true} | ||
// CHECK-CODEGEN: ![[MD_NOPTR]] = !{!"NoPtr", i1 false} | ||
// CHECK-CODEGEN: ![[MD_WITHPTR]] = !{!"WithPtr", i1 true} | ||
// CHECK-CODEGEN: ![[MD_UNKNOWN]] = !{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather separate sema changes from codegen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate llvm/.. from clang/.. changes?
Or clang/lib/CodeGen from others?
One is useless without the other, and at least this way, if there's a problem, we can atomically revert one commit instead of several or partially reverting one or several commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang part looks deppends on LLVM but can be separated.
To avoid unlikely complex revert I'd just rather lang them with delay in a few days.