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=7 -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=7 -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 7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 8 9; Test cases specifically designed for the "undefined behavior" abstract function attribute. 10; We want to verify that whenever undefined behavior is assumed, the code becomes unreachable. 11; We use FIXME's to indicate problems and missing attributes. 12 13; -- Load tests -- 14 15define void @load_wholly_unreachable() { 16; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 17; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable 18; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 19; CHECK-NEXT: unreachable 20; 21 %a = load i32, i32* null 22 ret void 23} 24 25define void @loads_wholly_unreachable() { 26; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 27; CHECK-LABEL: define {{[^@]+}}@loads_wholly_unreachable 28; CHECK-SAME: () #[[ATTR0]] { 29; CHECK-NEXT: unreachable 30; 31 %a = load i32, i32* null 32 %b = load i32, i32* null 33 ret void 34} 35 36 37define void @load_single_bb_unreachable(i1 %cond) { 38; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 39; CHECK-LABEL: define {{[^@]+}}@load_single_bb_unreachable 40; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { 41; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 42; CHECK: t: 43; CHECK-NEXT: unreachable 44; CHECK: e: 45; CHECK-NEXT: ret void 46; 47 br i1 %cond, label %t, label %e 48t: 49 %b = load i32, i32* null 50 br label %e 51e: 52 ret void 53} 54 55; Note that while the load is removed (because it's unused), the block 56; is not changed to unreachable 57define void @load_null_pointer_is_defined() null_pointer_is_valid { 58; CHECK: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn 59; CHECK-LABEL: define {{[^@]+}}@load_null_pointer_is_defined 60; CHECK-SAME: () #[[ATTR1:[0-9]+]] { 61; CHECK-NEXT: ret void 62; 63 %a = load i32, i32* null 64 ret void 65} 66 67define internal i32* @ret_null() { 68; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 69; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_null 70; IS__CGSCC____-SAME: () #[[ATTR0]] { 71; IS__CGSCC____-NEXT: ret i32* null 72; 73 ret i32* null 74} 75 76define void @load_null_propagated() { 77; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 78; IS__TUNIT____-LABEL: define {{[^@]+}}@load_null_propagated 79; IS__TUNIT____-SAME: () #[[ATTR0]] { 80; IS__TUNIT____-NEXT: unreachable 81; 82; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 83; IS__CGSCC____-LABEL: define {{[^@]+}}@load_null_propagated 84; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { 85; IS__CGSCC____-NEXT: ret void 86; 87 %ptr = call i32* @ret_null() 88 %a = load i32, i32* %ptr 89 ret void 90} 91 92; -- Store tests -- 93 94define void @store_wholly_unreachable() { 95; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 96; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable 97; CHECK-SAME: () #[[ATTR0]] { 98; CHECK-NEXT: unreachable 99; 100 store i32 5, i32* null 101 ret void 102} 103 104define void @store_wholly_unreachable_volatile() { 105; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 106; IS__TUNIT____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile 107; IS__TUNIT____-SAME: () #[[ATTR2:[0-9]+]] { 108; IS__TUNIT____-NEXT: store volatile i32 5, i32* null, align 4294967296 109; IS__TUNIT____-NEXT: ret void 110; 111; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn 112; IS__CGSCC____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile 113; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { 114; IS__CGSCC____-NEXT: store volatile i32 5, i32* null, align 4294967296 115; IS__CGSCC____-NEXT: ret void 116; 117 store volatile i32 5, i32* null 118 ret void 119} 120 121define void @store_single_bb_unreachable(i1 %cond) { 122; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 123; CHECK-LABEL: define {{[^@]+}}@store_single_bb_unreachable 124; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { 125; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 126; CHECK: t: 127; CHECK-NEXT: unreachable 128; CHECK: e: 129; CHECK-NEXT: ret void 130; 131 br i1 %cond, label %t, label %e 132t: 133 store i32 5, i32* null 134 br label %e 135e: 136 ret void 137} 138 139define void @store_null_pointer_is_defined() null_pointer_is_valid { 140; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly 141; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined 142; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { 143; IS__TUNIT____-NEXT: store i32 5, i32* null, align 4294967296 144; IS__TUNIT____-NEXT: ret void 145; 146; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly 147; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined 148; IS__CGSCC____-SAME: () #[[ATTR4:[0-9]+]] { 149; IS__CGSCC____-NEXT: store i32 5, i32* null, align 4294967296 150; IS__CGSCC____-NEXT: ret void 151; 152 store i32 5, i32* null 153 ret void 154} 155 156define void @store_null_propagated() { 157; ATTRIBUTOR-LABEL: @store_null_propagated( 158; ATTRIBUTOR-NEXT: unreachable 159; 160; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 161; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_propagated 162; IS__TUNIT____-SAME: () #[[ATTR0]] { 163; IS__TUNIT____-NEXT: unreachable 164; 165; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly 166; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_propagated 167; IS__CGSCC____-SAME: () #[[ATTR5:[0-9]+]] { 168; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias align 4294967296 i32* @ret_null() #[[ATTR10:[0-9]+]] 169; IS__CGSCC____-NEXT: ret void 170; 171 %ptr = call i32* @ret_null() 172 store i32 5, i32* %ptr 173 ret void 174} 175 176; -- AtomicRMW tests -- 177 178define void @atomicrmw_wholly_unreachable() { 179; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 180; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable 181; IS__TUNIT____-SAME: () #[[ATTR2]] { 182; IS__TUNIT____-NEXT: unreachable 183; 184; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn 185; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable 186; IS__CGSCC____-SAME: () #[[ATTR3]] { 187; IS__CGSCC____-NEXT: unreachable 188; 189 %a = atomicrmw add i32* null, i32 1 acquire 190 ret void 191} 192 193define void @atomicrmw_single_bb_unreachable(i1 %cond) { 194; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 195; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable 196; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { 197; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 198; IS__TUNIT____: t: 199; IS__TUNIT____-NEXT: unreachable 200; IS__TUNIT____: e: 201; IS__TUNIT____-NEXT: ret void 202; 203; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn 204; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable 205; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { 206; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 207; IS__CGSCC____: t: 208; IS__CGSCC____-NEXT: unreachable 209; IS__CGSCC____: e: 210; IS__CGSCC____-NEXT: ret void 211; 212 br i1 %cond, label %t, label %e 213t: 214 %a = atomicrmw add i32* null, i32 1 acquire 215 br label %e 216e: 217 ret void 218} 219 220define void @atomicrmw_null_pointer_is_defined() null_pointer_is_valid { 221; IS__TUNIT____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn 222; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined 223; IS__TUNIT____-SAME: () #[[ATTR4:[0-9]+]] { 224; IS__TUNIT____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 225; IS__TUNIT____-NEXT: ret void 226; 227; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn 228; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined 229; IS__CGSCC____-SAME: () #[[ATTR6:[0-9]+]] { 230; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire, align 4 231; IS__CGSCC____-NEXT: ret void 232; 233 %a = atomicrmw add i32* null, i32 1 acquire 234 ret void 235} 236 237define void @atomicrmw_null_propagated() { 238; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated( 239; ATTRIBUTOR-NEXT: unreachable 240; 241; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 242; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated 243; IS__TUNIT____-SAME: () #[[ATTR2]] { 244; IS__TUNIT____-NEXT: unreachable 245; 246; IS__CGSCC____: Function Attrs: nofree nounwind willreturn 247; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated 248; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] { 249; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias i32* @ret_null() #[[ATTR10]] 250; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* [[PTR]], i32 1 acquire, align 4 251; IS__CGSCC____-NEXT: ret void 252; 253 %ptr = call i32* @ret_null() 254 %a = atomicrmw add i32* %ptr, i32 1 acquire 255 ret void 256} 257 258; -- AtomicCmpXchg tests -- 259 260define void @atomiccmpxchg_wholly_unreachable() { 261; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 262; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable 263; IS__TUNIT____-SAME: () #[[ATTR2]] { 264; IS__TUNIT____-NEXT: unreachable 265; 266; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn 267; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable 268; IS__CGSCC____-SAME: () #[[ATTR3]] { 269; IS__CGSCC____-NEXT: unreachable 270; 271 %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic 272 ret void 273} 274 275define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { 276; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 277; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable 278; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { 279; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 280; IS__TUNIT____: t: 281; IS__TUNIT____-NEXT: unreachable 282; IS__TUNIT____: e: 283; IS__TUNIT____-NEXT: ret void 284; 285; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn 286; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable 287; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { 288; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 289; IS__CGSCC____: t: 290; IS__CGSCC____-NEXT: unreachable 291; IS__CGSCC____: e: 292; IS__CGSCC____-NEXT: ret void 293; 294 br i1 %cond, label %t, label %e 295t: 296 %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic 297 br label %e 298e: 299 ret void 300} 301 302define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid { 303; IS__TUNIT____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn 304; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined 305; IS__TUNIT____-SAME: () #[[ATTR4]] { 306; IS__TUNIT____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 307; IS__TUNIT____-NEXT: ret void 308; 309; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn 310; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined 311; IS__CGSCC____-SAME: () #[[ATTR6]] { 312; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic, align 4 313; IS__CGSCC____-NEXT: ret void 314; 315 %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic 316 ret void 317} 318 319define void @atomiccmpxchg_null_propagated() { 320; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated( 321; ATTRIBUTOR-NEXT: unreachable 322; 323; IS__TUNIT____: Function Attrs: nofree norecurse nounwind readnone willreturn 324; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated 325; IS__TUNIT____-SAME: () #[[ATTR2]] { 326; IS__TUNIT____-NEXT: unreachable 327; 328; IS__CGSCC____: Function Attrs: nofree nounwind willreturn 329; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated 330; IS__CGSCC____-SAME: () #[[ATTR7]] { 331; IS__CGSCC____-NEXT: [[PTR:%.*]] = call noalias i32* @ret_null() #[[ATTR10]] 332; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* [[PTR]], i32 2, i32 3 acq_rel monotonic, align 4 333; IS__CGSCC____-NEXT: ret void 334; 335 %ptr = call i32* @ret_null() 336 %a = cmpxchg i32* %ptr, i32 2, i32 3 acq_rel monotonic 337 ret void 338} 339 340; -- Conditional branching tests -- 341 342; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior 343 344define i32 @cond_br_on_undef() { 345; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn 346; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef 347; IS__TUNIT____-SAME: () #[[ATTR5:[0-9]+]] { 348; IS__TUNIT____-NEXT: unreachable 349; IS__TUNIT____: t: 350; IS__TUNIT____-NEXT: unreachable 351; IS__TUNIT____: e: 352; IS__TUNIT____-NEXT: unreachable 353; 354; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn 355; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef 356; IS__CGSCC____-SAME: () #[[ATTR8:[0-9]+]] { 357; IS__CGSCC____-NEXT: unreachable 358; IS__CGSCC____: t: 359; IS__CGSCC____-NEXT: unreachable 360; IS__CGSCC____: e: 361; IS__CGSCC____-NEXT: unreachable 362; 363 br i1 undef, label %t, label %e 364t: 365 ret i32 1 366e: 367 ret i32 2 368} 369 370; More complicated branching 371 ; Valid branch - verify that this is not converted 372 ; to unreachable. 373define void @cond_br_on_undef2(i1 %cond) { 374; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 375; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef2 376; CHECK-SAME: (i1 [[COND:%.*]]) #[[ATTR0]] { 377; CHECK-NEXT: br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]] 378; CHECK: t1: 379; CHECK-NEXT: unreachable 380; CHECK: t2: 381; CHECK-NEXT: unreachable 382; CHECK: e2: 383; CHECK-NEXT: unreachable 384; CHECK: e1: 385; CHECK-NEXT: ret void 386; 387 br i1 %cond, label %t1, label %e1 388t1: 389 br i1 undef, label %t2, label %e2 390t2: 391 ret void 392e2: 393 ret void 394e1: 395 ret void 396} 397 398define i1 @ret_undef() { 399; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 400; CHECK-LABEL: define {{[^@]+}}@ret_undef 401; CHECK-SAME: () #[[ATTR0]] { 402; CHECK-NEXT: ret i1 undef 403; 404 ret i1 undef 405} 406 407define void @cond_br_on_undef_interproc() { 408; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn 409; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc 410; IS__TUNIT____-SAME: () #[[ATTR5]] { 411; IS__TUNIT____-NEXT: unreachable 412; IS__TUNIT____: t: 413; IS__TUNIT____-NEXT: unreachable 414; IS__TUNIT____: e: 415; IS__TUNIT____-NEXT: unreachable 416; 417; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 418; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc 419; IS__CGSCC____-SAME: () #[[ATTR2]] { 420; IS__CGSCC____-NEXT: [[COND:%.*]] = call i1 @ret_undef() #[[ATTR10]] 421; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 422; IS__CGSCC____: t: 423; IS__CGSCC____-NEXT: ret void 424; IS__CGSCC____: e: 425; IS__CGSCC____-NEXT: ret void 426; 427 %cond = call i1 @ret_undef() 428 br i1 %cond, label %t, label %e 429t: 430 ret void 431e: 432 ret void 433} 434 435define i1 @ret_undef2() { 436; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 437; CHECK-LABEL: define {{[^@]+}}@ret_undef2 438; CHECK-SAME: () #[[ATTR0]] { 439; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[E:%.*]] 440; CHECK: t: 441; CHECK-NEXT: ret i1 undef 442; CHECK: e: 443; CHECK-NEXT: unreachable 444; 445 br i1 true, label %t, label %e 446t: 447 ret i1 undef 448e: 449 ret i1 undef 450} 451 452; More complicated interproc deduction of undef 453define void @cond_br_on_undef_interproc2() { 454; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn 455; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 456; IS__TUNIT____-SAME: () #[[ATTR5]] { 457; IS__TUNIT____-NEXT: unreachable 458; IS__TUNIT____: t: 459; IS__TUNIT____-NEXT: unreachable 460; IS__TUNIT____: e: 461; IS__TUNIT____-NEXT: unreachable 462; 463; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 464; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2 465; IS__CGSCC____-SAME: () #[[ATTR2]] { 466; IS__CGSCC____-NEXT: [[COND:%.*]] = call i1 @ret_undef2() #[[ATTR10]] 467; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 468; IS__CGSCC____: t: 469; IS__CGSCC____-NEXT: ret void 470; IS__CGSCC____: e: 471; IS__CGSCC____-NEXT: ret void 472; 473 %cond = call i1 @ret_undef2() 474 br i1 %cond, label %t, label %e 475t: 476 ret void 477e: 478 ret void 479} 480 481; Branch on undef that depends on propagation of 482; undef of a previous instruction. 483define i32 @cond_br_on_undef3() { 484; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 485; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef3 486; CHECK-SAME: () #[[ATTR0]] { 487; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 1, undef 488; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] 489; CHECK: t: 490; CHECK-NEXT: ret i32 1 491; CHECK: e: 492; CHECK-NEXT: ret i32 2 493; 494 %cond = icmp ne i32 1, undef 495 br i1 %cond, label %t, label %e 496t: 497 ret i32 1 498e: 499 ret i32 2 500} 501 502; Branch on undef because of uninitialized value. 503; FIXME: Currently it doesn't propagate the undef. 504define i32 @cond_br_on_undef_uninit() { 505; IS__TUNIT____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn 506; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit 507; IS__TUNIT____-SAME: () #[[ATTR5]] { 508; IS__TUNIT____-NEXT: unreachable 509; IS__TUNIT____: t: 510; IS__TUNIT____-NEXT: unreachable 511; IS__TUNIT____: e: 512; IS__TUNIT____-NEXT: unreachable 513; 514; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn 515; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit 516; IS__CGSCC____-SAME: () #[[ATTR8]] { 517; IS__CGSCC____-NEXT: unreachable 518; IS__CGSCC____: t: 519; IS__CGSCC____-NEXT: unreachable 520; IS__CGSCC____: e: 521; IS__CGSCC____-NEXT: unreachable 522; 523 %alloc = alloca i1 524 %cond = load i1, i1* %alloc 525 br i1 %cond, label %t, label %e 526t: 527 ret i32 1 528e: 529 ret i32 2 530} 531 532; Note that the `load` has UB (so it will be changed to unreachable) 533; and the branch is a terminator that can be constant-folded. 534; We want to test that doing both won't cause a segfault. 535; MODULE-NOT: @callee( 536define internal i32 @callee(i1 %C, i32* %A) { 537; 538; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 539; IS__CGSCC____-LABEL: define {{[^@]+}}@callee 540; IS__CGSCC____-SAME: () #[[ATTR0]] { 541; IS__CGSCC____-NEXT: entry: 542; IS__CGSCC____-NEXT: unreachable 543; IS__CGSCC____: T: 544; IS__CGSCC____-NEXT: unreachable 545; IS__CGSCC____: F: 546; IS__CGSCC____-NEXT: ret i32 1 547; 548entry: 549 %A.0 = load i32, i32* null 550 br i1 %C, label %T, label %F 551 552T: 553 ret i32 %A.0 554 555F: 556 ret i32 1 557} 558 559define i32 @foo() { 560; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 561; IS__TUNIT____-LABEL: define {{[^@]+}}@foo 562; IS__TUNIT____-SAME: () #[[ATTR0]] { 563; IS__TUNIT____-NEXT: ret i32 1 564; 565; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 566; IS__CGSCC____-LABEL: define {{[^@]+}}@foo 567; IS__CGSCC____-SAME: () #[[ATTR2]] { 568; IS__CGSCC____-NEXT: [[X:%.*]] = call noundef i32 @callee() #[[ATTR10]] 569; IS__CGSCC____-NEXT: ret i32 [[X]] 570; 571 %X = call i32 @callee(i1 false, i32* null) 572 ret i32 %X 573} 574 575; Tests for nonnull noundef attribute violation. 576; 577; Tests for argument position 578 579define void @arg_nonnull_1(i32* nonnull %a) { 580; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 581; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1 582; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6:[0-9]+]] { 583; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 584; IS__TUNIT____-NEXT: ret void 585; 586; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 587; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1 588; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9:[0-9]+]] { 589; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 590; IS__CGSCC____-NEXT: ret void 591; 592 store i32 0, i32* %a 593 ret void 594} 595 596define void @arg_nonnull_1_noundef_1(i32* nonnull noundef %a) { 597; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 598; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 599; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR6]] { 600; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 601; IS__TUNIT____-NEXT: ret void 602; 603; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 604; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_1_noundef_1 605; IS__CGSCC____-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR9]] { 606; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 607; IS__CGSCC____-NEXT: ret void 608; 609 store i32 0, i32* %a 610 ret void 611} 612 613define void @arg_nonnull_12(i32* nonnull %a, i32* nonnull %b, i32* %c) { 614; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 615; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12 616; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { 617; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null 618; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] 619; IS__TUNIT____: t: 620; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 621; IS__TUNIT____-NEXT: br label [[RET:%.*]] 622; IS__TUNIT____: f: 623; IS__TUNIT____-NEXT: store i32 1, i32* [[B]], align 4 624; IS__TUNIT____-NEXT: br label [[RET]] 625; IS__TUNIT____: ret: 626; IS__TUNIT____-NEXT: ret void 627; 628; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 629; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12 630; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { 631; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null 632; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] 633; IS__CGSCC____: t: 634; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 635; IS__CGSCC____-NEXT: br label [[RET:%.*]] 636; IS__CGSCC____: f: 637; IS__CGSCC____-NEXT: store i32 1, i32* [[B]], align 4 638; IS__CGSCC____-NEXT: br label [[RET]] 639; IS__CGSCC____: ret: 640; IS__CGSCC____-NEXT: ret void 641; 642 %d = icmp eq i32* %c, null 643 br i1 %d, label %t, label %f 644t: 645 store i32 0, i32* %a 646 br label %ret 647f: 648 store i32 1, i32* %b 649 br label %ret 650ret: 651 ret void 652} 653 654define void @arg_nonnull_12_noundef_2(i32* nonnull %a, i32* noundef nonnull %b, i32* %c) { 655; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 656; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 657; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR6]] { 658; IS__TUNIT____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null 659; IS__TUNIT____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] 660; IS__TUNIT____: t: 661; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4 662; IS__TUNIT____-NEXT: br label [[RET:%.*]] 663; IS__TUNIT____: f: 664; IS__TUNIT____-NEXT: store i32 1, i32* [[B]], align 4 665; IS__TUNIT____-NEXT: br label [[RET]] 666; IS__TUNIT____: ret: 667; IS__TUNIT____-NEXT: ret void 668; 669; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 670; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_12_noundef_2 671; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly [[A:%.*]], i32* nocapture nofree noundef nonnull writeonly [[B:%.*]], i32* nofree writeonly [[C:%.*]]) #[[ATTR9]] { 672; IS__CGSCC____-NEXT: [[D:%.*]] = icmp eq i32* [[C]], null 673; IS__CGSCC____-NEXT: br i1 [[D]], label [[T:%.*]], label [[F:%.*]] 674; IS__CGSCC____: t: 675; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4 676; IS__CGSCC____-NEXT: br label [[RET:%.*]] 677; IS__CGSCC____: f: 678; IS__CGSCC____-NEXT: store i32 1, i32* [[B]], align 4 679; IS__CGSCC____-NEXT: br label [[RET]] 680; IS__CGSCC____: ret: 681; IS__CGSCC____-NEXT: ret void 682; 683 %d = icmp eq i32* %c, null 684 br i1 %d, label %t, label %f 685t: 686 store i32 0, i32* %a 687 br label %ret 688f: 689 store i32 1, i32* %b 690 br label %ret 691ret: 692 ret void 693} 694 695; Pass null directly to argument with nonnull attribute 696define void @arg_nonnull_violation1_1() { 697; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 698; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 699; IS__TUNIT____-SAME: () #[[ATTR0]] { 700; IS__TUNIT____-NEXT: unreachable 701; 702; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 703; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_1 704; IS__CGSCC____-SAME: () #[[ATTR2]] { 705; IS__CGSCC____-NEXT: unreachable 706; 707 call void @arg_nonnull_1(i32* null) 708 ret void 709} 710 711define void @arg_nonnull_violation1_2() { 712; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 713; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 714; IS__TUNIT____-SAME: () #[[ATTR0]] { 715; IS__TUNIT____-NEXT: unreachable 716; 717; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 718; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation1_2 719; IS__CGSCC____-SAME: () #[[ATTR2]] { 720; IS__CGSCC____-NEXT: unreachable 721; 722 call void @arg_nonnull_1_noundef_1(i32* null) 723 ret void 724} 725 726; A case that depends on value simplification 727define void @arg_nonnull_violation2_1(i1 %c) { 728; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 729; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 730; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 731; IS__TUNIT____-NEXT: unreachable 732; 733; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 734; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_1 735; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 736; IS__CGSCC____-NEXT: unreachable 737; 738 %null = getelementptr i32, i32* null, i32 0 739 %mustnull = select i1 %c, i32* null, i32* %null 740 call void @arg_nonnull_1(i32* %mustnull) 741 ret void 742} 743 744define void @arg_nonnull_violation2_2(i1 %c) { 745; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 746; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 747; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 748; IS__TUNIT____-NEXT: unreachable 749; 750; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 751; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation2_2 752; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 753; IS__CGSCC____-NEXT: unreachable 754; 755 %null = getelementptr i32, i32* null, i32 0 756 %mustnull = select i1 %c, i32* null, i32* %null 757 call void @arg_nonnull_1_noundef_1(i32* %mustnull) 758 ret void 759} 760 761; Cases for single and multiple violation at a callsite 762define void @arg_nonnull_violation3_1(i1 %c) { 763; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 764; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 765; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 766; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 767; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 768; IS__TUNIT____: t: 769; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7:[0-9]+]] 770; IS__TUNIT____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR7]] 771; IS__TUNIT____-NEXT: unreachable 772; IS__TUNIT____: f: 773; IS__TUNIT____-NEXT: unreachable 774; IS__TUNIT____: ret: 775; IS__TUNIT____-NEXT: ret void 776; 777; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 778; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_1 779; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 780; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 781; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 782; IS__CGSCC____: t: 783; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR11:[0-9]+]] 784; IS__CGSCC____-NEXT: call void @arg_nonnull_12(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR11]] 785; IS__CGSCC____-NEXT: unreachable 786; IS__CGSCC____: f: 787; IS__CGSCC____-NEXT: unreachable 788; IS__CGSCC____: ret: 789; IS__CGSCC____-NEXT: ret void 790; 791 %ptr = alloca i32 792 br i1 %c, label %t, label %f 793t: 794 call void @arg_nonnull_12(i32* %ptr, i32* %ptr, i32* %ptr) 795 call void @arg_nonnull_12(i32* %ptr, i32* %ptr, i32* null) 796 call void @arg_nonnull_12(i32* %ptr, i32* null, i32* %ptr) 797 call void @arg_nonnull_12(i32* %ptr, i32* null, i32* null) 798 br label %ret 799f: 800 call void @arg_nonnull_12(i32* null, i32* %ptr, i32* %ptr) 801 call void @arg_nonnull_12(i32* null, i32* %ptr, i32* null) 802 call void @arg_nonnull_12(i32* null, i32* null, i32* %ptr) 803 call void @arg_nonnull_12(i32* null, i32* null, i32* null) 804 br label %ret 805ret: 806 ret void 807} 808 809define void @arg_nonnull_violation3_2(i1 %c) { 810; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 811; IS__TUNIT____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 812; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 813; IS__TUNIT____-NEXT: [[PTR:%.*]] = alloca i32, align 4 814; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 815; IS__TUNIT____: t: 816; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR7]] 817; IS__TUNIT____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR7]] 818; IS__TUNIT____-NEXT: unreachable 819; IS__TUNIT____: f: 820; IS__TUNIT____-NEXT: unreachable 821; IS__TUNIT____: ret: 822; IS__TUNIT____-NEXT: ret void 823; 824; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 825; IS__CGSCC____-LABEL: define {{[^@]+}}@arg_nonnull_violation3_2 826; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 827; IS__CGSCC____-NEXT: [[PTR:%.*]] = alloca i32, align 4 828; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 829; IS__CGSCC____: t: 830; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]]) #[[ATTR11]] 831; IS__CGSCC____-NEXT: call void @arg_nonnull_12_noundef_2(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[PTR]], i32* noalias nocapture nofree noundef writeonly align 4294967296 null) #[[ATTR11]] 832; IS__CGSCC____-NEXT: unreachable 833; IS__CGSCC____: f: 834; IS__CGSCC____-NEXT: unreachable 835; IS__CGSCC____: ret: 836; IS__CGSCC____-NEXT: ret void 837; 838 %ptr = alloca i32 839 br i1 %c, label %t, label %f 840t: 841 call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* %ptr, i32* %ptr) 842 call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* %ptr, i32* null) 843 call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* null, i32* %ptr) 844 call void @arg_nonnull_12_noundef_2(i32* %ptr, i32* null, i32* null) 845 br label %ret 846f: 847 call void @arg_nonnull_12_noundef_2(i32* null, i32* %ptr, i32* %ptr) 848 call void @arg_nonnull_12_noundef_2(i32* null, i32* %ptr, i32* null) 849 call void @arg_nonnull_12_noundef_2(i32* null, i32* null, i32* %ptr) 850 call void @arg_nonnull_12_noundef_2(i32* null, i32* null, i32* null) 851 br label %ret 852ret: 853 ret void 854} 855 856; Tests for returned position 857 858define nonnull i32* @returned_nonnnull(i32 %c) { 859; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 860; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull 861; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 862; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ 863; CHECK-NEXT: i32 0, label [[ONZERO:%.*]] 864; CHECK-NEXT: i32 1, label [[ONONE:%.*]] 865; CHECK-NEXT: ] 866; CHECK: onzero: 867; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4 868; CHECK-NEXT: ret i32* [[PTR]] 869; CHECK: onone: 870; CHECK-NEXT: ret i32* null 871; CHECK: ondefault: 872; CHECK-NEXT: ret i32* undef 873; 874 switch i32 %c, label %ondefault [ i32 0, label %onzero 875 i32 1, label %onone ] 876onzero: 877 %ptr = alloca i32 878 ret i32* %ptr 879onone: 880 ret i32* null 881ondefault: 882 ret i32* undef 883} 884 885define noundef i32* @returned_noundef(i32 %c) { 886; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 887; CHECK-LABEL: define {{[^@]+}}@returned_noundef 888; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 889; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ 890; CHECK-NEXT: i32 0, label [[ONZERO:%.*]] 891; CHECK-NEXT: i32 1, label [[ONONE:%.*]] 892; CHECK-NEXT: ] 893; CHECK: onzero: 894; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4 895; CHECK-NEXT: ret i32* [[PTR]] 896; CHECK: onone: 897; CHECK-NEXT: ret i32* null 898; CHECK: ondefault: 899; CHECK-NEXT: unreachable 900; 901 switch i32 %c, label %ondefault [ i32 0, label %onzero 902 i32 1, label %onone ] 903onzero: 904 %ptr = alloca i32 905 ret i32* %ptr 906onone: 907 ret i32* null 908ondefault: 909 ret i32* undef 910} 911 912define nonnull noundef i32* @returned_nonnnull_noundef(i32 %c) { 913; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 914; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef 915; CHECK-SAME: (i32 [[C:%.*]]) #[[ATTR0]] { 916; CHECK-NEXT: switch i32 [[C]], label [[ONDEFAULT:%.*]] [ 917; CHECK-NEXT: i32 0, label [[ONZERO:%.*]] 918; CHECK-NEXT: i32 1, label [[ONONE:%.*]] 919; CHECK-NEXT: ] 920; CHECK: onzero: 921; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 4 922; CHECK-NEXT: ret i32* [[PTR]] 923; CHECK: onone: 924; CHECK-NEXT: unreachable 925; CHECK: ondefault: 926; CHECK-NEXT: unreachable 927; 928 switch i32 %c, label %ondefault [ i32 0, label %onzero 929 i32 1, label %onone ] 930onzero: 931 %ptr = alloca i32 932 ret i32* %ptr 933onone: 934 ret i32* null 935ondefault: 936 ret i32* undef 937} 938 939define noundef i32 @returned_nonnnull_noundef_int() { 940; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 941; CHECK-LABEL: define {{[^@]+}}@returned_nonnnull_noundef_int 942; CHECK-SAME: () #[[ATTR0]] { 943; CHECK-NEXT: ret i32 0 944; 945 ret i32 0 946} 947 948declare void @callee_int_arg(i32) 949 950define void @callsite_noundef_1() { 951; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_1() { 952; CHECK-NEXT: call void @callee_int_arg(i32 noundef 0) 953; CHECK-NEXT: ret void 954; 955 call void @callee_int_arg(i32 noundef 0) 956 ret void 957} 958 959declare void @callee_ptr_arg(i32*) 960 961define void @callsite_noundef_2() { 962; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_2() { 963; CHECK-NEXT: unreachable 964; 965 call void @callee_ptr_arg(i32* noundef undef) 966 ret void 967} 968 969define i32 @argument_noundef1(i32 noundef %c) { 970; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 971; CHECK-LABEL: define {{[^@]+}}@argument_noundef1 972; CHECK-SAME: (i32 noundef returned [[C:%.*]]) #[[ATTR0]] { 973; CHECK-NEXT: ret i32 [[C]] 974; 975 ret i32 %c 976} 977 978define i32 @violate_noundef_nonpointer() { 979; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 980; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer 981; IS__TUNIT____-SAME: () #[[ATTR0]] { 982; IS__TUNIT____-NEXT: ret i32 undef 983; 984; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 985; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer 986; IS__CGSCC____-SAME: () #[[ATTR2]] { 987; IS__CGSCC____-NEXT: unreachable 988; 989 %ret = call i32 @argument_noundef1(i32 undef) 990 ret i32 %ret 991} 992 993define i32* @argument_noundef2(i32* noundef %c) { 994; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 995; CHECK-LABEL: define {{[^@]+}}@argument_noundef2 996; CHECK-SAME: (i32* nofree noundef readnone returned "no-capture-maybe-returned" [[C:%.*]]) #[[ATTR0]] { 997; CHECK-NEXT: ret i32* [[C]] 998; 999 ret i32* %c 1000} 1001 1002define i32* @violate_noundef_pointer() { 1003; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1004; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer 1005; IS__TUNIT____-SAME: () #[[ATTR0]] { 1006; IS__TUNIT____-NEXT: ret i32* undef 1007; 1008; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 1009; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer 1010; IS__CGSCC____-SAME: () #[[ATTR2]] { 1011; IS__CGSCC____-NEXT: ret i32* undef 1012; 1013 %ret = call i32* @argument_noundef2(i32* undef) 1014 ret i32* %ret 1015} 1016 1017define internal noundef i32 @assumed_undef_is_ok(i1 %c, i32 %arg) { 1018; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 1019; IS__CGSCC____-LABEL: define {{[^@]+}}@assumed_undef_is_ok 1020; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 1021; IS__CGSCC____-NEXT: br i1 [[C]], label [[REC:%.*]], label [[RET:%.*]] 1022; IS__CGSCC____: rec: 1023; IS__CGSCC____-NEXT: br label [[RET]] 1024; IS__CGSCC____: ret: 1025; IS__CGSCC____-NEXT: ret i32 0 1026; 1027 %stack = alloca i32 1028 store i32 %arg, i32* %stack 1029 br i1 %c, label %rec, label %ret 1030rec: 1031 %call = call i32 @assumed_undef_is_ok(i1 false, i32 0) 1032 store i32 %call, i32* %stack 1033 br label %ret 1034ret: 1035 %l = load i32, i32* %stack 1036 ret i32 %l 1037} 1038 1039define noundef i32 @assumed_undef_is_ok_caller(i1 %c) { 1040; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1041; IS__TUNIT____-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller 1042; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] { 1043; IS__TUNIT____-NEXT: ret i32 0 1044; 1045; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn 1046; IS__CGSCC____-LABEL: define {{[^@]+}}@assumed_undef_is_ok_caller 1047; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 1048; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @assumed_undef_is_ok(i1 [[C]]) #[[ATTR10]] 1049; IS__CGSCC____-NEXT: ret i32 [[CALL]] 1050; 1051 %call = call i32 @assumed_undef_is_ok(i1 %c, i32 undef) 1052 ret i32 %call 1053} 1054 1055;. 1056; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } 1057; IS__TUNIT____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } 1058; IS__TUNIT____: attributes #[[ATTR2]] = { nofree norecurse nounwind readnone willreturn } 1059; IS__TUNIT____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } 1060; IS__TUNIT____: attributes #[[ATTR4]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } 1061; IS__TUNIT____: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } 1062; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } 1063; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind willreturn writeonly } 1064;. 1065; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } 1066; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } 1067; IS__CGSCC____: attributes #[[ATTR2]] = { nofree nosync nounwind readnone willreturn } 1068; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nounwind readnone willreturn } 1069; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } 1070; IS__CGSCC____: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly } 1071; IS__CGSCC____: attributes #[[ATTR6]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } 1072; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nounwind willreturn } 1073; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } 1074; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } 1075; IS__CGSCC____: attributes #[[ATTR10]] = { readnone willreturn } 1076; IS__CGSCC____: attributes #[[ATTR11]] = { nounwind willreturn writeonly } 1077;. 1078