1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes 2; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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 14define i32* @test1(i32* align 8 %0) #0 { 15; CHECK-LABEL: define {{[^@]+}}@test1 16; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]]) 17; CHECK-NEXT: ret i32* [[TMP0]] 18; 19 ret i32* %0 20} 21 22; TEST 2 23define i32* @test2(i32* %0) #0 { 24; CHECK-LABEL: define {{[^@]+}}@test2 25; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]]) 26; CHECK-NEXT: ret i32* [[TMP0]] 27; 28 ret i32* %0 29} 30 31; TEST 3 32define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 { 33; CHECK-LABEL: define {{[^@]+}}@test3 34; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) 35; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] 36; CHECK-NEXT: ret i32* [[RET]] 37; 38 %ret = select i1 %2, i32* %0, i32* %1 39 ret i32* %ret 40} 41 42; TEST 4 43define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 { 44; CHECK-LABEL: define {{[^@]+}}@test4 45; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) 46; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]] 47; CHECK-NEXT: ret i32* [[RET]] 48; 49 %ret = select i1 %2, i32* %0, i32* %1 50 ret i32* %ret 51} 52 53; TEST 5 54declare i32* @unknown() 55declare align 8 i32* @align8() 56 57 58define i32* @test5_1() { 59; CHECK-LABEL: define {{[^@]+}}@test5_1() 60; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @unknown() 61; CHECK-NEXT: ret i32* [[RET]] 62; 63 %ret = tail call align 8 i32* @unknown() 64 ret i32* %ret 65} 66 67define i32* @test5_2() { 68; CHECK-LABEL: define {{[^@]+}}@test5_2() 69; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @align8() 70; CHECK-NEXT: ret i32* [[RET]] 71; 72 %ret = tail call i32* @align8() 73 ret i32* %ret 74} 75 76; TEST 6 77; SCC 78define i32* @test6_1() #0 { 79; CHECK-LABEL: define {{[^@]+}}@test6_1() 80; CHECK-NEXT: unreachable 81; 82 %ret = tail call i32* @test6_2() 83 ret i32* %ret 84} 85 86define i32* @test6_2() #0 { 87; CHECK-LABEL: define {{[^@]+}}@test6_2() 88; CHECK-NEXT: unreachable 89; 90 %ret = tail call i32* @test6_1() 91 ret i32* %ret 92} 93 94 95; char a1 __attribute__((aligned(8))); 96; char a2 __attribute__((aligned(16))); 97; 98; char* f1(char* a ){ 99; return a?a:f2(&a1); 100; } 101; char* f2(char* a){ 102; return a?f1(a):f3(&a2); 103; } 104; 105; char* f3(char* a){ 106; return a?&a1: f1(&a2); 107; } 108 109@a1 = common global i8 0, align 8 110@a2 = common global i8 0, align 16 111 112; Function Attrs: nounwind readnone ssp uwtable 113define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 { 114; IS__TUNIT____-LABEL: define {{[^@]+}}@f1 115; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr 116; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 117; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 118; IS__TUNIT____: 3: 119; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() 120; IS__TUNIT____-NEXT: br label [[TMP5]] 121; IS__TUNIT____: 5: 122; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] 123; IS__TUNIT____-NEXT: ret i8* [[TMP6]] 124; 125; IS__CGSCC____-LABEL: define {{[^@]+}}@f1 126; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr 127; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 128; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 129; IS__CGSCC____: 3: 130; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2() 131; IS__CGSCC____-NEXT: br label [[TMP5]] 132; IS__CGSCC____: 5: 133; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] 134; IS__CGSCC____-NEXT: ret i8* [[TMP6]] 135; 136 %2 = icmp eq i8* %0, null 137 br i1 %2, label %3, label %5 138 139; <label>:3: ; preds = %1 140 %4 = tail call i8* @f2(i8* nonnull @a1) 141 %l = load i8, i8* %4 142 br label %5 143 144; <label>:5: ; preds = %1, %3 145 %6 = phi i8* [ %4, %3 ], [ %0, %1 ] 146 ret i8* %6 147} 148 149; Function Attrs: nounwind readnone ssp uwtable 150define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 { 151; CHECK-LABEL: define {{[^@]+}}@f2() local_unnamed_addr 152; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null 153; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]] 154; CHECK: 2: 155; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) 156; CHECK-NEXT: br label [[TMP6:%.*]] 157; CHECK: 4: 158; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @f3() 159; CHECK-NEXT: br label [[TMP6]] 160; CHECK: 6: 161; CHECK-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ] 162; CHECK-NEXT: ret i8* [[TMP7]] 163; 164 %2 = icmp eq i8* %0, null 165 br i1 %2, label %5, label %3 166 167; <label>:3: ; preds = %1 168 169 %4 = tail call i8* @f1(i8* nonnull %0) 170 br label %7 171 172; <label>:5: ; preds = %1 173 %6 = tail call i8* @f3(i8* nonnull @a2) 174 br label %7 175 176; <label>:7: ; preds = %5, %3 177 %8 = phi i8* [ %4, %3 ], [ %6, %5 ] 178 ret i8* %8 179} 180 181; Function Attrs: nounwind readnone ssp uwtable 182define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 { 183; CHECK-LABEL: define {{[^@]+}}@f3() local_unnamed_addr 184; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null 185; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] 186; CHECK: 2: 187; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2) 188; CHECK-NEXT: br label [[TMP4]] 189; CHECK: 4: 190; CHECK-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ] 191; CHECK-NEXT: ret i8* [[TMP5]] 192; 193 %2 = icmp eq i8* %0, null 194 br i1 %2, label %3, label %5 195 196; <label>:3: ; preds = %1 197 %4 = tail call i8* @f1(i8* nonnull @a2) 198 br label %5 199 200; <label>:5: ; preds = %1, %3 201 %6 = phi i8* [ %4, %3 ], [ @a1, %1 ] 202 ret i8* %6 203} 204 205; TEST 7 206; Better than IR information 207define align 4 i8* @test7() #0 { 208; IS__TUNIT____-LABEL: define {{[^@]+}}@test7() 209; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) 210; IS__TUNIT____-NEXT: ret i8* [[C]] 211; 212; IS__CGSCC____-LABEL: define {{[^@]+}}@test7() 213; IS__CGSCC____-NEXT: [[C:%.*]] = tail call nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) 214; IS__CGSCC____-NEXT: ret i8* [[C]] 215; 216 %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1) 217 ret i8* %c 218} 219 220; TEST 7b 221; Function Attrs: nounwind readnone ssp uwtable 222define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 { 223; IS__TUNIT____-LABEL: define {{[^@]+}}@f1b 224; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr 225; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 226; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 227; IS__TUNIT____: 3: 228; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() 229; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 230; IS__TUNIT____-NEXT: store i8 [[L]], i8* @a1, align 8 231; IS__TUNIT____-NEXT: br label [[TMP5]] 232; IS__TUNIT____: 5: 233; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] 234; IS__TUNIT____-NEXT: ret i8* [[TMP6]] 235; 236; IS__CGSCC____-LABEL: define {{[^@]+}}@f1b 237; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr 238; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null 239; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]] 240; IS__CGSCC____: 3: 241; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b() 242; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8 243; IS__CGSCC____-NEXT: store i8 [[L]], i8* @a1, align 8 244; IS__CGSCC____-NEXT: br label [[TMP5]] 245; IS__CGSCC____: 5: 246; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ] 247; IS__CGSCC____-NEXT: ret i8* [[TMP6]] 248; 249 %2 = icmp eq i8* %0, null 250 br i1 %2, label %3, label %5 251 252; <label>:3: ; preds = %1 253 %4 = tail call i8* @f2b(i8* nonnull @a1) 254 %l = load i8, i8* %4 255 store i8 %l, i8* @a1 256 br label %5 257 258; <label>:5: ; preds = %1, %3 259 %6 = phi i8* [ %4, %3 ], [ %0, %1 ] 260 ret i8* %6 261} 262 263; Function Attrs: nounwind readnone ssp uwtable 264define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 { 265; 266; CHECK-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr 267; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null 268; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]] 269; CHECK: 2: 270; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) 271; CHECK-NEXT: br label [[TMP6:%.*]] 272; CHECK: 4: 273; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @f3b() 274; CHECK-NEXT: br label [[TMP6]] 275; CHECK: 6: 276; CHECK-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ [[TMP5]], [[TMP4]] ] 277; CHECK-NEXT: ret i8* [[TMP7]] 278; 279 %2 = icmp eq i8* %0, null 280 br i1 %2, label %5, label %3 281 282; <label>:3: ; preds = %1 283 284 %4 = tail call i8* @f1b(i8* nonnull %0) 285 br label %7 286 287; <label>:5: ; preds = %1 288 %6 = tail call i8* @f3b(i8* nonnull @a2) 289 br label %7 290 291; <label>:7: ; preds = %5, %3 292 %8 = phi i8* [ %4, %3 ], [ %6, %5 ] 293 ret i8* %8 294} 295 296; Function Attrs: nounwind readnone ssp uwtable 297define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 { 298; 299; CHECK-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr 300; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null 301; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]] 302; CHECK: 2: 303; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 16 dereferenceable(1) @a2) 304; CHECK-NEXT: br label [[TMP4]] 305; CHECK: 4: 306; CHECK-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1, [[TMP0:%.*]] ] 307; CHECK-NEXT: ret i8* [[TMP5]] 308; 309 %2 = icmp eq i8* %0, null 310 br i1 %2, label %3, label %5 311 312; <label>:3: ; preds = %1 313 %4 = tail call i8* @f1b(i8* nonnull @a2) 314 br label %5 315 316; <label>:5: ; preds = %1, %3 317 %6 = phi i8* [ %4, %3 ], [ @a1, %1 ] 318 ret i8* %6 319} 320 321define align 4 i32* @test7b(i32* align 32 %p) #0 { 322; CHECK-LABEL: define {{[^@]+}}@test7b 323; CHECK-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]]) 324; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1) 325; CHECK-NEXT: ret i32* [[P]] 326; 327 tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1) 328 ret i32* %p 329} 330 331; TEST 8 332define void @test8_helper() { 333; CHECK-LABEL: define {{[^@]+}}@test8_helper() 334; CHECK-NEXT: [[PTR0:%.*]] = tail call i32* @unknown() 335; CHECK-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown() 336; CHECK-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown() 337; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone [[PTR0]]) 338; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 8 [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]]) 339; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 8 [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone align 4 [[PTR1]]) 340; CHECK-NEXT: ret void 341; 342 %ptr0 = tail call i32* @unknown() 343 %ptr1 = tail call align 4 i32* @unknown() 344 %ptr2 = tail call align 8 i32* @unknown() 345 346 tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0) 347 tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1) 348 tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1) 349 ret void 350} 351 352declare void @user_i32_ptr(i32* nocapture readnone) nounwind 353define internal void @test8(i32* %a, i32* %b, i32* %c) { 354; IS__TUNIT____-LABEL: define {{[^@]+}}@test8 355; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]]) 356; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) 357; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) 358; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) 359; IS__TUNIT____-NEXT: ret void 360; 361; IS__CGSCC____-LABEL: define {{[^@]+}}@test8 362; IS__CGSCC____-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]]) 363; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]]) 364; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[B]]) 365; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]]) 366; IS__CGSCC____-NEXT: ret void 367; 368 call void @user_i32_ptr(i32* %a) 369 call void @user_i32_ptr(i32* %b) 370 call void @user_i32_ptr(i32* %c) 371 ret void 372} 373 374declare void @test9_helper(i32* %A) 375define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) { 376; CHECK-LABEL: define {{[^@]+}}@test9_traversal 377; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8 [[C:%.*]]) 378; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]] 379; CHECK-NEXT: call void @test9_helper(i32* align 4 [[SEL]]) 380; CHECK-NEXT: ret void 381; 382 %sel = select i1 %cnd, i32* %B, i32* %C 383 call void @test9_helper(i32* %sel) 384 ret void 385} 386 387; FIXME: This will work with an upcoming patch (D66618 or similar) 388; define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p) 389; FIXME: This will work with an upcoming patch (D66618 or similar) 390; store i32 1, i32* %r, align 32 391; FIXME: This will work with an upcoming patch (D66618 or similar) 392; store i32 -1, i32* %g1, align 32 393define i32* @test10a(i32* align 32 %p) { 394; CHECK-LABEL: define {{[^@]+}}@test10a 395; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) 396; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 397; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 398; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 399; CHECK: t: 400; CHECK-NEXT: [[R:%.*]] = call i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) 401; CHECK-NEXT: store i32 1, i32* [[R]] 402; CHECK-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 403; CHECK-NEXT: br label [[E:%.*]] 404; CHECK: f: 405; CHECK-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8 406; CHECK-NEXT: store i32 -1, i32* [[G1]], align 4 407; CHECK-NEXT: br label [[E]] 408; CHECK: e: 409; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] 410; CHECK-NEXT: ret i32* [[PHI]] 411; 412 %l = load i32, i32* %p 413 %c = icmp eq i32 %l, 0 414 br i1 %c, label %t, label %f 415t: 416 %r = call i32* @test10a(i32* %p) 417 store i32 1, i32* %r 418 %g0 = getelementptr i32, i32* %p, i32 8 419 br label %e 420f: 421 %g1 = getelementptr i32, i32* %p, i32 8 422 store i32 -1, i32* %g1 423 br label %e 424e: 425 %phi = phi i32* [%g0, %t], [%g1, %f] 426 ret i32* %phi 427} 428 429; FIXME: This will work with an upcoming patch (D66618 or similar) 430; define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p) 431; FIXME: This will work with an upcoming patch (D66618 or similar) 432; store i32 1, i32* %r, align 32 433; FIXME: This will work with an upcoming patch (D66618 or similar) 434; store i32 -1, i32* %g1, align 32 435define i32* @test10b(i32* align 32 %p) { 436; CHECK-LABEL: define {{[^@]+}}@test10b 437; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) 438; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32 439; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0 440; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 441; CHECK: t: 442; CHECK-NEXT: [[R:%.*]] = call i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P]]) 443; CHECK-NEXT: store i32 1, i32* [[R]] 444; CHECK-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8 445; CHECK-NEXT: br label [[E:%.*]] 446; CHECK: f: 447; CHECK-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8 448; CHECK-NEXT: store i32 -1, i32* [[G1]], align 4 449; CHECK-NEXT: br label [[E]] 450; CHECK: e: 451; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]], [[F]] ] 452; CHECK-NEXT: ret i32* [[PHI]] 453; 454 %l = load i32, i32* %p 455 %c = icmp eq i32 %l, 0 456 br i1 %c, label %t, label %f 457t: 458 %r = call i32* @test10b(i32* %p) 459 store i32 1, i32* %r 460 %g0 = getelementptr i32, i32* %p, i32 8 461 br label %e 462f: 463 %g1 = getelementptr i32, i32* %p, i32 -8 464 store i32 -1, i32* %g1 465 br label %e 466e: 467 %phi = phi i32* [%g0, %t], [%g1, %f] 468 ret i32* %phi 469} 470 471 472define i64 @test11(i32* %p) { 473; CHECK-LABEL: define {{[^@]+}}@test11 474; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]]) 475; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 476; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8 477; CHECK-NEXT: ret i64 [[RET]] 478; 479 %p-cast = bitcast i32* %p to i64* 480 %ret = load i64, i64* %p-cast, align 8 481 ret i64 %ret 482} 483 484; TEST 12 485; Test for deduction using must-be-executed-context and GEP instruction 486 487; FXIME: %p should have nonnull 488define i64 @test12-1(i32* align 4 %p) { 489; CHECK-LABEL: define {{[^@]+}}@test12-1 490; CHECK-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]]) 491; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 492; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 493; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 494; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16 495; CHECK-NEXT: ret i64 [[RET]] 496; 497 %p-cast = bitcast i32* %p to i64* 498 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 499 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 500 %ret = load i64, i64* %arrayidx1, align 16 501 ret i64 %ret 502} 503 504define i64 @test12-2(i32* align 4 %p) { 505; CHECK-LABEL: define {{[^@]+}}@test12-2 506; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]]) 507; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 508; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 509; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16 510; CHECK-NEXT: ret i64 [[RET]] 511; 512 %p-cast = bitcast i32* %p to i64* 513 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 514 %ret = load i64, i64* %arrayidx0, align 16 515 ret i64 %ret 516} 517 518; FXIME: %p should have nonnull 519define void @test12-3(i32* align 4 %p) { 520; CHECK-LABEL: define {{[^@]+}}@test12-3 521; CHECK-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]]) 522; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 523; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 524; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 525; CHECK-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16 526; CHECK-NEXT: ret void 527; 528 %p-cast = bitcast i32* %p to i64* 529 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 530 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 531 store i64 0, i64* %arrayidx1, align 16 532 ret void 533} 534 535define void @test12-4(i32* align 4 %p) { 536; CHECK-LABEL: define {{[^@]+}}@test12-4 537; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]]) 538; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 539; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 540; CHECK-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16 541; CHECK-NEXT: ret void 542; 543 %p-cast = bitcast i32* %p to i64* 544 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 545 store i64 0, i64* %arrayidx0, align 16 546 ret void 547} 548 549declare void @use(i64*) willreturn nounwind 550 551define void @test12-5(i32* align 4 %p) { 552; CHECK-LABEL: define {{[^@]+}}@test12-5 553; CHECK-SAME: (i32* align 16 [[P:%.*]]) 554; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 555; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1 556; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3 557; CHECK-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX1]]) 558; CHECK-NEXT: ret void 559; 560 %p-cast = bitcast i32* %p to i64* 561 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1 562 %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3 563 tail call void @use(i64* align 16 %arrayidx1) 564 ret void 565} 566 567define void @test12-6(i32* align 4 %p) { 568; CHECK-LABEL: define {{[^@]+}}@test12-6 569; CHECK-SAME: (i32* align 16 [[P:%.*]]) 570; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64* 571; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0 572; CHECK-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]]) 573; CHECK-NEXT: ret void 574; 575 %p-cast = bitcast i32* %p to i64* 576 %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0 577 tail call void @use(i64* align 16 %arrayidx0) 578 ret void 579} 580 581define void @test13(i1 %c, i32* align 32 %dst) #0 { 582; CHECK-LABEL: define {{[^@]+}}@test13 583; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) 584; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 585; CHECK: truebb: 586; CHECK-NEXT: br label [[END:%.*]] 587; CHECK: falsebb: 588; CHECK-NEXT: br label [[END]] 589; CHECK: end: 590; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ] 591; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 592; CHECK-NEXT: ret void 593; 594 br i1 %c, label %truebb, label %falsebb 595truebb: 596 br label %end 597falsebb: 598 br label %end 599end: 600 %ptr = phi i32* [ %dst, %truebb ], [ null, %falsebb ] 601 store i32 0, i32* %ptr 602 ret void 603} 604 605define void @test13-1(i1 %c, i32* align 32 %dst) { 606; CHECK-LABEL: define {{[^@]+}}@test13-1 607; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) 608; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 609; CHECK: truebb: 610; CHECK-NEXT: br label [[END:%.*]] 611; CHECK: falsebb: 612; CHECK-NEXT: br label [[END]] 613; CHECK: end: 614; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ] 615; CHECK-NEXT: store i32 0, i32* [[PTR]], align 16 616; CHECK-NEXT: ret void 617; 618 br i1 %c, label %truebb, label %falsebb 619truebb: 620 br label %end 621falsebb: 622 br label %end 623end: 624 %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 48 to i32*), %falsebb ] 625 store i32 0, i32* %ptr 626 ret void 627} 628 629define void @test13-2(i1 %c, i32* align 32 %dst) { 630; CHECK-LABEL: define {{[^@]+}}@test13-2 631; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) 632; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 633; CHECK: truebb: 634; CHECK-NEXT: br label [[END:%.*]] 635; CHECK: falsebb: 636; CHECK-NEXT: br label [[END]] 637; CHECK: end: 638; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ] 639; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 640; CHECK-NEXT: ret void 641; 642 br i1 %c, label %truebb, label %falsebb 643truebb: 644 br label %end 645falsebb: 646 br label %end 647end: 648 %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 160 to i32*), %falsebb ] 649 store i32 0, i32* %ptr 650 ret void 651} 652 653define void @test13-3(i1 %c, i32* align 32 %dst) { 654; CHECK-LABEL: define {{[^@]+}}@test13-3 655; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]]) 656; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]] 657; CHECK: truebb: 658; CHECK-NEXT: br label [[END:%.*]] 659; CHECK: falsebb: 660; CHECK-NEXT: br label [[END]] 661; CHECK: end: 662; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ] 663; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32 664; CHECK-NEXT: ret void 665; 666 br i1 %c, label %truebb, label %falsebb 667truebb: 668 br label %end 669falsebb: 670 br label %end 671end: 672 %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 128 to i32*), %falsebb ] 673 store i32 0, i32* %ptr 674 ret void 675} 676 677; Don't crash on ptr2int/int2ptr uses. 678define i64 @ptr2int(i32* %p) { 679; CHECK-LABEL: define {{[^@]+}}@ptr2int 680; CHECK-SAME: (i32* nofree readnone [[P:%.*]]) 681; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64 682; CHECK-NEXT: ret i64 [[P2I]] 683; 684 %p2i = ptrtoint i32* %p to i64 685 ret i64 %p2i 686} 687define i64* @int2ptr(i64 %i) { 688; CHECK-LABEL: define {{[^@]+}}@int2ptr 689; CHECK-SAME: (i64 [[I:%.*]]) 690; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64* 691; CHECK-NEXT: ret i64* [[I2P]] 692; 693 %i2p = inttoptr i64 %i to i64* 694 ret i64* %i2p 695} 696 697; Use the store alignment only for the pointer operand. 698define void @aligned_store(i8* %Value, i8** %Ptr) { 699; CHECK-LABEL: define {{[^@]+}}@aligned_store 700; CHECK-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]]) 701; CHECK-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32 702; CHECK-NEXT: ret void 703; 704 store i8* %Value, i8** %Ptr, align 32 705 ret void 706} 707 708declare i8* @some_func(i8*) 709define void @align_call_op_not_store(i8* align 2048 %arg) { 710; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store 711; CHECK-SAME: (i8* align 2048 [[ARG:%.*]]) 712; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048 [[ARG]]) 713; CHECK-NEXT: store i8 0, i8* [[UNKNOWN]] 714; CHECK-NEXT: ret void 715; 716 %unknown = call i8* @some_func(i8* %arg) 717 store i8 0, i8* %unknown 718 ret void 719} 720define void @align_store_after_bc(i32* align 2048 %arg) { 721; 722; CHECK-LABEL: define {{[^@]+}}@align_store_after_bc 723; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]]) 724; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8* 725; CHECK-NEXT: store i8 0, i8* [[BC]], align 2048 726; CHECK-NEXT: ret void 727; 728 %bc = bitcast i32* %arg to i8* 729 store i8 0, i8* %bc 730 ret void 731} 732 733; Make sure we do not annotate the callee of a must-tail call with an alignment 734; we cannot also put on the caller. 735@cnd = external global i1 736define i32 @musttail_callee_1(i32* %p) { 737; CHECK-LABEL: define {{[^@]+}}@musttail_callee_1 738; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]]) 739; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32 740; CHECK-NEXT: ret i32 [[V]] 741; 742 %v = load i32, i32* %p, align 32 743 ret i32 %v 744} 745define i32 @musttail_caller_1(i32* %p) { 746; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1 747; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) 748; IS__TUNIT____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 749; IS__TUNIT____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] 750; IS__TUNIT____: mt: 751; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree readonly [[P]]) 752; IS__TUNIT____-NEXT: ret i32 [[V]] 753; IS__TUNIT____: exit: 754; IS__TUNIT____-NEXT: ret i32 0 755; 756; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_caller_1 757; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]]) 758; IS__CGSCC____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1 759; IS__CGSCC____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]] 760; IS__CGSCC____: mt: 761; IS__CGSCC____-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree nonnull readonly dereferenceable(4) [[P]]) 762; IS__CGSCC____-NEXT: ret i32 [[V]] 763; IS__CGSCC____: exit: 764; IS__CGSCC____-NEXT: ret i32 0 765; 766 %c = load i1, i1* @cnd 767 br i1 %c, label %mt, label %exit 768mt: 769 %v = musttail call i32 @musttail_callee_1(i32* %p) 770 ret i32 %v 771exit: 772 ret i32 0 773} 774 775attributes #0 = { nounwind uwtable noinline } 776attributes #1 = { uwtable noinline } 777attributes #2 = { "null-pointer-is-valid"="true" } 778