diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2936,6 +2936,8 @@ "string">; def err_callback_attribute_no_callee : Error< "'callback' attribute specifies no callback callee">; +def err_callback_attribute_no_encoding_mode : Error< + "'callback' attribute specifies no parameter encoding mode">; def err_callback_attribute_invalid_callee : Error< "'callback' attribute specifies invalid callback callee">; def err_callback_attribute_multiple : Error< diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2126,19 +2126,23 @@ if (const auto *CB = FD->getAttr()) { // Annotate the callback behavior as metadata: + // - The callback argument encoding mode (as argument number) // - The callback callee (as argument number). // - The callback payloads (as argument numbers). llvm::LLVMContext &Ctx = F->getContext(); llvm::MDBuilder MDB(Ctx); - // The payload indices are all but the first one in the encoding. The first - // identifies the callback callee. - int CalleeIdx = *CB->encoding_begin(); - ArrayRef PayloadIndices(CB->encoding_begin() + 1, CB->encoding_end()); - F->addMetadata(llvm::LLVMContext::MD_callback, - *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding( - CalleeIdx, PayloadIndices, - /* VarArgsArePassed */ false)})); + // The payload indices are all but the first two in the encoding. The first + // identifies the callback argument encoding mode, and the second represents + // the callback callee. + int EncodingMode = *CB->encoding_begin(); + int CalleeIdx = *(CB->encoding_begin() + 1); + ArrayRef PayloadIndices(CB->encoding_begin() + 2, CB->encoding_end()); + F->addMetadata( + llvm::LLVMContext::MD_callback, + *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding( + EncodingMode, CalleeIdx, PayloadIndices, + /* VarArgsArePassed */ false)})); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3555,8 +3555,15 @@ /// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes. static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) { - // The index that identifies the callback callee is mandatory. + // The parameter encoding mode is mandatory. if (AL.getNumArgs() == 0) { + S.Diag(AL.getLoc(), diag::err_callback_attribute_no_encoding_mode) + << AL.getRange(); + return; + } + + // The index that identifies the callback callee is mandatory. + if (AL.getNumArgs() == 1) { S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee) << AL.getRange(); return; @@ -3618,7 +3625,7 @@ llvm_unreachable("Unexpected ParsedAttr argument type!"); } - if (ArgIdx == 0 && !HasImplicitThisParam) { + if (ArgIdx == 0 && I != 0 && !HasImplicitThisParam) { S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available) << (I + 1) << SR; return; @@ -3632,7 +3639,9 @@ EncodingIndices.push_back(ArgIdx); } - int CalleeIdx = EncodingIndices.front(); + assert(EncodingIndices.size() >= 2); + + int CalleeIdx = EncodingIndices[1]; // Check if the callee index is proper, thus not "this" and not "unknown". // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam" // is false and positive if "HasImplicitThisParam" is true. @@ -3665,15 +3674,9 @@ return; } - if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) { - S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) - << AL << (unsigned)(EncodingIndices.size() - 1); - return; - } - - if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) { + if (CalleeFnProtoType->getNumParams() != EncodingIndices.size() - 2) { S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) - << AL << (unsigned)(EncodingIndices.size() - 1); + << AL << (unsigned)(CalleeFnProtoType->getNumParams() + 2); return; } diff --git a/clang/test/CodeGen/attr-callback.c b/clang/test/CodeGen/attr-callback.c --- a/clang/test/CodeGen/attr-callback.c +++ b/clang/test/CodeGen/attr-callback.c @@ -3,26 +3,26 @@ void cb0(void); // CHECK-DAG: !callback ![[cid0:[0-9]+]] void @no_args -__attribute__((callback(1))) void no_args(void (*callback)(void)); +__attribute__((callback(0, 1))) void no_args(void (*callback)(void)); // CHECK-DAG: @args_1({{[^#]*#[0-9]+}} !callback ![[cid1:[0-9]+]] -__attribute__((callback(1, 2, 3))) void args_1(void (*callback)(int, double), int a, double b) { no_args(cb0); } +__attribute__((callback(0, 1, 2, 3))) void args_1(void (*callback)(int, double), int a, double b) { no_args(cb0); } // CHECK-DAG: !callback ![[cid2:[0-9]+]] void @args_2a -__attribute__((callback(2, 3, 3))) void args_2a(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, 2, 3, 3))) void args_2a(int a, void (*callback)(double, double), double b); // CHECK-DAG: !callback ![[cid2]] void @args_2b -__attribute__((callback(callback, b, b))) void args_2b(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, callback, b, b))) void args_2b(int a, void (*callback)(double, double), double b); // CHECK-DAG: void @args_3a({{[^#]*#[0-9]+}} !callback ![[cid3:[0-9]+]] -__attribute__((callback(2, -1, -1))) void args_3a(int a, void (*callback)(double, double), double b) { args_2a(a, callback, b); } +__attribute__((callback(0, 2, -1, -1))) void args_3a(int a, void (*callback)(double, double), double b) { args_2a(a, callback, b); } // CHECK-DAG: void @args_3b({{[^#]*#[0-9]+}} !callback ![[cid3]] -__attribute__((callback(callback, __, __))) void args_3b(int a, void (*callback)(double, double), double b) { args_2b(a, callback, b); } +__attribute__((callback(0, callback, __, __))) void args_3b(int a, void (*callback)(double, double), double b) { args_2b(a, callback, b); } // CHECK-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]} -// CHECK-DAG: ![[cid0b]] = !{i64 0, i1 false} +// CHECK-DAG: ![[cid0b]] = !{i64 0, i64 0, i1 false} // CHECK-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]} -// CHECK-DAG: ![[cid1b]] = !{i64 0, i64 1, i64 2, i1 false} +// CHECK-DAG: ![[cid1b]] = !{i64 0, i64 0, i64 1, i64 2, i1 false} // CHECK-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]} -// CHECK-DAG: ![[cid2b]] = !{i64 1, i64 2, i64 2, i1 false} +// CHECK-DAG: ![[cid2b]] = !{i64 0, i64 1, i64 2, i64 2, i1 false} // CHECK-DAG: ![[cid3]] = !{![[cid3b:[0-9]+]]} -// CHECK-DAG: ![[cid3b]] = !{i64 1, i64 -1, i64 -1, i1 false} +// CHECK-DAG: ![[cid3b]] = !{i64 0, i64 1, i64 -1, i64 -1, i1 false} diff --git a/clang/test/CodeGen/callback_annotated.c b/clang/test/CodeGen/callback_annotated.c --- a/clang/test/CodeGen/callback_annotated.c +++ b/clang/test/CodeGen/callback_annotated.c @@ -1,30 +1,30 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -fno-experimental-new-pass-manager %s -emit-llvm -o - -disable-llvm-optzns | FileCheck %s --check-prefix=RUN1 // RUN1-DAG: @broker0({{[^#]*#[0-9]+}} !callback ![[cid0:[0-9]+]] -__attribute__((callback(1, 2))) void *broker0(void *(*callee)(void *), void *payload) { +__attribute__((callback(0, 1, 2))) void *broker0(void *(*callee)(void *), void *payload) { return callee(payload); } // RUN1-DAG: @broker1({{[^#]*#[0-9]+}} !callback ![[cid1:[0-9]+]] -__attribute__((callback(callee, payload))) void *broker1(void *payload, void *(*callee)(void *)) { +__attribute__((callback(0, callee, payload))) void *broker1(void *payload, void *(*callee)(void *)) { return broker0(callee, payload); } void *broker2(void (*callee)(void)); // RUN1-DAG: declare !callback ![[cid2:[0-9]+]] i8* @broker2 -__attribute__((callback(callee))) void *broker2(void (*callee)(void)); +__attribute__((callback(0, callee))) void *broker2(void (*callee)(void)); void *broker2(void (*callee)(void)); // RUN1-DAG: declare !callback ![[cid3:[0-9]+]] i8* @broker3 -__attribute__((callback(4, 1, 2, c))) void *broker3(int, int, int c, int (*callee)(int, int, int), int); +__attribute__((callback(0, 4, 1, 2, c))) void *broker3(int, int, int c, int (*callee)(int, int, int), int); // RUN1-DAG: declare !callback ![[cid4:[0-9]+]] i8* @broker4 -__attribute__((callback(4, -1, a, __))) void *broker4(int a, int, int, int (*callee)(int, int, int), int); +__attribute__((callback(0, 4, -1, a, __))) void *broker4(int a, int, int, int (*callee)(int, int, int), int); // RUN1-DAG: declare !callback ![[cid5:[0-9]+]] i8* @broker5 -__attribute__((callback(4, d, 5, 2))) void *broker5(int, int, int, int (*callee)(int, int, int), int d); +__attribute__((callback(0, 4, d, 5, 2))) void *broker5(int, int, int, int (*callee)(int, int, int), int d); static void *VoidPtr2VoidPtr(void *payload) { return payload; @@ -44,14 +44,14 @@ } // RUN1-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]} -// RUN1-DAG: ![[cid0b]] = !{i64 0, i64 1, i1 false} +// RUN1-DAG: ![[cid0b]] = !{i64 0, i64 0, i64 1, i1 false} // RUN1-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]} -// RUN1-DAG: ![[cid1b]] = !{i64 1, i64 0, i1 false} +// RUN1-DAG: ![[cid1b]] = !{i64 0, i64 1, i64 0, i1 false} // RUN1-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]} -// RUN1-DAG: ![[cid2b]] = !{i64 0, i1 false} +// RUN1-DAG: ![[cid2b]] = !{i64 0, i64 0, i1 false} // RUN1-DAG: ![[cid3]] = !{![[cid3b:[0-9]+]]} -// RUN1-DAG: ![[cid3b]] = !{i64 3, i64 0, i64 1, i64 2, i1 false} +// RUN1-DAG: ![[cid3b]] = !{i64 0, i64 3, i64 0, i64 1, i64 2, i1 false} // RUN1-DAG: ![[cid4]] = !{![[cid4b:[0-9]+]]} -// RUN1-DAG: ![[cid4b]] = !{i64 3, i64 -1, i64 0, i64 -1, i1 false} +// RUN1-DAG: ![[cid4b]] = !{i64 0, i64 3, i64 -1, i64 0, i64 -1, i1 false} // RUN1-DAG: ![[cid5]] = !{![[cid5b:[0-9]+]]} -// RUN1-DAG: ![[cid5b]] = !{i64 3, i64 4, i64 4, i64 1, i1 false} +// RUN1-DAG: ![[cid5b]] = !{i64 0, i64 3, i64 4, i64 4, i64 1, i1 false} diff --git a/clang/test/CodeGen/callback_openmp.c b/clang/test/CodeGen/callback_openmp.c --- a/clang/test/CodeGen/callback_openmp.c +++ b/clang/test/CodeGen/callback_openmp.c @@ -3,7 +3,7 @@ // CHECK: declare !callback ![[cid:[0-9]+]] void @__kmpc_fork_call // CHECK: declare !callback ![[cid]] void @__kmpc_fork_teams // CHECK: ![[cid]] = !{![[cidb:[0-9]+]]} -// CHECK: ![[cidb]] = !{i64 2, i64 -1, i64 -1, i1 true} +// CHECK: ![[cidb]] = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} void work1(int, int); void work2(int, int); diff --git a/clang/test/CodeGenCXX/attr-callback.cpp b/clang/test/CodeGenCXX/attr-callback.cpp --- a/clang/test/CodeGenCXX/attr-callback.cpp +++ b/clang/test/CodeGenCXX/attr-callback.cpp @@ -3,28 +3,28 @@ struct Base { void no_args_1(void (*callback)(void)); - __attribute__((callback(1))) void no_args_2(void (*callback1)(void), void (*callback2)(void)); - __attribute__((callback(callback1))) void no_args_3(void (*callback1)(void), void (*callback2)(void)); + __attribute__((callback(0, 1))) void no_args_2(void (*callback1)(void), void (*callback2)(void)); + __attribute__((callback(0, callback1))) void no_args_3(void (*callback1)(void), void (*callback2)(void)); // TODO: There should probably be a warning or even an error for different // callbacks on the same method. - __attribute__((callback(1))) virtual void + __attribute__((callback(0, 1))) virtual void virtual_1(void (*callback)(void)); - __attribute__((callback(callback, this, __, this))) virtual void + __attribute__((callback(0, callback, this, __, this))) virtual void this_unknown_this(void (*callback)(Base *, Base *, Base *)); }; // CHECK-DAG: define{{.*}} void @_ZN4Base9no_args_1EPFvvE({{[^!]*!callback}} ![[cid0:[0-9]+]] -__attribute__((callback(1))) void +__attribute__((callback(0, 1))) void Base::no_args_1(void (*callback)(void)) { } // CHECK-DAG: define{{.*}} void @_ZN4Base9no_args_2EPFvvES1_({{[^!]*!callback}} ![[cid1:[0-9]+]] -__attribute__((callback(2))) void Base::no_args_2(void (*callback1)(void), void (*callback2)(void)) { +__attribute__((callback(0, 2))) void Base::no_args_2(void (*callback1)(void), void (*callback2)(void)) { } // CHECK-DAG: define{{.*}} void @_ZN4Base9no_args_3EPFvvES1_({{[^!]*!callback}} ![[cid1]] -__attribute__((callback(callback2))) void Base::no_args_3(void (*callback1)(void), void (*callback2)(void)) { +__attribute__((callback(0, callback2))) void Base::no_args_3(void (*callback1)(void), void (*callback2)(void)) { } // CHECK-DAG: define{{.*}} void @_ZN4Base17this_unknown_thisEPFvPS_S0_S0_E({{[^!]*!callback}} ![[cid2:[0-9]+]] @@ -32,7 +32,7 @@ } struct Derived_1 : public Base { - __attribute__((callback(1))) virtual void + __attribute__((callback(0, 1))) virtual void virtual_1(void (*callback)(void)) override; }; @@ -48,8 +48,8 @@ void Derived_2::virtual_1(void (*callback)(void)) {} // CHECK-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]} -// CHECK-DAG: ![[cid0b]] = !{i64 1, i1 false} +// CHECK-DAG: ![[cid0b]] = !{i64 0, i64 1, i1 false} // CHECK-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]} -// CHECK-DAG: ![[cid1b]] = !{i64 2, i1 false} +// CHECK-DAG: ![[cid1b]] = !{i64 0, i64 2, i1 false} // CHECK-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]} -// CHECK-DAG: ![[cid2b]] = !{i64 1, i64 0, i64 -1, i64 0, i1 false} +// CHECK-DAG: ![[cid2b]] = !{i64 0, i64 1, i64 0, i64 -1, i64 0, i1 false} diff --git a/clang/test/OpenMP/parallel_codegen.cpp b/clang/test/OpenMP/parallel_codegen.cpp --- a/clang/test/OpenMP/parallel_codegen.cpp +++ b/clang/test/OpenMP/parallel_codegen.cpp @@ -182,5 +182,5 @@ // ALL: attributes #[[FN_ATTRS]] = {{.+}} nounwind // ALL-DEBUG: attributes #[[FN_ATTRS]] = {{.+}} nounwind // ALL: ![[cbid]] = !{![[cbidb:[0-9]+]]} -// ALL: ![[cbidb]] = !{i64 2, i64 -1, i64 -1, i1 true} +// ALL: ![[cbidb]] = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} #endif diff --git a/clang/test/Sema/attr-callback-broken.c b/clang/test/Sema/attr-callback-broken.c --- a/clang/test/Sema/attr-callback-broken.c +++ b/clang/test/Sema/attr-callback-broken.c @@ -1,75 +1,76 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -__attribute__((callback())) void no_callee(void (*callback)(void)); // expected-error {{'callback' attribute specifies no callback callee}} +__attribute__((callback())) void no_encoding_mode(void (*callback)(void)); // expected-error {{'callback' attribute specifies no parameter encoding mode}} +__attribute__((callback(0))) void no_callee(void (*callback)(void)); // expected-error {{'callback' attribute specifies no callback callee}} -__attribute__((callback(1, 1))) void too_many_args_1(void (*callback)(void)) {} // expected-error {{'callback' attribute takes one argument}} -__attribute__((callback(1, -1))) void too_many_args_2(double (*callback)(void)); // expected-error {{'callback' attribute takes one argument}} -__attribute__((callback(1, 2, 2))) void too_many_args_3(void (*callback)(int), int); // expected-error {{'callback' attribute requires exactly 2 arguments}} +__attribute__((callback(0, 1, 1))) void too_many_args_1(void (*callback)(void)) {} // expected-error {{'callback' attribute requires exactly 2 arguments}} +__attribute__((callback(0, 1, -1))) void too_many_args_2(double (*callback)(void)); // expected-error {{'callback' attribute requires exactly 2 arguments}} +__attribute__((callback(0, 1, 2, 2))) void too_many_args_3(void (*callback)(int), int); // expected-error {{'callback' attribute requires exactly 3 arguments}} -__attribute__((callback(1, 2))) void too_few_args_1(void (*callback)(int, int), int); // expected-error {{'callback' attribute takes one argument}} -__attribute__((callback(1))) void too_few_args_2(int (*callback)(int)); // expected-error {{'callback' attribute takes no arguments}} -__attribute__((callback(1, -1))) void too_few_args_3(void (*callback)(int, int)) {} // expected-error {{'callback' attribute takes one argument}} +__attribute__((callback(0, 1, 2))) void too_few_args_1(void (*callback)(int, int), int); // expected-error {{'callback' attribute requires exactly 4 arguments}} +__attribute__((callback(0, 1))) void too_few_args_2(int (*callback)(int)); // expected-error {{'callback' attribute requires exactly 3 arguments}} +__attribute__((callback(0, 1, -1))) void too_few_args_3(void (*callback)(int, int)) {} // expected-error {{'callback' attribute requires exactly 4 arguments}} -__attribute__((callback(-1))) void oob_args_1(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} -__attribute__((callback(2))) void oob_args_2(int *(*callback)(void)) {} // expected-error {{'callback' attribute parameter 1 is out of bounds}} -__attribute__((callback(1, 3))) void oob_args_3(short (*callback)(int), int); // expected-error {{'callback' attribute parameter 2 is out of bounds}} -__attribute__((callback(-2, 2))) void oob_args_4(void *(*callback)(int), int); // expected-error {{'callback' attribute parameter 1 is out of bounds}} -__attribute__((callback(1, -2))) void oob_args_5(void *(*callback)(int), int); // expected-error {{'callback' attribute parameter 2 is out of bounds}} -__attribute__((callback(1, 2))) void oob_args_6(void *(*callback)(int), ...); // expected-error {{'callback' attribute parameter 2 is out of bounds}} +__attribute__((callback(0, -1))) void oob_args_1(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} +__attribute__((callback(0, 2))) void oob_args_2(int *(*callback)(void)) {} // expected-error {{'callback' attribute parameter 2 is out of bounds}} +__attribute__((callback(0, 1, 3))) void oob_args_3(short (*callback)(int), int); // expected-error {{'callback' attribute parameter 3 is out of bounds}} +__attribute__((callback(0, -2, 2))) void oob_args_4(void *(*callback)(int), int); // expected-error {{'callback' attribute parameter 2 is out of bounds}} +__attribute__((callback(0, 1, -2))) void oob_args_5(void *(*callback)(int), int); // expected-error {{'callback' attribute parameter 3 is out of bounds}} +__attribute__((callback(0, 1, 2))) void oob_args_6(void *(*callback)(int), ...); // expected-error {{'callback' attribute parameter 3 is out of bounds}} -__attribute__((callback(1))) __attribute__((callback(1))) void multiple_cb_1(void (*callback)(void)); // expected-error {{multiple 'callback' attributes specified}} -__attribute__((callback(1))) __attribute__((callback(2))) void multiple_cb_2(void (*callback1)(void), void (*callback2)(void)); // expected-error {{multiple 'callback' attributes specified}} +__attribute__((callback(0, 1))) __attribute__((callback(0, 1))) void multiple_cb_1(void (*callback)(void)); // expected-error {{multiple 'callback' attributes specified}} +__attribute__((callback(0, 1))) __attribute__((callback(0, 2))) void multiple_cb_2(void (*callback1)(void), void (*callback2)(void)); // expected-error {{multiple 'callback' attributes specified}} #ifdef HAS_THIS -__attribute__((callback(0))) void oob_args_0(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} +__attribute__((callback(0, 0))) void oob_args_0(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} #else -__attribute__((callback(0))) void oob_args_0(void (*callback)(void)); // expected-error {{'callback' argument at position 1 references unavailable implicit 'this'}} -__attribute__((callback(1, 0))) void no_this_1(void *(*callback)(void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}} -__attribute__((callback(1, 0))) void no_this_2(void *(*callback)(int, void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}} +__attribute__((callback(0, 0))) void oob_args_0(void (*callback)(void)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}} +__attribute__((callback(0, 1, 0))) void no_this_1(void *(*callback)(void *)); // expected-error {{'callback' argument at position 3 references unavailable implicit 'this'}} +__attribute__((callback(0, 1, 0))) void no_this_2(void *(*callback)(int, void *)); // expected-error {{'callback' argument at position 3 references unavailable implicit 'this'}} #endif // We could allow the following declarations if we at some point need to: -__attribute__((callback(1, -1))) void vararg_cb_1(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute callee may not be variadic}} -__attribute__((callback(1, 1))) void vararg_cb_2(void (*callback)(int, ...), int a); // expected-error {{'callback' attribute callee may not be variadic}} +__attribute__((callback(0, 1, -1))) void vararg_cb_1(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute callee may not be variadic}} +__attribute__((callback(0, 1, 1))) void vararg_cb_2(void (*callback)(int, ...), int a); // expected-error {{'callback' attribute callee may not be variadic}} -__attribute__((callback(1, -1, 1, 2, 3, 4, -1))) void varargs_1(void (*callback)(int, ...), int a, float b, double c) {} // expected-error {{'callback' attribute requires exactly 6 arguments}} -__attribute__((callback(1, -1, 4, 2, 3, 4, -1))) void varargs_2(void (*callback)(void *, double, int, ...), int a, float b, double c); // expected-error {{'callback' attribute requires exactly 6 arguments}} +__attribute__((callback(0, 1, -1, 1, 2, 3, 4, -1))) void varargs_1(void (*callback)(int, ...), int a, float b, double c) {} // expected-error {{'callback' attribute requires exactly 3 arguments}} +__attribute__((callback(0, 1, -1, 4, 2, 3, 4, -1))) void varargs_2(void (*callback)(void *, double, int, ...), int a, float b, double c); // expected-error {{'callback' attribute requires exactly 5 arguments}} -__attribute__((callback(1, -1, 1))) void self_arg_1(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute requires exactly 2 arguments}} -__attribute__((callback(1, -1, 1, -1, -1, 1))) void self_arg_2(void (*callback)(int, ...)); // expected-error {{'callback' attribute requires exactly 5 arguments}} +__attribute__((callback(0, 1, -1, 1))) void self_arg_1(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute requires exactly 3 arguments}} +__attribute__((callback(0, 1, -1, 1, -1, -1, 1))) void self_arg_2(void (*callback)(int, ...)); // expected-error {{'callback' attribute requires exactly 3 arguments}} -__attribute__((callback(cb))) void unknown_name1(void (*callback)(void)) {} // expected-error {{'callback' attribute argument 'cb' is not a known function parameter}} -__attribute__((callback(cb, ab))) void unknown_name2(void (*cb)(int), int a) {} // expected-error {{'callback' attribute argument 'ab' is not a known function parameter}} +__attribute__((callback(0, cb))) void unknown_name1(void (*callback)(void)) {} // expected-error {{'callback' attribute argument 'cb' is not a known function parameter}} +__attribute__((callback(0, cb, ab))) void unknown_name2(void (*cb)(int), int a) {} // expected-error {{'callback' attribute argument 'ab' is not a known function parameter}} -__attribute__((callback(callback, 1))) void too_many_args_1b(void (*callback)(void)) {} // expected-error {{'callback' attribute takes one argument}} -__attribute__((callback(callback, __))) void too_many_args_2b(double (*callback)(void)); // expected-error {{'callback' attribute takes one argument}} -__attribute__((callback(callback, 2, 2))) void too_many_args_3b(void (*callback)(int), int); // expected-error {{'callback' attribute requires exactly 2 arguments}} +__attribute__((callback(0, callback, 1))) void too_many_args_1b(void (*callback)(void)) {} // expected-error {{'callback' attribute requires exactly 2 arguments}} +__attribute__((callback(0, callback, __))) void too_many_args_2b(double (*callback)(void)); // expected-error {{'callback' attribute requires exactly 2 arguments}} +__attribute__((callback(0, callback, 2, 2))) void too_many_args_3b(void (*callback)(int), int); // expected-error {{'callback' attribute requires exactly 3 arguments}} -__attribute__((callback(callback, a))) void too_few_args_1b(void (*callback)(int, int), int a); // expected-error {{'callback' attribute takes one argument}} -__attribute__((callback(callback))) void too_few_args_2b(int (*callback)(int)); // expected-error {{'callback' attribute takes no arguments}} -__attribute__((callback(callback, __))) void too_few_args_3b(void (*callback)(int, int)) {} // expected-error {{'callback' attribute takes one argument}} +__attribute__((callback(0, callback, a))) void too_few_args_1b(void (*callback)(int, int), int a); // expected-error {{'callback' attribute requires exactly 4 arguments}} +__attribute__((callback(0, callback))) void too_few_args_2b(int (*callback)(int)); // expected-error {{'callback' attribute requires exactly 3 arguments}} +__attribute__((callback(0, callback, __))) void too_few_args_3b(void (*callback)(int, int)) {} // expected-error {{'callback' attribute requires exactly 4 arguments}} -__attribute__((callback(__))) void oob_args_1b(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} +__attribute__((callback(0, __))) void oob_args_1b(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} -__attribute__((callback(callback))) __attribute__((callback(callback))) void multiple_cb_1b(void (*callback)(void)); // expected-error {{multiple 'callback' attributes specified}} -__attribute__((callback(1))) __attribute__((callback(callback2))) void multiple_cb_2b(void (*callback1)(void), void (*callback2)(void)); // expected-error {{multiple 'callback' attributes specified}} +__attribute__((callback(0, callback))) __attribute__((callback(0, callback))) void multiple_cb_1b(void (*callback)(void)); // expected-error {{multiple 'callback' attributes specified}} +__attribute__((callback(0, 1))) __attribute__((callback(0, callback2))) void multiple_cb_2b(void (*callback1)(void), void (*callback2)(void)); // expected-error {{multiple 'callback' attributes specified}} #ifdef HAS_THIS -__attribute__((callback(this))) void oob_args_0b(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} +__attribute__((callback(0, this))) void oob_args_0b(void (*callback)(void)); // expected-error {{'callback' attribute specifies invalid callback callee}} #else -__attribute__((callback(this))) void oob_args_0b(void (*callback)(void)); // expected-error {{'callback' argument at position 1 references unavailable implicit 'this'}} -__attribute__((callback(1, this))) void no_this_1b(void *(*callback)(void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}} -__attribute__((callback(1, this))) void no_this_2b(void *(*callback)(int, void *)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}} +__attribute__((callback(0, this))) void oob_args_0b(void (*callback)(void)); // expected-error {{'callback' argument at position 2 references unavailable implicit 'this'}} +__attribute__((callback(0, 1, this))) void no_this_1b(void *(*callback)(void *)); // expected-error {{'callback' argument at position 3 references unavailable implicit 'this'}} +__attribute__((callback(0, 1, this))) void no_this_2b(void *(*callback)(int, void *)); // expected-error {{'callback' argument at position 3 references unavailable implicit 'this'}} #endif // We could allow the following declarations if we at some point need to: -__attribute__((callback(callback, __))) void vararg_cb_1b(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute callee may not be variadic}} -__attribute__((callback(1, a))) void vararg_cb_2b(void (*callback)(int, ...), int a); // expected-error {{'callback' attribute callee may not be variadic}} +__attribute__((callback(0, callback, __))) void vararg_cb_1b(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute callee may not be variadic}} +__attribute__((callback(0, 1, a))) void vararg_cb_2b(void (*callback)(int, ...), int a); // expected-error {{'callback' attribute callee may not be variadic}} -__attribute__((callback(callback, __, callback, a, b, c, __))) void varargs_1b(void (*callback)(int, ...), int a, float b, double c) {} // expected-error {{'callback' attribute requires exactly 6 arguments}} -__attribute__((callback(1, __, c, a, b, c, -1))) void varargs_2b(void (*callback)(void *, double, int, ...), int a, float b, double c); // expected-error {{'callback' attribute requires exactly 6 arguments}} +__attribute__((callback(0, callback, __, callback, a, b, c, __))) void varargs_1b(void (*callback)(int, ...), int a, float b, double c) {} // expected-error {{'callback' attribute requires exactly 3 arguments}} +__attribute__((callback(0, 1, __, c, a, b, c, -1))) void varargs_2b(void (*callback)(void *, double, int, ...), int a, float b, double c); // expected-error {{'callback' attribute requires exactly 5 arguments}} -__attribute__((callback(1, __, callback))) void self_arg_1b(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute requires exactly 2 arguments}} -__attribute__((callback(callback, __, callback, __, __, callback))) void self_arg_2b(void (*callback)(int, ...)); // expected-error {{'callback' attribute requires exactly 5 arguments}} +__attribute__((callback(0, 1, __, callback))) void self_arg_1b(void (*callback)(int, ...)) {} // expected-error {{'callback' attribute requires exactly 3 arguments}} +__attribute__((callback(0, callback, __, callback, __, __, callback))) void self_arg_2b(void (*callback)(int, ...)); // expected-error {{'callback' attribute requires exactly 3 arguments}} diff --git a/clang/test/Sema/attr-callback.c b/clang/test/Sema/attr-callback.c --- a/clang/test/Sema/attr-callback.c +++ b/clang/test/Sema/attr-callback.c @@ -2,13 +2,13 @@ // expected-no-diagnostics -__attribute__((callback(1))) void no_args(void (*callback)(void)); -__attribute__((callback(1, 2, 3))) void args_1(void (*callback)(int, double), int a, double b); -__attribute__((callback(2, 3, 3))) void args_2(int a, void (*callback)(double, double), double b); -__attribute__((callback(2, -1, -1))) void args_3(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, 1))) void no_args(void (*callback)(void)); +__attribute__((callback(0, 1, 2, 3))) void args_1(void (*callback)(int, double), int a, double b); +__attribute__((callback(0, 2, 3, 3))) void args_2(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, 2, -1, -1))) void args_3(int a, void (*callback)(double, double), double b); -__attribute__((callback(callback))) void no_argsb(void (*callback)(void)); -__attribute__((callback(callback, a, 3))) void args_1b(void (*callback)(int, double), int a, double b); -__attribute__((callback(callback, b, b))) void args_2b(int a, void (*callback)(double, double), double b); -__attribute__((callback(2, __, __))) void args_3b(int a, void (*callback)(double, double), double b); -__attribute__((callback(callback, -1, __))) void args_3c(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, callback))) void no_argsb(void (*callback)(void)); +__attribute__((callback(0, callback, a, 3))) void args_1b(void (*callback)(int, double), int a, double b); +__attribute__((callback(0, callback, b, b))) void args_2b(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, 2, __, __))) void args_3b(int a, void (*callback)(double, double), double b); +__attribute__((callback(0, callback, -1, __))) void args_3c(int a, void (*callback)(double, double), double b); diff --git a/clang/test/SemaCXX/attr-callback.cpp b/clang/test/SemaCXX/attr-callback.cpp --- a/clang/test/SemaCXX/attr-callback.cpp +++ b/clang/test/SemaCXX/attr-callback.cpp @@ -9,26 +9,26 @@ struct Base { void no_args_1(void (*callback)(void)); - __attribute__((callback(1))) void no_args_2(void (*callback)(void)); - __attribute__((callback(callback))) void no_args_3(void (*callback)(void)) {} + __attribute__((callback(0, 1))) void no_args_2(void (*callback)(void)); + __attribute__((callback(0, callback))) void no_args_3(void (*callback)(void)) {} - __attribute__((callback(1, 0))) virtual void + __attribute__((callback(0, 1, 0))) virtual void this_tr(void (*callback)(Base *)); - __attribute__((callback(1, this, __, this))) virtual void + __attribute__((callback(0, 1, this, __, this))) virtual void this_unknown_this(void (*callback)(Base *, Base *, Base *)); - __attribute__((callback(1))) virtual void + __attribute__((callback(0, 1))) virtual void virtual_1(void (*callback)(void)); - __attribute__((callback(callback))) virtual void + __attribute__((callback(0, callback))) virtual void virtual_2(void (*callback)(void)); - __attribute__((callback(1))) virtual void + __attribute__((callback(0, 1))) virtual void virtual_3(void (*callback)(void)); }; -__attribute__((callback(1))) void +__attribute__((callback(0, 1))) void Base::no_args_1(void (*callback)(void)) { } @@ -37,10 +37,10 @@ struct Derived_1 : public Base { - __attribute__((callback(1, 0))) virtual void + __attribute__((callback(0, 1, 0))) virtual void this_tr(void (*callback)(Base *)) override; - __attribute__((callback(1))) virtual void + __attribute__((callback(0, 1))) virtual void virtual_1(void (*callback)(void)) override {} virtual void @@ -49,7 +49,7 @@ struct Derived_2 : public Base { - __attribute__((callback(callback))) virtual void + __attribute__((callback(0, callback))) virtual void virtual_1(void (*callback)(void)) override; virtual void @@ -61,7 +61,7 @@ void Derived_2::virtual_1(void (*callback)(void)) {} -__attribute__((callback(1))) void +__attribute__((callback(0, 1))) void Derived_2::virtual_2(void (*callback)(void)) {} void Derived_2::virtual_3(void (*callback)(void)) {} diff --git a/llvm/include/llvm/IR/AbstractCallSite.h b/llvm/include/llvm/IR/AbstractCallSite.h --- a/llvm/include/llvm/IR/AbstractCallSite.h +++ b/llvm/include/llvm/IR/AbstractCallSite.h @@ -52,6 +52,10 @@ /// The encoding of a callback with regards to the underlying instruction. struct CallbackInfo { + enum ParameterEncodingModeTy : int64_t { + FLATTEN = 0, + STACK = 1 + }; /// For direct/indirect calls the parameter encoding is empty. If it is not, /// the abstract call site represents a callback. In that case, the first @@ -65,7 +69,7 @@ /// unknown values that are passed to the callee. using ParameterEncodingTy = SmallVector; ParameterEncodingTy ParameterEncoding; - + ParameterEncodingModeTy ParameterEncodingMode; }; private: diff --git a/llvm/include/llvm/IR/MDBuilder.h b/llvm/include/llvm/IR/MDBuilder.h --- a/llvm/include/llvm/IR/MDBuilder.h +++ b/llvm/include/llvm/IR/MDBuilder.h @@ -102,7 +102,8 @@ //===------------------------------------------------------------------===// /// Return metadata describing a callback (see llvm::AbstractCallSite). - MDNode *createCallbackEncoding(unsigned CalleeArgNo, ArrayRef Arguments, + MDNode *createCallbackEncoding(unsigned EncodeMode, unsigned CalleeArgNo, + ArrayRef Arguments, bool VarArgsArePassed); /// Merge the new callback encoding \p NewCB into \p ExistingCallbacks. diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -94,10 +94,10 @@ // - The first two arguments of the callback callee are unknown (-1). // - All variadic arguments to the runtime function are passed to the // callback callee. - Fn->addMetadata( - LLVMContext::MD_callback, - *MDNode::get(Ctx, {MDB.createCallbackEncoding( - 2, {-1, -1}, /* VarArgsArePassed */ true)})); + Fn->addMetadata(LLVMContext::MD_callback, + *MDNode::get(Ctx, {MDB.createCallbackEncoding( + 0, 2, {-1, -1}, + /* VarArgsArePassed */ true)})); } } @@ -596,7 +596,7 @@ F->addMetadata( llvm::LLVMContext::MD_callback, *llvm::MDNode::get( - Ctx, {MDB.createCallbackEncoding(2, {-1, -1}, + Ctx, {MDB.createCallbackEncoding(0, 2, {-1, -1}, /* VarArgsArePassed */ true)})); } } diff --git a/llvm/lib/IR/AbstractCallSite.cpp b/llvm/lib/IR/AbstractCallSite.cpp --- a/llvm/lib/IR/AbstractCallSite.cpp +++ b/llvm/lib/IR/AbstractCallSite.cpp @@ -44,7 +44,7 @@ for (const MDOperand &Op : CallbackMD->operands()) { MDNode *OpMD = cast(Op.get()); - auto *CBCalleeIdxAsCM = cast(OpMD->getOperand(0)); + auto *CBCalleeIdxAsCM = cast(OpMD->getOperand(1)); uint64_t CBCalleeIdx = cast(CBCalleeIdxAsCM->getValue())->getZExtValue(); if (CBCalleeIdx < CB.arg_size()) @@ -102,7 +102,7 @@ MDNode *CallbackEncMD = nullptr; for (const MDOperand &Op : CallbackMD->operands()) { MDNode *OpMD = cast(Op.get()); - auto *CBCalleeIdxAsCM = cast(OpMD->getOperand(0)); + auto *CBCalleeIdxAsCM = cast(OpMD->getOperand(1)); uint64_t CBCalleeIdx = cast(CBCalleeIdxAsCM->getValue())->getZExtValue(); if (CBCalleeIdx != UseIdx) @@ -119,11 +119,13 @@ NumCallbackCallSites++; - assert(CallbackEncMD->getNumOperands() >= 2 && "Incomplete !callback metadata"); + assert(CallbackEncMD->getNumOperands() >= 3 && + "Incomplete !callback metadata"); unsigned NumCallOperands = CB->getNumArgOperands(); - // Skip the var-arg flag at the end when reading the metadata. - for (unsigned u = 0, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) { + // Skip the var-arg flag at the end and mode at the beginning when reading the + // metadata. + for (unsigned u = 1, e = CallbackEncMD->getNumOperands() - 1; u < e; u++) { Metadata *OpAsM = CallbackEncMD->getOperand(u).get(); auto *OpAsCM = cast(OpAsM); assert(OpAsCM->getType()->isIntegerTy(64) && @@ -151,4 +153,16 @@ // Add all variadic arguments at the end. for (unsigned u = Callee->arg_size(); u < NumCallOperands; u++) CI.ParameterEncoding.push_back(u); + + Metadata *EncodingModeAsM = CallbackEncMD->getOperand(0).get(); + auto *EncodingModeAsCM = cast(EncodingModeAsM); + assert(EncodingModeAsCM->getType()->isIntegerTy(64) && + "Malformed !callback metadata parameter encoding mode"); + int64_t EncodingMode = + cast(EncodingModeAsCM->getValue())->getSExtValue(); + assert((EncodingMode == CallbackInfo::ParameterEncodingModeTy::FLATTEN || + EncodingMode == CallbackInfo::ParameterEncodingModeTy::STACK) && + "Unnown !callback metadata parameter encoding mode"); + CI.ParameterEncodingMode = + static_cast(EncodingMode); } diff --git a/llvm/lib/IR/MDBuilder.cpp b/llvm/lib/IR/MDBuilder.cpp --- a/llvm/lib/IR/MDBuilder.cpp +++ b/llvm/lib/IR/MDBuilder.cpp @@ -104,12 +104,14 @@ return MDNode::get(Context, Ops); } -MDNode *MDBuilder::createCallbackEncoding(unsigned CalleeArgNo, +MDNode *MDBuilder::createCallbackEncoding(unsigned EncodeMode, + unsigned CalleeArgNo, ArrayRef Arguments, bool VarArgArePassed) { SmallVector Ops; Type *Int64 = Type::getInt64Ty(Context); + Ops.push_back(createConstant(ConstantInt::get(Int64, EncodeMode))); Ops.push_back(createConstant(ConstantInt::get(Int64, CalleeArgNo))); for (int ArgNo : Arguments) diff --git a/llvm/test/Analysis/CallGraph/callback-calls.ll b/llvm/test/Analysis/CallGraph/callback-calls.ll --- a/llvm/test/Analysis/CallGraph/callback-calls.ll +++ b/llvm/test/Analysis/CallGraph/callback-calls.ll @@ -17,4 +17,4 @@ declare !callback !0 void @broker(void (i32*)*, i32*) !0 = !{!1} -!1 = !{i64 0, i64 1, i1 false} +!1 = !{i64 0, i64 0, i64 1, i1 false} diff --git a/llvm/test/Analysis/CallGraph/ignore-callback-uses.ll b/llvm/test/Analysis/CallGraph/ignore-callback-uses.ll --- a/llvm/test/Analysis/CallGraph/ignore-callback-uses.ll +++ b/llvm/test/Analysis/CallGraph/ignore-callback-uses.ll @@ -48,4 +48,4 @@ declare !callback !2 void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) #2 !2 = !{!3} -!3 = !{i64 2, i64 -1, i64 -1, i1 true} +!3 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll @@ -146,7 +146,7 @@ declare !callback !3 void @broker(i32 (i32)*, i32 (i32)*, i32 (i32)*, i32, i32) -!0 = !{i64 0, i64 3, i1 false} -!1 = !{i64 1, i64 4, i1 false} -!2 = !{i64 2, i64 3, i1 false} +!0 = !{i64 0, i64 0, i64 3, i1 false} +!1 = !{i64 0, i64 1, i64 4, i1 false} +!2 = !{i64 0, i64 2, i64 3, i1 false} !3 = !{!0, !2, !1} diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll @@ -285,5 +285,5 @@ declare !callback !0 dso_local void @__kmpc_fork_call(%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) -!1 = !{i64 2, i64 -1, i64 -1, i1 true} +!1 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} !0 = !{!1} diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll @@ -134,5 +134,5 @@ ret i8* %arg } -!1 = !{i64 2, i64 3, i1 false} +!1 = !{i64 0, i64 2, i64 3, i1 false} !0 = !{!1} diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll --- a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll +++ b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll @@ -67,5 +67,5 @@ declare !callback !0 dso_local void @broker(i32*, i32 (i32*, i32*)*, i32*) -!1 = !{i64 1, i64 0, i64 2, i1 false} +!1 = !{i64 0, i64 1, i64 0, i64 2, i1 false} !0 = !{!1} diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll --- a/llvm/test/Transforms/Attributor/callbacks.ll +++ b/llvm/test/Transforms/Attributor/callbacks.ll @@ -417,4 +417,4 @@ declare !callback !0 void @t3_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...) !0 = !{!1} -!1 = !{i64 2, i64 -1, i64 -1, i1 true} +!1 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} diff --git a/llvm/test/Transforms/Attributor/noundef.ll b/llvm/test/Transforms/Attributor/noundef.ll --- a/llvm/test/Transforms/Attributor/noundef.ll +++ b/llvm/test/Transforms/Attributor/noundef.ll @@ -122,5 +122,5 @@ } declare !callback !0 void @callback_broker(void (i8*)*, i8*) -!1 = !{i64 0, i64 1, i1 false} +!1 = !{i64 0, i64 0, i64 1, i1 false} !0 = !{!1} diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion.ll b/llvm/test/Transforms/OpenMP/parallel_deletion.ll --- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll +++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll @@ -442,7 +442,7 @@ !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang"} !2 = !{!3} -!3 = !{i64 2, i64 -1, i64 -1, i1 true} +!3 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} !4 = !{!5, !5, i64 0} !5 = !{!"int", !6, i64 0} !6 = !{!"omnipotent char", !7, i64 0} diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion_cg_update.ll b/llvm/test/Transforms/OpenMP/parallel_deletion_cg_update.ll --- a/llvm/test/Transforms/OpenMP/parallel_deletion_cg_update.ll +++ b/llvm/test/Transforms/OpenMP/parallel_deletion_cg_update.ll @@ -9,7 +9,7 @@ ; CHECK: CS calls function 'd' ; ; CHECK: Call graph node for function: '.omp_outlined..0'<<{{.*}}>> #uses=1 -; +; ; CHECK: Call graph node for function: '.omp_outlined..1'<<{{.*}}>> #uses=3 ; CHECK: CS<{{.*}}> calls function 'd' ; @@ -89,4 +89,4 @@ !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang version 11.0.0"} !2 = !{!3} -!3 = !{i64 2, i64 -1, i64 -1, i1 true} +!3 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} diff --git a/llvm/test/Transforms/OpenMP/parallel_deletion_remarks.ll b/llvm/test/Transforms/OpenMP/parallel_deletion_remarks.ll --- a/llvm/test/Transforms/OpenMP/parallel_deletion_remarks.ll +++ b/llvm/test/Transforms/OpenMP/parallel_deletion_remarks.ll @@ -96,7 +96,7 @@ !21 = !DILocation(line: 14, column: 1, scope: !15) !22 = !DILocation(line: 16, column: 1, scope: !15) !23 = !{!24} -!24 = !{i64 2, i64 -1, i64 -1, i1 true} +!24 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} !25 = distinct !DISubprogram(name: ".omp_outlined.", scope: !1, file: !1, line: 9, type: !26, scopeLine: 9, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !33) !26 = !DISubroutineType(types: !27) !27 = !{null, !28, !28} diff --git a/llvm/test/Transforms/OpenMP/parallel_region_merging.ll b/llvm/test/Transforms/OpenMP/parallel_region_merging.ll --- a/llvm/test/Transforms/OpenMP/parallel_region_merging.ll +++ b/llvm/test/Transforms/OpenMP/parallel_region_merging.ll @@ -786,7 +786,7 @@ !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!2} -!2 = !{i64 2, i64 -1, i64 -1, i1 true} +!2 = !{i64 0, i64 2, i64 -1, i64 -1, i1 true} ; CHECK-LABEL: define {{[^@]+}}@merge ; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr { ; CHECK-NEXT: entry: diff --git a/llvm/unittests/IR/AbstractCallSiteTest.cpp b/llvm/unittests/IR/AbstractCallSiteTest.cpp --- a/llvm/unittests/IR/AbstractCallSiteTest.cpp +++ b/llvm/unittests/IR/AbstractCallSiteTest.cpp @@ -36,7 +36,7 @@ "}\n" "declare !callback !0 void @broker(i32, void (i8*, ...)*, ...)\n" "!0 = !{!1}\n" - "!1 = !{i64 1, i64 -1, i1 true}"; + "!1 = !{i64 0, i64 1, i64 -1, i1 true}"; std::unique_ptr M = parseIR(C, IR); ASSERT_TRUE(M); diff --git a/llvm/unittests/IR/LegacyPassManagerTest.cpp b/llvm/unittests/IR/LegacyPassManagerTest.cpp --- a/llvm/unittests/IR/LegacyPassManagerTest.cpp +++ b/llvm/unittests/IR/LegacyPassManagerTest.cpp @@ -768,7 +768,7 @@ "}\n" "\n" "!0 = !{!1}\n" - "!1 = !{i64 0, i64 1, i1 false}"; + "!1 = !{i64 0, i64 0, i64 1, i1 false}"; SMDiagnostic Err; std::unique_ptr M = parseAssemblyString(IR, Err, Context);