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