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=4 -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=4 -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 "align" attribute. 10; We use FIXME's to indicate problems and missing attributes. 11 12 13; TEST 1 14;; 15;. 16; CHECK: @[[A1:[a-zA-Z0-9_$"\\.-]+]] = common global i8 0, align 8 17; CHECK: @[[A2:[a-zA-Z0-9_$"\\.-]+]] = common global i8 0, align 16 18; CHECK: @[[CND:[a-zA-Z0-9_$"\\.-]+]] = external global i1 19; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = global i8 0, align 32 20;. 21define i32* @test1(i32* align 8 %0) #0 { 22; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 23; CHECK-LABEL: define {{[^@]+}}@test1 24; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { 25; CHECK-NEXT: ret i32* [[TMP0]] 26; 27 ret i32* %0 28} 29 30; TEST 2 31define i32* @test2(i32* %0) #0 { 32; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 33; CHECK-LABEL: define {{[^@]+}}@test2 34; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]]) #[[ATTR0]] { 35; CHECK-NEXT: ret i32* [[TMP0]] 36; 37 ret i32* %0 38} 39 40; TEST 3 41define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 { 42; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 43; CHECK-LABEL: define {{[^@]+}}@test3 44; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) #[[ATTR0]] { 45; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] 46; CHECK-NEXT: ret i32* [[RET]] 47; 48 %ret = select i1 %2, i32* %0, i32* %1 49 ret i32* %ret 50} 51 52; TEST 4 53define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 { 54; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 55; CHECK-LABEL: define {{[^@]+}}@test4 56; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) #[[ATTR0]] { 57; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] 58; CHECK-NEXT: ret i32* [[RET]] 59; 60 %ret = select i1 %2, i32* %0, i32* %1 61 ret i32* %ret 62} 63 64; TEST 5 65declare i32* @unknown() 66declare align 8 i32* @align8() 67 68 69define i32* @test5_1() { 70; CHECK-LABEL: define {{[^@]+}}@test5_1() { 71; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @unknown() 72; CHECK-NEXT: ret i32* [[RET]] 73; 74 %ret = tail call align 8 i32* @unknown() 75 ret i32* %ret 76} 77 78define i32* @test5_2() { 79; CHECK-LABEL: define {{[^@]+}}@test5_2() { 80; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @align8() 81; CHECK-NEXT: ret i32* [[RET]] 82; 83 %ret = tail call i32* @align8() 84 ret i32* %ret 85} 86 87; TEST 6 88; SCC 89define i32* @test6_1() #0 { 90; NOT_CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable 91; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1 92; NOT_CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] { 93; NOT_CGSCC_NPM-NEXT: ret i32* undef 94; 95; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 96; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1 97; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 98; IS__CGSCC_NPM-NEXT: ret i32* undef 99; 100 %ret = tail call i32* @test6_2() 101 ret i32* %ret 102} 103 104define i32* @test6_2() #0 { 105; NOT_CGSCC_NPM: Function Attrs: nofree noinline nosync nounwind readnone willreturn uwtable 106; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2 107; NOT_CGSCC_NPM-SAME: () #[[ATTR1]] { 108; NOT_CGSCC_NPM-NEXT: ret i32* undef 109; 110; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 111; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2 112; IS__CGSCC_NPM-SAME: () #[[ATTR0]] { 113; IS__CGSCC_NPM-NEXT: ret i32* undef 114; 115 %ret = tail call i32* @test6_1() 116 ret i32* %ret 117} 118 119 120; char a1 __attribute__((aligned(8))); 121; char a2 __attribute__((aligned(16))); 122; 123; char* f1(char* a ){ 124; return a?a:f2(&a1); 125; } 126; char* f2(char* a){ 127; return a?f1(a):f3(&a2); 128; } 129; 130; char* f3(char* a){ 131; return a?&a1: f1(&a2); 132; } 133 134@a1 = common global i8 0, align 8 135@a2 = common global i8 0, align 16 136 137; Function Attrs: nounwind readnone ssp uwtable 138define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { 139; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 140; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 141; IS__CGSCC____-SAME: (i8* noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { 142; IS__CGSCC____-NEXT: br label [[TMP3:%.*]] 143; IS__CGSCC____: 2: 144; IS__CGSCC____-NEXT: unreachable 145; IS__CGSCC____: 3: 146; IS__CGSCC____-NEXT: ret i8* [[TMP0]] 147; 148 %2 = icmp eq i8* %0, null 149 br i1 %2, label %3, label %5 150 151; <label>:3: ; preds = %1 152 %4 = tail call i8* @f2(i8* nonnull @a1) 153 %l = load i8, i8* %4 154 br label %5 155 156; <label>:5: ; preds = %1, %3 157 %6 = phi i8* [ %4, %3 ], [ %0, %1 ] 158 ret i8* %6 159} 160 161; Function Attrs: nounwind readnone ssp uwtable 162define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 { 163; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable 164; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2 165; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { 166; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 167; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] 168; IS__CGSCC_OPM: 3: 169; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = tail call i8* @f1(i8* noalias noundef nonnull readnone align 4294967296 dereferenceable(4294967295) [[TMP0]]) 170; IS__CGSCC_OPM-NEXT: br label [[TMP7:%.*]] 171; IS__CGSCC_OPM: 5: 172; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = tail call i8* @f3(i8* nonnull @a2) 173; IS__CGSCC_OPM-NEXT: br label [[TMP7]] 174; IS__CGSCC_OPM: 7: 175; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ] 176; IS__CGSCC_OPM-NEXT: ret i8* [[TMP8]] 177; 178; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable 179; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2 180; IS__CGSCC_NPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { 181; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 182; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]] 183; IS__CGSCC_NPM: 3: 184; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = tail call i8* @f1(i8* noalias noundef nonnull readnone align 4294967296 dereferenceable(4294967295) [[TMP0]]) 185; IS__CGSCC_NPM-NEXT: br label [[TMP7:%.*]] 186; IS__CGSCC_NPM: 5: 187; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = tail call i8* @f3() 188; IS__CGSCC_NPM-NEXT: br label [[TMP7]] 189; IS__CGSCC_NPM: 7: 190; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ] 191; IS__CGSCC_NPM-NEXT: ret i8* [[TMP8]] 192; 193 %2 = icmp eq i8* %0, null 194 br i1 %2, label %5, label %3 195 196; <label>:3: ; preds = %1 197 198 %4 = tail call i8* @f1(i8* nonnull %0) 199 br label %7 200 201; <label>:5: ; preds = %1 202 %6 = tail call i8* @f3(i8* nonnull @a2) 203 br label %7 204 205; <label>:7: ; preds = %5, %3 206 %8 = phi i8* [ %4, %3 ], [ %6, %5 ] 207 ret i8* %8 208} 209 210; Function Attrs: nounwind readnone ssp uwtable 211define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { 212; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable 213; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3 214; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { 215; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 216; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 217; IS__CGSCC_OPM: 3: 218; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = tail call i8* @f1(i8* noalias noundef nonnull readnone align 16 dereferenceable(1) @a2) 219; IS__CGSCC_OPM-NEXT: br label [[TMP5]] 220; IS__CGSCC_OPM: 5: 221; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ @a1, [[TMP1:%.*]] ] 222; IS__CGSCC_OPM-NEXT: ret i8* [[TMP6]] 223; 224; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 225; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3 226; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] { 227; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]] 228; IS__CGSCC_NPM: 1: 229; IS__CGSCC_NPM-NEXT: unreachable 230; IS__CGSCC_NPM: 2: 231; IS__CGSCC_NPM-NEXT: ret i8* @a1 232; 233 %2 = icmp eq i8* %0, null 234 br i1 %2, label %3, label %5 235 236; <label>:3: ; preds = %1 237 %4 = tail call i8* @f1(i8* nonnull @a2) 238 br label %5 239 240; <label>:5: ; preds = %1, %3 241 %6 = phi i8* [ %4, %3 ], [ @a1, %1 ] 242 ret i8* %6 243} 244 245; TEST 7 246; Better than IR information 247define align 4 i8* @test7() #0 { 248; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 249; CHECK-LABEL: define {{[^@]+}}@test7 250; CHECK-SAME: () #[[ATTR0]] { 251; CHECK-NEXT: ret i8* @a1 252; 253 %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1) 254 ret i8* %c 255} 256 257; TEST 7b 258; Function Attrs: nounwind readnone ssp uwtable 259define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { 260; IS__CGSCC_OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 261; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b 262; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { 263; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]] 264; IS__CGSCC_OPM: 2: 265; IS__CGSCC_OPM-NEXT: unreachable 266; IS__CGSCC_OPM: 3: 267; IS__CGSCC_OPM-NEXT: ret i8* undef 268; 269; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 270; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b 271; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] { 272; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]] 273; IS__CGSCC_NPM: 1: 274; IS__CGSCC_NPM-NEXT: unreachable 275; IS__CGSCC_NPM: 2: 276; IS__CGSCC_NPM-NEXT: ret i8* undef 277; 278 %2 = icmp eq i8* %0, null 279 br i1 %2, label %3, label %5 280 281; <label>:3: ; preds = %1 282 %4 = tail call i8* @f2b(i8* nonnull @a1) 283 %l = load i8, i8* %4 284 store i8 %l, i8* @a1 285 br label %5 286 287; <label>:5: ; preds = %1, %3 288 %6 = phi i8* [ %4, %3 ], [ %0, %1 ] 289 ret i8* %6 290} 291 292; Function Attrs: nounwind readnone ssp uwtable 293define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 { 294; 295; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable 296; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f2b 297; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { 298; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 299; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] 300; IS__CGSCC_OPM: 3: 301; IS__CGSCC_OPM-NEXT: br label [[TMP6:%.*]] 302; IS__CGSCC_OPM: 4: 303; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = tail call i8* @f3b(i8* nonnull @a2) 304; IS__CGSCC_OPM-NEXT: br label [[TMP6]] 305; IS__CGSCC_OPM: 6: 306; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i8* [ undef, [[TMP3]] ], [ [[TMP5]], [[TMP4]] ] 307; IS__CGSCC_OPM-NEXT: ret i8* [[TMP7]] 308; 309; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable 310; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2b 311; IS__CGSCC_NPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] { 312; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 313; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] 314; IS__CGSCC_NPM: 3: 315; IS__CGSCC_NPM-NEXT: br label [[TMP6:%.*]] 316; IS__CGSCC_NPM: 4: 317; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = tail call i8* @f3b() 318; IS__CGSCC_NPM-NEXT: br label [[TMP6]] 319; IS__CGSCC_NPM: 6: 320; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = phi i8* [ undef, [[TMP3]] ], [ [[TMP5]], [[TMP4]] ] 321; IS__CGSCC_NPM-NEXT: ret i8* [[TMP7]] 322; 323 %2 = icmp eq i8* %0, null 324 br i1 %2, label %5, label %3 325 326; <label>:3: ; preds = %1 327 328 %4 = tail call i8* @f1b(i8* nonnull %0) 329 br label %7 330 331; <label>:5: ; preds = %1 332 %6 = tail call i8* @f3b(i8* nonnull @a2) 333 br label %7 334 335; <label>:7: ; preds = %5, %3 336 %8 = phi i8* [ %4, %3 ], [ %6, %5 ] 337 ret i8* %8 338} 339 340; Function Attrs: nounwind readnone ssp uwtable 341define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 { 342; 343; IS__CGSCC_OPM: Function Attrs: noinline nounwind uwtable 344; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f3b 345; IS__CGSCC_OPM-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { 346; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 347; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] 348; IS__CGSCC_OPM: 3: 349; IS__CGSCC_OPM-NEXT: br label [[TMP4]] 350; IS__CGSCC_OPM: 4: 351; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = phi i8* [ @a2, [[TMP3]] ], [ @a1, [[TMP1:%.*]] ] 352; IS__CGSCC_OPM-NEXT: ret i8* [[TMP5]] 353; 354; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 355; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f3b 356; IS__CGSCC_NPM-SAME: () local_unnamed_addr #[[ATTR0]] { 357; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]] 358; IS__CGSCC_NPM: 1: 359; IS__CGSCC_NPM-NEXT: unreachable 360; IS__CGSCC_NPM: 2: 361; IS__CGSCC_NPM-NEXT: ret i8* @a1 362; 363 %2 = icmp eq i8* %0, null 364 br i1 %2, label %3, label %5 365 366; <label>:3: ; preds = %1 367 %4 = tail call i8* @f1b(i8* nonnull @a2) 368 br label %5 369 370; <label>:5: ; preds = %1, %3 371 %6 = phi i8* [ %4, %3 ], [ @a1, %1 ] 372 ret i8* %6 373} 374 375define align 4 i32* @test7b(i32* align 32 %p) #0 { 376; CHECK: Function Attrs: nofree noinline norecurse nosync nounwind readnone willreturn uwtable 377; CHECK-LABEL: define {{[^@]+}}@test7b 378; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR0]] { 379; CHECK-NEXT: ret i32* [[P]] 380; 381 tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1) 382 ret i32* %p 383} 384 385; TEST 8 386define void @test8_helper() { 387; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8_helper() { 388; NOT_CGSCC_OPM-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() 389; NOT_CGSCC_OPM-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() 390; NOT_CGSCC_OPM-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() 391; NOT_CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR2:[0-9]+]] 392; NOT_CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]] 393; NOT_CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR2]] 394; NOT_CGSCC_OPM-NEXT: ret void 395; 396; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8_helper() { 397; IS__CGSCC_OPM-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() 398; IS__CGSCC_OPM-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() 399; IS__CGSCC_OPM-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() 400; IS__CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone [[PTR0]]) #[[ATTR3:[0-9]+]] 401; IS__CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]] 402; IS__CGSCC_OPM-NEXT: tail call void @test8(i32* noalias nocapture readnone align 8 [[PTR2]], i32* noalias nocapture readnone align 4 [[PTR1]], i32* noalias nocapture readnone align 4 [[PTR1]]) #[[ATTR3]] 403; IS__CGSCC_OPM-NEXT: ret void 404; 405 %ptr0 = tail call i32* @unknown() 406 %ptr1 = tail call align 4 i32* @unknown() 407 %ptr2 = tail call align 8 i32* @unknown() 408 409 tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0) 410 tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1) 411 tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1) 412 ret void 413} 414 415declare void @user_i32_ptr(i32* nocapture readnone) nounwind 416define internal void @test8(i32* %a, i32* %b, i32* %c) { 417; NOT_CGSCC_OPM: Function Attrs: nounwind 418; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test8 419; NOT_CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR2]] { 420; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR2]] 421; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR2]] 422; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR2]] 423; NOT_CGSCC_OPM-NEXT: ret void 424; 425; IS__CGSCC_OPM: Function Attrs: nounwind 426; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8 427; IS__CGSCC_OPM-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) #[[ATTR3]] { 428; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) #[[ATTR3]] 429; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) #[[ATTR3]] 430; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) #[[ATTR3]] 431; IS__CGSCC_OPM-NEXT: ret void 432; 433 call void @user_i32_ptr(i32* %a) 434 call void @user_i32_ptr(i32* %b) 435 call void @user_i32_ptr(i32* %c) 436 ret void 437} 438 439declare void @test9_helper(i32* %A) 440define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) { 441; CHECK-LABEL: define {{[^@]+}}@test9_traversal 442; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8 [[C:%.*]]) { 443; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]] 444; CHECK-NEXT: call void @test9_helper(i32* align 4 [[SEL]]) 445; CHECK-NEXT: ret void 446; 447 %sel = select i1 %cnd, i32* %B, i32* %C 448 call void @test9_helper(i32* %sel) 449 ret void 450} 451 452; FIXME: This will work with an upcoming patch (D66618 or similar) 453; define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p) 454; FIXME: This will work with an upcoming patch (D66618 or similar) 455; store i32 1, i32* %r, align 32 456; FIXME: This will work with an upcoming patch (D66618 or similar) 457; store i32 -1, i32* %g1, align 32 458define i32* @test10a(i32* align 32 %p) { 459; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind 460; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10a 461; NOT_CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3:[0-9]+]] { 462; NOT_CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 463; NOT_CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 464; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 465; NOT_CGSCC_OPM: t: 466; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]] 467; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 468; NOT_CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 469; NOT_CGSCC_OPM-NEXT: br label [[E:%.*]] 470; NOT_CGSCC_OPM: f: 471; NOT_CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 472; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 473; NOT_CGSCC_OPM-NEXT: br label [[E]] 474; NOT_CGSCC_OPM: e: 475; NOT_CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] 476; NOT_CGSCC_OPM-NEXT: ret i32* [[PHI]] 477; 478; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind 479; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10a 480; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4:[0-9]+]] { 481; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 482; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 483; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 484; IS__CGSCC_OPM: t: 485; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10a(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]] 486; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 487; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 488; IS__CGSCC_OPM-NEXT: br label [[E:%.*]] 489; IS__CGSCC_OPM: f: 490; IS__CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 491; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 492; IS__CGSCC_OPM-NEXT: br label [[E]] 493; IS__CGSCC_OPM: e: 494; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] 495; IS__CGSCC_OPM-NEXT: ret i32* [[PHI]] 496; 497 %l = load i32, i32* %p 498 %c = icmp eq i32 %l, 0 499 br i1 %c, label %t, label %f 500t: 501 %r = call i32* @test10a(i32* %p) 502 store i32 1, i32* %r 503 %g0 = getelementptr i32, i32* %p, i32 8 504 br label %e 505f: 506 %g1 = getelementptr i32, i32* %p, i32 8 507 store i32 -1, i32* %g1 508 br label %e 509e: 510 %phi = phi i32* [%g0, %t], [%g1, %f] 511 ret i32* %phi 512} 513 514; FIXME: This will work with an upcoming patch (D66618 or similar) 515; define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p) 516; FIXME: This will work with an upcoming patch (D66618 or similar) 517; store i32 1, i32* %r, align 32 518; FIXME: This will work with an upcoming patch (D66618 or similar) 519; store i32 -1, i32* %g1, align 32 520define i32* @test10b(i32* align 32 %p) { 521; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind 522; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test10b 523; NOT_CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] { 524; NOT_CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 525; NOT_CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 526; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 527; NOT_CGSCC_OPM: t: 528; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR3]] 529; NOT_CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 530; NOT_CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 531; NOT_CGSCC_OPM-NEXT: br label [[E:%.*]] 532; NOT_CGSCC_OPM: f: 533; NOT_CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 534; NOT_CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 535; NOT_CGSCC_OPM-NEXT: br label [[E]] 536; NOT_CGSCC_OPM: e: 537; NOT_CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] 538; NOT_CGSCC_OPM-NEXT: ret i32* [[PHI]] 539; 540; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind 541; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test10b 542; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] { 543; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 544; IS__CGSCC_OPM-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 545; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 546; IS__CGSCC_OPM: t: 547; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 32 i32* @test10b(i32* nofree noundef nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) #[[ATTR4]] 548; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[R]], align 32 549; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 550; IS__CGSCC_OPM-NEXT: br label [[E:%.*]] 551; IS__CGSCC_OPM: f: 552; IS__CGSCC_OPM-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 553; IS__CGSCC_OPM-NEXT: store i32 -1, i32* [[G1]], align 32 554; IS__CGSCC_OPM-NEXT: br label [[E]] 555; IS__CGSCC_OPM: e: 556; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] 557; IS__CGSCC_OPM-NEXT: ret i32* [[PHI]] 558; 559 %l = load i32, i32* %p 560 %c = icmp eq i32 %l, 0 561 br i1 %c, label %t, label %f 562t: 563 %r = call i32* @test10b(i32* %p) 564 store i32 1, i32* %r 565 %g0 = getelementptr i32, i32* %p, i32 8 566 br label %e 567f: 568 %g1 = getelementptr i32, i32* %p, i32 -8 569 store i32 -1, i32* %g1 570 br label %e 571e: 572 %phi = phi i32* [%g0, %t], [%g1, %f] 573 ret i32* %phi 574} 575 576 577define i64 @test11(i32* %p) { 578; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 579; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test11 580; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR4:[0-9]+]] { 581; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 582; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 583; NOT_CGSCC_OPM-NEXT: ret i64 [[RET]] 584; 585; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 586; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test11 587; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) #[[ATTR5:[0-9]+]] { 588; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 589; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 590; IS__CGSCC_OPM-NEXT: ret i64 [[RET]] 591; 592 %p-cast = bitcast i32* %p to i64* 593 %ret = load i64, i64* %p-cast, align 8 594 ret i64 %ret 595} 596 597; TEST 12 598; Test for deduction using must-be-executed-context and GEP instruction 599 600; FXIME: %p should have nonnull 601define i64 @test12-1(i32* align 4 %p) { 602; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 603; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-1 604; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR4]] { 605; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 606; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 607; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 608; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 609; NOT_CGSCC_OPM-NEXT: ret i64 [[RET]] 610; 611; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 612; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-1 613; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) #[[ATTR5]] { 614; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 615; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 616; IS__CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 617; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 618; IS__CGSCC_OPM-NEXT: ret i64 [[RET]] 619; 620 %p-cast = bitcast i32* %p to i64* 621 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 622 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 623 %ret = load i64, i64* %arrayidx1, align 16 624 ret i64 %ret 625} 626 627define i64 @test12-2(i32* align 4 %p) { 628; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 629; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-2 630; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR4]] { 631; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 632; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 633; NOT_CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 634; NOT_CGSCC_OPM-NEXT: ret i64 [[RET]] 635; 636; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 637; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-2 638; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { 639; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 640; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 641; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 642; IS__CGSCC_OPM-NEXT: ret i64 [[RET]] 643; 644 %p-cast = bitcast i32* %p to i64* 645 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 646 %ret = load i64, i64* %arrayidx0, align 16 647 ret i64 %ret 648} 649 650; FXIME: %p should have nonnull 651define void @test12-3(i32* align 4 %p) { 652; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 653; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-3 654; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR5:[0-9]+]] { 655; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 656; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 657; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 658; NOT_CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 659; NOT_CGSCC_OPM-NEXT: ret void 660; 661; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 662; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-3 663; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { 664; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 665; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 666; IS__CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 667; IS__CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 668; IS__CGSCC_OPM-NEXT: ret void 669; 670 %p-cast = bitcast i32* %p to i64* 671 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 672 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 673 store i64 0, i64* %arrayidx1, align 16 674 ret void 675} 676 677define void @test12-4(i32* align 4 %p) { 678; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 679; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-4 680; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR5]] { 681; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 682; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 683; NOT_CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 684; NOT_CGSCC_OPM-NEXT: ret void 685; 686; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 687; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-4 688; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) #[[ATTR6]] { 689; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 690; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 691; IS__CGSCC_OPM-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 692; IS__CGSCC_OPM-NEXT: ret void 693; 694 %p-cast = bitcast i32* %p to i64* 695 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 696 store i64 0, i64* %arrayidx0, align 16 697 ret void 698} 699 700declare void @use(i64*) willreturn nounwind 701 702define void @test12-5(i32* align 4 %p) { 703; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 704; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-5 705; NOT_CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6:[0-9]+]] { 706; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 707; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 708; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 709; NOT_CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR6]] 710; NOT_CGSCC_OPM-NEXT: ret void 711; 712; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 713; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-5 714; IS__CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7:[0-9]+]] { 715; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 716; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 717; IS__CGSCC_OPM-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 718; IS__CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) #[[ATTR7]] 719; IS__CGSCC_OPM-NEXT: ret void 720; 721 %p-cast = bitcast i32* %p to i64* 722 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 723 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 724 tail call void @use(i64* align 16 %arrayidx1) 725 ret void 726} 727 728define void @test12-6(i32* align 4 %p) { 729; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn 730; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test12-6 731; NOT_CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR6]] { 732; NOT_CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 733; NOT_CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 734; NOT_CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR6]] 735; NOT_CGSCC_OPM-NEXT: ret void 736; 737; IS__CGSCC_OPM: Function Attrs: nounwind willreturn 738; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test12-6 739; IS__CGSCC_OPM-SAME: (i32* align 16 [[P:%.*]]) #[[ATTR7]] { 740; IS__CGSCC_OPM-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 741; IS__CGSCC_OPM-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 742; IS__CGSCC_OPM-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) #[[ATTR7]] 743; IS__CGSCC_OPM-NEXT: ret void 744; 745 %p-cast = bitcast i32* %p to i64* 746 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 747 tail call void @use(i64* align 16 %arrayidx0) 748 ret void 749} 750 751define void @test13(i1 %c, i32* align 32 %dst) #0 { 752; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable 753; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13 754; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR7:[0-9]+]] { 755; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 756; NOT_CGSCC_OPM: truebb: 757; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] 758; NOT_CGSCC_OPM: falsebb: 759; NOT_CGSCC_OPM-NEXT: br label [[END]] 760; NOT_CGSCC_OPM: end: 761; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] 762; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 763; NOT_CGSCC_OPM-NEXT: ret void 764; 765; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable 766; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13 767; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { 768; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 769; IS__CGSCC_OPM: truebb: 770; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] 771; IS__CGSCC_OPM: falsebb: 772; IS__CGSCC_OPM-NEXT: br label [[END]] 773; IS__CGSCC_OPM: end: 774; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] 775; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 776; IS__CGSCC_OPM-NEXT: ret void 777; 778 br i1 %c, label %truebb, label %falsebb 779truebb: 780 br label %end 781falsebb: 782 br label %end 783end: 784 %ptr = phi i32* [ %dst, %truebb ], [ null, %falsebb ] 785 store i32 0, i32* %ptr 786 ret void 787} 788 789define void @test13-1(i1 %c, i32* align 32 %dst) { 790; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly 791; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-1 792; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8:[0-9]+]] { 793; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 794; NOT_CGSCC_OPM: truebb: 795; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] 796; NOT_CGSCC_OPM: falsebb: 797; NOT_CGSCC_OPM-NEXT: br label [[END]] 798; NOT_CGSCC_OPM: end: 799; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] 800; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 16 801; NOT_CGSCC_OPM-NEXT: ret void 802; 803; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly 804; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-1 805; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9:[0-9]+]] { 806; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 807; IS__CGSCC_OPM: truebb: 808; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] 809; IS__CGSCC_OPM: falsebb: 810; IS__CGSCC_OPM-NEXT: br label [[END]] 811; IS__CGSCC_OPM: end: 812; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] 813; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 16 814; IS__CGSCC_OPM-NEXT: ret void 815; 816 br i1 %c, label %truebb, label %falsebb 817truebb: 818 br label %end 819falsebb: 820 br label %end 821end: 822 %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 48 to i32*), %falsebb ] 823 store i32 0, i32* %ptr 824 ret void 825} 826 827define void @test13-2(i1 %c, i32* align 32 %dst) { 828; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly 829; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-2 830; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { 831; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 832; NOT_CGSCC_OPM: truebb: 833; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] 834; NOT_CGSCC_OPM: falsebb: 835; NOT_CGSCC_OPM-NEXT: br label [[END]] 836; NOT_CGSCC_OPM: end: 837; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] 838; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 839; NOT_CGSCC_OPM-NEXT: ret void 840; 841; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly 842; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-2 843; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { 844; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 845; IS__CGSCC_OPM: truebb: 846; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] 847; IS__CGSCC_OPM: falsebb: 848; IS__CGSCC_OPM-NEXT: br label [[END]] 849; IS__CGSCC_OPM: end: 850; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] 851; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 852; IS__CGSCC_OPM-NEXT: ret void 853; 854 br i1 %c, label %truebb, label %falsebb 855truebb: 856 br label %end 857falsebb: 858 br label %end 859end: 860 %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 160 to i32*), %falsebb ] 861 store i32 0, i32* %ptr 862 ret void 863} 864 865define void @test13-3(i1 %c, i32* align 32 %dst) { 866; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly 867; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13-3 868; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR8]] { 869; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 870; NOT_CGSCC_OPM: truebb: 871; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] 872; NOT_CGSCC_OPM: falsebb: 873; NOT_CGSCC_OPM-NEXT: br label [[END]] 874; NOT_CGSCC_OPM: end: 875; NOT_CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] 876; NOT_CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 877; NOT_CGSCC_OPM-NEXT: ret void 878; 879; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly 880; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13-3 881; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) #[[ATTR9]] { 882; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 883; IS__CGSCC_OPM: truebb: 884; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] 885; IS__CGSCC_OPM: falsebb: 886; IS__CGSCC_OPM-NEXT: br label [[END]] 887; IS__CGSCC_OPM: end: 888; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] 889; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[PTR]], align 32 890; IS__CGSCC_OPM-NEXT: ret void 891; 892 br i1 %c, label %truebb, label %falsebb 893truebb: 894 br label %end 895falsebb: 896 br label %end 897end: 898 %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 128 to i32*), %falsebb ] 899 store i32 0, i32* %ptr 900 ret void 901} 902 903; Don't crash on ptr2int/int2ptr uses. 904define i64 @ptr2int(i32* %p) { 905; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 906; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@ptr2int 907; NOT_CGSCC_OPM-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] { 908; NOT_CGSCC_OPM-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 909; NOT_CGSCC_OPM-NEXT: ret i64 [[P2I]] 910; 911; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 912; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ptr2int 913; IS__CGSCC_OPM-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR10:[0-9]+]] { 914; IS__CGSCC_OPM-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 915; IS__CGSCC_OPM-NEXT: ret i64 [[P2I]] 916; 917 %p2i = ptrtoint i32* %p to i64 918 ret i64 %p2i 919} 920define i64* @int2ptr(i64 %i) { 921; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 922; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@int2ptr 923; NOT_CGSCC_OPM-SAME: (i64 [[I:%.*]]) #[[ATTR9]] { 924; NOT_CGSCC_OPM-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* 925; NOT_CGSCC_OPM-NEXT: ret i64* [[I2P]] 926; 927; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 928; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@int2ptr 929; IS__CGSCC_OPM-SAME: (i64 [[I:%.*]]) #[[ATTR10]] { 930; IS__CGSCC_OPM-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* 931; IS__CGSCC_OPM-NEXT: ret i64* [[I2P]] 932; 933 %i2p = inttoptr i64 %i to i64* 934 ret i64* %i2p 935} 936 937; Use the store alignment only for the pointer operand. 938define void @aligned_store(i8* %Value, i8** %Ptr) { 939; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 940; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_store 941; NOT_CGSCC_OPM-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR5]] { 942; NOT_CGSCC_OPM-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 943; NOT_CGSCC_OPM-NEXT: ret void 944; 945; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 946; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_store 947; IS__CGSCC_OPM-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree noundef nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) #[[ATTR6]] { 948; IS__CGSCC_OPM-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 949; IS__CGSCC_OPM-NEXT: ret void 950; 951 store i8* %Value, i8** %Ptr, align 32 952 ret void 953} 954 955declare i8* @some_func(i8*) 956define void @align_call_op_not_store(i8* align 2048 %arg) { 957; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store 958; CHECK-SAME: (i8* align 2048 [[ARG:%.*]]) { 959; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]]) 960; CHECK-NEXT: store i8 0, i8* [[UNKNOWN]], align 1 961; CHECK-NEXT: ret void 962; 963 %unknown = call i8* @some_func(i8* %arg) 964 store i8 0, i8* %unknown 965 ret void 966} 967define void @align_store_after_bc(i32* align 2048 %arg) { 968; 969; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 970; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@align_store_after_bc 971; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR5]] { 972; NOT_CGSCC_OPM-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* 973; NOT_CGSCC_OPM-NEXT: store i8 0, i8* [[BC]], align 2048 974; NOT_CGSCC_OPM-NEXT: ret void 975; 976; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly 977; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@align_store_after_bc 978; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) #[[ATTR6]] { 979; IS__CGSCC_OPM-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* 980; IS__CGSCC_OPM-NEXT: store i8 0, i8* [[BC]], align 2048 981; IS__CGSCC_OPM-NEXT: ret void 982; 983 %bc = bitcast i32* %arg to i8* 984 store i8 0, i8* %bc 985 ret void 986} 987 988; Make sure we do not annotate the callee of a must-tail call with an alignment 989; we cannot also put on the caller. 990@cnd = external global i1 991define i32 @musttail_callee_1(i32* %p) { 992; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 993; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_callee_1 994; NOT_CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR4]] { 995; NOT_CGSCC_OPM-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 996; NOT_CGSCC_OPM-NEXT: ret i32 [[V]] 997; 998; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn 999; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_callee_1 1000; IS__CGSCC_OPM-SAME: (i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P:%.*]]) #[[ATTR5]] { 1001; IS__CGSCC_OPM-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 1002; IS__CGSCC_OPM-NEXT: ret i32 [[V]] 1003; 1004 %v = load i32, i32* %p, align 32 1005 ret i32 %v 1006} 1007define i32 @musttail_caller_1(i32* %p) { 1008; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn 1009; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1 1010; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] { 1011; IS__TUNIT____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 1012; IS__TUNIT____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] 1013; IS__TUNIT____: mt: 1014; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) #[[ATTR11:[0-9]+]] 1015; IS__TUNIT____-NEXT: ret i32 [[V]] 1016; IS__TUNIT____: exit: 1017; IS__TUNIT____-NEXT: ret i32 0 1018; 1019; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn 1020; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@musttail_caller_1 1021; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR11:[0-9]+]] { 1022; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 1023; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] 1024; IS__CGSCC_OPM: mt: 1025; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR12:[0-9]+]] 1026; IS__CGSCC_OPM-NEXT: ret i32 [[V]] 1027; IS__CGSCC_OPM: exit: 1028; IS__CGSCC_OPM-NEXT: ret i32 0 1029; 1030; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn 1031; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@musttail_caller_1 1032; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) #[[ATTR10:[0-9]+]] { 1033; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 1034; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] 1035; IS__CGSCC_NPM: mt: 1036; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR11:[0-9]+]] 1037; IS__CGSCC_NPM-NEXT: ret i32 [[V]] 1038; IS__CGSCC_NPM: exit: 1039; IS__CGSCC_NPM-NEXT: ret i32 0 1040; 1041 %c = load i1, i1* @cnd 1042 br i1 %c, label %mt, label %exit 1043mt: 1044 %v = musttail call i32 @musttail_callee_1(i32* %p) 1045 ret i32 %v 1046exit: 1047 ret i32 0 1048} 1049 1050define i32* @checkAndAdvance(i32* align(16) %p) { 1051; NOT_CGSCC_OPM: Function Attrs: nounwind 1052; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance 1053; NOT_CGSCC_OPM-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR2]] { 1054; NOT_CGSCC_OPM-NEXT: entry: 1055; NOT_CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16 1056; NOT_CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 1057; NOT_CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 1058; NOT_CGSCC_OPM: if.then: 1059; NOT_CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 1060; NOT_CGSCC_OPM-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR2]] 1061; NOT_CGSCC_OPM-NEXT: br label [[RETURN]] 1062; NOT_CGSCC_OPM: return: 1063; NOT_CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ] 1064; NOT_CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR2]] 1065; NOT_CGSCC_OPM-NEXT: ret i32* [[RETVAL_0]] 1066; 1067; IS__CGSCC_OPM: Function Attrs: nounwind 1068; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@checkAndAdvance 1069; IS__CGSCC_OPM-SAME: (i32* noundef nonnull readonly align 16 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR3]] { 1070; IS__CGSCC_OPM-NEXT: entry: 1071; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 16 1072; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0 1073; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]] 1074; IS__CGSCC_OPM: if.then: 1075; IS__CGSCC_OPM-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 4 1076; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call nonnull align 16 i32* @checkAndAdvance(i32* nonnull readonly align 16 "no-capture-maybe-returned" [[ADD_PTR]]) #[[ATTR3]] 1077; IS__CGSCC_OPM-NEXT: br label [[RETURN]] 1078; IS__CGSCC_OPM: return: 1079; IS__CGSCC_OPM-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL]], [[IF_THEN]] ], [ [[P]], [[ENTRY:%.*]] ] 1080; IS__CGSCC_OPM-NEXT: call void @user_i32_ptr(i32* noalias nocapture nonnull readnone align 16 [[RETVAL_0]]) #[[ATTR3]] 1081; IS__CGSCC_OPM-NEXT: ret i32* [[RETVAL_0]] 1082; 1083entry: 1084 %0 = load i32, i32* %p, align 4 1085 %cmp = icmp eq i32 %0, 0 1086 br i1 %cmp, label %if.then, label %return 1087 1088if.then: ; preds = %entry 1089 %add.ptr = getelementptr inbounds i32, i32* %p, i64 4 1090 %call = call i32* @checkAndAdvance(i32* nonnull %add.ptr) 1091 br label %return 1092 1093return: ; preds = %entry, %if.then 1094 %retval.0 = phi i32* [ %call, %if.then ], [ %p, %entry ] 1095 call void @user_i32_ptr(i32* %retval.0) 1096 ret i32* %retval.0 1097} 1098 1099; FIXME: align 4 should not be propagated to the caller's p unless there is noundef 1100define void @align4_caller(i8* %p) { 1101; CHECK-LABEL: define {{[^@]+}}@align4_caller 1102; CHECK-SAME: (i8* align 4 [[P:%.*]]) { 1103; CHECK-NEXT: call void @align4_callee(i8* align 4 [[P]]) 1104; CHECK-NEXT: ret void 1105; 1106 call void @align4_callee(i8* %p) 1107 ret void 1108} 1109 1110declare void @align4_callee(i8* align(4) %p) 1111 1112@G = global i8 0, align 32 1113 1114define internal i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) norecurse { 1115; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1116; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return 1117; NOT_CGSCC_OPM-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { 1118; NOT_CGSCC_OPM-NEXT: [[STACK:%.*]] = alloca i8*, align 8 1119; NOT_CGSCC_OPM-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] 1120; NOT_CGSCC_OPM: t: 1121; NOT_CGSCC_OPM-NEXT: [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8 1122; NOT_CGSCC_OPM-NEXT: [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]] 1123; NOT_CGSCC_OPM-NEXT: store i8* [[SEL]], i8** [[STACK]], align 8 1124; NOT_CGSCC_OPM-NEXT: br label [[END:%.*]] 1125; NOT_CGSCC_OPM: f: 1126; NOT_CGSCC_OPM-NEXT: store i8* @G, i8** [[STACK]], align 8 1127; NOT_CGSCC_OPM-NEXT: br label [[END]] 1128; NOT_CGSCC_OPM: end: 1129; NOT_CGSCC_OPM-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 1130; NOT_CGSCC_OPM-NEXT: ret i8* [[L]] 1131; 1132; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1133; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return 1134; IS__CGSCC_OPM-SAME: (i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] { 1135; IS__CGSCC_OPM-NEXT: [[STACK:%.*]] = alloca i8*, align 8 1136; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] 1137; IS__CGSCC_OPM: t: 1138; IS__CGSCC_OPM-NEXT: [[GEP:%.*]] = getelementptr i8, i8* @G, i32 8 1139; IS__CGSCC_OPM-NEXT: [[SEL:%.*]] = select i1 [[C2]], i8* [[A]], i8* [[GEP]] 1140; IS__CGSCC_OPM-NEXT: store i8* [[SEL]], i8** [[STACK]], align 8 1141; IS__CGSCC_OPM-NEXT: br label [[END:%.*]] 1142; IS__CGSCC_OPM: f: 1143; IS__CGSCC_OPM-NEXT: store i8* @G, i8** [[STACK]], align 8 1144; IS__CGSCC_OPM-NEXT: br label [[END]] 1145; IS__CGSCC_OPM: end: 1146; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i8*, i8** [[STACK]], align 8 1147; IS__CGSCC_OPM-NEXT: ret i8* [[L]] 1148; 1149 %stack = alloca i8* 1150 br i1 %c1, label %t, label %f 1151t: 1152 %gep = getelementptr i8, i8* @G, i32 8 1153 %sel = select i1 %c2, i8* %a, i8* %gep 1154 store i8* %sel, i8** %stack 1155 br label %end 1156f: 1157 store i8* @G, i8** %stack 1158 br label %end 1159end: 1160 %l = load i8*, i8** %stack 1161 ret i8* %l 1162} 1163 1164define i8* @aligned_8_return_caller(i8* align(16) %a, i1 %c1, i1 %c2) { 1165; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1166; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return_caller 1167; NOT_CGSCC_OPM-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR9]] { 1168; NOT_CGSCC_OPM-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR12:[0-9]+]] 1169; NOT_CGSCC_OPM-NEXT: ret i8* [[R]] 1170; 1171; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 1172; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@aligned_8_return_caller 1173; IS__CGSCC_OPM-SAME: (i8* nofree readnone align 16 "no-capture-maybe-returned" [[A:%.*]], i1 [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR10]] { 1174; IS__CGSCC_OPM-NEXT: [[R:%.*]] = call align 8 i8* @aligned_8_return(i8* noalias nofree readnone align 16 "no-capture-maybe-returned" [[A]], i1 [[C1]], i1 [[C2]]) #[[ATTR13:[0-9]+]] 1175; IS__CGSCC_OPM-NEXT: ret i8* [[R]] 1176; 1177 %r = call i8* @aligned_8_return(i8* %a, i1 %c1, i1 %c2) 1178 ret i8* %r 1179} 1180 1181attributes #0 = { nounwind uwtable noinline } 1182attributes #1 = { uwtable noinline } 1183attributes #2 = { null_pointer_is_valid } 1184;. 1185; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1186; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable } 1187; IS__TUNIT____: attributes #[[ATTR2]] = { nounwind } 1188; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind } 1189; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1190; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } 1191; IS__TUNIT____: attributes #[[ATTR6]] = { nounwind willreturn } 1192; IS__TUNIT____: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } 1193; IS__TUNIT____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } 1194; IS__TUNIT____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn } 1195; IS__TUNIT____: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn } 1196; IS__TUNIT____: attributes #[[ATTR11]] = { nofree nosync nounwind readonly willreturn } 1197; IS__TUNIT____: attributes #[[ATTR12]] = { nofree nosync nounwind readnone willreturn } 1198;. 1199; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1200; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone willreturn uwtable } 1201; IS__CGSCC_OPM: attributes #[[ATTR2]] = { noinline nounwind uwtable } 1202; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nounwind } 1203; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nofree nosync nounwind } 1204; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1205; IS__CGSCC_OPM: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } 1206; IS__CGSCC_OPM: attributes #[[ATTR7]] = { nounwind willreturn } 1207; IS__CGSCC_OPM: attributes #[[ATTR8]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } 1208; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly } 1209; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn } 1210; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readonly willreturn } 1211; IS__CGSCC_OPM: attributes #[[ATTR12]] = { readonly willreturn } 1212; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readnone willreturn } 1213;. 1214; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone willreturn uwtable } 1215; IS__CGSCC_NPM: attributes #[[ATTR1]] = { noinline nounwind uwtable } 1216; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nounwind } 1217; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind } 1218; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind readonly willreturn } 1219; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly } 1220; IS__CGSCC_NPM: attributes #[[ATTR6]] = { nounwind willreturn } 1221; IS__CGSCC_NPM: attributes #[[ATTR7]] = { argmemonly nofree noinline norecurse nosync nounwind willreturn writeonly uwtable } 1222; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind willreturn writeonly } 1223; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone willreturn } 1224; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readonly willreturn } 1225; IS__CGSCC_NPM: attributes #[[ATTR11]] = { readonly willreturn } 1226; IS__CGSCC_NPM: attributes #[[ATTR12]] = { readnone willreturn } 1227;. 1228