brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.3 KiB · a701d78 Raw
368 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt -S -passes='sroa<preserve-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG3; RUN: opt -S -passes='sroa<modify-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG4 5%pair = type { i32, i32 }6 7define i32 @test_sroa_select_gep(i1 %cond) {8; CHECK-LABEL: @test_sroa_select_gep(9; CHECK-NEXT:  bb:10; CHECK-NEXT:    [[LOAD_SROA_SPECULATED:%.*]] = select i1 [[COND:%.*]], i32 1, i32 211; CHECK-NEXT:    ret i32 [[LOAD_SROA_SPECULATED]]12;13bb:14  %a = alloca %pair, align 415  %b = alloca %pair, align 416  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 117  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 118  store i32 1, ptr %gep_a, align 419  store i32 2, ptr %gep_b, align 420  %select = select i1 %cond, ptr %a, ptr %b21  %gep = getelementptr inbounds %pair, ptr %select, i32 0, i32 122  %load = load i32, ptr %gep, align 423  ret i32 %load24}25 26define i32 @test_sroa_select_gep_non_inbound(i1 %cond) {27; CHECK-LABEL: @test_sroa_select_gep_non_inbound(28; CHECK-NEXT:  bb:29; CHECK-NEXT:    [[LOAD_SROA_SPECULATED:%.*]] = select i1 [[COND:%.*]], i32 1, i32 230; CHECK-NEXT:    ret i32 [[LOAD_SROA_SPECULATED]]31;32bb:33  %a = alloca %pair, align 434  %b = alloca %pair, align 435  %gep_a = getelementptr %pair, ptr %a, i32 0, i32 136  %gep_b = getelementptr %pair, ptr %b, i32 0, i32 137  store i32 1, ptr %gep_a, align 438  store i32 2, ptr %gep_b, align 439  %select = select i1 %cond, ptr %a, ptr %b40  %gep = getelementptr %pair, ptr %select, i32 0, i32 141  %load = load i32, ptr %gep, align 442  ret i32 %load43}44 45define i32 @test_sroa_select_gep_volatile_load(i1 %cond) {46; CHECK-LABEL: @test_sroa_select_gep_volatile_load(47; CHECK-NEXT:  bb:48; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 449; CHECK-NEXT:    [[A_SROA_2:%.*]] = alloca i32, align 450; CHECK-NEXT:    [[B_SROA_0:%.*]] = alloca i32, align 451; CHECK-NEXT:    [[B_SROA_2:%.*]] = alloca i32, align 452; CHECK-NEXT:    store i32 11, ptr [[A_SROA_0]], align 453; CHECK-NEXT:    store i32 12, ptr [[B_SROA_0]], align 454; CHECK-NEXT:    store i32 21, ptr [[A_SROA_2]], align 455; CHECK-NEXT:    store i32 22, ptr [[B_SROA_2]], align 456; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND:%.*]], ptr [[A_SROA_0]], ptr [[B_SROA_0]]57; CHECK-NEXT:    [[LOAD1:%.*]] = load volatile i32, ptr [[SELECT]], align 458; CHECK-NEXT:    [[SELECT_SROA_SEL:%.*]] = select i1 [[COND]], ptr [[A_SROA_2]], ptr [[B_SROA_2]]59; CHECK-NEXT:    [[LOAD2:%.*]] = load volatile i32, ptr [[SELECT_SROA_SEL]], align 460; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[LOAD1]], [[LOAD2]]61; CHECK-NEXT:    ret i32 [[ADD]]62;63bb:64  %a = alloca %pair, align 465  %b = alloca %pair, align 466  store i32 11, ptr %a, align 467  store i32 12, ptr %b, align 468  %gep_a1 = getelementptr inbounds %pair, ptr %a, i32 0, i32 169  %gep_b1 = getelementptr inbounds %pair, ptr %b, i32 0, i32 170  store i32 21, ptr %gep_a1, align 471  store i32 22, ptr %gep_b1, align 472  %select = select i1 %cond, ptr %a, ptr %b73  %load1 = load volatile i32, ptr %select, align 474  %gep2 = getelementptr inbounds %pair, ptr %select, i32 0, i32 175  %load2 = load volatile i32, ptr %gep2, align 476  %add = add i32 %load1, %load277  ret i32 %add78}79 80define i32 @test_sroa_select_gep_poison(i1 %cond) {81; CHECK-PRESERVE-CFG-LABEL: @test_sroa_select_gep_poison(82; CHECK-PRESERVE-CFG-NEXT:  bb:83; CHECK-PRESERVE-CFG-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 484; CHECK-PRESERVE-CFG-NEXT:    [[SELECT_SROA_SEL:%.*]] = select i1 [[COND:%.*]], ptr [[A_SROA_0]], ptr poison85; CHECK-PRESERVE-CFG-NEXT:    [[LOAD:%.*]] = load i32, ptr [[SELECT_SROA_SEL]], align 486; CHECK-PRESERVE-CFG-NEXT:    ret i32 [[LOAD]]87;88; CHECK-MODIFY-CFG-LABEL: @test_sroa_select_gep_poison(89; CHECK-MODIFY-CFG-NEXT:  bb:90; CHECK-MODIFY-CFG-NEXT:    br i1 [[COND:%.*]], label [[BB_CONT:%.*]], label [[BB_ELSE:%.*]]91; CHECK-MODIFY-CFG:       bb.else:92; CHECK-MODIFY-CFG-NEXT:    [[LOAD_ELSE_VAL:%.*]] = load i32, ptr poison, align 493; CHECK-MODIFY-CFG-NEXT:    br label [[BB_CONT]]94; CHECK-MODIFY-CFG:       bb.cont:95; CHECK-MODIFY-CFG-NEXT:    [[LOAD:%.*]] = phi i32 [ undef, [[BB:%.*]] ], [ [[LOAD_ELSE_VAL]], [[BB_ELSE]] ]96; CHECK-MODIFY-CFG-NEXT:    ret i32 [[LOAD]]97;98bb:99  %a = alloca %pair, align 4100  %select = select i1 %cond, ptr %a, ptr poison101  %gep = getelementptr inbounds %pair, ptr %select, i32 0, i32 1102  %load = load i32, ptr %gep, align 4103  ret i32 %load104}105 106define i32 @test_sroa_gep_select_gep(i1 %cond) {107; CHECK-LABEL: @test_sroa_gep_select_gep(108; CHECK-NEXT:  bb:109; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4110; CHECK-NEXT:    [[B_SROA_0:%.*]] = alloca i32, align 4111; CHECK-NEXT:    store i32 1, ptr [[A_SROA_0]], align 4112; CHECK-NEXT:    store i32 2, ptr [[B_SROA_0]], align 4113; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND:%.*]], ptr [[A_SROA_0]], ptr [[B_SROA_0]]114; CHECK-NEXT:    [[SELECT2:%.*]] = select i1 [[COND]], ptr [[SELECT]], ptr [[A_SROA_0]]115; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[SELECT2]], align 4116; CHECK-NEXT:    ret i32 [[LOAD]]117;118bb:119  %a = alloca %pair, align 4120  %b = alloca %pair, align 4121  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1122  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1123  store i32 1, ptr %gep_a, align 4124  store i32 2, ptr %gep_b, align 4125  %select = select i1 %cond, ptr %gep_a, ptr %gep_b126  %select2 = select i1 %cond, ptr %select, ptr %gep_a127  %load = load i32, ptr %select2, align 4128  ret i32 %load129}130 131define i32 @test_sroa_gep_select_gep_nonconst_idx(i1 %cond, i32 %idx) {132; CHECK-LABEL: @test_sroa_gep_select_gep_nonconst_idx(133; CHECK-NEXT:  bb:134; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4135; CHECK-NEXT:    [[B:%.*]] = alloca [[PAIR]], align 4136; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], ptr [[A]], i32 0, i32 1137; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], ptr [[B]], i32 0, i32 1138; CHECK-NEXT:    store i32 1, ptr [[GEP_A]], align 4139; CHECK-NEXT:    store i32 2, ptr [[GEP_B]], align 4140; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND:%.*]], ptr [[A]], ptr [[B]]141; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[SELECT]], i32 [[IDX:%.*]], i32 1142; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4143; CHECK-NEXT:    ret i32 [[LOAD]]144;145bb:146  %a = alloca %pair, align 4147  %b = alloca %pair, align 4148  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1149  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1150  store i32 1, ptr %gep_a, align 4151  store i32 2, ptr %gep_b, align 4152  %select = select i1 %cond, ptr %a, ptr %b153  %gep = getelementptr inbounds %pair, ptr %select, i32 %idx, i32 1154  %load = load i32, ptr %gep, align 4155  ret i32 %load156}157 158; Test gep of index select unfolding on an alloca that is splittable, but not159; promotable. The allocas here will be optimized away by subsequent passes.160define i32 @test_select_idx_memcpy(i1 %c, ptr %p) {161; CHECK-LABEL: @test_select_idx_memcpy(162; CHECK-NEXT:    [[ALLOCA_SROA_0:%.*]] = alloca [4 x i8], align 8163; CHECK-NEXT:    [[ALLOCA_SROA_2:%.*]] = alloca [20 x i8], align 4164; CHECK-NEXT:    [[ALLOCA_SROA_22:%.*]] = alloca [4 x i8], align 8165; CHECK-NEXT:    [[ALLOCA_SROA_3:%.*]] = alloca [132 x i8], align 4166; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[ALLOCA_SROA_0]], ptr align 1 [[P:%.*]], i64 4, i1 false)167; CHECK-NEXT:    [[ALLOCA_SROA_2_0_P_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 4168; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[ALLOCA_SROA_2]], ptr align 1 [[ALLOCA_SROA_2_0_P_SROA_IDX]], i64 20, i1 false)169; CHECK-NEXT:    [[ALLOCA_SROA_22_0_P_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 24170; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[ALLOCA_SROA_22]], ptr align 1 [[ALLOCA_SROA_22_0_P_SROA_IDX]], i64 4, i1 false)171; CHECK-NEXT:    [[ALLOCA_SROA_3_0_P_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 28172; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[ALLOCA_SROA_3]], ptr align 1 [[ALLOCA_SROA_3_0_P_SROA_IDX]], i64 132, i1 false)173; CHECK-NEXT:    [[IDX:%.*]] = select i1 [[C:%.*]], i64 24, i64 0174; CHECK-NEXT:    [[IDX_SROA_SEL:%.*]] = select i1 [[C]], ptr [[ALLOCA_SROA_22]], ptr [[ALLOCA_SROA_0]]175; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[IDX_SROA_SEL]], align 4176; CHECK-NEXT:    ret i32 [[RES]]177;178  %alloca = alloca [20 x i64], align 8179  call void @llvm.memcpy.p0.p0.i64(ptr %alloca, ptr %p, i64 160, i1 false)180  %idx = select i1 %c, i64 24, i64 0181  %gep = getelementptr inbounds i8, ptr %alloca, i64 %idx182  %res = load i32, ptr %gep, align 4183  ret i32 %res184}185 186; Test gep of index select unfolding on an alloca that is splittable and187; promotable.188define i32 @test_select_idx_mem2reg(i1 %c) {189; CHECK-LABEL: @test_select_idx_mem2reg(190; CHECK-NEXT:    [[IDX:%.*]] = select i1 [[C:%.*]], i64 24, i64 0191; CHECK-NEXT:    [[RES_SROA_SPECULATED:%.*]] = select i1 [[C]], i32 2, i32 1192; CHECK-NEXT:    ret i32 [[RES_SROA_SPECULATED]]193;194  %alloca = alloca [20 x i64], align 8195  store i32 1, ptr %alloca196  %gep1 = getelementptr inbounds i8, ptr %alloca, i64 24197  store i32 2, ptr %gep1198  %idx = select i1 %c, i64 24, i64 0199  %gep2 = getelementptr inbounds i8, ptr %alloca, i64 %idx200  %res = load i32, ptr %gep2, align 4201  ret i32 %res202}203 204; Test gep with a select-like zext index unfolding on an alloca that is205; splittable and promotable.206define i64 @test_select_like_zext_idx_mem2reg(i1 %c) !prof !0 {207; CHECK-LABEL: @test_select_like_zext_idx_mem2reg(208; CHECK-NEXT:    [[IDX:%.*]] = zext i1 [[C:%.*]] to i64209; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C]], i64 2, i64 1, !prof [[PROF1:![0-9]+]]210; CHECK-NEXT:    ret i64 [[RES]]211;212  %alloca = alloca [2 x i64], align 8213  store i64 1, ptr %alloca214  %gep1 = getelementptr inbounds i64, ptr %alloca, i64 1215  store i64 2, ptr %gep1216  %idx = zext i1 %c to i64217  %gep2 = getelementptr inbounds i64, ptr %alloca, i64 %idx218  %res = load i64, ptr %gep2219  ret i64 %res220}221 222; Test gep with a zext index that is not equivalent to a select. No unfolding223; or promotion should take place.224define i64 @test_zext_unlike_select_idx_mem2reg(i8 %c) {225; CHECK-LABEL: @test_zext_unlike_select_idx_mem2reg(226; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [2 x i64], align 8227; CHECK-NEXT:    store i64 1, ptr [[ALLOCA]], align 4228; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 1229; CHECK-NEXT:    store i64 2, ptr [[GEP1]], align 4230; CHECK-NEXT:    [[IDX:%.*]] = zext i8 [[C:%.*]] to i64231; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 [[IDX]]232; CHECK-NEXT:    [[RES:%.*]] = load i64, ptr [[GEP2]], align 4233; CHECK-NEXT:    ret i64 [[RES]]234;235  %alloca = alloca [2 x i64], align 8236  store i64 1, ptr %alloca237  %gep1 = getelementptr inbounds i64, ptr %alloca, i64 1238  store i64 2, ptr %gep1239  %idx = zext i8 %c to i64240  %gep2 = getelementptr inbounds i64, ptr %alloca, i64 %idx241  %res = load i64, ptr %gep2242  ret i64 %res243}244 245; Test gep of index select unfolding on an alloca that escaped, and as such246; is not splittable or promotable.247; FIXME: Ideally, no transform would take place in this case.248define i32 @test_select_idx_escaped(i1 %c, ptr %p) {249; CHECK-LABEL: @test_select_idx_escaped(250; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [20 x i64], align 8251; CHECK-NEXT:    store ptr [[ALLOCA]], ptr [[P:%.*]], align 8252; CHECK-NEXT:    store i32 1, ptr [[ALLOCA]], align 4253; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 24254; CHECK-NEXT:    store i32 2, ptr [[GEP1]], align 4255; CHECK-NEXT:    [[IDX:%.*]] = select i1 [[C:%.*]], i64 24, i64 0256; CHECK-NEXT:    [[DOTSROA_GEP:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 24257; CHECK-NEXT:    [[DOTSROA_GEP1:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 0258; CHECK-NEXT:    [[IDX_SROA_SEL:%.*]] = select i1 [[C]], ptr [[DOTSROA_GEP]], ptr [[DOTSROA_GEP1]]259; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[IDX_SROA_SEL]], align 4260; CHECK-NEXT:    ret i32 [[RES]]261;262  %alloca = alloca [20 x i64], align 8263  store ptr %alloca, ptr %p264  store i32 1, ptr %alloca265  %gep1 = getelementptr inbounds i8, ptr %alloca, i64 24266  store i32 2, ptr %gep1267  %idx = select i1 %c, i64 24, i64 0268  %gep2 = getelementptr inbounds i8, ptr %alloca, i64 %idx269  %res = load i32, ptr %gep2, align 4270  ret i32 %res271}272 273; FIXME: Should we allow recursive select unfolding if all the leaves are274; constants?275define i32 @test_select_idx_nested(i1 %c, i1 %c2) {276; CHECK-LABEL: @test_select_idx_nested(277; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [20 x i64], align 8278; CHECK-NEXT:    store i32 1, ptr [[ALLOCA]], align 4279; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 8280; CHECK-NEXT:    store i32 2, ptr [[GEP1]], align 4281; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 24282; CHECK-NEXT:    store i32 3, ptr [[GEP2]], align 4283; CHECK-NEXT:    [[IDX1:%.*]] = select i1 [[C:%.*]], i64 24, i64 0284; CHECK-NEXT:    [[IDX2:%.*]] = select i1 [[C2:%.*]], i64 [[IDX1]], i64 8285; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 [[IDX2]]286; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[GEP3]], align 4287; CHECK-NEXT:    ret i32 [[RES]]288;289  %alloca = alloca [20 x i64], align 8290  store i32 1, ptr %alloca291  %gep1 = getelementptr inbounds i8, ptr %alloca, i64 8292  store i32 2, ptr %gep1293  %gep2 = getelementptr inbounds i8, ptr %alloca, i64 24294  store i32 3, ptr %gep2295  %idx1 = select i1 %c, i64 24, i64 0296  %idx2 = select i1 %c2, i64 %idx1, i64 8297  %gep3 = getelementptr inbounds i8, ptr %alloca, i64 %idx2298  %res = load i32, ptr %gep3, align 4299  ret i32 %res300}301 302; The following cases involve non-constant indices and should not be303; transformed.304 305define i32 @test_select_idx_not_constant1(i1 %c, ptr %p, i64 %arg) {306; CHECK-LABEL: @test_select_idx_not_constant1(307; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [20 x i64], align 8308; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[ALLOCA]], ptr [[P:%.*]], i64 160, i1 false)309; CHECK-NEXT:    [[IDX:%.*]] = select i1 [[C:%.*]], i64 24, i64 [[ARG:%.*]]310; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 [[IDX]]311; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[GEP]], align 4312; CHECK-NEXT:    ret i32 [[RES]]313;314  %alloca = alloca [20 x i64], align 8315  call void @llvm.memcpy.p0.p0.i64(ptr %alloca, ptr %p, i64 160, i1 false)316  %idx = select i1 %c, i64 24, i64 %arg317  %gep = getelementptr inbounds i8, ptr %alloca, i64 %idx318  %res = load i32, ptr %gep, align 4319  ret i32 %res320}321 322define i32 @test_select_idx_not_constant2(i1 %c, ptr %p, i64 %arg) {323; CHECK-LABEL: @test_select_idx_not_constant2(324; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [20 x i64], align 8325; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[ALLOCA]], ptr [[P:%.*]], i64 160, i1 false)326; CHECK-NEXT:    [[IDX:%.*]] = select i1 [[C:%.*]], i64 [[ARG:%.*]], i64 0327; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[ALLOCA]], i64 [[IDX]]328; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[GEP]], align 4329; CHECK-NEXT:    ret i32 [[RES]]330;331  %alloca = alloca [20 x i64], align 8332  call void @llvm.memcpy.p0.p0.i64(ptr %alloca, ptr %p, i64 160, i1 false)333  %idx = select i1 %c, i64 %arg, i64 0334  %gep = getelementptr inbounds i8, ptr %alloca, i64 %idx335  %res = load i32, ptr %gep, align 4336  ret i32 %res337}338 339define i32 @test_select_idx_not_constant3(i1 %c, ptr %p, i64 %arg) {340; CHECK-LABEL: @test_select_idx_not_constant3(341; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [20 x i64], align 8342; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[ALLOCA]], ptr [[P:%.*]], i64 160, i1 false)343; CHECK-NEXT:    [[IDX:%.*]] = select i1 [[C:%.*]], i64 24, i64 0344; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x i8], ptr [[ALLOCA]], i64 [[IDX]], i64 [[ARG:%.*]]345; CHECK-NEXT:    [[RES:%.*]] = load i32, ptr [[GEP]], align 4346; CHECK-NEXT:    ret i32 [[RES]]347;348  %alloca = alloca [20 x i64], align 8349  call void @llvm.memcpy.p0.p0.i64(ptr %alloca, ptr %p, i64 160, i1 false)350  %idx = select i1 %c, i64 24, i64 0351  %gep = getelementptr inbounds [1 x i8], ptr %alloca, i64 %idx, i64 %arg352  %res = load i32, ptr %gep, align 4353  ret i32 %res354}355 356!0 = !{!"function_entry_count", i32 10}357;.358; CHECK-PRESERVE-CFG: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }359;.360; CHECK-MODIFY-CFG: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }361;.362; CHECK-PRESERVE-CFG: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}363; CHECK-PRESERVE-CFG: [[PROF1]] = !{!"unknown", !"sroa"}364;.365; CHECK-MODIFY-CFG: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}366; CHECK-MODIFY-CFG: [[PROF1]] = !{!"unknown", !"sroa"}367;.368