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:o-i64:64-f80:128-n8:16:32:64-S128" 6declare void @f(i32) 7declare token @llvm.call.preallocated.setup(i32) 8declare ptr @llvm.call.preallocated.arg(token, i32) 9 10@str = private unnamed_addr addrspace(4) constant [1 x i8] c"\00", align 1 11@ConstAS3Ptr = addrspace(3) global i32 0, align 4 12@ConstPtr = constant i32 0, align 4 13@ConstWeakPtr = weak constant i32 0, align 4 14@ConstWeakODRPtr = weak_odr constant i32 0, align 4 15 16;. 17; CHECK: @str = private unnamed_addr addrspace(4) constant [1 x i8] zeroinitializer, align 1 18; CHECK: @ConstAS3Ptr = addrspace(3) global i32 0, align 4 19; CHECK: @ConstPtr = constant i32 0, align 4 20; CHECK: @ConstWeakPtr = weak constant i32 0, align 4 21; CHECK: @ConstWeakODRPtr = weak_odr constant i32 0, align 4 22; CHECK: @S = external global %struct.X 23; CHECK: @g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] } 24; CHECK: @x = external global i32 25;. 26define internal ptr addrspace(3) @const_ptr_return_as3() { 27; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 28; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return_as3 29; CGSCC-SAME: () #[[ATTR1:[0-9]+]] { 30; CGSCC-NEXT: ret ptr addrspace(3) @ConstAS3Ptr 31; 32 ret ptr addrspace(3) @ConstAS3Ptr 33} 34define internal ptr @const_ptr_return() { 35; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 36; CGSCC-LABEL: define {{[^@]+}}@const_ptr_return 37; CGSCC-SAME: () #[[ATTR1]] { 38; CGSCC-NEXT: ret ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr) 39; 40 ret ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr) 41} 42 43; Test1: Replace argument with constant 44define internal void @test1(i32 %a) { 45; TUNIT: Function Attrs: memory(readwrite, argmem: none) 46; TUNIT-LABEL: define {{[^@]+}}@test1 47; TUNIT-SAME: () #[[ATTR1:[0-9]+]] { 48; TUNIT-NEXT: tail call void @f(i32 noundef 1) 49; TUNIT-NEXT: ret void 50; 51; CGSCC: Function Attrs: memory(readwrite, argmem: none) 52; CGSCC-LABEL: define {{[^@]+}}@test1 53; CGSCC-SAME: () #[[ATTR2:[0-9]+]] { 54; CGSCC-NEXT: tail call void @f(i32 noundef 1) 55; CGSCC-NEXT: ret void 56; 57 tail call void @f(i32 %a) 58 ret void 59} 60 61define void @test1_helper() { 62; CHECK-LABEL: define {{[^@]+}}@test1_helper() { 63; CHECK-NEXT: tail call void @test1() 64; CHECK-NEXT: ret void 65; 66 tail call void @test1(i32 1) 67 ret void 68} 69 70; TEST 2 : Simplify return value 71define i32 @return0() { 72; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 73; TUNIT-LABEL: define {{[^@]+}}@return0 74; TUNIT-SAME: () #[[ATTR2:[0-9]+]] { 75; TUNIT-NEXT: ret i32 0 76; 77; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 78; CGSCC-LABEL: define {{[^@]+}}@return0 79; CGSCC-SAME: () #[[ATTR1]] { 80; CGSCC-NEXT: ret i32 0 81; 82 ret i32 0 83} 84 85define i32 @return1() { 86; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 87; TUNIT-LABEL: define {{[^@]+}}@return1 88; TUNIT-SAME: () #[[ATTR2]] { 89; TUNIT-NEXT: ret i32 1 90; 91; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 92; CGSCC-LABEL: define {{[^@]+}}@return1 93; CGSCC-SAME: () #[[ATTR1]] { 94; CGSCC-NEXT: ret i32 1 95; 96 ret i32 1 97} 98 99define i32 @test2_1(i1 %c) { 100; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 101; TUNIT-LABEL: define {{[^@]+}}@test2_1 102; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] { 103; TUNIT-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 104; TUNIT: if.true: 105; TUNIT-NEXT: [[RET0:%.*]] = add i32 0, 1 106; TUNIT-NEXT: br label [[END:%.*]] 107; TUNIT: if.false: 108; TUNIT-NEXT: br label [[END]] 109; TUNIT: end: 110; TUNIT-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] 111; TUNIT-NEXT: ret i32 1 112; 113; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 114; CGSCC-LABEL: define {{[^@]+}}@test2_1 115; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3:[0-9]+]] { 116; CGSCC-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 117; CGSCC: if.true: 118; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @return0() #[[ATTR12:[0-9]+]] 119; CGSCC-NEXT: [[RET0:%.*]] = add i32 [[CALL]], 1 120; CGSCC-NEXT: br label [[END:%.*]] 121; CGSCC: if.false: 122; CGSCC-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR12]] 123; CGSCC-NEXT: br label [[END]] 124; CGSCC: end: 125; CGSCC-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] 126; CGSCC-NEXT: ret i32 1 127; 128 br i1 %c, label %if.true, label %if.false 129if.true: 130 %call = tail call i32 @return0() 131 %ret0 = add i32 %call, 1 132 br label %end 133if.false: 134 %ret1 = tail call i32 @return1() 135 br label %end 136end: 137 138 %ret = phi i32 [ %ret0, %if.true ], [ %ret1, %if.false ] 139 140 ret i32 1 141} 142 143 144 145define i32 @test2_2(i1 %c) { 146; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 147; TUNIT-LABEL: define {{[^@]+}}@test2_2 148; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 149; TUNIT-NEXT: ret i32 1 150; 151; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 152; CGSCC-LABEL: define {{[^@]+}}@test2_2 153; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] { 154; CGSCC-NEXT: [[RET:%.*]] = tail call noundef i32 @test2_1(i1 noundef [[C]]) #[[ATTR12]] 155; CGSCC-NEXT: ret i32 [[RET]] 156; 157 %ret = tail call i32 @test2_1(i1 %c) 158 ret i32 %ret 159} 160 161declare void @use(i32) 162define void @test3(i1 %c) { 163; TUNIT-LABEL: define {{[^@]+}}@test3 164; TUNIT-SAME: (i1 noundef [[C:%.*]]) { 165; TUNIT-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 166; TUNIT: if.true: 167; TUNIT-NEXT: br label [[END:%.*]] 168; TUNIT: if.false: 169; TUNIT-NEXT: br label [[END]] 170; TUNIT: end: 171; TUNIT-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] 172; TUNIT-NEXT: tail call void @use(i32 noundef 1) 173; TUNIT-NEXT: ret void 174; 175; CGSCC-LABEL: define {{[^@]+}}@test3 176; CGSCC-SAME: (i1 noundef [[C:%.*]]) { 177; CGSCC-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 178; CGSCC: if.true: 179; CGSCC-NEXT: br label [[END:%.*]] 180; CGSCC: if.false: 181; CGSCC-NEXT: [[RET1:%.*]] = tail call i32 @return1() #[[ATTR13:[0-9]+]] 182; CGSCC-NEXT: br label [[END]] 183; CGSCC: end: 184; CGSCC-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ [[RET1]], [[IF_FALSE]] ] 185; CGSCC-NEXT: tail call void @use(i32 noundef [[R]]) 186; CGSCC-NEXT: ret void 187; 188 br i1 %c, label %if.true, label %if.false 189if.true: 190 br label %end 191if.false: 192 %ret1 = tail call i32 @return1() 193 br label %end 194end: 195 196 %r = phi i32 [ 1, %if.true ], [ %ret1, %if.false ] 197 198 tail call void @use(i32 %r) 199 ret void 200} 201 202define void @test-select-phi(i1 %c) { 203; CHECK-LABEL: define {{[^@]+}}@test-select-phi 204; CHECK-SAME: (i1 [[C:%.*]]) { 205; CHECK-NEXT: tail call void @use(i32 noundef 1) 206; CHECK-NEXT: [[SELECT_NOT_SAME:%.*]] = select i1 [[C]], i32 1, i32 0 207; CHECK-NEXT: tail call void @use(i32 noundef [[SELECT_NOT_SAME]]) 208; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] 209; CHECK: if-true: 210; CHECK-NEXT: br label [[END:%.*]] 211; CHECK: if-false: 212; CHECK-NEXT: br label [[END]] 213; CHECK: end: 214; CHECK-NEXT: [[PHI_SAME:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] 215; CHECK-NEXT: [[PHI_NOT_SAME:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] 216; CHECK-NEXT: [[PHI_SAME_PROP:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ] 217; CHECK-NEXT: [[PHI_SAME_UNDEF:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ undef, [[IF_FALSE]] ] 218; CHECK-NEXT: [[SELECT_NOT_SAME_UNDEF:%.*]] = select i1 [[C]], i32 [[PHI_NOT_SAME]], i32 undef 219; CHECK-NEXT: tail call void @use(i32 noundef 1) 220; CHECK-NEXT: tail call void @use(i32 noundef [[PHI_NOT_SAME]]) 221; CHECK-NEXT: tail call void @use(i32 noundef 1) 222; CHECK-NEXT: tail call void @use(i32 1) 223; CHECK-NEXT: tail call void @use(i32 [[SELECT_NOT_SAME_UNDEF]]) 224; CHECK-NEXT: ret void 225; 226 %select-same = select i1 %c, i32 1, i32 1 227 tail call void @use(i32 %select-same) 228 229 %select-not-same = select i1 %c, i32 1, i32 0 230 tail call void @use(i32 %select-not-same) 231 br i1 %c, label %if-true, label %if-false 232if-true: 233 br label %end 234if-false: 235 br label %end 236end: 237 %phi-same = phi i32 [ 1, %if-true ], [ 1, %if-false ] 238 %phi-not-same = phi i32 [ 0, %if-true ], [ 1, %if-false ] 239 %phi-same-prop = phi i32 [ 1, %if-true ], [ %select-same, %if-false ] 240 %phi-same-undef = phi i32 [ 1, %if-true ], [ undef, %if-false ] 241 %select-not-same-undef = select i1 %c, i32 %phi-not-same, i32 undef 242 243 244 tail call void @use(i32 %phi-same) 245 246 tail call void @use(i32 %phi-not-same) 247 248 tail call void @use(i32 %phi-same-prop) 249 250 tail call void @use(i32 %phi-same-undef) 251 252 tail call void @use(i32 %select-not-same-undef) 253 254 ret void 255 256} 257 258define i32 @ipccp1(i32 %a) { 259; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 260; TUNIT-LABEL: define {{[^@]+}}@ipccp1 261; TUNIT-SAME: (i32 returned [[A:%.*]]) #[[ATTR2]] { 262; TUNIT-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]] 263; TUNIT: t: 264; TUNIT-NEXT: ret i32 [[A]] 265; TUNIT: f: 266; TUNIT-NEXT: unreachable 267; 268; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 269; CGSCC-LABEL: define {{[^@]+}}@ipccp1 270; CGSCC-SAME: (i32 returned [[A:%.*]]) #[[ATTR1]] { 271; CGSCC-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]] 272; CGSCC: t: 273; CGSCC-NEXT: ret i32 [[A]] 274; CGSCC: f: 275; CGSCC-NEXT: unreachable 276; 277 br i1 true, label %t, label %f 278t: 279 ret i32 %a 280f: 281 %r = call i32 @ipccp1(i32 5) 282 ret i32 %r 283} 284 285define internal i1 @ipccp2i(i1 %a) { 286; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 287; CGSCC-LABEL: define {{[^@]+}}@ipccp2i 288; CGSCC-SAME: () #[[ATTR1]] { 289; CGSCC-NEXT: br label [[T:%.*]] 290; CGSCC: t: 291; CGSCC-NEXT: ret i1 true 292; CGSCC: f: 293; CGSCC-NEXT: unreachable 294; 295 br i1 %a, label %t, label %f 296t: 297 ret i1 %a 298f: 299 %r = call i1 @ipccp2i(i1 false) 300 ret i1 %r 301} 302 303define i1 @ipccp2() { 304; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 305; TUNIT-LABEL: define {{[^@]+}}@ipccp2 306; TUNIT-SAME: () #[[ATTR2]] { 307; TUNIT-NEXT: ret i1 true 308; 309; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 310; CGSCC-LABEL: define {{[^@]+}}@ipccp2 311; CGSCC-SAME: () #[[ATTR3]] { 312; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @ipccp2i() #[[ATTR12]] 313; CGSCC-NEXT: ret i1 [[R]] 314; 315 %r = call i1 @ipccp2i(i1 true) 316 ret i1 %r 317} 318 319define internal i1 @ipccp2ib(i1 %a) { 320; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 321; CGSCC-LABEL: define {{[^@]+}}@ipccp2ib 322; CGSCC-SAME: () #[[ATTR1]] { 323; CGSCC-NEXT: br label [[T:%.*]] 324; CGSCC: t: 325; CGSCC-NEXT: ret i1 true 326; CGSCC: f: 327; CGSCC-NEXT: unreachable 328; 329 br i1 %a, label %t, label %f 330t: 331 ret i1 true 332f: 333 %r = call i1 @ipccp2ib(i1 false) 334 ret i1 %r 335} 336 337define i1 @ipccp2b() { 338; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 339; TUNIT-LABEL: define {{[^@]+}}@ipccp2b 340; TUNIT-SAME: () #[[ATTR2]] { 341; TUNIT-NEXT: ret i1 true 342; 343; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 344; CGSCC-LABEL: define {{[^@]+}}@ipccp2b 345; CGSCC-SAME: () #[[ATTR3]] { 346; CGSCC-NEXT: [[R:%.*]] = call noundef i1 @ipccp2ib() #[[ATTR12]] 347; CGSCC-NEXT: ret i1 [[R]] 348; 349 %r = call i1 @ipccp2ib(i1 true) 350 ret i1 %r 351} 352 353define internal i32 @ipccp3i(i32 %a) { 354; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 355; CGSCC-LABEL: define {{[^@]+}}@ipccp3i 356; CGSCC-SAME: () #[[ATTR1]] { 357; CGSCC-NEXT: br label [[T:%.*]] 358; CGSCC: t: 359; CGSCC-NEXT: ret i32 7 360; CGSCC: f: 361; CGSCC-NEXT: unreachable 362; 363 %c = icmp eq i32 %a, 7 364 br i1 %c, label %t, label %f 365t: 366 ret i32 %a 367f: 368 %r = call i32 @ipccp3i(i32 5) 369 ret i32 %r 370} 371 372define i32 @ipccp3() { 373; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 374; TUNIT-LABEL: define {{[^@]+}}@ipccp3 375; TUNIT-SAME: () #[[ATTR2]] { 376; TUNIT-NEXT: ret i32 7 377; 378; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 379; CGSCC-LABEL: define {{[^@]+}}@ipccp3 380; CGSCC-SAME: () #[[ATTR3]] { 381; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp3i() #[[ATTR12]] 382; CGSCC-NEXT: ret i32 [[R]] 383; 384 %r = call i32 @ipccp3i(i32 7) 385 ret i32 %r 386} 387 388define internal i32 @ipccp4ia(i1 %c) { 389; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 390; CGSCC-LABEL: define {{[^@]+}}@ipccp4ia 391; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] { 392; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 393; CGSCC: t: 394; CGSCC-NEXT: ret i32 0 395; CGSCC: f: 396; CGSCC-NEXT: ret i32 1 397; 398 br i1 %c, label %t, label %f 399t: 400 ret i32 0 401f: 402 ret i32 1 403} 404define internal i32 @ipccp4ib(i32 %a) { 405; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 406; CGSCC-LABEL: define {{[^@]+}}@ipccp4ib 407; CGSCC-SAME: () #[[ATTR3]] { 408; CGSCC-NEXT: br label [[T:%.*]] 409; CGSCC: t: 410; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ia(i1 noundef true) #[[ATTR12]] 411; CGSCC-NEXT: ret i32 [[R]] 412; CGSCC: f: 413; CGSCC-NEXT: unreachable 414; 415 %c = icmp eq i32 %a, 7 416 br i1 %c, label %t, label %f 417t: 418 %r = call i32 @ipccp4ia(i1 %c) 419 ret i32 %r 420f: 421 ret i32 1 422} 423 424define i32 @ipccp4(i1 %c) { 425; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 426; TUNIT-LABEL: define {{[^@]+}}@ipccp4 427; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] { 428; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 429; TUNIT: t: 430; TUNIT-NEXT: br label [[F]] 431; TUNIT: f: 432; TUNIT-NEXT: ret i32 0 433; 434; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 435; CGSCC-LABEL: define {{[^@]+}}@ipccp4 436; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] { 437; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 438; CGSCC: t: 439; CGSCC-NEXT: br label [[F]] 440; CGSCC: f: 441; CGSCC-NEXT: [[R:%.*]] = call noundef i32 @ipccp4ib() #[[ATTR12]] 442; CGSCC-NEXT: ret i32 [[R]] 443; 444 br i1 %c, label %t, label %f 445t: 446 %q = call i32 @ipccp4ia(i1 undef) 447 br label %f 448f: 449 %r = call i32 @ipccp4ib(i32 7) 450 ret i32 %r 451} 452 453; Do not touch complicated arguments (for now) 454%struct.X = type { ptr } 455define internal ptr @test_inalloca(ptr inalloca(i32) %a) { 456; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 457; TUNIT-LABEL: define {{[^@]+}}@test_inalloca 458; TUNIT-SAME: (ptr noalias nofree nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { 459; TUNIT-NEXT: ret ptr [[A]] 460; 461; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 462; CGSCC-LABEL: define {{[^@]+}}@test_inalloca 463; CGSCC-SAME: (ptr noalias nofree noundef nonnull returned writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { 464; CGSCC-NEXT: ret ptr [[A]] 465; 466 ret ptr %a 467} 468define ptr @complicated_args_inalloca(ptr %arg) { 469; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 470; TUNIT-LABEL: define {{[^@]+}}@complicated_args_inalloca 471; TUNIT-SAME: (ptr nofree nonnull readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR2]] { 472; TUNIT-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree nonnull writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR9:[0-9]+]] 473; TUNIT-NEXT: ret ptr [[CALL]] 474; 475; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 476; CGSCC-LABEL: define {{[^@]+}}@complicated_args_inalloca 477; CGSCC-SAME: (ptr nofree noundef nonnull readnone dereferenceable(4) [[ARG:%.*]]) #[[ATTR3]] { 478; CGSCC-NEXT: [[CALL:%.*]] = call noalias noundef nonnull dereferenceable(4) ptr @test_inalloca(ptr noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) [[ARG]]) #[[ATTR12]] 479; CGSCC-NEXT: ret ptr [[CALL]] 480; 481 %call = call ptr @test_inalloca(ptr inalloca(i32) %arg) 482 ret ptr %call 483} 484 485define internal ptr @test_preallocated(ptr preallocated(i32) %a) { 486; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 487; TUNIT-LABEL: define {{[^@]+}}@test_preallocated 488; TUNIT-SAME: (ptr noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR2]] { 489; TUNIT-NEXT: ret ptr [[A]] 490; 491; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 492; CGSCC-LABEL: define {{[^@]+}}@test_preallocated 493; CGSCC-SAME: (ptr noalias nofree noundef nonnull returned writeonly preallocated(i32) align 4294967296 dereferenceable(4) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] { 494; CGSCC-NEXT: ret ptr [[A]] 495; 496 ret ptr %a 497} 498define ptr @complicated_args_preallocated() { 499; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn 500; TUNIT-LABEL: define {{[^@]+}}@complicated_args_preallocated 501; TUNIT-SAME: () #[[ATTR3:[0-9]+]] { 502; TUNIT-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR10:[0-9]+]] 503; TUNIT-NEXT: [[CALL:%.*]] = call noundef nonnull align 4294967296 dereferenceable(4) ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR9]] [ "preallocated"(token [[C]]) ] 504; TUNIT-NEXT: ret ptr [[CALL]] 505; 506; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 507; CGSCC-LABEL: define {{[^@]+}}@complicated_args_preallocated 508; CGSCC-SAME: () #[[ATTR4:[0-9]+]] { 509; CGSCC-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR13]] 510; CGSCC-NEXT: [[CALL:%.*]] = call ptr @test_preallocated(ptr nofree noundef writeonly preallocated(i32) align 4294967296 null) #[[ATTR14:[0-9]+]] [ "preallocated"(token [[C]]) ] 511; CGSCC-NEXT: unreachable 512; 513 %c = call token @llvm.call.preallocated.setup(i32 1) 514 %call = call ptr @test_preallocated(ptr preallocated(i32) null) ["preallocated"(token %c)] 515 ret ptr %call 516} 517 518define internal void @test_sret(ptr sret(%struct.X) %a, ptr %b) { 519; 520; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 521; TUNIT-LABEL: define {{[^@]+}}@test_sret 522; TUNIT-SAME: (ptr noalias nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) [[A:%.*]], ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR4:[0-9]+]] { 523; TUNIT-NEXT: store ptr [[A]], ptr [[B]], align 8 524; TUNIT-NEXT: ret void 525; 526; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 527; CGSCC-LABEL: define {{[^@]+}}@test_sret 528; CGSCC-SAME: (ptr noalias nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) [[A:%.*]], ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR5:[0-9]+]] { 529; CGSCC-NEXT: store ptr [[A]], ptr [[B]], align 8 530; CGSCC-NEXT: ret void 531; 532 store ptr %a, ptr %b 533 ret void 534} 535; FIXME: Alignment and dereferenceability are not propagated to the argument 536define void @complicated_args_sret(ptr %b) { 537; 538; 539; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 540; TUNIT-LABEL: define {{[^@]+}}@complicated_args_sret 541; TUNIT-SAME: (ptr nofree writeonly captures(none) [[B:%.*]]) #[[ATTR4]] { 542; TUNIT-NEXT: call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 null, ptr nofree noundef writeonly align 8 captures(none) [[B]]) #[[ATTR11:[0-9]+]] 543; TUNIT-NEXT: ret void 544; 545; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: write) 546; CGSCC-LABEL: define {{[^@]+}}@complicated_args_sret 547; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B:%.*]]) #[[ATTR6:[0-9]+]] { 548; CGSCC-NEXT: call void @test_sret(ptr nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 4294967296 dereferenceable_or_null(8) null, ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[B]]) #[[ATTR15:[0-9]+]] 549; CGSCC-NEXT: ret void 550; 551 call void @test_sret(ptr sret(%struct.X) null, ptr %b) 552 ret void 553} 554 555define internal ptr @test_nest(ptr nest %a) { 556; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 557; CGSCC-LABEL: define {{[^@]+}}@test_nest 558; CGSCC-SAME: (ptr nest noalias nofree readnone align 4294967296 captures(none) [[A:%.*]]) #[[ATTR1]] { 559; CGSCC-NEXT: ret ptr null 560; 561 ret ptr %a 562} 563define ptr @complicated_args_nest() { 564; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 565; TUNIT-LABEL: define {{[^@]+}}@complicated_args_nest 566; TUNIT-SAME: () #[[ATTR2]] { 567; TUNIT-NEXT: ret ptr null 568; 569; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 570; CGSCC-LABEL: define {{[^@]+}}@complicated_args_nest 571; CGSCC-SAME: () #[[ATTR3]] { 572; CGSCC-NEXT: [[CALL:%.*]] = call noalias noundef align 4294967296 ptr @test_nest(ptr nofree noundef readnone align 4294967296 null) #[[ATTR12]] 573; CGSCC-NEXT: ret ptr [[CALL]] 574; 575 %call = call ptr @test_nest(ptr null) 576 ret ptr %call 577} 578 579@S = external global %struct.X 580define internal void @test_byval(ptr byval(%struct.X) %a) { 581; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 582; TUNIT-LABEL: define {{[^@]+}}@test_byval 583; TUNIT-SAME: (ptr [[TMP0:%.*]]) #[[ATTR4]] { 584; TUNIT-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 585; TUNIT-NEXT: store ptr [[TMP0]], ptr [[A_PRIV]], align 8 586; TUNIT-NEXT: store ptr null, ptr [[A_PRIV]], align 8 587; TUNIT-NEXT: ret void 588; 589; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 590; CGSCC-LABEL: define {{[^@]+}}@test_byval 591; CGSCC-SAME: (ptr nofree [[TMP0:%.*]]) #[[ATTR5]] { 592; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 593; CGSCC-NEXT: store ptr [[TMP0]], ptr [[A_PRIV]], align 8 594; CGSCC-NEXT: store ptr null, ptr [[A_PRIV]], align 8 595; CGSCC-NEXT: ret void 596; 597 store ptr null, ptr %a 598 ret void 599} 600define void @complicated_args_byval() { 601; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 602; TUNIT-LABEL: define {{[^@]+}}@complicated_args_byval 603; TUNIT-SAME: () #[[ATTR5:[0-9]+]] { 604; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8 605; TUNIT-NEXT: call void @test_byval(ptr [[TMP1]]) #[[ATTR11]] 606; TUNIT-NEXT: ret void 607; 608; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn 609; CGSCC-LABEL: define {{[^@]+}}@complicated_args_byval 610; CGSCC-SAME: () #[[ATTR4]] { 611; CGSCC-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8 612; CGSCC-NEXT: call void @test_byval(ptr nofree writeonly [[TMP1]]) #[[ATTR15]] 613; CGSCC-NEXT: ret void 614; 615 call void @test_byval(ptr byval(%struct.X) @S) 616 ret void 617} 618 619declare void @sync() 620; Make sure we *do not* load @S here! 621define internal ptr @test_byval2(ptr byval(%struct.X) %a) { 622; CHECK-LABEL: define {{[^@]+}}@test_byval2 623; CHECK-SAME: (ptr [[TMP0:%.*]]) { 624; CHECK-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8 625; CHECK-NEXT: store ptr [[TMP0]], ptr [[A_PRIV]], align 8 626; CHECK-NEXT: call void @sync() 627; CHECK-NEXT: [[L:%.*]] = load ptr, ptr [[A_PRIV]], align 8 628; CHECK-NEXT: ret ptr [[L]] 629; 630 call void @sync() 631 %l = load ptr, ptr %a 632 ret ptr %l 633} 634define ptr @complicated_args_byval2() { 635; 636; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval2() { 637; CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr @S, align 8 638; CHECK-NEXT: [[C:%.*]] = call ptr @test_byval2(ptr [[TMP1]]) 639; CHECK-NEXT: ret ptr [[C]] 640; 641 %c = call ptr @test_byval2(ptr byval(%struct.X) @S) 642 ret ptr %c 643} 644 645define void @fixpoint_changed(ptr %p) { 646; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 647; TUNIT-LABEL: define {{[^@]+}}@fixpoint_changed 648; TUNIT-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR4]] { 649; TUNIT-NEXT: entry: 650; TUNIT-NEXT: br label [[FOR_COND:%.*]] 651; TUNIT: for.cond: 652; TUNIT-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] 653; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 654; TUNIT-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] 655; TUNIT: for.body: 656; TUNIT-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ 657; TUNIT-NEXT: i32 1, label [[SW_BB:%.*]] 658; TUNIT-NEXT: ] 659; TUNIT: sw.bb: 660; TUNIT-NEXT: br label [[SW_EPILOG]] 661; TUNIT: sw.epilog: 662; TUNIT-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] 663; TUNIT-NEXT: store i32 [[X_0]], ptr [[P]], align 4 664; TUNIT-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 665; TUNIT-NEXT: br label [[FOR_COND]] 666; TUNIT: for.end: 667; TUNIT-NEXT: ret void 668; 669; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 670; CGSCC-LABEL: define {{[^@]+}}@fixpoint_changed 671; CGSCC-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) #[[ATTR5]] { 672; CGSCC-NEXT: entry: 673; CGSCC-NEXT: br label [[FOR_COND:%.*]] 674; CGSCC: for.cond: 675; CGSCC-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ] 676; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30 677; CGSCC-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]] 678; CGSCC: for.body: 679; CGSCC-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [ 680; CGSCC-NEXT: i32 1, label [[SW_BB:%.*]] 681; CGSCC-NEXT: ] 682; CGSCC: sw.bb: 683; CGSCC-NEXT: br label [[SW_EPILOG]] 684; CGSCC: sw.epilog: 685; CGSCC-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ] 686; CGSCC-NEXT: store i32 [[X_0]], ptr [[P]], align 4 687; CGSCC-NEXT: [[INC]] = add nsw i32 [[J_0]], 1 688; CGSCC-NEXT: br label [[FOR_COND]] 689; CGSCC: for.end: 690; CGSCC-NEXT: ret void 691; 692entry: 693 br label %for.cond 694 695for.cond: 696 %j.0 = phi i32 [ 0, %entry ], [ %inc, %sw.epilog ] 697 %cmp = icmp slt i32 %j.0, 30 698 br i1 %cmp, label %for.body, label %for.end 699 700for.body: 701 switch i32 %j.0, label %sw.epilog [ 702 i32 1, label %sw.bb 703 ] 704 705sw.bb: 706 br label %sw.epilog 707 708sw.epilog: 709 %x.0 = phi i32 [ 255, %for.body ], [ 253, %sw.bb ] 710 store i32 %x.0, ptr %p 711 %inc = add nsw i32 %j.0, 1 712 br label %for.cond 713 714for.end: 715 ret void 716} 717 718; Check we merge undef and a constant properly. 719define i8 @caller0() { 720; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 721; TUNIT-LABEL: define {{[^@]+}}@caller0 722; TUNIT-SAME: () #[[ATTR2]] { 723; TUNIT-NEXT: ret i8 49 724; 725; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 726; CGSCC-LABEL: define {{[^@]+}}@caller0 727; CGSCC-SAME: () #[[ATTR3]] { 728; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] 729; CGSCC-NEXT: ret i8 [[C]] 730; 731 %c = call i8 @callee(i8 undef) 732 ret i8 %c 733} 734define i8 @caller1() { 735; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 736; TUNIT-LABEL: define {{[^@]+}}@caller1 737; TUNIT-SAME: () #[[ATTR2]] { 738; TUNIT-NEXT: ret i8 49 739; 740; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 741; CGSCC-LABEL: define {{[^@]+}}@caller1 742; CGSCC-SAME: () #[[ATTR3]] { 743; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] 744; CGSCC-NEXT: ret i8 [[C]] 745; 746 %c = call i8 @callee(i8 undef) 747 ret i8 %c 748} 749define i8 @caller2() { 750; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 751; TUNIT-LABEL: define {{[^@]+}}@caller2 752; TUNIT-SAME: () #[[ATTR2]] { 753; TUNIT-NEXT: ret i8 49 754; 755; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 756; CGSCC-LABEL: define {{[^@]+}}@caller2 757; CGSCC-SAME: () #[[ATTR3]] { 758; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] 759; CGSCC-NEXT: ret i8 [[C]] 760; 761 %c = call i8 @callee(i8 undef) 762 ret i8 %c 763} 764define i8 @caller_middle() { 765; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 766; TUNIT-LABEL: define {{[^@]+}}@caller_middle 767; TUNIT-SAME: () #[[ATTR2]] { 768; TUNIT-NEXT: ret i8 49 769; 770; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 771; CGSCC-LABEL: define {{[^@]+}}@caller_middle 772; CGSCC-SAME: () #[[ATTR3]] { 773; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] 774; CGSCC-NEXT: ret i8 [[C]] 775; 776 %c = call i8 @callee(i8 42) 777 ret i8 %c 778} 779define i8 @caller3() { 780; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 781; TUNIT-LABEL: define {{[^@]+}}@caller3 782; TUNIT-SAME: () #[[ATTR2]] { 783; TUNIT-NEXT: ret i8 49 784; 785; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 786; CGSCC-LABEL: define {{[^@]+}}@caller3 787; CGSCC-SAME: () #[[ATTR3]] { 788; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] 789; CGSCC-NEXT: ret i8 [[C]] 790; 791 %c = call i8 @callee(i8 undef) 792 ret i8 %c 793} 794define i8 @caller4() { 795; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 796; TUNIT-LABEL: define {{[^@]+}}@caller4 797; TUNIT-SAME: () #[[ATTR2]] { 798; TUNIT-NEXT: ret i8 49 799; 800; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 801; CGSCC-LABEL: define {{[^@]+}}@caller4 802; CGSCC-SAME: () #[[ATTR3]] { 803; CGSCC-NEXT: [[C:%.*]] = call noundef i8 @callee() #[[ATTR12]] 804; CGSCC-NEXT: ret i8 [[C]] 805; 806 %c = call i8 @callee(i8 undef) 807 ret i8 %c 808} 809define internal i8 @callee(i8 %a) { 810; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 811; CGSCC-LABEL: define {{[^@]+}}@callee 812; CGSCC-SAME: () #[[ATTR1]] { 813; CGSCC-NEXT: ret i8 49 814; 815 %c = add i8 %a, 7 816 ret i8 %c 817} 818 819define void @user_as3() { 820; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 821; TUNIT-LABEL: define {{[^@]+}}@user_as3 822; TUNIT-SAME: () #[[ATTR5]] { 823; TUNIT-NEXT: store i32 0, ptr addrspace(3) @ConstAS3Ptr, align 4 824; TUNIT-NEXT: ret void 825; 826; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write) 827; CGSCC-LABEL: define {{[^@]+}}@user_as3 828; CGSCC-SAME: () #[[ATTR7:[0-9]+]] { 829; CGSCC-NEXT: [[CALL:%.*]] = call fastcc align 4 ptr addrspace(3) @const_ptr_return_as3() #[[ATTR12]] 830; CGSCC-NEXT: store i32 0, ptr addrspace(3) [[CALL]], align 4 831; CGSCC-NEXT: ret void 832; 833 %call = call fastcc ptr addrspace(3) @const_ptr_return_as3() 834 store i32 0, ptr addrspace(3) %call 835 ret void 836} 837define void @user() { 838; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 839; TUNIT-LABEL: define {{[^@]+}}@user 840; TUNIT-SAME: () #[[ATTR5]] { 841; TUNIT-NEXT: store i32 0, ptr addrspacecast (ptr addrspace(3) @ConstAS3Ptr to ptr), align 4 842; TUNIT-NEXT: ret void 843; 844; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(write) 845; CGSCC-LABEL: define {{[^@]+}}@user 846; CGSCC-SAME: () #[[ATTR7]] { 847; CGSCC-NEXT: [[CALL:%.*]] = call fastcc align 4 ptr @const_ptr_return() #[[ATTR12]] 848; CGSCC-NEXT: store i32 0, ptr [[CALL]], align 4 849; CGSCC-NEXT: ret void 850; 851 %call = call fastcc ptr @const_ptr_return() 852 store i32 0, ptr %call 853 ret void 854} 855 856 857define i1 @test_merge_with_undef_values_ptr(i1 %c) { 858; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 859; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr 860; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 861; TUNIT-NEXT: ret i1 false 862; 863; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 864; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr 865; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 866; CGSCC-NEXT: [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR12]] 867; CGSCC-NEXT: ret i1 [[R1]] 868; 869 %r1 = call i1 @undef_then_null(i1 %c, ptr undef, ptr undef) 870 ret i1 %r1 871} 872define internal i1 @undef_then_null(i1 %c, ptr %i32Aptr, ptr %i32Bptr) { 873; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 874; CGSCC-LABEL: define {{[^@]+}}@undef_then_null 875; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 876; CGSCC-NEXT: [[OR:%.*]] = or i1 false, [[C]] 877; CGSCC-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]] 878; CGSCC: a: 879; CGSCC-NEXT: ret i1 false 880; CGSCC: b: 881; CGSCC-NEXT: ret i1 false 882; 883 %cmp1 = icmp eq ptr %i32Aptr, %i32Bptr 884 %cmp2 = icmp eq i1 %cmp1, false 885 %or = or i1 %cmp2, %c 886 br i1 %or, label %a, label %b 887a: 888 %r2 = call i1 @undef_then_null(i1 false, ptr null, ptr null) 889 ret i1 %r2 890b: 891 ret i1 %cmp2 892} 893 894define i1 @test_merge_with_undef_values(i1 %c) { 895; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 896; TUNIT-LABEL: define {{[^@]+}}@test_merge_with_undef_values 897; TUNIT-SAME: (i1 [[C:%.*]]) #[[ATTR2]] { 898; TUNIT-NEXT: ret i1 false 899; 900; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 901; CGSCC-LABEL: define {{[^@]+}}@test_merge_with_undef_values 902; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 903; CGSCC-NEXT: [[R1:%.*]] = call i1 @undef_then_1(i1 [[C]]) #[[ATTR12]] 904; CGSCC-NEXT: ret i1 [[R1]] 905; 906 %r1 = call i1 @undef_then_1(i1 %c, i32 undef, i32 undef) 907 ret i1 %r1 908} 909define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) { 910; 911; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 912; CGSCC-LABEL: define {{[^@]+}}@undef_then_1 913; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { 914; CGSCC-NEXT: [[OR:%.*]] = or i1 false, [[C]] 915; CGSCC-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]] 916; CGSCC: a: 917; CGSCC-NEXT: ret i1 false 918; CGSCC: b: 919; CGSCC-NEXT: ret i1 false 920; 921 %cmp1 = icmp eq i32 %i32A, %i32B 922 %cmp2 = icmp eq i1 %cmp1, false 923 %or = or i1 %cmp2, %c 924 br i1 %or, label %a, label %b 925a: 926 %r2 = call i1 @undef_then_1(i1 false, i32 1, i32 1) 927 ret i1 %r2 928b: 929 ret i1 %cmp2 930} 931 932define i32 @test_select(i32 %c) { 933; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 934; TUNIT-LABEL: define {{[^@]+}}@test_select 935; TUNIT-SAME: (i32 [[C:%.*]]) #[[ATTR2]] { 936; TUNIT-NEXT: ret i32 42 937; 938; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 939; CGSCC-LABEL: define {{[^@]+}}@test_select 940; CGSCC-SAME: (i32 [[C:%.*]]) #[[ATTR3]] { 941; CGSCC-NEXT: [[CALL:%.*]] = call noundef i32 @select() #[[ATTR12]] 942; CGSCC-NEXT: ret i32 [[CALL]] 943; 944 %call = call i32 @select(i1 1, i32 42, i32 %c) 945 ret i32 %call 946} 947 948define internal i32 @select(i1 %a, i32 %b, i32 %c) { 949; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 950; CGSCC-LABEL: define {{[^@]+}}@select 951; CGSCC-SAME: () #[[ATTR1]] { 952; CGSCC-NEXT: ret i32 42 953; 954 %s = select i1 %a, i32 %b, i32 %c 955 ret i32 %s 956} 957 958define i1 @icmp() { 959; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 960; TUNIT-LABEL: define {{[^@]+}}@icmp 961; TUNIT-SAME: () #[[ATTR2]] { 962; TUNIT-NEXT: ret i1 true 963; 964; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 965; CGSCC-LABEL: define {{[^@]+}}@icmp 966; CGSCC-SAME: () #[[ATTR1]] { 967; CGSCC-NEXT: ret i1 true 968; 969 %c = icmp eq ptr null, null 970 ret i1 %c 971} 972 973define void @test_callee_is_undef(ptr %fn) { 974; TUNIT-LABEL: define {{[^@]+}}@test_callee_is_undef 975; TUNIT-SAME: (ptr nofree captures(none) [[FN:%.*]]) { 976; TUNIT-NEXT: call void @unknown_calle_arg_is_undef(ptr nofree noundef captures(none) [[FN]]) 977; TUNIT-NEXT: ret void 978; 979; CGSCC-LABEL: define {{[^@]+}}@test_callee_is_undef 980; CGSCC-SAME: (ptr nofree noundef nonnull captures(none) [[FN:%.*]]) { 981; CGSCC-NEXT: call void @unknown_calle_arg_is_undef(ptr nofree noundef nonnull captures(none) [[FN]]) 982; CGSCC-NEXT: ret void 983; 984 call void @callee_is_undef(ptr undef) 985 call void @unknown_calle_arg_is_undef(ptr %fn, i32 undef) 986 ret void 987} 988define internal void @callee_is_undef(ptr %fn) { 989; 990; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 991; CGSCC-LABEL: define {{[^@]+}}@callee_is_undef 992; CGSCC-SAME: () #[[ATTR1]] { 993; CGSCC-NEXT: unreachable 994; 995 call void %fn() 996 ret void 997} 998define internal void @unknown_calle_arg_is_undef(ptr %fn, i32 %arg) { 999; 1000; CHECK-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef 1001; CHECK-SAME: (ptr nofree noundef nonnull captures(none) [[FN:%.*]]) { 1002; CHECK-NEXT: call void [[FN]](i32 undef) 1003; CHECK-NEXT: ret void 1004; 1005 call void %fn(i32 %arg) 1006 ret void 1007} 1008 1009; Taken from 50683 1010; {{{ 1011 1012@g = internal constant { [2 x ptr] } { [2 x ptr] [ptr @f1, ptr @f2] } 1013 1014define internal void @f1(ptr %a) { 1015; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 1016; TUNIT-LABEL: define {{[^@]+}}@f1 1017; TUNIT-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR4]] { 1018; TUNIT-NEXT: entry: 1019; TUNIT-NEXT: store ptr @g, ptr [[A]], align 8 1020; TUNIT-NEXT: ret void 1021; 1022; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) 1023; CGSCC-LABEL: define {{[^@]+}}@f1 1024; CGSCC-SAME: (ptr nofree noundef nonnull writeonly align 8 captures(none) dereferenceable(8) [[A:%.*]]) #[[ATTR5]] { 1025; CGSCC-NEXT: entry: 1026; CGSCC-NEXT: store ptr @g, ptr [[A]], align 8 1027; CGSCC-NEXT: ret void 1028; 1029entry: 1030 store ptr @g , ptr %a, align 8 1031 ret void 1032} 1033 1034define internal void @f2(ptr %a) { 1035; CHECK-LABEL: define {{[^@]+}}@f2 1036; CHECK-SAME: (ptr [[A:%.*]]) { 1037; CHECK-NEXT: cont461: 1038; CHECK-NEXT: call void @f3(ptr [[A]], ptr nofree captures(none) [[A]]) 1039; CHECK-NEXT: ret void 1040; 1041cont461: 1042 call void @f3(ptr %a, ptr %a) 1043 ret void 1044} 1045 1046define internal void @f3(ptr %a1, ptr %a) { 1047; CHECK-LABEL: define {{[^@]+}}@f3 1048; CHECK-SAME: (ptr [[A1:%.*]], ptr nofree captures(none) [[A:%.*]]) { 1049; CHECK-NEXT: entry: 1050; CHECK-NEXT: [[CALL20:%.*]] = call i1 @f9() 1051; CHECK-NEXT: br i1 [[CALL20]], label [[LAND_LHS_TRUE:%.*]], label [[IF_END40:%.*]] 1052; CHECK: land.lhs.true: 1053; CHECK-NEXT: [[TMP0:%.*]] = call i1 [[A]](ptr [[A1]]) 1054; CHECK-NEXT: br label [[IF_END40]] 1055; CHECK: if.end40: 1056; CHECK-NEXT: ret void 1057; 1058entry: 1059 %call20 = call i1 @f9() 1060 br i1 %call20, label %land.lhs.true, label %if.end40 1061 1062land.lhs.true: 1063 call i1 %a(ptr %a1) 1064 br label %if.end40 1065 1066if.end40: 1067 ret void 1068} 1069 1070define linkonce_odr i1 @f9() { 1071; CHECK-LABEL: define {{[^@]+}}@f9() { 1072; CHECK-NEXT: entry: 1073; CHECK-NEXT: ret i1 false 1074; 1075entry: 1076 ret i1 false 1077} 1078 1079; }}} 1080 1081 1082define i1 @test_cmp_null_after_cast() { 1083; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1084; TUNIT-LABEL: define {{[^@]+}}@test_cmp_null_after_cast 1085; TUNIT-SAME: () #[[ATTR2]] { 1086; TUNIT-NEXT: ret i1 true 1087; 1088; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 1089; CGSCC-LABEL: define {{[^@]+}}@test_cmp_null_after_cast 1090; CGSCC-SAME: () #[[ATTR3]] { 1091; CGSCC-NEXT: [[C:%.*]] = call noundef i1 @cmp_null_after_cast() #[[ATTR12]] 1092; CGSCC-NEXT: ret i1 [[C]] 1093; 1094 %c = call i1 @cmp_null_after_cast(i32 0, i8 0) 1095 ret i1 %c 1096} 1097define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) { 1098; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1099; CGSCC-LABEL: define {{[^@]+}}@cmp_null_after_cast 1100; CGSCC-SAME: () #[[ATTR1]] { 1101; CGSCC-NEXT: ret i1 true 1102; 1103 %t = trunc i32 %a to i8 1104 %c = icmp eq i8 %t, %b 1105 ret i1 %c 1106} 1107 1108 1109declare ptr @m() 1110 1111define i32 @test(i1 %c) { 1112; TUNIT-LABEL: define {{[^@]+}}@test 1113; TUNIT-SAME: (i1 [[C:%.*]]) { 1114; TUNIT-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 noundef [[C]]) 1115; TUNIT-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 noundef [[C]]), !range [[RNG0:![0-9]+]] 1116; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]] 1117; TUNIT-NEXT: ret i32 [[ADD]] 1118; 1119; CGSCC-LABEL: define {{[^@]+}}@test 1120; CGSCC-SAME: (i1 noundef [[C:%.*]]) { 1121; CGSCC-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 noundef [[C]]) 1122; CGSCC-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 noundef [[C]]) 1123; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]] 1124; CGSCC-NEXT: ret i32 [[ADD]] 1125; 1126 %r1 = call i32 @ctx_test1(i1 %c) 1127 %r2 = call i32 @ctx_test2(i1 %c) 1128 %add = add i32 %r1, %r2 1129 ret i32 %add 1130} 1131 1132define internal i32 @ctx_test1(i1 %c) { 1133; CHECK-LABEL: define {{[^@]+}}@ctx_test1 1134; CHECK-SAME: (i1 noundef [[C:%.*]]) { 1135; CHECK-NEXT: entry: 1136; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]] 1137; CHECK: then: 1138; CHECK-NEXT: [[M:%.*]] = tail call ptr @m() 1139; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[M]] to i64 1140; CHECK-NEXT: br label [[JOIN]] 1141; CHECK: join: 1142; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ] 1143; CHECK-NEXT: [[RET:%.*]] = trunc i64 [[PHI]] to i32 1144; CHECK-NEXT: ret i32 [[RET]] 1145; 1146entry: 1147 br i1 %c, label %then, label %join 1148 1149then: 1150 %m = tail call ptr @m() 1151 %i = ptrtoint ptr %m to i64 1152 br label %join 1153 1154join: 1155 %phi = phi i64 [ %i, %then ], [ undef, %entry ] 1156 %ret = trunc i64 %phi to i32 1157 ret i32 %ret 1158} 1159 1160define internal i32 @ctx_test2(i1 %c) { 1161; CHECK-LABEL: define {{[^@]+}}@ctx_test2 1162; CHECK-SAME: (i1 noundef [[C:%.*]]) { 1163; CHECK-NEXT: entry: 1164; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]] 1165; CHECK: then: 1166; CHECK-NEXT: [[M:%.*]] = tail call ptr @m() 1167; CHECK-NEXT: [[I:%.*]] = ptrtoint ptr [[M]] to i32 1168; CHECK-NEXT: br label [[JOIN]] 1169; CHECK: join: 1170; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ] 1171; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[PHI]], 1 1172; CHECK-NEXT: ret i32 [[RET]] 1173; 1174entry: 1175 br i1 %c, label %then, label %join 1176 1177then: 1178 %m = tail call ptr @m() 1179 %i = ptrtoint ptr %m to i32 1180 br label %join 1181 1182join: 1183 %phi = phi i32 [ %i, %then ], [ undef, %entry ] 1184 %ret = lshr i32 %phi, 1 1185 ret i32 %ret 1186 1187 uselistorder label %join, { 1, 0 } 1188} 1189 1190define i1 @test_liveness(i1 %c) { 1191; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1192; TUNIT-LABEL: define {{[^@]+}}@test_liveness 1193; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR2]] { 1194; TUNIT-NEXT: entry: 1195; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1196; TUNIT: t: 1197; TUNIT-NEXT: br label [[F]] 1198; TUNIT: f: 1199; TUNIT-NEXT: ret i1 false 1200; 1201; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 1202; CGSCC-LABEL: define {{[^@]+}}@test_liveness 1203; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR3]] { 1204; CGSCC-NEXT: entry: 1205; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1206; CGSCC: t: 1207; CGSCC-NEXT: br label [[F]] 1208; CGSCC: f: 1209; CGSCC-NEXT: [[P:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[T]] ] 1210; CGSCC-NEXT: [[RC1:%.*]] = call noundef i1 @ret(i1 noundef [[P]]) #[[ATTR12]] 1211; CGSCC-NEXT: ret i1 [[RC1]] 1212; 1213entry: 1214 br i1 %c, label %t, label %f 1215t: 1216 br label %f 1217f: 1218 %p = phi i1 [true, %entry], [false, %t] 1219 %rc1 = call i1 @ret(i1 %p) 1220 ret i1 %rc1 1221} 1222 1223define internal i1 @ret(i1 %c) { 1224; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1225; CGSCC-LABEL: define {{[^@]+}}@ret 1226; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR1]] { 1227; CGSCC-NEXT: entry: 1228; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 1229; CGSCC: t: 1230; CGSCC-NEXT: br label [[F]] 1231; CGSCC: f: 1232; CGSCC-NEXT: [[P:%.*]] = phi i1 [ [[C]], [[ENTRY:%.*]] ], [ false, [[T]] ] 1233; CGSCC-NEXT: ret i1 false 1234; 1235entry: 1236 br i1 %c, label %t, label %f 1237t: 1238 br label %f 1239f: 1240 %p = phi i1 [%c, %entry], [false, %t] 1241 ret i1 %p 1242} 1243 1244declare ptr @unknown() 1245define internal i8 @dead_ret() { 1246; CHECK-LABEL: define {{[^@]+}}@dead_ret() { 1247; CHECK-NEXT: [[R:%.*]] = call ptr @unknown() 1248; CHECK-NEXT: ret i8 undef 1249; 1250 %r = call ptr @unknown() 1251 %l = load i8, ptr %r 1252 ret i8 %l 1253} 1254 1255define void @dead_ret_caller() { 1256; CHECK-LABEL: define {{[^@]+}}@dead_ret_caller() { 1257; CHECK-NEXT: [[R:%.*]] = call i8 @dead_ret() 1258; CHECK-NEXT: ret void 1259; 1260 %r = call i8 @dead_ret() 1261 ret void 1262} 1263 1264declare void @llvm.memcpy(ptr %dest, ptr %src, i32 %len, i1 %isvolatile) 1265define internal i8 @memcpy_uses_store(i8 %arg) { 1266; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1267; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store 1268; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { 1269; TUNIT-NEXT: [[SRC:%.*]] = alloca i8, align 1 1270; TUNIT-NEXT: [[DST:%.*]] = alloca i8, align 1 1271; TUNIT-NEXT: store i8 [[ARG]], ptr [[SRC]], align 1 1272; TUNIT-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR12:[0-9]+]] 1273; TUNIT-NEXT: [[L:%.*]] = load i8, ptr [[DST]], align 1 1274; TUNIT-NEXT: ret i8 [[L]] 1275; 1276; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1277; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store 1278; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR1]] { 1279; CGSCC-NEXT: [[SRC:%.*]] = alloca i8, align 1 1280; CGSCC-NEXT: [[DST:%.*]] = alloca i8, align 1 1281; CGSCC-NEXT: store i8 [[ARG]], ptr [[SRC]], align 1 1282; CGSCC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noalias nofree noundef nonnull writeonly captures(none) dereferenceable(1) [[DST]], ptr noalias nofree noundef nonnull readonly captures(none) dereferenceable(1) [[SRC]], i32 noundef 1, i1 noundef false) #[[ATTR16:[0-9]+]] 1283; CGSCC-NEXT: [[L:%.*]] = load i8, ptr [[DST]], align 1 1284; CGSCC-NEXT: ret i8 [[L]] 1285; 1286 %src = alloca i8 1287 %dst = alloca i8 1288 store i8 %arg, ptr %src 1289 call void @llvm.memcpy(ptr %dst, ptr %src, i32 1, i1 false) 1290 %l = load i8, ptr %dst 1291 ret i8 %l 1292} 1293 1294define i8 @memcpy_uses_store_caller(i8 %arg) { 1295; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1296; TUNIT-LABEL: define {{[^@]+}}@memcpy_uses_store_caller 1297; TUNIT-SAME: (i8 [[ARG:%.*]]) #[[ATTR2]] { 1298; TUNIT-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR13:[0-9]+]] 1299; TUNIT-NEXT: ret i8 [[R]] 1300; 1301; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none) 1302; CGSCC-LABEL: define {{[^@]+}}@memcpy_uses_store_caller 1303; CGSCC-SAME: (i8 [[ARG:%.*]]) #[[ATTR3]] { 1304; CGSCC-NEXT: [[R:%.*]] = call i8 @memcpy_uses_store(i8 [[ARG]]) #[[ATTR12]] 1305; CGSCC-NEXT: ret i8 [[R]] 1306; 1307 %r = call i8 @memcpy_uses_store(i8 %arg) 1308 ret i8 %r 1309} 1310 1311 1312declare i32 @speculatable() speculatable readnone 1313 1314define i32 @test_speculatable_expr() norecurse { 1315; TUNIT: Function Attrs: norecurse nosync memory(none) 1316; TUNIT-LABEL: define {{[^@]+}}@test_speculatable_expr 1317; TUNIT-SAME: () #[[ATTR7:[0-9]+]] { 1318; TUNIT-NEXT: [[STACK:%.*]] = alloca i32, align 4 1319; TUNIT-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR14:[0-9]+]] 1320; TUNIT-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 1321; TUNIT-NEXT: store i32 [[PLUS1]], ptr [[STACK]], align 4 1322; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[STACK]], align 4 1323; TUNIT-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[TMP1]]) #[[ATTR15:[0-9]+]] 1324; TUNIT-NEXT: ret i32 [[RSPEC]] 1325; 1326; CGSCC: Function Attrs: norecurse nosync memory(none) 1327; CGSCC-LABEL: define {{[^@]+}}@test_speculatable_expr 1328; CGSCC-SAME: () #[[ATTR9:[0-9]+]] { 1329; CGSCC-NEXT: [[STACK:%.*]] = alloca i32, align 4 1330; CGSCC-NEXT: [[SPEC_RESULT:%.*]] = call i32 @speculatable() #[[ATTR17:[0-9]+]] 1331; CGSCC-NEXT: [[PLUS1:%.*]] = add i32 [[SPEC_RESULT]], 1 1332; CGSCC-NEXT: store i32 [[PLUS1]], ptr [[STACK]], align 4 1333; CGSCC-NEXT: [[RSPEC:%.*]] = call i32 @ret_speculatable_expr(i32 [[PLUS1]]) #[[ATTR17]] 1334; CGSCC-NEXT: ret i32 [[RSPEC]] 1335; 1336 %stack = alloca i32 1337 %spec_result = call i32 @speculatable() 1338 %plus1 = add i32 %spec_result, 1 1339 store i32 %plus1, ptr %stack 1340 %rspec = call i32 @ret_speculatable_expr(ptr %stack, i32 13) 1341 ret i32 %rspec 1342} 1343 1344define internal i32 @ret_speculatable_expr(ptr %mem, i32 %a2) { 1345; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1346; TUNIT-LABEL: define {{[^@]+}}@ret_speculatable_expr 1347; TUNIT-SAME: (i32 [[TMP0:%.*]]) #[[ATTR2]] { 1348; TUNIT-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 1349; TUNIT-NEXT: store i32 [[TMP0]], ptr [[MEM_PRIV]], align 4 1350; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[MEM_PRIV]], align 4 1351; TUNIT-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 1352; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 1353; TUNIT-NEXT: ret i32 [[ADD]] 1354; 1355; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1356; CGSCC-LABEL: define {{[^@]+}}@ret_speculatable_expr 1357; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1]] { 1358; CGSCC-NEXT: [[MEM_PRIV:%.*]] = alloca i32, align 4 1359; CGSCC-NEXT: store i32 [[TMP0]], ptr [[MEM_PRIV]], align 4 1360; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[MEM_PRIV]], align 4 1361; CGSCC-NEXT: [[MUL:%.*]] = mul i32 [[L]], 13 1362; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 7 1363; CGSCC-NEXT: ret i32 [[ADD]] 1364; 1365 %l = load i32, ptr %mem 1366 %mul = mul i32 %l, %a2 1367 %add = add i32 %mul, 7 1368 ret i32 %add 1369} 1370 1371define internal void @not_called1() { 1372; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1373; TUNIT-LABEL: define {{[^@]+}}@not_called1 1374; TUNIT-SAME: () #[[ATTR2]] { 1375; TUNIT-NEXT: ret void 1376; 1377; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1378; CGSCC-LABEL: define {{[^@]+}}@not_called1 1379; CGSCC-SAME: () #[[ATTR1]] { 1380; CGSCC-NEXT: ret void 1381; 1382 ret void 1383} 1384define internal void @not_called2() { 1385; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1386; TUNIT-LABEL: define {{[^@]+}}@not_called2 1387; TUNIT-SAME: () #[[ATTR2]] { 1388; TUNIT-NEXT: ret void 1389; 1390; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1391; CGSCC-LABEL: define {{[^@]+}}@not_called2 1392; CGSCC-SAME: () #[[ATTR1]] { 1393; CGSCC-NEXT: ret void 1394; 1395 ret void 1396} 1397define internal void @not_called3() { 1398; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1399; CGSCC-LABEL: define {{[^@]+}}@not_called3 1400; CGSCC-SAME: () #[[ATTR1]] { 1401; CGSCC-NEXT: ret void 1402; 1403 ret void 1404} 1405declare void @useFnDecl(ptr addrspace(42)); 1406define void @useFnDef(ptr addrspace(42) %arg) { 1407; CHECK-LABEL: define {{[^@]+}}@useFnDef 1408; CHECK-SAME: (ptr addrspace(42) [[ARG:%.*]]) { 1409; CHECK-NEXT: call void @useFnDecl(ptr addrspace(42) [[ARG]]) 1410; CHECK-NEXT: ret void 1411; 1412 call void @useFnDecl(ptr addrspace(42) %arg) 1413 ret void 1414} 1415define i1 @user_of_not_called() { 1416; CHECK-LABEL: define {{[^@]+}}@user_of_not_called() { 1417; CHECK-NEXT: call void @useFnDecl(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called1 to ptr addrspace(42))) 1418; CHECK-NEXT: call void @useFnDef(ptr addrspace(42) noundef nonnull addrspacecast (ptr @not_called2 to ptr addrspace(42))) 1419; CHECK-NEXT: ret i1 false 1420; 1421 call void @useFnDecl(ptr addrspace(42) addrspacecast (ptr @not_called1 to ptr addrspace(42))) 1422 call void @useFnDef(ptr addrspace(42) addrspacecast (ptr @not_called2 to ptr addrspace(42))) 1423 %cmp = icmp eq ptr addrspace(42) addrspacecast (ptr @not_called3 to ptr addrspace(42)), null 1424 ret i1 %cmp 1425} 1426 1427@x = external global i32 1428define internal void @indirect() { 1429; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1430; TUNIT-LABEL: define {{[^@]+}}@indirect 1431; TUNIT-SAME: () #[[ATTR5]] { 1432; TUNIT-NEXT: store i32 0, ptr @x, align 4 1433; TUNIT-NEXT: ret void 1434; 1435; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write) 1436; CGSCC-LABEL: define {{[^@]+}}@indirect 1437; CGSCC-SAME: () #[[ATTR10:[0-9]+]] { 1438; CGSCC-NEXT: store i32 0, ptr @x, align 4 1439; CGSCC-NEXT: ret void 1440; 1441 store i32 0, ptr @x 1442 ret void 1443} 1444 1445define internal void @broker(ptr %ptr) { 1446; TUNIT: Function Attrs: memory(readwrite, argmem: none) 1447; TUNIT-LABEL: define {{[^@]+}}@broker 1448; TUNIT-SAME: () #[[ATTR1]] { 1449; TUNIT-NEXT: entry: 1450; TUNIT-NEXT: call void @indirect() #[[ATTR16:[0-9]+]] 1451; TUNIT-NEXT: call void @unknown() 1452; TUNIT-NEXT: ret void 1453; 1454; CGSCC: Function Attrs: memory(readwrite, argmem: none) 1455; CGSCC-LABEL: define {{[^@]+}}@broker 1456; CGSCC-SAME: () #[[ATTR2]] { 1457; CGSCC-NEXT: entry: 1458; CGSCC-NEXT: call void @indirect() #[[ATTR18:[0-9]+]] 1459; CGSCC-NEXT: call void @unknown() 1460; CGSCC-NEXT: ret void 1461; 1462entry: 1463 call void %ptr() 1464 call void @unknown() 1465 ret void 1466} 1467 1468define void @entry() { 1469; CHECK-LABEL: define {{[^@]+}}@entry() { 1470; CHECK-NEXT: entry: 1471; CHECK-NEXT: call void @broker() 1472; CHECK-NEXT: ret void 1473; 1474entry: 1475 call void @broker(ptr @indirect) 1476 ret void 1477} 1478 1479define i8 @switch(i1 %c1, i1 %c2) { 1480; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1481; TUNIT-LABEL: define {{[^@]+}}@switch 1482; TUNIT-SAME: (i1 noundef [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR2]] { 1483; TUNIT-NEXT: entry: 1484; TUNIT-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] 1485; TUNIT: t: 1486; TUNIT-NEXT: br label [[M:%.*]] 1487; TUNIT: f: 1488; TUNIT-NEXT: br label [[M]] 1489; TUNIT: m: 1490; TUNIT-NEXT: [[J:%.*]] = phi i32 [ 0, [[T]] ], [ 4, [[F]] ] 1491; TUNIT-NEXT: switch i32 [[J]], label [[DEFAULT1:%.*]] [ 1492; TUNIT-NEXT: i32 1, label [[DEAD1:%.*]] 1493; TUNIT-NEXT: i32 2, label [[DEAD2:%.*]] 1494; TUNIT-NEXT: i32 3, label [[DEAD3:%.*]] 1495; TUNIT-NEXT: i32 4, label [[ALIVE1:%.*]] 1496; TUNIT-NEXT: ] 1497; TUNIT: default1: 1498; TUNIT-NEXT: br label [[ALIVE1]] 1499; TUNIT: alive1: 1500; TUNIT-NEXT: [[K:%.*]] = phi i32 [ 1, [[M]] ], [ 4, [[DEFAULT1]] ] 1501; TUNIT-NEXT: switch i32 [[K]], label [[DEAD4:%.*]] [ 1502; TUNIT-NEXT: i32 1, label [[END1:%.*]] 1503; TUNIT-NEXT: i32 2, label [[DEAD5:%.*]] 1504; TUNIT-NEXT: i32 4, label [[END2:%.*]] 1505; TUNIT-NEXT: ] 1506; TUNIT: end1: 1507; TUNIT-NEXT: ret i8 -1 1508; TUNIT: end2: 1509; TUNIT-NEXT: ret i8 -2 1510; TUNIT: dead1: 1511; TUNIT-NEXT: unreachable 1512; TUNIT: dead2: 1513; TUNIT-NEXT: unreachable 1514; TUNIT: dead3: 1515; TUNIT-NEXT: unreachable 1516; TUNIT: dead4: 1517; TUNIT-NEXT: unreachable 1518; TUNIT: dead5: 1519; TUNIT-NEXT: unreachable 1520; 1521; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1522; CGSCC-LABEL: define {{[^@]+}}@switch 1523; CGSCC-SAME: (i1 noundef [[C1:%.*]], i1 [[C2:%.*]]) #[[ATTR1]] { 1524; CGSCC-NEXT: entry: 1525; CGSCC-NEXT: br i1 [[C1]], label [[T:%.*]], label [[F:%.*]] 1526; CGSCC: t: 1527; CGSCC-NEXT: br label [[M:%.*]] 1528; CGSCC: f: 1529; CGSCC-NEXT: br label [[M]] 1530; CGSCC: m: 1531; CGSCC-NEXT: [[J:%.*]] = phi i32 [ 0, [[T]] ], [ 4, [[F]] ] 1532; CGSCC-NEXT: switch i32 [[J]], label [[DEFAULT1:%.*]] [ 1533; CGSCC-NEXT: i32 1, label [[DEAD1:%.*]] 1534; CGSCC-NEXT: i32 2, label [[DEAD2:%.*]] 1535; CGSCC-NEXT: i32 3, label [[DEAD3:%.*]] 1536; CGSCC-NEXT: i32 4, label [[ALIVE1:%.*]] 1537; CGSCC-NEXT: ] 1538; CGSCC: default1: 1539; CGSCC-NEXT: br label [[ALIVE1]] 1540; CGSCC: alive1: 1541; CGSCC-NEXT: [[K:%.*]] = phi i32 [ 1, [[M]] ], [ 4, [[DEFAULT1]] ] 1542; CGSCC-NEXT: switch i32 [[K]], label [[DEAD4:%.*]] [ 1543; CGSCC-NEXT: i32 1, label [[END1:%.*]] 1544; CGSCC-NEXT: i32 2, label [[DEAD5:%.*]] 1545; CGSCC-NEXT: i32 4, label [[END2:%.*]] 1546; CGSCC-NEXT: ] 1547; CGSCC: end1: 1548; CGSCC-NEXT: ret i8 -1 1549; CGSCC: end2: 1550; CGSCC-NEXT: ret i8 -2 1551; CGSCC: dead1: 1552; CGSCC-NEXT: unreachable 1553; CGSCC: dead2: 1554; CGSCC-NEXT: unreachable 1555; CGSCC: dead3: 1556; CGSCC-NEXT: unreachable 1557; CGSCC: dead4: 1558; CGSCC-NEXT: unreachable 1559; CGSCC: dead5: 1560; CGSCC-NEXT: unreachable 1561; 1562entry: 1563 br i1 %c1, label %t, label %f 1564 1565t: 1566 br label %m 1567 1568f: 1569 br label %m 1570 1571m: 1572 %j = phi i32 [ 0, %t ], [ 4, %f ] 1573 switch i32 %j, label %default1 [ 1574 i32 1, label %dead1 1575 i32 2, label %dead2 1576 i32 3, label %dead3 1577 i32 4, label %alive1 1578 ] 1579 1580default1: 1581 br label %alive1 1582 1583alive1: 1584 %k = phi i32 [ 1, %m ], [ 4, %default1 ] 1585 switch i32 %k, label %dead4 [ 1586 i32 1, label %end1 1587 i32 2, label %dead5 1588 i32 4, label %end2 1589 ] 1590 1591end1: 1592 ret i8 -1 1593end2: 1594 ret i8 -2 1595dead1: 1596 ret i8 1 1597dead2: 1598 ret i8 2 1599dead3: 1600 ret i8 3 1601dead4: 1602 ret i8 4 1603dead5: 1604 ret i8 5 1605} 1606 1607define i32 @readConst() { 1608; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1609; TUNIT-LABEL: define {{[^@]+}}@readConst 1610; TUNIT-SAME: () #[[ATTR2]] { 1611; TUNIT-NEXT: ret i32 0 1612; 1613; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1614; CGSCC-LABEL: define {{[^@]+}}@readConst 1615; CGSCC-SAME: () #[[ATTR1]] { 1616; CGSCC-NEXT: ret i32 0 1617; 1618 %l = load i32, ptr @ConstPtr 1619 ret i32 %l 1620} 1621 1622define i32 @readWeakConst() { 1623; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1624; TUNIT-LABEL: define {{[^@]+}}@readWeakConst 1625; TUNIT-SAME: () #[[ATTR2]] { 1626; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @ConstWeakPtr, align 4 1627; TUNIT-NEXT: ret i32 [[L]] 1628; 1629; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1630; CGSCC-LABEL: define {{[^@]+}}@readWeakConst 1631; CGSCC-SAME: () #[[ATTR1]] { 1632; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @ConstWeakPtr, align 4 1633; CGSCC-NEXT: ret i32 [[L]] 1634; 1635 %l = load i32, ptr @ConstWeakPtr 1636 ret i32 %l 1637} 1638 1639define i32 @readWeakOdrConst() { 1640; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1641; TUNIT-LABEL: define {{[^@]+}}@readWeakOdrConst 1642; TUNIT-SAME: () #[[ATTR2]] { 1643; TUNIT-NEXT: ret i32 0 1644; 1645; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) 1646; CGSCC-LABEL: define {{[^@]+}}@readWeakOdrConst 1647; CGSCC-SAME: () #[[ATTR1]] { 1648; CGSCC-NEXT: ret i32 0 1649; 1650 %l = load i32, ptr @ConstWeakODRPtr 1651 ret i32 %l 1652} 1653 1654;. 1655; TUNIT: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } 1656; TUNIT: attributes #[[ATTR1]] = { memory(readwrite, argmem: none) } 1657; TUNIT: attributes #[[ATTR2]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 1658; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn } 1659; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) } 1660; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) } 1661; TUNIT: attributes #[[ATTR6:[0-9]+]] = { speculatable memory(none) } 1662; TUNIT: attributes #[[ATTR7]] = { norecurse nosync memory(none) } 1663; TUNIT: attributes #[[ATTR8:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } 1664; TUNIT: attributes #[[ATTR9]] = { nofree nosync nounwind willreturn memory(none) } 1665; TUNIT: attributes #[[ATTR10]] = { nofree willreturn } 1666; TUNIT: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn memory(write) } 1667; TUNIT: attributes #[[ATTR12]] = { nofree willreturn memory(readwrite) } 1668; TUNIT: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn } 1669; TUNIT: attributes #[[ATTR14]] = { nosync } 1670; TUNIT: attributes #[[ATTR15]] = { nosync nounwind memory(read) } 1671; TUNIT: attributes #[[ATTR16]] = { nounwind memory(write) } 1672;. 1673; TUNIT: [[RNG0]] = !{i32 0, i32 -2147483648} 1674;. 1675; CGSCC: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn } 1676; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } 1677; CGSCC: attributes #[[ATTR2]] = { memory(readwrite, argmem: none) } 1678; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn memory(none) } 1679; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree nosync nounwind willreturn } 1680; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) } 1681; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: write) } 1682; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree nosync nounwind willreturn memory(write) } 1683; CGSCC: attributes #[[ATTR8:[0-9]+]] = { speculatable memory(none) } 1684; CGSCC: attributes #[[ATTR9]] = { norecurse nosync memory(none) } 1685; CGSCC: attributes #[[ATTR10]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) } 1686; CGSCC: attributes #[[ATTR11:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } 1687; CGSCC: attributes #[[ATTR12]] = { nofree nosync willreturn } 1688; CGSCC: attributes #[[ATTR13]] = { nofree willreturn } 1689; CGSCC: attributes #[[ATTR14]] = { nofree nounwind willreturn } 1690; CGSCC: attributes #[[ATTR15]] = { nofree nounwind willreturn memory(write) } 1691; CGSCC: attributes #[[ATTR16]] = { nofree willreturn memory(readwrite) } 1692; CGSCC: attributes #[[ATTR17]] = { nosync } 1693; CGSCC: attributes #[[ATTR18]] = { nounwind } 1694;. 1695