322 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT3; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC4 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"6 7; Test 08;9; Make sure we propagate information from the caller to the callback callee but10; only for arguments that are mapped through the callback metadata. Here, the11; first two arguments of the call and the callback callee do not correspond to12; each other but argument 3-5 of the transitive call site in the caller match13; arguments 2-4 of the callback callee. Here we should see information and value14; transfer in both directions.15 16define void @t0_caller(ptr %a) {17; TUNIT-LABEL: define {{[^@]+}}@t0_caller18; TUNIT-SAME: (ptr align 256 [[A:%.*]]) {19; TUNIT-NEXT: entry:20; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 3221; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 6422; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 12823; TUNIT-NEXT: store i32 42, ptr [[B]], align 3224; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 6425; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr noundef null, ptr noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr noundef nonnull @t0_callback_callee, ptr align 256 [[A]], i64 undef, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])26; TUNIT-NEXT: ret void27;28; CGSCC-LABEL: define {{[^@]+}}@t0_caller29; CGSCC-SAME: (ptr align 256 [[A:%.*]]) {30; CGSCC-NEXT: entry:31; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 3232; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 6433; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 12834; CGSCC-NEXT: store i32 42, ptr [[B]], align 3235; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 6436; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr noundef null, ptr noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr noundef nonnull @t0_callback_callee, ptr align 256 [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])37; CGSCC-NEXT: ret void38;39entry:40 %b = alloca i32, align 3241 %c = alloca ptr, align 6442 %ptr = alloca i32, align 12843 store i32 42, ptr %b, align 444 store ptr %b, ptr %c, align 845 call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr null, ptr %ptr, ptr @t0_callback_callee, ptr %a, i64 99, ptr %c)46 ret void47}48 49; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!50; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.51define internal void @t0_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {52;53; TUNIT-LABEL: define {{[^@]+}}@t0_callback_callee54; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {55; TUNIT-NEXT: entry:56; TUNIT-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 857; TUNIT-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 458; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 6459; TUNIT-NEXT: tail call void @t0_check(ptr align 256 [[A]], i64 noundef 99, ptr align 32 [[TMP0]])60; TUNIT-NEXT: ret void61;62; CGSCC-LABEL: define {{[^@]+}}@t0_callback_callee63; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {64; CGSCC-NEXT: entry:65; CGSCC-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 866; CGSCC-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 467; CGSCC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 6468; CGSCC-NEXT: tail call void @t0_check(ptr align 256 [[A]], i64 noundef 99, ptr [[TMP0]])69; CGSCC-NEXT: ret void70;71entry:72 %ptr_val = load i32, ptr %ptr, align 873 store i32 %ptr_val, ptr %is_not_null74 %0 = load ptr, ptr %c, align 875 tail call void @t0_check(ptr %a, i64 %b, ptr %0)76 ret void77}78 79declare void @t0_check(ptr align 256, i64, ptr)80 81declare !callback !0 void @t0_callback_broker(ptr, ptr, ptr, ...)82 83; Test 184;85; Similar to test 0 but with some additional annotations (noalias/nocapute) to make sure86; we deduce and propagate noalias and others properly.87 88define void @t1_caller(ptr noalias %a) {89;90; TUNIT-LABEL: define {{[^@]+}}@t1_caller91; TUNIT-SAME: (ptr noalias align 256 captures(none) [[A:%.*]]) {92; TUNIT-NEXT: entry:93; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 3294; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 6495; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 12896; TUNIT-NEXT: store i32 42, ptr [[B]], align 3297; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 6498; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t1_callback_callee, ptr align 256 captures(none) [[A]], i64 undef, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])99; TUNIT-NEXT: ret void100;101; CGSCC-LABEL: define {{[^@]+}}@t1_caller102; CGSCC-SAME: (ptr noalias align 256 captures(none) [[A:%.*]]) {103; CGSCC-NEXT: entry:104; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 32105; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 64106; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 128107; CGSCC-NEXT: store i32 42, ptr [[B]], align 32108; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 64109; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t1_callback_callee, ptr align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])110; CGSCC-NEXT: ret void111;112entry:113 %b = alloca i32, align 32114 %c = alloca ptr, align 64115 %ptr = alloca i32, align 128116 store i32 42, ptr %b, align 4117 store ptr %b, ptr %c, align 8118 call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr null, ptr %ptr, ptr @t1_callback_callee, ptr %a, i64 99, ptr %c)119 ret void120}121 122; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!123; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.124define internal void @t1_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {125;126; TUNIT: Function Attrs: nosync127; TUNIT-LABEL: define {{[^@]+}}@t1_callback_callee128; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {129; TUNIT-NEXT: entry:130; TUNIT-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8131; TUNIT-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4132; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 64133; TUNIT-NEXT: tail call void @t1_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr align 32 captures(none) [[TMP0]])134; TUNIT-NEXT: ret void135;136; CGSCC: Function Attrs: nosync137; CGSCC-LABEL: define {{[^@]+}}@t1_callback_callee138; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {139; CGSCC-NEXT: entry:140; CGSCC-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8141; CGSCC-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4142; CGSCC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 64143; CGSCC-NEXT: tail call void @t1_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr captures(none) [[TMP0]])144; CGSCC-NEXT: ret void145;146entry:147 %ptr_val = load i32, ptr %ptr, align 8148 store i32 %ptr_val, ptr %is_not_null149 %0 = load ptr, ptr %c, align 8150 tail call void @t1_check(ptr %a, i64 %b, ptr %0)151 ret void152}153 154declare void @t1_check(ptr nocapture align 256, i64, ptr nocapture) nosync155 156declare !callback !0 void @t1_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)157 158; Test 2159;160; Similar to test 1 but checking that the noalias is only placed if potential synchronization through @t2_check is preserved.161 162define void @t2_caller(ptr noalias %a) {163; TUNIT-LABEL: define {{[^@]+}}@t2_caller164; TUNIT-SAME: (ptr noalias align 256 captures(none) [[A:%.*]]) {165; TUNIT-NEXT: entry:166; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 32167; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 64168; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 128169; TUNIT-NEXT: store i32 42, ptr [[B]], align 32170; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 64171; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t2_callback_callee, ptr align 256 captures(none) [[A]], i64 undef, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])172; TUNIT-NEXT: ret void173;174; CGSCC-LABEL: define {{[^@]+}}@t2_caller175; CGSCC-SAME: (ptr noalias align 256 captures(none) [[A:%.*]]) {176; CGSCC-NEXT: entry:177; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 32178; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 64179; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 128180; CGSCC-NEXT: store i32 42, ptr [[B]], align 32181; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 64182; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t2_callback_callee, ptr align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])183; CGSCC-NEXT: ret void184;185entry:186 %b = alloca i32, align 32187 %c = alloca ptr, align 64188 %ptr = alloca i32, align 128189 store i32 42, ptr %b, align 4190 store ptr %b, ptr %c, align 8191 call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr null, ptr %ptr, ptr @t2_callback_callee, ptr %a, i64 99, ptr %c)192 ret void193}194 195; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!196; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.197;198; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.199define internal void @t2_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {200;201; TUNIT-LABEL: define {{[^@]+}}@t2_callback_callee202; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {203; TUNIT-NEXT: entry:204; TUNIT-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8205; TUNIT-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4206; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 64207; TUNIT-NEXT: tail call void @t2_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr align 32 captures(none) [[TMP0]])208; TUNIT-NEXT: ret void209;210; CGSCC-LABEL: define {{[^@]+}}@t2_callback_callee211; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {212; CGSCC-NEXT: entry:213; CGSCC-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8214; CGSCC-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4215; CGSCC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 64216; CGSCC-NEXT: tail call void @t2_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr captures(none) [[TMP0]])217; CGSCC-NEXT: ret void218;219entry:220 %ptr_val = load i32, ptr %ptr, align 8221 store i32 %ptr_val, ptr %is_not_null222 %0 = load ptr, ptr %c, align 8223 tail call void @t2_check(ptr %a, i64 %b, ptr %0)224 ret void225}226 227declare void @t2_check(ptr nocapture align 256, i64, ptr nocapture)228 229declare !callback !0 void @t2_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)230 231; Test 3232;233; Basically test 2 with the casted callback callee used twice.234 235define void @t3_caller(ptr noalias %a) {236; TUNIT-LABEL: define {{[^@]+}}@t3_caller237; TUNIT-SAME: (ptr noalias align 256 captures(none) [[A:%.*]]) {238; TUNIT-NEXT: entry:239; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 32240; TUNIT-NEXT: [[C:%.*]] = alloca ptr, align 64241; TUNIT-NEXT: [[PTR:%.*]] = alloca i32, align 128242; TUNIT-NEXT: store i32 42, ptr [[B]], align 32243; TUNIT-NEXT: store ptr [[B]], ptr [[C]], align 64244; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t3_callback_callee, ptr align 256 captures(none) [[A]], i64 undef, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])245; TUNIT-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t3_callback_callee, ptr align 256 captures(none) [[A]], i64 undef, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])246; TUNIT-NEXT: ret void247;248; CGSCC-LABEL: define {{[^@]+}}@t3_caller249; CGSCC-SAME: (ptr noalias align 256 captures(none) [[A:%.*]]) {250; CGSCC-NEXT: entry:251; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 32252; CGSCC-NEXT: [[C:%.*]] = alloca ptr, align 64253; CGSCC-NEXT: [[PTR:%.*]] = alloca i32, align 128254; CGSCC-NEXT: store i32 42, ptr [[B]], align 32255; CGSCC-NEXT: store ptr [[B]], ptr [[C]], align 64256; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t3_callback_callee, ptr align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])257; CGSCC-NEXT: call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef null, ptr noalias noundef nonnull align 128 captures(none) dereferenceable(4) [[PTR]], ptr noundef nonnull captures(none) @t3_callback_callee, ptr align 256 captures(none) [[A]], i64 noundef 99, ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C]])258; CGSCC-NEXT: ret void259;260entry:261 %b = alloca i32, align 32262 %c = alloca ptr, align 64263 %ptr = alloca i32, align 128264 store i32 42, ptr %b, align 4265 store ptr %b, ptr %c, align 8266 call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr null, ptr %ptr, ptr @t3_callback_callee, ptr %a, i64 99, ptr %c)267 call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr null, ptr %ptr, ptr @t3_callback_callee, ptr %a, i64 99, ptr %c)268 ret void269}270 271; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!272; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.273;274; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.275define internal void @t3_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {276;277; TUNIT-LABEL: define {{[^@]+}}@t3_callback_callee278; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {279; TUNIT-NEXT: entry:280; TUNIT-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8281; TUNIT-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4282; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 64283; TUNIT-NEXT: tail call void @t3_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr align 32 captures(none) [[TMP0]])284; TUNIT-NEXT: ret void285;286; CGSCC-LABEL: define {{[^@]+}}@t3_callback_callee287; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nofree noundef nonnull readonly align 8 captures(none) dereferenceable(4) [[PTR:%.*]], ptr align 256 captures(none) [[A:%.*]], i64 [[B:%.*]], ptr noalias nofree noundef nonnull readonly align 64 captures(none) dereferenceable(8) [[C:%.*]]) {288; CGSCC-NEXT: entry:289; CGSCC-NEXT: [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8290; CGSCC-NEXT: store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4291; CGSCC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[C]], align 64292; CGSCC-NEXT: tail call void @t3_check(ptr align 256 captures(none) [[A]], i64 noundef 99, ptr captures(none) [[TMP0]])293; CGSCC-NEXT: ret void294;295entry:296 %ptr_val = load i32, ptr %ptr, align 8297 store i32 %ptr_val, ptr %is_not_null298 %0 = load ptr, ptr %c, align 8299 tail call void @t3_check(ptr %a, i64 %b, ptr %0)300 ret void301}302 303declare void @t3_check(ptr nocapture align 256, i64, ptr nocapture)304 305declare !callback !0 void @t3_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)306 307!0 = !{!1}308!1 = !{i64 2, i64 -1, i64 -1, i1 true}309;.310; TUNIT: attributes #[[ATTR0]] = { nosync }311;.312; CGSCC: attributes #[[ATTR0]] = { nosync }313;.314; TUNIT: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}315; TUNIT: [[META1]] = !{i64 2, i64 -1, i64 -1, i1 true}316;.317; CGSCC: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]}318; CGSCC: [[META1]] = !{i64 2, i64 -1, i64 -1, i1 true}319;.320;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:321; CHECK: {{.*}}322