1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM 4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM 5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM 6 7 8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 9 10declare nonnull i8* @ret_nonnull() 11declare void @llvm.assume(i1) 12 13; Return a pointer trivially nonnull (call return attribute) 14define i8* @test1() { 15; CHECK-LABEL: define {{[^@]+}}@test1() { 16; CHECK-NEXT: [[RET:%.*]] = call nonnull i8* @ret_nonnull() 17; CHECK-NEXT: ret i8* [[RET]] 18; 19 %ret = call i8* @ret_nonnull() 20 ret i8* %ret 21} 22 23; Return a pointer trivially nonnull (argument attribute) 24define i8* @test2(i8* nonnull %p) { 25; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 26; IS__TUNIT____-LABEL: define {{[^@]+}}@test2 27; IS__TUNIT____-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1:[0-9]+]] { 28; IS__TUNIT____-NEXT: ret i8* [[P]] 29; 30; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 31; IS__CGSCC____-LABEL: define {{[^@]+}}@test2 32; IS__CGSCC____-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1:[0-9]+]] { 33; IS__CGSCC____-NEXT: ret i8* [[P]] 34; 35 ret i8* %p 36} 37 38define i8* @test2A(i1 %c, i8* %ret) { 39; ATTRIBUTOR: define nonnull i8* @test2A(i1 %c, i8* nofree nonnull readnone returned %ret) 40; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 41; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2A 42; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] { 43; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] 44; NOT_CGSCC_OPM: A: 45; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] 46; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]] 47; NOT_CGSCC_OPM: B: 48; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nonnull"(i8* [[RET]]) ] 49; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]] 50; 51; IS__CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 52; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2A 53; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] { 54; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] 55; IS__CGSCC_OPM: A: 56; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13:[0-9]+]] [ "nonnull"(i8* [[RET]]) ] 57; IS__CGSCC_OPM-NEXT: ret i8* [[RET]] 58; IS__CGSCC_OPM: B: 59; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[RET]]) ] 60; IS__CGSCC_OPM-NEXT: ret i8* [[RET]] 61; 62 br i1 %c, label %A, label %B 63A: 64 call void @llvm.assume(i1 true) [ "nonnull"(i8* %ret) ] 65 ret i8* %ret 66B: 67 call void @llvm.assume(i1 true) [ "nonnull"(i8* %ret) ] 68 ret i8* %ret 69} 70 71define i8* @test2B(i1 %c, i8* %ret) { 72; ATTRIBUTOR: define nonnull dereferenceable(4) i8* @test2B(i1 %c, i8* nofree nonnull readnone returned dereferenceable(4) %ret) 73; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 74; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2B 75; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] { 76; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] 77; NOT_CGSCC_OPM: A: 78; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ] 79; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]] 80; NOT_CGSCC_OPM: B: 81; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "dereferenceable"(i8* [[RET]], i32 4) ] 82; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]] 83; 84; IS__CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 85; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2B 86; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] { 87; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]] 88; IS__CGSCC_OPM: A: 89; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] 90; IS__CGSCC_OPM-NEXT: ret i8* [[RET]] 91; IS__CGSCC_OPM: B: 92; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "dereferenceable"(i8* [[RET]], i32 4) ] 93; IS__CGSCC_OPM-NEXT: ret i8* [[RET]] 94; 95 br i1 %c, label %A, label %B 96A: 97 call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %ret, i32 4) ] 98 ret i8* %ret 99B: 100 call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %ret, i32 4) ] 101 ret i8* %ret 102} 103 104; Given an SCC where one of the functions can not be marked nonnull, 105; can we still mark the other one which is trivially nonnull 106define i8* @scc_binder(i1 %c) { 107; IS________OPM-LABEL: define {{[^@]+}}@scc_binder 108; IS________OPM-SAME: (i1 [[C:%.*]]) { 109; IS________OPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 110; IS________OPM: rec: 111; IS________OPM-NEXT: [[TMP1:%.*]] = call i8* @test3(i1 [[C]]) 112; IS________OPM-NEXT: br label [[END]] 113; IS________OPM: end: 114; IS________OPM-NEXT: ret i8* null 115; 116; IS________NPM-LABEL: define {{[^@]+}}@scc_binder 117; IS________NPM-SAME: (i1 [[C:%.*]]) { 118; IS________NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 119; IS________NPM: rec: 120; IS________NPM-NEXT: [[TMP1:%.*]] = call i8* @test3(i1 noundef [[C]]) 121; IS________NPM-NEXT: br label [[END]] 122; IS________NPM: end: 123; IS________NPM-NEXT: ret i8* null 124; 125 br i1 %c, label %rec, label %end 126rec: 127 call i8* @test3(i1 %c) 128 br label %end 129end: 130 ret i8* null 131} 132 133define i8* @test3(i1 %c) { 134; CHECK-LABEL: define {{[^@]+}}@test3 135; CHECK-SAME: (i1 [[C:%.*]]) { 136; CHECK-NEXT: [[TMP1:%.*]] = call i8* @scc_binder(i1 [[C]]) 137; CHECK-NEXT: [[RET:%.*]] = call nonnull i8* @ret_nonnull() 138; CHECK-NEXT: ret i8* [[RET]] 139; 140 call i8* @scc_binder(i1 %c) 141 %ret = call i8* @ret_nonnull() 142 ret i8* %ret 143} 144 145; Given a mutual recursive set of functions, we can mark them 146; nonnull if neither can ever return null. (In this case, they 147; just never return period.) 148define i8* @test4_helper() { 149; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone 150; CHECK-LABEL: define {{[^@]+}}@test4_helper 151; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 152; CHECK-NEXT: [[RET:%.*]] = call i8* @test4() #[[ATTR2]] 153; CHECK-NEXT: unreachable 154; 155 %ret = call i8* @test4() 156 ret i8* %ret 157} 158 159define i8* @test4() { 160; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone 161; CHECK-LABEL: define {{[^@]+}}@test4 162; CHECK-SAME: () #[[ATTR2]] { 163; CHECK-NEXT: [[RET:%.*]] = call i8* @test4_helper() #[[ATTR2]] 164; CHECK-NEXT: unreachable 165; 166 %ret = call i8* @test4_helper() 167 ret i8* %ret 168} 169 170; Given a mutual recursive set of functions which *can* return null 171; make sure we haven't marked them as nonnull. 172define i8* @test5_helper(i1 %c) { 173; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 174; IS__TUNIT____-LABEL: define {{[^@]+}}@test5_helper 175; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 176; IS__TUNIT____-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 177; IS__TUNIT____: rec: 178; IS__TUNIT____-NEXT: br label [[END]] 179; IS__TUNIT____: end: 180; IS__TUNIT____-NEXT: ret i8* null 181; 182; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 183; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5_helper 184; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3:[0-9]+]] { 185; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 186; IS__CGSCC_OPM: rec: 187; IS__CGSCC_OPM-NEXT: br label [[END]] 188; IS__CGSCC_OPM: end: 189; IS__CGSCC_OPM-NEXT: ret i8* null 190; 191; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 192; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5_helper 193; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 194; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]] 195; IS__CGSCC_NPM: rec: 196; IS__CGSCC_NPM-NEXT: br label [[END]] 197; IS__CGSCC_NPM: end: 198; IS__CGSCC_NPM-NEXT: ret i8* null 199; 200 br i1 %c, label %rec, label %end 201rec: 202 %ret = call i8* @test5(i1 %c) 203 br label %end 204end: 205 ret i8* null 206} 207 208define i8* @test5(i1 %c) { 209; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 210; IS__TUNIT____-LABEL: define {{[^@]+}}@test5 211; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 212; IS__TUNIT____-NEXT: ret i8* null 213; 214; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn 215; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5 216; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 217; IS__CGSCC_OPM-NEXT: ret i8* null 218; 219; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 220; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5 221; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 222; IS__CGSCC_NPM-NEXT: ret i8* null 223; 224 %ret = call i8* @test5_helper(i1 %c) 225 ret i8* %ret 226} 227 228; Local analysis, but going through a self recursive phi 229define i8* @test6a() { 230; NOT_CGSCC_OPM: Function Attrs: noreturn 231; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6a 232; NOT_CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] { 233; NOT_CGSCC_OPM-NEXT: entry: 234; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = call i8* @ret_nonnull() 235; NOT_CGSCC_OPM-NEXT: br label [[LOOP:%.*]] 236; NOT_CGSCC_OPM: loop: 237; NOT_CGSCC_OPM-NEXT: unreachable 238; NOT_CGSCC_OPM: exit: 239; NOT_CGSCC_OPM-NEXT: unreachable 240; 241; IS__CGSCC_OPM: Function Attrs: noreturn 242; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6a 243; IS__CGSCC_OPM-SAME: () #[[ATTR4:[0-9]+]] { 244; IS__CGSCC_OPM-NEXT: entry: 245; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i8* @ret_nonnull() 246; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]] 247; IS__CGSCC_OPM: loop: 248; IS__CGSCC_OPM-NEXT: unreachable 249; IS__CGSCC_OPM: exit: 250; IS__CGSCC_OPM-NEXT: unreachable 251; 252entry: 253 %ret = call i8* @ret_nonnull() 254 br label %loop 255loop: 256 %phi = phi i8* [%ret, %entry], [%phi, %loop] 257 br i1 undef, label %loop, label %exit 258exit: 259 ret i8* %phi 260} 261 262define i8* @test6b(i1 %c) { 263; CHECK-LABEL: define {{[^@]+}}@test6b 264; CHECK-SAME: (i1 [[C:%.*]]) { 265; CHECK-NEXT: entry: 266; CHECK-NEXT: [[RET:%.*]] = call nonnull i8* @ret_nonnull() 267; CHECK-NEXT: br label [[LOOP:%.*]] 268; CHECK: loop: 269; CHECK-NEXT: [[PHI:%.*]] = phi i8* [ [[RET]], [[ENTRY:%.*]] ], [ [[PHI]], [[LOOP]] ] 270; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]] 271; CHECK: exit: 272; CHECK-NEXT: ret i8* [[PHI]] 273; 274entry: 275 %ret = call i8* @ret_nonnull() 276 br label %loop 277loop: 278 %phi = phi i8* [%ret, %entry], [%phi, %loop] 279 br i1 %c, label %loop, label %exit 280exit: 281 ret i8* %phi 282} 283 284define i8* @test7(i8* %a) { 285; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 286; IS__TUNIT____-LABEL: define {{[^@]+}}@test7 287; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { 288; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0 289; IS__TUNIT____-NEXT: ret i8* [[B]] 290; 291; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 292; IS__CGSCC____-LABEL: define {{[^@]+}}@test7 293; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { 294; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0 295; IS__CGSCC____-NEXT: ret i8* [[B]] 296; 297 %b = getelementptr inbounds i8, i8* %a, i64 0 298 ret i8* %b 299} 300 301define i8* @test8(i8* %a) { 302; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 303; IS__TUNIT____-LABEL: define {{[^@]+}}@test8 304; IS__TUNIT____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { 305; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1 306; IS__TUNIT____-NEXT: ret i8* [[B]] 307; 308; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 309; IS__CGSCC____-LABEL: define {{[^@]+}}@test8 310; IS__CGSCC____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { 311; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1 312; IS__CGSCC____-NEXT: ret i8* [[B]] 313; 314 %b = getelementptr inbounds i8, i8* %a, i64 1 315 ret i8* %b 316} 317 318define i8* @test9(i8* %a, i64 %n) { 319; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 320; IS__TUNIT____-LABEL: define {{[^@]+}}@test9 321; IS__TUNIT____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR1]] { 322; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] 323; IS__TUNIT____-NEXT: ret i8* [[B]] 324; 325; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 326; IS__CGSCC____-LABEL: define {{[^@]+}}@test9 327; IS__CGSCC____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR1]] { 328; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] 329; IS__CGSCC____-NEXT: ret i8* [[B]] 330; 331 %b = getelementptr inbounds i8, i8* %a, i64 %n 332 ret i8* %b 333} 334 335; ATTRIBUTOR_OPM: define i8* @test10 336; ATTRIBUTOR_NPM: define nonnull i8* @test10 337define i8* @test10(i8* %a, i64 %n) { 338; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 339; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10 340; NOT_CGSCC_OPM-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { 341; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] 342; NOT_CGSCC_OPM-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] 343; NOT_CGSCC_OPM-NEXT: ret i8* [[B]] 344; 345; IS__CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn 346; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10 347; IS__CGSCC_OPM-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { 348; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] 349; IS__CGSCC_OPM-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]] 350; IS__CGSCC_OPM-NEXT: ret i8* [[B]] 351; 352 %cmp = icmp ne i64 %n, 0 353 call void @llvm.assume(i1 %cmp) 354 %b = getelementptr inbounds i8, i8* %a, i64 %n 355 ret i8* %b 356} 357 358; TEST 11 359; char* test11(char *p) { 360; return p? p: nonnull(); 361; } 362; FIXME: missing nonnull 363define i8* @test11(i8*) local_unnamed_addr { 364; CHECK-LABEL: define {{[^@]+}}@test11 365; CHECK-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr { 366; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 367; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 368; CHECK: 3: 369; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @ret_nonnull() 370; CHECK-NEXT: br label [[TMP5]] 371; CHECK: 5: 372; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] 373; CHECK-NEXT: ret i8* [[TMP6]] 374; 375 %2 = icmp eq i8* %0, null 376 br i1 %2, label %3, label %5 377 378; <label>:3: ; preds = %1 379 %4 = tail call i8* @ret_nonnull() 380 br label %5 381 382; <label>:5: ; preds = %3, %1 383 %6 = phi i8* [ %4, %3 ], [ %0, %1 ] 384 ret i8* %6 385} 386 387; TEST 12 388; Simple CallSite Test 389declare void @test12_helper(i8*) 390define void @test12(i8* nonnull %a) { 391; CHECK-LABEL: define {{[^@]+}}@test12 392; CHECK-SAME: (i8* nonnull [[A:%.*]]) { 393; CHECK-NEXT: tail call void @test12_helper(i8* nonnull [[A]]) 394; CHECK-NEXT: ret void 395; 396 tail call void @test12_helper(i8* %a) 397 ret void 398} 399 400; TEST 13 401; Simple Argument Tests 402declare i8* @unknown() 403define void @test13_helper() { 404; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13_helper() { 405; NOT_CGSCC_OPM-NEXT: [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull() 406; NOT_CGSCC_OPM-NEXT: [[MAYBENULLPTR:%.*]] = tail call i8* @unknown() 407; NOT_CGSCC_OPM-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR4:[0-9]+]] 408; NOT_CGSCC_OPM-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR4]] 409; NOT_CGSCC_OPM-NEXT: ret void 410; 411; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_helper() { 412; IS__CGSCC_OPM-NEXT: [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull() 413; IS__CGSCC_OPM-NEXT: [[MAYBENULLPTR:%.*]] = tail call i8* @unknown() 414; IS__CGSCC_OPM-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]]) #[[ATTR5:[0-9]+]] 415; IS__CGSCC_OPM-NEXT: tail call void @test13(i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]], i8* noalias nocapture nofree readnone [[MAYBENULLPTR]], i8* noalias nocapture nofree nonnull readnone [[NONNULLPTR]]) #[[ATTR5]] 416; IS__CGSCC_OPM-NEXT: ret void 417; 418 %nonnullptr = tail call i8* @ret_nonnull() 419 %maybenullptr = tail call i8* @unknown() 420 tail call void @test13(i8* %nonnullptr, i8* %nonnullptr, i8* %maybenullptr) 421 tail call void @test13(i8* %nonnullptr, i8* %maybenullptr, i8* %nonnullptr) 422 ret void 423} 424define internal void @test13(i8* %a, i8* %b, i8* %c) { 425; NOT_CGSCC_OPM: Function Attrs: nounwind 426; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13 427; NOT_CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR4]] { 428; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR4]] 429; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR4]] 430; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR4]] 431; NOT_CGSCC_OPM-NEXT: ret void 432; 433; IS__CGSCC_OPM: Function Attrs: nounwind 434; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13 435; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR5]] { 436; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]]) #[[ATTR5]] 437; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[B]]) #[[ATTR5]] 438; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]]) #[[ATTR5]] 439; IS__CGSCC_OPM-NEXT: ret void 440; 441 call void @use_i8_ptr(i8* %a) 442 call void @use_i8_ptr(i8* %b) 443 call void @use_i8_ptr(i8* %c) 444 ret void 445} 446 447declare nonnull i8* @nonnull() 448 449; TEST 14 450; Complex propagation 451; Argument of f1, f2, f3 can be marked with nonnull. 452 453; * Argument 454; 1. In f1:bb6, %arg can be marked with nonnull because of the comparison in bb1 455; 2. Because f2 is internal function, f2(i32* %arg) -> @f2(i32* nonnull %arg) 456; 3. In f1:bb4 %tmp5 is nonnull and f3 is internal function. 457; Then, f3(i32* %arg) -> @f3(i32* nonnull %arg) 458; 4. We get nonnull in whole f1 call sites so f1(i32* %arg) -> @f1(i32* nonnull %arg) 459 460 461define internal i32* @f1(i32* %arg) { 462; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg) 463; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly 464; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f1 465; NOT_CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5:[0-9]+]] { 466; NOT_CGSCC_OPM-NEXT: bb: 467; NOT_CGSCC_OPM-NEXT: [[TMP:%.*]] = icmp eq i32* [[ARG]], null 468; NOT_CGSCC_OPM-NEXT: br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]] 469; NOT_CGSCC_OPM: bb1: 470; NOT_CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4 471; NOT_CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0 472; NOT_CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]] 473; NOT_CGSCC_OPM: bb4: 474; NOT_CGSCC_OPM-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1 475; NOT_CGSCC_OPM-NEXT: [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR13:[0-9]+]] 476; NOT_CGSCC_OPM-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1 477; NOT_CGSCC_OPM-NEXT: br label [[BB9]] 478; NOT_CGSCC_OPM: bb6: 479; NOT_CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call nonnull i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR13]] 480; NOT_CGSCC_OPM-NEXT: ret i32* [[TMP7]] 481; NOT_CGSCC_OPM: bb9: 482; NOT_CGSCC_OPM-NEXT: [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ] 483; NOT_CGSCC_OPM-NEXT: ret i32* [[TMP10]] 484; 485; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly 486; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1 487; IS__CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6:[0-9]+]] { 488; IS__CGSCC_OPM-NEXT: bb: 489; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = icmp eq i32* [[ARG]], null 490; IS__CGSCC_OPM-NEXT: br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]] 491; IS__CGSCC_OPM: bb1: 492; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4 493; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0 494; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]] 495; IS__CGSCC_OPM: bb4: 496; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]], i64 1 497; IS__CGSCC_OPM-NEXT: [[TMP5B:%.*]] = tail call i32* @f3(i32* nofree nonnull readonly [[TMP5]]) #[[ATTR14:[0-9]+]] 498; IS__CGSCC_OPM-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, i32* [[TMP5B]], i64 -1 499; IS__CGSCC_OPM-NEXT: br label [[BB9]] 500; IS__CGSCC_OPM: bb6: 501; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = tail call nonnull i32* @f2(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]] 502; IS__CGSCC_OPM-NEXT: ret i32* [[TMP7]] 503; IS__CGSCC_OPM: bb9: 504; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [ inttoptr (i64 4 to i32*), [[BB:%.*]] ] 505; IS__CGSCC_OPM-NEXT: ret i32* [[TMP10]] 506; 507 508bb: 509 %tmp = icmp eq i32* %arg, null 510 br i1 %tmp, label %bb9, label %bb1 511 512bb1: ; preds = %bb 513 %tmp2 = load i32, i32* %arg, align 4 514 %tmp3 = icmp eq i32 %tmp2, 0 515 br i1 %tmp3, label %bb6, label %bb4 516 517bb4: ; preds = %bb1 518 %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1 519 %tmp5b = tail call i32* @f3(i32* %tmp5) 520 %tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1 521 br label %bb9 522 523bb6: ; preds = %bb1 524 %tmp7 = tail call i32* @f2(i32* %arg) 525 ret i32* %tmp7 526 527bb9: ; preds = %bb4, %bb 528 %tmp10 = phi i32* [ %tmp5c, %bb4 ], [ inttoptr (i64 4 to i32*), %bb ] 529 ret i32* %tmp10 530} 531 532define internal i32* @f2(i32* %arg) { 533; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly 534; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f2 535; NOT_CGSCC_OPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR5]] { 536; NOT_CGSCC_OPM-NEXT: bb: 537; NOT_CGSCC_OPM-NEXT: [[TMP:%.*]] = tail call nonnull i32* @f1(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR13]] 538; NOT_CGSCC_OPM-NEXT: ret i32* [[TMP]] 539; 540; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly 541; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2 542; IS__CGSCC_OPM-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]]) #[[ATTR6]] { 543; IS__CGSCC_OPM-NEXT: bb: 544; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = tail call nonnull i32* @f1(i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG]]) #[[ATTR14]] 545; IS__CGSCC_OPM-NEXT: ret i32* [[TMP]] 546; 547bb: 548 %tmp = tail call i32* @f1(i32* %arg) 549 ret i32* %tmp 550} 551 552define dso_local noalias i32* @f3(i32* %arg) { 553; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg) 554; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly 555; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f3 556; NOT_CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR5]] { 557; NOT_CGSCC_OPM-NEXT: bb: 558; NOT_CGSCC_OPM-NEXT: [[TMP:%.*]] = call nonnull i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR13]] 559; NOT_CGSCC_OPM-NEXT: ret i32* [[TMP]] 560; 561; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly 562; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3 563; IS__CGSCC_OPM-SAME: (i32* nofree readonly [[ARG:%.*]]) #[[ATTR6]] { 564; IS__CGSCC_OPM-NEXT: bb: 565; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = call nonnull i32* @f1(i32* nofree readonly [[ARG]]) #[[ATTR14]] 566; IS__CGSCC_OPM-NEXT: ret i32* [[TMP]] 567; 568bb: 569; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg) 570 %tmp = call i32* @f1(i32* %arg) 571 ret i32* %tmp 572} 573 574; TEST 15 575define void @f15(i8* %arg) { 576; CHECK-LABEL: define {{[^@]+}}@f15 577; CHECK-SAME: (i8* noundef nonnull dereferenceable(4) [[ARG:%.*]]) { 578; CHECK-NEXT: tail call void @use1(i8* noundef nonnull dereferenceable(4) [[ARG]]) 579; CHECK-NEXT: ret void 580; 581 582 tail call void @use1(i8* dereferenceable(4) %arg) 583 ret void 584} 585 586declare void @fun0() #1 587declare void @fun1(i8*) #1 588declare void @fun2(i8*, i8*) #1 589declare void @fun3(i8*, i8*, i8*) #1 590; TEST 16 simple path test 591; if(..) 592; fun2(nonnull %a, nonnull %b) 593; else 594; fun2(nonnull %a, %b) 595; We can say that %a is nonnull but %b is not. 596define void @f16(i8* %a, i8 * %b, i8 %c) { 597; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 598; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f16 599; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6:[0-9]+]] { 600; NOT_CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 601; NOT_CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 602; NOT_CGSCC_OPM: if.then: 603; NOT_CGSCC_OPM-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR6]] 604; NOT_CGSCC_OPM-NEXT: ret void 605; NOT_CGSCC_OPM: if.else: 606; NOT_CGSCC_OPM-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR6]] 607; NOT_CGSCC_OPM-NEXT: ret void 608; 609; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 610; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f16 611; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7:[0-9]+]] { 612; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 613; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 614; IS__CGSCC_OPM: if.then: 615; IS__CGSCC_OPM-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* nonnull [[B]]) #[[ATTR7]] 616; IS__CGSCC_OPM-NEXT: ret void 617; IS__CGSCC_OPM: if.else: 618; IS__CGSCC_OPM-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* [[B]]) #[[ATTR7]] 619; IS__CGSCC_OPM-NEXT: ret void 620; 621 %cmp = icmp eq i8 %c, 0 622 br i1 %cmp, label %if.then, label %if.else 623if.then: 624 tail call void @fun2(i8* nonnull %a, i8* nonnull %b) 625 ret void 626if.else: 627 tail call void @fun2(i8* nonnull %a, i8* %b) 628 ret void 629} 630; TEST 17 explore child BB test 631; if(..) 632; ... (willreturn & nounwind) 633; else 634; ... (willreturn & nounwind) 635; fun1(nonnull %a) 636; We can say that %a is nonnull 637define void @f17(i8* %a, i8 %c) { 638; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 639; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f17 640; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR6]] { 641; NOT_CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 642; NOT_CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 643; NOT_CGSCC_OPM: if.then: 644; NOT_CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR6]] 645; NOT_CGSCC_OPM-NEXT: br label [[CONT:%.*]] 646; NOT_CGSCC_OPM: if.else: 647; NOT_CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR6]] 648; NOT_CGSCC_OPM-NEXT: br label [[CONT]] 649; NOT_CGSCC_OPM: cont: 650; NOT_CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]] 651; NOT_CGSCC_OPM-NEXT: ret void 652; 653; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 654; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f17 655; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR7]] { 656; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0 657; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 658; IS__CGSCC_OPM: if.then: 659; IS__CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR7]] 660; IS__CGSCC_OPM-NEXT: br label [[CONT:%.*]] 661; IS__CGSCC_OPM: if.else: 662; IS__CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR7]] 663; IS__CGSCC_OPM-NEXT: br label [[CONT]] 664; IS__CGSCC_OPM: cont: 665; IS__CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]] 666; IS__CGSCC_OPM-NEXT: ret void 667; 668 %cmp = icmp eq i8 %c, 0 669 br i1 %cmp, label %if.then, label %if.else 670if.then: 671 tail call void @fun0() 672 br label %cont 673if.else: 674 tail call void @fun0() 675 br label %cont 676cont: 677 tail call void @fun1(i8* nonnull %a) 678 ret void 679} 680; TEST 18 More complex test 681; if(..) 682; ... (willreturn & nounwind) 683; else 684; ... (willreturn & nounwind) 685; if(..) 686; ... (willreturn & nounwind) 687; else 688; ... (willreturn & nounwind) 689; fun1(nonnull %a) 690 691define void @f18(i8* %a, i8* %b, i8 %c) { 692; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 693; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f18 694; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR6]] { 695; NOT_CGSCC_OPM-NEXT: [[CMP1:%.*]] = icmp eq i8 [[C]], 0 696; NOT_CGSCC_OPM-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 697; NOT_CGSCC_OPM: if.then: 698; NOT_CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR6]] 699; NOT_CGSCC_OPM-NEXT: br label [[CONT:%.*]] 700; NOT_CGSCC_OPM: if.else: 701; NOT_CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR6]] 702; NOT_CGSCC_OPM-NEXT: br label [[CONT]] 703; NOT_CGSCC_OPM: cont: 704; NOT_CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 1 705; NOT_CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]] 706; NOT_CGSCC_OPM: cont.then: 707; NOT_CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR6]] 708; NOT_CGSCC_OPM-NEXT: br label [[CONT2:%.*]] 709; NOT_CGSCC_OPM: cont.else: 710; NOT_CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR6]] 711; NOT_CGSCC_OPM-NEXT: br label [[CONT2]] 712; NOT_CGSCC_OPM: cont2: 713; NOT_CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR6]] 714; NOT_CGSCC_OPM-NEXT: ret void 715; 716; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 717; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f18 718; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]]) #[[ATTR7]] { 719; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = icmp eq i8 [[C]], 0 720; IS__CGSCC_OPM-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 721; IS__CGSCC_OPM: if.then: 722; IS__CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR7]] 723; IS__CGSCC_OPM-NEXT: br label [[CONT:%.*]] 724; IS__CGSCC_OPM: if.else: 725; IS__CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR7]] 726; IS__CGSCC_OPM-NEXT: br label [[CONT]] 727; IS__CGSCC_OPM: cont: 728; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 1 729; IS__CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[CONT_THEN:%.*]], label [[CONT_ELSE:%.*]] 730; IS__CGSCC_OPM: cont.then: 731; IS__CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR7]] 732; IS__CGSCC_OPM-NEXT: br label [[CONT2:%.*]] 733; IS__CGSCC_OPM: cont.else: 734; IS__CGSCC_OPM-NEXT: tail call void @fun0() #[[ATTR7]] 735; IS__CGSCC_OPM-NEXT: br label [[CONT2]] 736; IS__CGSCC_OPM: cont2: 737; IS__CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR7]] 738; IS__CGSCC_OPM-NEXT: ret void 739; 740 %cmp1 = icmp eq i8 %c, 0 741 br i1 %cmp1, label %if.then, label %if.else 742if.then: 743 tail call void @fun0() 744 br label %cont 745if.else: 746 tail call void @fun0() 747 br label %cont 748cont: 749 %cmp2 = icmp eq i8 %c, 1 750 br i1 %cmp2, label %cont.then, label %cont.else 751cont.then: 752 tail call void @fun1(i8* nonnull %b) 753 br label %cont2 754cont.else: 755 tail call void @fun0() 756 br label %cont2 757cont2: 758 tail call void @fun1(i8* nonnull %a) 759 ret void 760} 761 762; TEST 19: Loop 763 764define void @f19(i8* %a, i8* %b, i8 %c) { 765; NOT_CGSCC_OPM: Function Attrs: nounwind 766; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f19 767; NOT_CGSCC_OPM-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR4]] { 768; NOT_CGSCC_OPM-NEXT: br label [[LOOP_HEADER:%.*]] 769; NOT_CGSCC_OPM: loop.header: 770; NOT_CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 0 771; NOT_CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]] 772; NOT_CGSCC_OPM: loop.body: 773; NOT_CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR4]] 774; NOT_CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR4]] 775; NOT_CGSCC_OPM-NEXT: br label [[LOOP_HEADER]] 776; NOT_CGSCC_OPM: loop.exit: 777; NOT_CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR4]] 778; NOT_CGSCC_OPM-NEXT: ret void 779; 780; IS__CGSCC_OPM: Function Attrs: nounwind 781; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f19 782; IS__CGSCC_OPM-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]]) #[[ATTR5]] { 783; IS__CGSCC_OPM-NEXT: br label [[LOOP_HEADER:%.*]] 784; IS__CGSCC_OPM: loop.header: 785; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 0 786; IS__CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label [[LOOP_EXIT:%.*]] 787; IS__CGSCC_OPM: loop.body: 788; IS__CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR5]] 789; IS__CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[A]]) #[[ATTR5]] 790; IS__CGSCC_OPM-NEXT: br label [[LOOP_HEADER]] 791; IS__CGSCC_OPM: loop.exit: 792; IS__CGSCC_OPM-NEXT: tail call void @fun1(i8* nonnull [[B]]) #[[ATTR5]] 793; IS__CGSCC_OPM-NEXT: ret void 794; 795 br label %loop.header 796loop.header: 797 %cmp2 = icmp eq i8 %c, 0 798 br i1 %cmp2, label %loop.body, label %loop.exit 799loop.body: 800 tail call void @fun1(i8* nonnull %b) 801 tail call void @fun1(i8* nonnull %a) 802 br label %loop.header 803loop.exit: 804 tail call void @fun1(i8* nonnull %b) 805 ret void 806} 807 808; Test propagation of nonnull callsite args back to caller. 809 810declare void @use1(i8* %x) 811declare void @use2(i8* %x, i8* %y); 812declare void @use3(i8* %x, i8* %y, i8* %z); 813 814declare void @use1nonnull(i8* nonnull %x); 815declare void @use2nonnull(i8* nonnull %x, i8* nonnull %y); 816declare void @use3nonnull(i8* nonnull %x, i8* nonnull %y, i8* nonnull %z); 817 818declare i8 @use1safecall(i8* %x) readonly nounwind willreturn ; nounwind+willreturn guarantees that execution continues to successor 819 820; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute. 821 822define void @parent1(i8* %a, i8* %b, i8* %c) { 823; CHECK-LABEL: define {{[^@]+}}@parent1 824; CHECK-SAME: (i8* [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]]) { 825; CHECK-NEXT: call void @use3(i8* [[C]], i8* [[A]], i8* [[B]]) 826; CHECK-NEXT: call void @use3nonnull(i8* nonnull [[B]], i8* nonnull [[C]], i8* nonnull [[A]]) 827; CHECK-NEXT: ret void 828; 829 call void @use3(i8* %c, i8* %a, i8* %b) 830 call void @use3nonnull(i8* %b, i8* %c, i8* %a) 831 ret void 832} 833 834; Extend non-null to parent for all arguments. 835 836define void @parent2(i8* %a, i8* %b, i8* %c) { 837; CHECK-LABEL: define {{[^@]+}}@parent2 838; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull [[C:%.*]]) { 839; CHECK-NEXT: call void @use3nonnull(i8* nonnull [[B]], i8* nonnull [[C]], i8* nonnull [[A]]) 840; CHECK-NEXT: call void @use3(i8* nonnull [[C]], i8* nonnull [[A]], i8* nonnull [[B]]) 841; CHECK-NEXT: ret void 842; 843 844 call void @use3nonnull(i8* %b, i8* %c, i8* %a) 845 call void @use3(i8* %c, i8* %a, i8* %b) 846 ret void 847} 848 849; Extend non-null to parent for 1st argument. 850 851define void @parent3(i8* %a, i8* %b, i8* %c) { 852; CHECK-LABEL: define {{[^@]+}}@parent3 853; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]]) { 854; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]]) 855; CHECK-NEXT: call void @use3(i8* [[C]], i8* [[B]], i8* nonnull [[A]]) 856; CHECK-NEXT: ret void 857; 858 859 860 call void @use1nonnull(i8* %a) 861 call void @use3(i8* %c, i8* %b, i8* %a) 862 ret void 863} 864 865; Extend non-null to parent for last 2 arguments. 866 867define void @parent4(i8* %a, i8* %b, i8* %c) { 868; CHECK-LABEL: define {{[^@]+}}@parent4 869; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull [[C:%.*]]) { 870; CHECK-NEXT: call void @use2nonnull(i8* nonnull [[C]], i8* nonnull [[B]]) 871; CHECK-NEXT: call void @use2(i8* [[A]], i8* nonnull [[C]]) 872; CHECK-NEXT: call void @use1(i8* nonnull [[B]]) 873; CHECK-NEXT: ret void 874; 875 876 877 878 call void @use2nonnull(i8* %c, i8* %b) 879 call void @use2(i8* %a, i8* %c) 880 call void @use1(i8* %b) 881 ret void 882} 883 884; The callsite must execute in order for the attribute to transfer to the parent. 885; It appears benign to extend non-null to the parent in this case, but we can't do that 886; because it would incorrectly propagate the wrong information to its callers. 887 888define void @parent5(i8* %a, i1 %a_is_notnull) { 889; CHECK-LABEL: define {{[^@]+}}@parent5 890; CHECK-SAME: (i8* [[A:%.*]], i1 [[A_IS_NOTNULL:%.*]]) { 891; CHECK-NEXT: br i1 [[A_IS_NOTNULL]], label [[T:%.*]], label [[F:%.*]] 892; CHECK: t: 893; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]]) 894; CHECK-NEXT: ret void 895; CHECK: f: 896; CHECK-NEXT: ret void 897; 898 899 br i1 %a_is_notnull, label %t, label %f 900t: 901 call void @use1nonnull(i8* %a) 902 ret void 903f: 904 ret void 905} 906 907; The callsite must execute in order for the attribute to transfer to the parent. 908; The volatile load can't trap, so we can guarantee that we'll get to the call. 909 910define i8 @parent6(i8* %a, i8* %b) { 911; CHECK-LABEL: define {{[^@]+}}@parent6 912; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* noundef [[B:%.*]]) { 913; CHECK-NEXT: [[C:%.*]] = load volatile i8, i8* [[B]], align 1 914; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]]) 915; CHECK-NEXT: ret i8 [[C]] 916; 917 918 %c = load volatile i8, i8* %b 919 call void @use1nonnull(i8* %a) 920 ret i8 %c 921} 922 923; The nonnull callsite is guaranteed to execute, so the argument must be nonnull throughout the parent. 924 925define i8 @parent7(i8* %a) { 926; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent7 927; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]]) { 928; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR14:[0-9]+]] 929; NOT_CGSCC_OPM-NEXT: call void @use1nonnull(i8* nonnull [[A]]) 930; NOT_CGSCC_OPM-NEXT: ret i8 [[RET]] 931; 932; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent7 933; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]]) { 934; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly [[A]]) #[[ATTR15:[0-9]+]] 935; IS__CGSCC_OPM-NEXT: call void @use1nonnull(i8* nonnull [[A]]) 936; IS__CGSCC_OPM-NEXT: ret i8 [[RET]] 937; 938 939 940 %ret = call i8 @use1safecall(i8* %a) 941 call void @use1nonnull(i8* %a) 942 ret i8 %ret 943} 944 945; Make sure that an invoke works similarly to a call. 946 947declare i32 @esfp(...) 948 949define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){ 950; NOT_CGSCC_OPM: Function Attrs: nounwind 951; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent8 952; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR4]] personality i8* bitcast (i32 (...)* @esfp to i8*) { 953; NOT_CGSCC_OPM-NEXT: entry: 954; NOT_CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]]) 955; NOT_CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]] 956; NOT_CGSCC_OPM: cont: 957; NOT_CGSCC_OPM-NEXT: ret i1 false 958; NOT_CGSCC_OPM: exc: 959; NOT_CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 } 960; NOT_CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer 961; NOT_CGSCC_OPM-NEXT: unreachable 962; 963; IS__CGSCC_OPM: Function Attrs: nounwind 964; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent8 965; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #[[ATTR5]] personality i8* bitcast (i32 (...)* @esfp to i8*) { 966; IS__CGSCC_OPM-NEXT: entry: 967; IS__CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8* nonnull [[B]]) 968; IS__CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]] 969; IS__CGSCC_OPM: cont: 970; IS__CGSCC_OPM-NEXT: ret i1 false 971; IS__CGSCC_OPM: exc: 972; IS__CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 } 973; IS__CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer 974; IS__CGSCC_OPM-NEXT: unreachable 975; 976 977entry: 978 invoke void @use2nonnull(i8* %a, i8* %b) 979 to label %cont unwind label %exc 980 981cont: 982 %null_check = icmp eq i8* %b, null 983 ret i1 %null_check 984 985exc: 986 %lp = landingpad { i8*, i32 } 987 filter [0 x i8*] zeroinitializer 988 unreachable 989} 990 991define i32* @gep1(i32* %p) { 992; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 993; IS__TUNIT____-LABEL: define {{[^@]+}}@gep1 994; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { 995; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 996; IS__TUNIT____-NEXT: ret i32* [[Q]] 997; 998; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 999; IS__CGSCC____-LABEL: define {{[^@]+}}@gep1 1000; IS__CGSCC____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { 1001; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 1002; IS__CGSCC____-NEXT: ret i32* [[Q]] 1003; 1004 %q = getelementptr inbounds i32, i32* %p, i32 1 1005 ret i32* %q 1006} 1007 1008define i32* @gep1_no_null_opt(i32* %p) #0 { 1009; Should't be able to derive nonnull based on gep. 1010; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn 1011; IS__TUNIT____-LABEL: define {{[^@]+}}@gep1_no_null_opt 1012; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR8:[0-9]+]] { 1013; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 1014; IS__TUNIT____-NEXT: ret i32* [[Q]] 1015; 1016; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn 1017; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@gep1_no_null_opt 1018; IS__CGSCC_OPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR9:[0-9]+]] { 1019; IS__CGSCC_OPM-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 1020; IS__CGSCC_OPM-NEXT: ret i32* [[Q]] 1021; 1022; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn 1023; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@gep1_no_null_opt 1024; IS__CGSCC_NPM-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR8:[0-9]+]] { 1025; IS__CGSCC_NPM-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1 1026; IS__CGSCC_NPM-NEXT: ret i32* [[Q]] 1027; 1028 %q = getelementptr inbounds i32, i32* %p, i32 1 1029 ret i32* %q 1030} 1031 1032define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) { 1033; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 1034; IS__TUNIT____-LABEL: define {{[^@]+}}@gep2 1035; IS__TUNIT____-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { 1036; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1 1037; IS__TUNIT____-NEXT: ret i32 addrspace(3)* [[Q]] 1038; 1039; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1040; IS__CGSCC____-LABEL: define {{[^@]+}}@gep2 1041; IS__CGSCC____-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { 1042; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1 1043; IS__CGSCC____-NEXT: ret i32 addrspace(3)* [[Q]] 1044; 1045 %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1 1046 ret i32 addrspace(3)* %q 1047} 1048 1049; FIXME: We should propagate dereferenceable here but *not* nonnull 1050define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) { 1051; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 1052; IS__TUNIT____-LABEL: define {{[^@]+}}@as 1053; IS__TUNIT____-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { 1054; IS__TUNIT____-NEXT: ret i32 addrspace(3)* [[P]] 1055; 1056; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1057; IS__CGSCC____-LABEL: define {{[^@]+}}@as 1058; IS__CGSCC____-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR1]] { 1059; IS__CGSCC____-NEXT: ret i32 addrspace(3)* [[P]] 1060; 1061 ret i32 addrspace(3)* %p 1062} 1063 1064; CHECK-NOT: @g2() 1065define internal i32* @g2() { 1066; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1067; IS__CGSCC____-LABEL: define {{[^@]+}}@g2 1068; IS__CGSCC____-SAME: () #[[ATTR1]] { 1069; IS__CGSCC____-NEXT: ret i32* undef 1070; 1071 ret i32* inttoptr (i64 4 to i32*) 1072} 1073 1074define i32* @g1() { 1075; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 1076; IS__TUNIT____-LABEL: define {{[^@]+}}@g1 1077; IS__TUNIT____-SAME: () #[[ATTR1]] { 1078; IS__TUNIT____-NEXT: ret i32* inttoptr (i64 4 to i32*) 1079; 1080; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1081; IS__CGSCC____-LABEL: define {{[^@]+}}@g1 1082; IS__CGSCC____-SAME: () #[[ATTR1]] { 1083; IS__CGSCC____-NEXT: ret i32* inttoptr (i64 4 to i32*) 1084; 1085 %c = call i32* @g2() 1086 ret i32* %c 1087} 1088 1089declare void @use_i32_ptr(i32* readnone nocapture) nounwind 1090define internal void @called_by_weak(i32* %a) { 1091; NOT_CGSCC_OPM: Function Attrs: nounwind 1092; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_weak 1093; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR4]] { 1094; NOT_CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]] 1095; NOT_CGSCC_OPM-NEXT: ret void 1096; 1097; IS__CGSCC_OPM: Function Attrs: nounwind 1098; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_weak 1099; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]]) #[[ATTR5]] { 1100; IS__CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR5]] 1101; IS__CGSCC_OPM-NEXT: ret void 1102; 1103 call void @use_i32_ptr(i32* %a) 1104 ret void 1105} 1106 1107; Check we do not annotate the function interface of this weak function. 1108define weak_odr void @weak_caller(i32* nonnull %a) { 1109; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@weak_caller 1110; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]]) { 1111; NOT_CGSCC_OPM-NEXT: call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]] 1112; NOT_CGSCC_OPM-NEXT: ret void 1113; 1114; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@weak_caller 1115; IS__CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]]) { 1116; IS__CGSCC_OPM-NEXT: call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR5]] 1117; IS__CGSCC_OPM-NEXT: ret void 1118; 1119 call void @called_by_weak(i32* %a) 1120 ret void 1121} 1122 1123; Expect nonnull 1124define internal void @control(i32* dereferenceable(4) %a) { 1125; NOT_CGSCC_OPM: Function Attrs: nounwind 1126; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@control 1127; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { 1128; NOT_CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR4]] 1129; NOT_CGSCC_OPM-NEXT: ret void 1130; 1131; IS__CGSCC_OPM: Function Attrs: nounwind 1132; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@control 1133; IS__CGSCC_OPM-SAME: (i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A:%.*]]) #[[ATTR5]] { 1134; IS__CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR5]] 1135; IS__CGSCC_OPM-NEXT: ret void 1136; 1137 call void @use_i32_ptr(i32* %a) 1138 ret void 1139} 1140; Avoid nonnull as we do not touch naked functions 1141define internal void @naked(i32* dereferenceable(4) %a) naked { 1142; NOT_CGSCC_OPM: Function Attrs: naked 1143; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@naked 1144; NOT_CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] { 1145; NOT_CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* [[A]]) 1146; NOT_CGSCC_OPM-NEXT: ret void 1147; 1148; IS__CGSCC_OPM: Function Attrs: naked 1149; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@naked 1150; IS__CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] { 1151; IS__CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* [[A]]) 1152; IS__CGSCC_OPM-NEXT: ret void 1153; 1154 call void @use_i32_ptr(i32* %a) 1155 ret void 1156} 1157; Avoid nonnull as we do not touch optnone 1158define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline { 1159; NOT_CGSCC_OPM: Function Attrs: noinline optnone 1160; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@optnone 1161; NOT_CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] { 1162; NOT_CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* [[A]]) 1163; NOT_CGSCC_OPM-NEXT: ret void 1164; 1165; IS__CGSCC_OPM: Function Attrs: noinline optnone 1166; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optnone 1167; IS__CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR11:[0-9]+]] { 1168; IS__CGSCC_OPM-NEXT: call void @use_i32_ptr(i32* [[A]]) 1169; IS__CGSCC_OPM-NEXT: ret void 1170; 1171 call void @use_i32_ptr(i32* %a) 1172 ret void 1173} 1174define void @make_live(i32* nonnull dereferenceable(8) %a) { 1175; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@make_live 1176; NOT_CGSCC_OPM-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) { 1177; NOT_CGSCC_OPM-NEXT: call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]]) 1178; NOT_CGSCC_OPM-NEXT: call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR4]] 1179; NOT_CGSCC_OPM-NEXT: call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]]) 1180; NOT_CGSCC_OPM-NEXT: ret void 1181; 1182; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@make_live 1183; IS__CGSCC_OPM-SAME: (i32* noundef nonnull align 16 dereferenceable(8) [[A:%.*]]) { 1184; IS__CGSCC_OPM-NEXT: call void @naked(i32* noundef nonnull align 16 dereferenceable(8) [[A]]) 1185; IS__CGSCC_OPM-NEXT: call void @control(i32* noalias nocapture noundef nonnull readnone align 16 dereferenceable(8) [[A]]) #[[ATTR5]] 1186; IS__CGSCC_OPM-NEXT: call void @optnone(i32* noundef nonnull align 16 dereferenceable(8) [[A]]) 1187; IS__CGSCC_OPM-NEXT: ret void 1188; 1189 call void @naked(i32* nonnull dereferenceable(8) align 16 %a) 1190 call void @control(i32* nonnull dereferenceable(8) align 16 %a) 1191 call void @optnone(i32* nonnull dereferenceable(8) align 16 %a) 1192 ret void 1193} 1194 1195 1196;int f(int *u, int n){ 1197; for(int i = 0;i<n;i++){ 1198; h(u); 1199; } 1200; return g(nonnull u); 1201;} 1202declare void @h(i32*) willreturn nounwind 1203declare i32 @g(i32*) willreturn nounwind 1204define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) { 1205; 1206; IS__TUNIT_OPM: Function Attrs: nounwind 1207; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1 1208; IS__TUNIT_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR4]] { 1209; IS__TUNIT_OPM-NEXT: en: 1210; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1211; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1212; IS__TUNIT_OPM: ex: 1213; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]] 1214; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]] 1215; IS__TUNIT_OPM: hd: 1216; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] 1217; IS__TUNIT_OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR4]] 1218; IS__TUNIT_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1219; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1220; IS__TUNIT_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1221; 1222; IS________NPM: Function Attrs: nounwind willreturn 1223; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1 1224; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { 1225; IS________NPM-NEXT: en: 1226; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1227; IS________NPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1228; IS________NPM: ex: 1229; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]] 1230; IS________NPM-NEXT: ret i32 [[TMP5]] 1231; IS________NPM: hd: 1232; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] 1233; IS________NPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR6]] 1234; IS________NPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1235; IS________NPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1236; IS________NPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1237; 1238; IS__CGSCC_OPM: Function Attrs: nounwind 1239; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1 1240; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR5]] { 1241; IS__CGSCC_OPM-NEXT: en: 1242; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1243; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1244; IS__CGSCC_OPM: ex: 1245; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]] 1246; IS__CGSCC_OPM-NEXT: ret i32 [[TMP5]] 1247; IS__CGSCC_OPM: hd: 1248; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] 1249; IS__CGSCC_OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR5]] 1250; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1251; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1252; IS__CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1253; 1254en: 1255 %tmp3 = icmp eq i32 %b, 0 1256 br i1 %tmp3, label %ex, label %hd 1257 1258ex: 1259 %tmp5 = tail call i32 @g(i32* nonnull %a) 1260 ret i32 %tmp5 1261 1262hd: 1263 %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ] 1264 tail call void @h(i32* %a) 1265 %tmp8 = add nuw i32 %tmp7, 1 1266 %tmp9 = icmp eq i32 %tmp8, %b 1267 br i1 %tmp9, label %ex, label %hd 1268} 1269 1270define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) { 1271; 1272; IS__TUNIT_OPM: Function Attrs: nounwind 1273; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b 1274; IS__TUNIT_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR4]] { 1275; IS__TUNIT_OPM-NEXT: en: 1276; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1277; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1278; IS__TUNIT_OPM: ex: 1279; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]] 1280; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]] 1281; IS__TUNIT_OPM: hd: 1282; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] 1283; IS__TUNIT_OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR4]] 1284; IS__TUNIT_OPM-NEXT: br label [[HD2]] 1285; IS__TUNIT_OPM: hd2: 1286; IS__TUNIT_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1287; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1288; IS__TUNIT_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1289; 1290; IS________NPM: Function Attrs: nounwind willreturn 1291; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b 1292; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { 1293; IS________NPM-NEXT: en: 1294; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1295; IS________NPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1296; IS________NPM: ex: 1297; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR6]] 1298; IS________NPM-NEXT: ret i32 [[TMP5]] 1299; IS________NPM: hd: 1300; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] 1301; IS________NPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR6]] 1302; IS________NPM-NEXT: br label [[HD2]] 1303; IS________NPM: hd2: 1304; IS________NPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1305; IS________NPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1306; IS________NPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1307; 1308; IS__CGSCC_OPM: Function Attrs: nounwind 1309; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b 1310; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]]) #[[ATTR5]] { 1311; IS__CGSCC_OPM-NEXT: en: 1312; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1313; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1314; IS__CGSCC_OPM: ex: 1315; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]] 1316; IS__CGSCC_OPM-NEXT: ret i32 [[TMP5]] 1317; IS__CGSCC_OPM: hd: 1318; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] 1319; IS__CGSCC_OPM-NEXT: tail call void @h(i32* [[A]]) #[[ATTR5]] 1320; IS__CGSCC_OPM-NEXT: br label [[HD2]] 1321; IS__CGSCC_OPM: hd2: 1322; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1323; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1324; IS__CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1325; 1326en: 1327 %tmp3 = icmp eq i32 %b, 0 1328 br i1 %tmp3, label %ex, label %hd 1329 1330ex: 1331 %tmp5 = tail call i32 @g(i32* nonnull %a) 1332 ret i32 %tmp5 1333 1334hd: 1335 %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ] 1336 tail call void @h(i32* %a) 1337 br label %hd2 1338 1339hd2: 1340 %tmp8 = add nuw i32 %tmp7, 1 1341 %tmp9 = icmp eq i32 %tmp8, %b 1342 br i1 %tmp9, label %ex, label %hd 1343} 1344 1345define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind { 1346; 1347; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 1348; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2 1349; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { 1350; NOT_CGSCC_OPM-NEXT: en: 1351; NOT_CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1352; NOT_CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1353; NOT_CGSCC_OPM: ex: 1354; NOT_CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]] 1355; NOT_CGSCC_OPM-NEXT: ret i32 [[TMP5]] 1356; NOT_CGSCC_OPM: hd: 1357; NOT_CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] 1358; NOT_CGSCC_OPM-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR4]] 1359; NOT_CGSCC_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1360; NOT_CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1361; NOT_CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1362; 1363; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 1364; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2 1365; IS__CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { 1366; IS__CGSCC_OPM-NEXT: en: 1367; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1368; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1369; IS__CGSCC_OPM: ex: 1370; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]] 1371; IS__CGSCC_OPM-NEXT: ret i32 [[TMP5]] 1372; IS__CGSCC_OPM: hd: 1373; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ] 1374; IS__CGSCC_OPM-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR5]] 1375; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1376; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1377; IS__CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1378; 1379en: 1380 %tmp3 = icmp eq i32 %b, 0 1381 br i1 %tmp3, label %ex, label %hd 1382 1383ex: 1384 %tmp5 = tail call i32 @g(i32* nonnull %a) 1385 ret i32 %tmp5 1386 1387hd: 1388 %tmp7 = phi i32 [ %tmp8, %hd ], [ 0, %en ] 1389 tail call void @h(i32* %a) 1390 %tmp8 = add nuw i32 %tmp7, 1 1391 %tmp9 = icmp eq i32 %tmp8, %b 1392 br i1 %tmp9, label %ex, label %hd 1393} 1394 1395define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind { 1396; 1397; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 1398; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b 1399; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR6]] { 1400; NOT_CGSCC_OPM-NEXT: en: 1401; NOT_CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1402; NOT_CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1403; NOT_CGSCC_OPM: ex: 1404; NOT_CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR4]] 1405; NOT_CGSCC_OPM-NEXT: ret i32 [[TMP5]] 1406; NOT_CGSCC_OPM: hd: 1407; NOT_CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] 1408; NOT_CGSCC_OPM-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR4]] 1409; NOT_CGSCC_OPM-NEXT: br label [[HD2]] 1410; NOT_CGSCC_OPM: hd2: 1411; NOT_CGSCC_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1412; NOT_CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1413; NOT_CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1414; 1415; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 1416; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b 1417; IS__CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]]) #[[ATTR7]] { 1418; IS__CGSCC_OPM-NEXT: en: 1419; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0 1420; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]] 1421; IS__CGSCC_OPM: ex: 1422; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]]) #[[ATTR5]] 1423; IS__CGSCC_OPM-NEXT: ret i32 [[TMP5]] 1424; IS__CGSCC_OPM: hd: 1425; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ] 1426; IS__CGSCC_OPM-NEXT: tail call void @h(i32* nonnull [[A]]) #[[ATTR5]] 1427; IS__CGSCC_OPM-NEXT: br label [[HD2]] 1428; IS__CGSCC_OPM: hd2: 1429; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1 1430; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]] 1431; IS__CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]] 1432; 1433en: 1434 %tmp3 = icmp eq i32 %b, 0 1435 br i1 %tmp3, label %ex, label %hd 1436 1437ex: 1438 %tmp5 = tail call i32 @g(i32* nonnull %a) 1439 ret i32 %tmp5 1440 1441hd: 1442 %tmp7 = phi i32 [ %tmp8, %hd2 ], [ 0, %en ] 1443 tail call void @h(i32* %a) 1444 br label %hd2 1445 1446hd2: 1447 %tmp8 = add nuw i32 %tmp7, 1 1448 %tmp9 = icmp eq i32 %tmp8, %b 1449 br i1 %tmp9, label %ex, label %hd 1450} 1451 1452; Original from PR43833 1453declare void @sink(i32*) 1454 1455define void @PR43833(i32* %0, i32 %1) { 1456; IS________OPM-LABEL: define {{[^@]+}}@PR43833 1457; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) { 1458; IS________OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1 1459; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] 1460; IS________OPM: 4: 1461; IS________OPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 1462; IS________OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]] 1463; IS________OPM-NEXT: br label [[TMP8:%.*]] 1464; IS________OPM: 7: 1465; IS________OPM-NEXT: ret void 1466; IS________OPM: 8: 1467; IS________OPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] 1468; IS________OPM-NEXT: tail call void @sink(i32* [[TMP6]]) 1469; IS________OPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 1470; IS________OPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] 1471; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] 1472; 1473; IS________NPM-LABEL: define {{[^@]+}}@PR43833 1474; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) { 1475; IS________NPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1 1476; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] 1477; IS________NPM: 4: 1478; IS________NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 1479; IS________NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]] 1480; IS________NPM-NEXT: br label [[TMP8:%.*]] 1481; IS________NPM: 7: 1482; IS________NPM-NEXT: ret void 1483; IS________NPM: 8: 1484; IS________NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] 1485; IS________NPM-NEXT: tail call void @sink(i32* nonnull [[TMP6]]) 1486; IS________NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 1487; IS________NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] 1488; IS________NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] 1489; 1490 %3 = icmp sgt i32 %1, 1 1491 br i1 %3, label %4, label %7 1492 14934: ; preds = %2 1494 %5 = zext i32 %1 to i64 1495 %6 = getelementptr inbounds i32, i32* %0, i64 %5 1496 br label %8 1497 14987: ; preds = %8, %2 1499 ret void 1500 15018: ; preds = %8, %4 1502 %9 = phi i32 [ 1, %4 ], [ %10, %8 ] 1503 tail call void @sink(i32* %6) 1504 %10 = add nuw nsw i32 %9, 1 1505 %11 = icmp eq i32 %10, %1 1506 br i1 %11, label %7, label %8 1507} 1508 1509; Adjusted from PR43833 1510define void @PR43833_simple(i32* %0, i32 %1) { 1511; IS________OPM-LABEL: define {{[^@]+}}@PR43833_simple 1512; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) { 1513; IS________OPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 1514; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] 1515; IS________OPM: 4: 1516; IS________OPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 1517; IS________OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]] 1518; IS________OPM-NEXT: br label [[TMP8:%.*]] 1519; IS________OPM: 7: 1520; IS________OPM-NEXT: ret void 1521; IS________OPM: 8: 1522; IS________OPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] 1523; IS________OPM-NEXT: tail call void @sink(i32* [[TMP6]]) 1524; IS________OPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 1525; IS________OPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] 1526; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] 1527; 1528; IS________NPM-LABEL: define {{[^@]+}}@PR43833_simple 1529; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]]) { 1530; IS________NPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 1531; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]] 1532; IS________NPM: 4: 1533; IS________NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64 1534; IS________NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP5]] 1535; IS________NPM-NEXT: br label [[TMP8:%.*]] 1536; IS________NPM: 7: 1537; IS________NPM-NEXT: ret void 1538; IS________NPM: 8: 1539; IS________NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ] 1540; IS________NPM-NEXT: tail call void @sink(i32* nonnull [[TMP6]]) 1541; IS________NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1 1542; IS________NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]] 1543; IS________NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]] 1544; 1545 %3 = icmp ne i32 %1, 0 1546 br i1 %3, label %4, label %7 1547 15484: ; preds = %2 1549 %5 = zext i32 %1 to i64 1550 %6 = getelementptr inbounds i32, i32* %0, i64 %5 1551 br label %8 1552 15537: ; preds = %8, %2 1554 ret void 1555 15568: ; preds = %8, %4 1557 %9 = phi i32 [ 1, %4 ], [ %10, %8 ] 1558 tail call void @sink(i32* %6) 1559 %10 = add nuw nsw i32 %9, 1 1560 %11 = icmp eq i32 %10, %1 1561 br i1 %11, label %7, label %8 1562} 1563 1564declare i8* @strrchr(i8* %0, i32 %1) nofree nounwind readonly willreturn 1565 1566; We should not mark the return of @strrchr as `nonnull`, it may well be NULL! 1567define i8* @mybasename(i8* nofree readonly %str) { 1568; NOT_CGSCC_OPM: Function Attrs: nofree nounwind readonly willreturn 1569; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@mybasename 1570; NOT_CGSCC_OPM-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR11:[0-9]+]] { 1571; NOT_CGSCC_OPM-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR14]] 1572; NOT_CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null 1573; NOT_CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 1574; NOT_CGSCC_OPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] 1575; NOT_CGSCC_OPM-NEXT: ret i8* [[COND]] 1576; 1577; IS__CGSCC_OPM: Function Attrs: nofree nounwind readonly willreturn 1578; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@mybasename 1579; IS__CGSCC_OPM-SAME: (i8* nofree readonly [[STR:%.*]]) #[[ATTR12:[0-9]+]] { 1580; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 noundef 47) #[[ATTR15]] 1581; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null 1582; IS__CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8* [[CALL]], i64 1 1583; IS__CGSCC_OPM-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]], i8* [[STR]] 1584; IS__CGSCC_OPM-NEXT: ret i8* [[COND]] 1585; 1586 %call = call i8* @strrchr(i8* %str, i32 47) 1587 %tobool = icmp ne i8* %call, null 1588 %add.ptr = getelementptr inbounds i8, i8* %call, i64 1 1589 %cond = select i1 %tobool, i8* %add.ptr, i8* %str 1590 ret i8* %cond 1591} 1592 1593define void @nonnull_assume_pos(i8* %arg) { 1594; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_pos 1595; ATTRIBUTOR-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) 1596; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[ARG]]) ] 1597; ATTRIBUTOR-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) 1598; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i8* @unknown() 1599; ATTRIBUTOR-NEXT: ret void 1600; 1601; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos 1602; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) { 1603; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR12]] [ "nonnull"(i8* [[ARG]]) ] 1604; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]] 1605; NOT_CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown() 1606; NOT_CGSCC_OPM-NEXT: ret void 1607; 1608; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos 1609; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]]) { 1610; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) #[[ATTR13]] [ "nonnull"(i8* [[ARG]]) ] 1611; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]] 1612; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown() 1613; IS__CGSCC_OPM-NEXT: ret void 1614; 1615 call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)] 1616 call void @use_i8_ptr(i8* %arg) 1617 call i8* @unknown() 1618 ret void 1619} 1620define void @nonnull_assume_neg(i8* %arg) { 1621; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_assume_neg 1622; ATTRIBUTOR-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) 1623; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i8* @unknown() 1624; ATTRIBUTOR-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) 1625; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]]) ] 1626; ATTRIBUTOR-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) 1627; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = call i8* @unknown() 1628; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) 1629; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]]) ] 1630; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) 1631; ATTRIBUTOR-NEXT: ret void 1632; 1633; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_neg 1634; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) { 1635; NOT_CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown() 1636; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR4]] 1637; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ] 1638; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]] 1639; NOT_CGSCC_OPM-NEXT: [[TMP2:%.*]] = call i8* @unknown() 1640; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]] 1641; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ] 1642; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR4]] 1643; NOT_CGSCC_OPM-NEXT: ret void 1644; 1645; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_neg 1646; IS__CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) { 1647; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown() 1648; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[ARG]]) #[[ATTR5]] 1649; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ] 1650; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]] 1651; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = call i8* @unknown() 1652; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]] 1653; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 noundef true) [ "nonnull"(i8* [[ARG]]) ] 1654; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]]) #[[ATTR5]] 1655; IS__CGSCC_OPM-NEXT: ret void 1656; 1657 call i8* @unknown() 1658 call void @use_i8_ptr(i8* %arg) 1659 call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)] 1660 call void @use_i8_ptr(i8* %arg) 1661 call i8* @unknown() 1662 call void @use_i8_ptr_ret(i8* %arg) 1663 call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)] 1664 call void @use_i8_ptr_ret(i8* %arg) 1665 ret void 1666} 1667declare void @use_i8_ptr(i8* nofree nocapture readnone) nounwind 1668declare void @use_i8_ptr_ret(i8* nofree nocapture readnone) nounwind willreturn 1669 1670define i8* @nonnull_function_ptr_1() { 1671; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 1672; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1 1673; IS__TUNIT____-SAME: () #[[ATTR1]] { 1674; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* ()* @nonnull_function_ptr_1 to i8* 1675; IS__TUNIT____-NEXT: ret i8* [[BC]] 1676; 1677; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1678; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_1 1679; IS__CGSCC____-SAME: () #[[ATTR1]] { 1680; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* ()* @nonnull_function_ptr_1 to i8* 1681; IS__CGSCC____-NEXT: ret i8* [[BC]] 1682; 1683 %bc = bitcast i8*()* @nonnull_function_ptr_1 to i8* 1684 ret i8* %bc 1685} 1686 1687declare i8* @function_decl() 1688define i8* @nonnull_function_ptr_2() { 1689; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn 1690; IS__TUNIT____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2 1691; IS__TUNIT____-SAME: () #[[ATTR1]] { 1692; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* ()* @function_decl to i8* 1693; IS__TUNIT____-NEXT: ret i8* [[BC]] 1694; 1695; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1696; IS__CGSCC____-LABEL: define {{[^@]+}}@nonnull_function_ptr_2 1697; IS__CGSCC____-SAME: () #[[ATTR1]] { 1698; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* ()* @function_decl to i8* 1699; IS__CGSCC____-NEXT: ret i8* [[BC]] 1700; 1701 %bc = bitcast i8*()* @function_decl to i8* 1702 ret i8* %bc 1703} 1704 1705; FIXME: nonnull should not be propagated to the caller's p unless there is noundef 1706define void @nonnull_caller(i8* %p) { 1707; CHECK-LABEL: define {{[^@]+}}@nonnull_caller 1708; CHECK-SAME: (i8* nonnull [[P:%.*]]) { 1709; CHECK-NEXT: call void @nonnull_callee(i8* nonnull [[P]]) 1710; CHECK-NEXT: ret void 1711; 1712 call void @nonnull_callee(i8* %p) 1713 ret void 1714} 1715 1716declare void @nonnull_callee(i8* nonnull %p) 1717 1718attributes #0 = { null_pointer_is_valid } 1719attributes #1 = { nounwind willreturn} 1720;. 1721; IS__TUNIT____: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn } 1722; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn } 1723; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone } 1724; IS__TUNIT____: attributes #[[ATTR3]] = { noreturn } 1725; IS__TUNIT____: attributes #[[ATTR4]] = { nounwind } 1726; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly } 1727; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind willreturn } 1728; IS__TUNIT____: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn } 1729; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn } 1730; IS__TUNIT____: attributes #[[ATTR9]] = { naked } 1731; IS__TUNIT____: attributes #[[ATTR10]] = { noinline optnone } 1732; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nounwind readonly willreturn } 1733; IS__TUNIT____: attributes #[[ATTR12]] = { willreturn } 1734; IS__TUNIT____: attributes #[[ATTR13]] = { nofree nosync nounwind readonly } 1735; IS__TUNIT____: attributes #[[ATTR14]] = { readonly willreturn } 1736;. 1737; IS__CGSCC_OPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn } 1738; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 1739; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone } 1740; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn } 1741; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noreturn } 1742; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind } 1743; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind readonly } 1744; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn } 1745; IS__CGSCC_OPM: attributes #[[ATTR8:[0-9]+]] = { nounwind readonly willreturn } 1746; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } 1747; IS__CGSCC_OPM: attributes #[[ATTR10]] = { naked } 1748; IS__CGSCC_OPM: attributes #[[ATTR11]] = { noinline optnone } 1749; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree nounwind readonly willreturn } 1750; IS__CGSCC_OPM: attributes #[[ATTR13]] = { willreturn } 1751; IS__CGSCC_OPM: attributes #[[ATTR14]] = { nofree nosync nounwind readonly } 1752; IS__CGSCC_OPM: attributes #[[ATTR15]] = { readonly willreturn } 1753;. 1754; IS__CGSCC_NPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn } 1755; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 1756; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone } 1757; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noreturn } 1758; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nounwind } 1759; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly } 1760; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn } 1761; IS__CGSCC_NPM: attributes #[[ATTR7:[0-9]+]] = { nounwind readonly willreturn } 1762; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } 1763; IS__CGSCC_NPM: attributes #[[ATTR9]] = { naked } 1764; IS__CGSCC_NPM: attributes #[[ATTR10]] = { noinline optnone } 1765; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree nounwind readonly willreturn } 1766; IS__CGSCC_NPM: attributes #[[ATTR12]] = { willreturn } 1767; IS__CGSCC_NPM: attributes #[[ATTR13]] = { nofree nosync nounwind readonly } 1768; IS__CGSCC_NPM: attributes #[[ATTR14]] = { readonly willreturn } 1769;. 1770