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