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