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