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=17 -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=17 -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:o-i64:64-f80:128-n8:16:32:64-S128" 8 9declare i1* @geti1Ptr() 10 11; Make sure we do *not* return true. 12;. 13; CHECK: @[[G1:[a-zA-Z0-9_$"\\.-]+]] = private global i1* undef 14; CHECK: @[[G2:[a-zA-Z0-9_$"\\.-]+]] = private global i1* undef 15; CHECK: @[[G3:[a-zA-Z0-9_$"\\.-]+]] = private global i1 undef 16;. 17define internal i1 @recursive_inst_comparator(i1* %a, i1* %b) { 18; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 19; CHECK-LABEL: define {{[^@]+}}@recursive_inst_comparator 20; CHECK-SAME: (i1* noalias nofree readnone [[A:%.*]], i1* noalias nofree readnone [[B:%.*]]) #[[ATTR0:[0-9]+]] { 21; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[B]] 22; CHECK-NEXT: ret i1 [[CMP]] 23; 24 %cmp = icmp eq i1* %a, %b 25 ret i1 %cmp 26} 27 28define internal i1 @recursive_inst_generator(i1 %c, i1* %p) { 29; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_inst_generator 30; IS__TUNIT____-SAME: (i1 [[C:%.*]], i1* nofree [[P:%.*]]) { 31; IS__TUNIT____-NEXT: [[A:%.*]] = call i1* @geti1Ptr() 32; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 33; IS__TUNIT____: t: 34; IS__TUNIT____-NEXT: [[R1:%.*]] = call i1 @recursive_inst_comparator(i1* noalias nofree readnone [[A]], i1* noalias nofree readnone [[P]]) #[[ATTR6:[0-9]+]] 35; IS__TUNIT____-NEXT: ret i1 [[R1]] 36; IS__TUNIT____: f: 37; IS__TUNIT____-NEXT: [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, i1* nofree [[A]]) 38; IS__TUNIT____-NEXT: ret i1 [[R2]] 39; 40; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_inst_generator 41; IS__CGSCC____-SAME: (i1 [[C:%.*]], i1* nofree [[P:%.*]]) { 42; IS__CGSCC____-NEXT: [[A:%.*]] = call i1* @geti1Ptr() 43; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 44; IS__CGSCC____: t: 45; IS__CGSCC____-NEXT: [[R1:%.*]] = call i1 @recursive_inst_comparator(i1* noalias nofree readnone [[A]], i1* noalias nofree readnone [[P]]) 46; IS__CGSCC____-NEXT: ret i1 [[R1]] 47; IS__CGSCC____: f: 48; IS__CGSCC____-NEXT: [[R2:%.*]] = call i1 @recursive_inst_generator(i1 noundef true, i1* nofree [[A]]) 49; IS__CGSCC____-NEXT: ret i1 [[R2]] 50; 51 %a = call i1* @geti1Ptr() 52 br i1 %c, label %t, label %f 53t: 54 %r1 = call i1 @recursive_inst_comparator(i1* %a, i1* %p) 55 ret i1 %r1 56f: 57 %r2 = call i1 @recursive_inst_generator(i1 true, i1* %a) 58 ret i1 %r2 59} 60 61; FIXME: This should *not* return true. 62define i1 @recursive_inst_generator_caller(i1 %c) { 63; CHECK-LABEL: define {{[^@]+}}@recursive_inst_generator_caller 64; CHECK-SAME: (i1 [[C:%.*]]) { 65; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_generator(i1 [[C]], i1* undef) 66; CHECK-NEXT: ret i1 [[CALL]] 67; 68 %call = call i1 @recursive_inst_generator(i1 %c, i1* undef) 69 ret i1 %call 70} 71 72; Make sure we do *not* return true. 73define internal i1 @recursive_inst_compare(i1 %c, i1* %p) { 74; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare 75; CHECK-SAME: (i1 [[C:%.*]], i1* [[P:%.*]]) { 76; CHECK-NEXT: [[A:%.*]] = call i1* @geti1Ptr() 77; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 78; CHECK: t: 79; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] 80; CHECK-NEXT: ret i1 [[CMP]] 81; CHECK: f: 82; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 noundef true, i1* [[A]]) 83; CHECK-NEXT: ret i1 [[CALL]] 84; 85 %a = call i1* @geti1Ptr() 86 br i1 %c, label %t, label %f 87t: 88 %cmp = icmp eq i1* %a, %p 89 ret i1 %cmp 90f: 91 %call = call i1 @recursive_inst_compare(i1 true, i1* %a) 92 ret i1 %call 93} 94 95; FIXME: This should *not* return true. 96define i1 @recursive_inst_compare_caller(i1 %c) { 97; CHECK-LABEL: define {{[^@]+}}@recursive_inst_compare_caller 98; CHECK-SAME: (i1 [[C:%.*]]) { 99; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare(i1 [[C]], i1* undef) 100; CHECK-NEXT: ret i1 [[CALL]] 101; 102 %call = call i1 @recursive_inst_compare(i1 %c, i1* undef) 103 ret i1 %call 104} 105 106; Make sure we do *not* return true. 107define internal i1 @recursive_alloca_compare(i1 %c, i1* %p) { 108; CHECK: Function Attrs: nofree nosync nounwind readnone 109; CHECK-LABEL: define {{[^@]+}}@recursive_alloca_compare 110; CHECK-SAME: (i1 [[C:%.*]], i1* noalias nofree nonnull readnone [[P:%.*]]) #[[ATTR1:[0-9]+]] { 111; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1 112; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 113; CHECK: t: 114; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] 115; CHECK-NEXT: ret i1 [[CMP]] 116; CHECK: f: 117; CHECK-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 noundef true, i1* noalias nofree noundef nonnull readnone dereferenceable(1) [[A]]) #[[ATTR1]] 118; CHECK-NEXT: ret i1 [[CALL]] 119; 120 %a = alloca i1 121 br i1 %c, label %t, label %f 122t: 123 %cmp = icmp eq i1* %a, %p 124 ret i1 %cmp 125f: 126 %call = call i1 @recursive_alloca_compare(i1 true, i1* %a) 127 ret i1 %call 128} 129 130; FIXME: This should *not* return true. 131define i1 @recursive_alloca_compare_caller(i1 %c) { 132; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone 133; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller 134; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] { 135; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR1]] 136; IS__TUNIT____-NEXT: ret i1 [[CALL]] 137; 138; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone 139; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller 140; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 141; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare(i1 [[C]], i1* undef) #[[ATTR4:[0-9]+]] 142; IS__CGSCC____-NEXT: ret i1 [[CALL]] 143; 144 %call = call i1 @recursive_alloca_compare(i1 %c, i1* undef) 145 ret i1 %call 146} 147 148; Make sure we do *not* simplify this to return 0 or 1, return 42 is ok though. 149define internal i8 @recursive_alloca_load_return(i1 %c, i8* %p, i8 %v) { 150; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind 151; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_load_return 152; IS__TUNIT____-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR3:[0-9]+]] { 153; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i8, align 1 154; IS__TUNIT____-NEXT: store i8 [[V]], i8* [[A]], align 1 155; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 156; IS__TUNIT____: t: 157; IS__TUNIT____-NEXT: store i8 0, i8* [[A]], align 1 158; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 159; IS__TUNIT____-NEXT: ret i8 [[L]] 160; IS__TUNIT____: f: 161; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR4:[0-9]+]] 162; IS__TUNIT____-NEXT: ret i8 [[CALL]] 163; 164; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind 165; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_load_return 166; IS__CGSCC____-SAME: (i1 [[C:%.*]], i8* nocapture nofree nonnull readonly [[P:%.*]], i8 noundef [[V:%.*]]) #[[ATTR2:[0-9]+]] { 167; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i8, align 1 168; IS__CGSCC____-NEXT: store i8 [[V]], i8* [[A]], align 1 169; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 170; IS__CGSCC____: t: 171; IS__CGSCC____-NEXT: store i8 0, i8* [[A]], align 1 172; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[P]], align 1 173; IS__CGSCC____-NEXT: ret i8 [[L]] 174; IS__CGSCC____: f: 175; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 noundef true, i8* noalias nocapture nofree noundef nonnull readonly dereferenceable(1) [[A]], i8 noundef 1) #[[ATTR3:[0-9]+]] 176; IS__CGSCC____-NEXT: ret i8 [[CALL]] 177; 178 %a = alloca i8 179 store i8 %v, i8* %a 180 br i1 %c, label %t, label %f 181t: 182 store i8 0, i8* %a 183 %l = load i8, i8* %p 184 ret i8 %l 185f: 186 %call = call i8 @recursive_alloca_load_return(i1 true, i8* %a, i8 1) 187 ret i8 %call 188} 189 190define i8 @recursive_alloca_load_return_caller(i1 %c) { 191; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone 192; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller 193; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 194; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR4]] 195; IS__TUNIT____-NEXT: ret i8 [[CALL]] 196; 197; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone 198; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_load_return_caller 199; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] { 200; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i8 @recursive_alloca_load_return(i1 [[C]], i8* undef, i8 noundef 42) #[[ATTR5:[0-9]+]] 201; IS__CGSCC____-NEXT: ret i8 [[CALL]] 202; 203 %call = call i8 @recursive_alloca_load_return(i1 %c, i8* undef, i8 42) 204 ret i8 %call 205} 206 207@G1 = private global i1* undef 208@G2 = private global i1* undef 209@G3 = private global i1 undef 210 211; Make sure we do *not* return true. 212define internal i1 @recursive_alloca_compare_global1(i1 %c) { 213; IS__TUNIT____: Function Attrs: nofree nosync nounwind 214; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1 215; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { 216; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i1, align 1 217; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 218; IS__TUNIT____: t: 219; IS__TUNIT____-NEXT: [[P:%.*]] = load i1*, i1** @G1, align 8 220; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] 221; IS__TUNIT____-NEXT: ret i1 [[CMP]] 222; IS__TUNIT____: f: 223; IS__TUNIT____-NEXT: store i1* [[A]], i1** @G1, align 8 224; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR4]] 225; IS__TUNIT____-NEXT: ret i1 [[CALL]] 226; 227; IS__CGSCC____: Function Attrs: nofree nosync nounwind 228; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global1 229; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 230; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i1, align 1 231; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 232; IS__CGSCC____: t: 233; IS__CGSCC____-NEXT: [[P:%.*]] = load i1*, i1** @G1, align 8 234; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] 235; IS__CGSCC____-NEXT: ret i1 [[CMP]] 236; IS__CGSCC____: f: 237; IS__CGSCC____-NEXT: store i1* [[A]], i1** @G1, align 8 238; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 noundef true) #[[ATTR3]] 239; IS__CGSCC____-NEXT: ret i1 [[CALL]] 240; 241 %a = alloca i1 242 br i1 %c, label %t, label %f 243t: 244 %p = load i1*, i1** @G1 245 %cmp = icmp eq i1* %a, %p 246 ret i1 %cmp 247f: 248 store i1* %a, i1** @G1 249 %call = call i1 @recursive_alloca_compare_global1(i1 true) 250 ret i1 %call 251} 252 253; FIXME: This should *not* return true. 254define i1 @recursive_alloca_compare_caller_global1(i1 %c) { 255; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind 256; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global1 257; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR5:[0-9]+]] { 258; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR4]] 259; IS__TUNIT____-NEXT: ret i1 [[CALL]] 260; 261; IS__CGSCC____: Function Attrs: nofree nosync nounwind 262; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global1 263; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 264; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global1(i1 [[C]]) #[[ATTR5]] 265; IS__CGSCC____-NEXT: ret i1 [[CALL]] 266; 267 %call = call i1 @recursive_alloca_compare_global1(i1 %c) 268 ret i1 %call 269} 270 271define internal i1 @recursive_alloca_compare_global2(i1 %c) { 272; IS__TUNIT____: Function Attrs: nofree nosync nounwind 273; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2 274; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { 275; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i1, align 1 276; IS__TUNIT____-NEXT: [[P:%.*]] = load i1*, i1** @G2, align 8 277; IS__TUNIT____-NEXT: store i1* [[A]], i1** @G2, align 8 278; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 279; IS__TUNIT____: t: 280; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] 281; IS__TUNIT____-NEXT: ret i1 [[CMP]] 282; IS__TUNIT____: f: 283; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR4]] 284; IS__TUNIT____-NEXT: ret i1 [[CALL]] 285; 286; IS__CGSCC____: Function Attrs: nofree nosync nounwind 287; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_global2 288; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 289; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i1, align 1 290; IS__CGSCC____-NEXT: [[P:%.*]] = load i1*, i1** @G2, align 8 291; IS__CGSCC____-NEXT: store i1* [[A]], i1** @G2, align 8 292; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 293; IS__CGSCC____: t: 294; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i1* [[A]], [[P]] 295; IS__CGSCC____-NEXT: ret i1 [[CMP]] 296; IS__CGSCC____: f: 297; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 noundef true) #[[ATTR3]] 298; IS__CGSCC____-NEXT: ret i1 [[CALL]] 299; 300 %a = alloca i1 301 %p = load i1*, i1** @G2 302 store i1* %a, i1** @G2 303 br i1 %c, label %t, label %f 304t: 305 %cmp = icmp eq i1* %a, %p 306 ret i1 %cmp 307f: 308 %call = call i1 @recursive_alloca_compare_global2(i1 true) 309 ret i1 %call 310} 311 312; FIXME: This should *not* return true. 313define i1 @recursive_alloca_compare_caller_global2(i1 %c) { 314; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind 315; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global2 316; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR5]] { 317; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR4]] 318; IS__TUNIT____-NEXT: ret i1 [[CALL]] 319; 320; IS__CGSCC____: Function Attrs: nofree nosync nounwind 321; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_alloca_compare_caller_global2 322; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 323; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_alloca_compare_global2(i1 [[C]]) #[[ATTR5]] 324; IS__CGSCC____-NEXT: ret i1 [[CALL]] 325; 326 %call = call i1 @recursive_alloca_compare_global2(i1 %c) 327 ret i1 %call 328} 329define internal i1 @recursive_inst_compare_global3(i1 %c) { 330; 331; IS__TUNIT____: Function Attrs: nofree nosync nounwind 332; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_inst_compare_global3 333; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR4]] { 334; IS__TUNIT____-NEXT: [[P:%.*]] = load i1, i1* @G3, align 1 335; IS__TUNIT____-NEXT: store i1 [[C]], i1* @G3, align 1 336; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 337; IS__TUNIT____: t: 338; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i1 [[C]], [[P]] 339; IS__TUNIT____-NEXT: ret i1 [[CMP]] 340; IS__TUNIT____: f: 341; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR4]] 342; IS__TUNIT____-NEXT: ret i1 [[CALL]] 343; 344; IS__CGSCC____: Function Attrs: nofree nosync nounwind 345; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_inst_compare_global3 346; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 347; IS__CGSCC____-NEXT: [[P:%.*]] = load i1, i1* @G3, align 1 348; IS__CGSCC____-NEXT: store i1 [[C]], i1* @G3, align 1 349; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 350; IS__CGSCC____: t: 351; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i1 [[C]], [[P]] 352; IS__CGSCC____-NEXT: ret i1 [[CMP]] 353; IS__CGSCC____: f: 354; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 noundef true) #[[ATTR3]] 355; IS__CGSCC____-NEXT: ret i1 [[CALL]] 356; 357 %p = load i1, i1* @G3 358 store i1 %c, i1* @G3 359 br i1 %c, label %t, label %f 360t: 361 %cmp = icmp eq i1 %c, %p 362 ret i1 %cmp 363f: 364 %call = call i1 @recursive_inst_compare_global3(i1 true) 365 ret i1 %call 366} 367 368; FIXME: This should *not* return true. 369define i1 @recursive_inst_compare_caller_global3(i1 %c) { 370; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind 371; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_inst_compare_caller_global3 372; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR5]] { 373; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR4]] 374; IS__TUNIT____-NEXT: ret i1 [[CALL]] 375; 376; IS__CGSCC____: Function Attrs: nofree nosync nounwind 377; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_inst_compare_caller_global3 378; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 379; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i1 @recursive_inst_compare_global3(i1 [[C]]) #[[ATTR5]] 380; IS__CGSCC____-NEXT: ret i1 [[CALL]] 381; 382 %call = call i1 @recursive_inst_compare_global3(i1 %c) 383 ret i1 %call 384} 385;. 386; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } 387; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone } 388; IS__TUNIT____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind readnone } 389; IS__TUNIT____: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind } 390; IS__TUNIT____: attributes #[[ATTR4]] = { nofree nosync nounwind } 391; IS__TUNIT____: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind } 392; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind readnone } 393;. 394; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } 395; IS__CGSCC____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone } 396; IS__CGSCC____: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind } 397; IS__CGSCC____: attributes #[[ATTR3]] = { nofree nosync nounwind } 398; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind readnone } 399; IS__CGSCC____: attributes #[[ATTR5]] = { nounwind } 400;. 401