908 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; 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 5define i32 @alloca_used_in_call(ptr %data, i64 %n) {6; CHECK-LABEL: @alloca_used_in_call(7; CHECK-NEXT: entry:8; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 49; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 410; CHECK-NEXT: br label [[LOOP:%.*]]11; CHECK: loop:12; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]13; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]14; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]15; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 416; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]17; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 418; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 119; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]20; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]21; CHECK: exit:22; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])23; CHECK-NEXT: ret i32 [[RDX_INC]]24;25entry:26 %retval = alloca i32, align 427 store i32 0, ptr %retval, align 428 br label %loop29 30loop:31 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]32 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv33 %ld = load i32, ptr %arrayidx, align 434 %rdx = load i32, ptr %retval, align 435 %rdx.inc = add nsw i32 %rdx, %ld36 store i32 %rdx.inc, ptr %retval, align 437 %indvars.iv.next = add nsw i64 %indvars.iv, 138 %exitcond = icmp ne i64 %indvars.iv.next, %n39 br i1 %exitcond, label %loop, label %exit40 41exit:42 %i0 = call i32 @user_of_alloca(ptr %retval)43 %i1 = load i32, ptr %retval, align 444 ret i32 %i145}46 47define i32 @alloca_captured_in_call(ptr %data, i64 %n) {48; CHECK-LABEL: @alloca_captured_in_call(49; CHECK-NEXT: entry:50; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 451; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 452; CHECK-NEXT: br label [[LOOP:%.*]]53; CHECK: loop:54; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]55; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]56; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 457; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 458; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]59; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 460; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 161; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]62; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]63; CHECK: exit:64; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr [[RETVAL]])65; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 466; CHECK-NEXT: ret i32 [[I1]]67;68entry:69 %retval = alloca i32, align 470 store i32 0, ptr %retval, align 471 br label %loop72 73loop:74 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]75 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv76 %ld = load i32, ptr %arrayidx, align 477 %rdx = load i32, ptr %retval, align 478 %rdx.inc = add nsw i32 %rdx, %ld79 store i32 %rdx.inc, ptr %retval, align 480 %indvars.iv.next = add nsw i64 %indvars.iv, 181 %exitcond = icmp ne i64 %indvars.iv.next, %n82 br i1 %exitcond, label %loop, label %exit83 84exit:85 %i0 = call i32 @capture_of_alloca(ptr %retval)86 %i1 = load i32, ptr %retval, align 487 ret i32 %i188}89 90define i32 @alloca_not_captured_as_per_operand_attr(ptr %data, i64 %n) {91; CHECK-LABEL: @alloca_not_captured_as_per_operand_attr(92; CHECK-NEXT: entry:93; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 494; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 495; CHECK-NEXT: br label [[LOOP:%.*]]96; CHECK: loop:97; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]98; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]99; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4100; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4101; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]102; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4103; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1104; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]105; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]106; CHECK: exit:107; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr captures(none) [[RETVAL]])108; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4109; CHECK-NEXT: ret i32 [[I1]]110;111entry:112 %retval = alloca i32, align 4113 store i32 0, ptr %retval, align 4114 br label %loop115 116loop:117 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]118 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv119 %ld = load i32, ptr %arrayidx, align 4120 %rdx = load i32, ptr %retval, align 4121 %rdx.inc = add nsw i32 %rdx, %ld122 store i32 %rdx.inc, ptr %retval, align 4123 %indvars.iv.next = add nsw i64 %indvars.iv, 1124 %exitcond = icmp ne i64 %indvars.iv.next, %n125 br i1 %exitcond, label %loop, label %exit126 127exit:128 %i0 = call i32 @capture_of_alloca(ptr nocapture %retval)129 %i1 = load i32, ptr %retval, align 4130 ret i32 %i1131}132 133define i32 @alloca_not_captured_and_readonly_as_per_operand_attr(ptr %data, i64 %n) {134; CHECK-LABEL: @alloca_not_captured_and_readonly_as_per_operand_attr(135; CHECK-NEXT: entry:136; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4137; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4138; CHECK-NEXT: br label [[LOOP:%.*]]139; CHECK: loop:140; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]141; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]142; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]143; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4144; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]145; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4146; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1147; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]148; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]149; CHECK: exit:150; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr readonly captures(none) [[RETVAL]])151; CHECK-NEXT: ret i32 [[RDX_INC]]152;153entry:154 %retval = alloca i32, align 4155 store i32 0, ptr %retval, align 4156 br label %loop157 158loop:159 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]160 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv161 %ld = load i32, ptr %arrayidx, align 4162 %rdx = load i32, ptr %retval, align 4163 %rdx.inc = add nsw i32 %rdx, %ld164 store i32 %rdx.inc, ptr %retval, align 4165 %indvars.iv.next = add nsw i64 %indvars.iv, 1166 %exitcond = icmp ne i64 %indvars.iv.next, %n167 br i1 %exitcond, label %loop, label %exit168 169exit:170 %i0 = call i32 @capture_of_alloca(ptr nocapture readonly %retval)171 %i1 = load i32, ptr %retval, align 4172 ret i32 %i1173}174 175define i32 @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase_attr(ptr %data, i64 %n) {176; CHECK-LABEL: @alloca_not_captured_as_per_operand_attr_and_readonly_as_per_callbase_attr(177; CHECK-NEXT: entry:178; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4179; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4180; CHECK-NEXT: br label [[LOOP:%.*]]181; CHECK: loop:182; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]183; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]184; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4185; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4186; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]187; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4188; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1189; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]190; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]191; CHECK: exit:192; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr captures(none) [[RETVAL]]) #[[ATTR2:[0-9]+]]193; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4194; CHECK-NEXT: ret i32 [[I1]]195;196entry:197 %retval = alloca i32, align 4198 store i32 0, ptr %retval, align 4199 br label %loop200 201loop:202 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]203 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv204 %ld = load i32, ptr %arrayidx, align 4205 %rdx = load i32, ptr %retval, align 4206 %rdx.inc = add nsw i32 %rdx, %ld207 store i32 %rdx.inc, ptr %retval, align 4208 %indvars.iv.next = add nsw i64 %indvars.iv, 1209 %exitcond = icmp ne i64 %indvars.iv.next, %n210 br i1 %exitcond, label %loop, label %exit211 212exit:213 %i0 = call i32 @capture_of_alloca(ptr nocapture %retval) readonly214 %i1 = load i32, ptr %retval, align 4215 ret i32 %i1216}217 218define i32 @alloca_not_readonly_as_per_operand_attr(ptr %data, i64 %n) {219; CHECK-LABEL: @alloca_not_readonly_as_per_operand_attr(220; CHECK-NEXT: entry:221; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4222; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4223; CHECK-NEXT: br label [[LOOP:%.*]]224; CHECK: loop:225; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]226; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]227; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4228; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4229; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]230; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4231; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1232; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]233; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]234; CHECK: exit:235; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_of_alloca(ptr readonly [[RETVAL]])236; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4237; CHECK-NEXT: ret i32 [[I1]]238;239entry:240 %retval = alloca i32, align 4241 store i32 0, ptr %retval, align 4242 br label %loop243 244loop:245 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]246 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv247 %ld = load i32, ptr %arrayidx, align 4248 %rdx = load i32, ptr %retval, align 4249 %rdx.inc = add nsw i32 %rdx, %ld250 store i32 %rdx.inc, ptr %retval, align 4251 %indvars.iv.next = add nsw i64 %indvars.iv, 1252 %exitcond = icmp ne i64 %indvars.iv.next, %n253 br i1 %exitcond, label %loop, label %exit254 255exit:256 %i0 = call i32 @capture_of_alloca(ptr readonly %retval)257 %i1 = load i32, ptr %retval, align 4258 ret i32 %i1259}260 261define i32 @alloca_with_gep_used_in_call(ptr %data, i64 %n) {262; CHECK-LABEL: @alloca_with_gep_used_in_call(263; CHECK-NEXT: entry:264; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4265; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4266; CHECK-NEXT: br label [[LOOP:%.*]]267; CHECK: loop:268; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]269; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]270; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]271; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4272; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]273; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4274; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1275; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]276; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]277; CHECK: exit:278; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])279; CHECK-NEXT: ret i32 [[RDX_INC]]280;281entry:282 %retval = alloca i32, align 4283 store i32 0, ptr %retval, align 4284 br label %loop285 286loop:287 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]288 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv289 %ld = load i32, ptr %arrayidx, align 4290 %rdx = load i32, ptr %retval, align 4291 %rdx.inc = add nsw i32 %rdx, %ld292 store i32 %rdx.inc, ptr %retval, align 4293 %indvars.iv.next = add nsw i64 %indvars.iv, 1294 %exitcond = icmp ne i64 %indvars.iv.next, %n295 br i1 %exitcond, label %loop, label %exit296 297exit:298 %i0 = call i32 @user_of_alloca(ptr %retval)299 %i1 = load i32, ptr %retval, align 4300 ret i32 %i1301}302 303define i32 @alloca_captured_second_arg(ptr %data, i64 %n) {304; CHECK-LABEL: @alloca_captured_second_arg(305; CHECK-NEXT: entry:306; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4307; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4308; CHECK-NEXT: br label [[LOOP:%.*]]309; CHECK: loop:310; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]311; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]312; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4313; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4314; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]315; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4316; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1317; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]318; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]319; CHECK: exit:320; CHECK-NEXT: [[I0:%.*]] = call i32 @capture_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL]])321; CHECK-NEXT: [[I1:%.*]] = load i32, ptr [[RETVAL]], align 4322; CHECK-NEXT: ret i32 [[I1]]323;324entry:325 %retval = alloca i32, align 4326 store i32 0, ptr %retval, align 4327 br label %loop328 329loop:330 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]331 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv332 %ld = load i32, ptr %arrayidx, align 4333 %rdx = load i32, ptr %retval, align 4334 %rdx.inc = add nsw i32 %rdx, %ld335 store i32 %rdx.inc, ptr %retval, align 4336 %indvars.iv.next = add nsw i64 %indvars.iv, 1337 %exitcond = icmp ne i64 %indvars.iv.next, %n338 br i1 %exitcond, label %loop, label %exit339 340exit:341 %i0 = call i32 @capture_with_multiple_args(ptr %retval, ptr %retval)342 %i1 = load i32, ptr %retval, align 4343 ret i32 %i1344}345 346define i32 @alloca_used_in_maybe_throwing_call(ptr %data, i64 %n) personality ptr @__gxx_personality_v0 {347; CHECK-LABEL: @alloca_used_in_maybe_throwing_call(348; CHECK-NEXT: entry:349; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4350; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4351; CHECK-NEXT: br label [[LOOP:%.*]]352; CHECK: loop:353; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]354; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]355; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]356; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4357; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]358; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4359; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1360; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]361; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]362; CHECK: exit:363; CHECK-NEXT: [[I0:%.*]] = invoke i32 @user_of_alloca(ptr [[RETVAL]])364; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[UW:%.*]]365; CHECK: cont:366; CHECK-NEXT: br label [[END:%.*]]367; CHECK: uw:368; CHECK-NEXT: [[I1:%.*]] = landingpad { ptr, i32 }369; CHECK-NEXT: catch ptr null370; CHECK-NEXT: br label [[END]]371; CHECK: end:372; CHECK-NEXT: ret i32 [[RDX_INC]]373;374entry:375 %retval = alloca i32, align 4376 store i32 0, ptr %retval, align 4377 br label %loop378 379loop:380 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]381 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv382 %ld = load i32, ptr %arrayidx, align 4383 %rdx = load i32, ptr %retval, align 4384 %rdx.inc = add nsw i32 %rdx, %ld385 store i32 %rdx.inc, ptr %retval, align 4386 %indvars.iv.next = add nsw i64 %indvars.iv, 1387 %exitcond = icmp ne i64 %indvars.iv.next, %n388 br i1 %exitcond, label %loop, label %exit389 390exit:391 %i0 = invoke i32 @user_of_alloca(ptr %retval) to label %cont unwind label %uw392 393cont:394 br label %end395 396uw:397 %i1 = landingpad { ptr, i32 } catch ptr null398 br label %end399 400end:401 %i2 = load i32, ptr %retval, align 4402 ret i32 %i2403}404 405define i32 @alloca_used_in_maybe_throwing_call_with_same_dests(ptr %data, i64 %n) personality ptr @__gxx_personality_v0 {406; CHECK-LABEL: @alloca_used_in_maybe_throwing_call_with_same_dests(407; CHECK-NEXT: entry:408; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4409; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4410; CHECK-NEXT: br label [[LOOP:%.*]]411; CHECK: loop:412; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]413; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]414; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]415; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4416; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]417; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4418; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1419; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]420; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]421; CHECK: exit:422; CHECK-NEXT: [[I0:%.*]] = invoke i32 @user_of_alloca(ptr [[RETVAL]])423; CHECK-NEXT: to label [[END:%.*]] unwind label [[UW:%.*]]424; CHECK: uw:425; CHECK-NEXT: [[I1:%.*]] = landingpad { ptr, i32 }426; CHECK-NEXT: catch ptr null427; CHECK-NEXT: br label [[END]]428; CHECK: end:429; CHECK-NEXT: ret i32 [[RDX_INC]]430;431entry:432 %retval = alloca i32, align 4433 store i32 0, ptr %retval, align 4434 br label %loop435 436loop:437 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]438 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv439 %ld = load i32, ptr %arrayidx, align 4440 %rdx = load i32, ptr %retval, align 4441 %rdx.inc = add nsw i32 %rdx, %ld442 store i32 %rdx.inc, ptr %retval, align 4443 %indvars.iv.next = add nsw i64 %indvars.iv, 1444 %exitcond = icmp ne i64 %indvars.iv.next, %n445 br i1 %exitcond, label %loop, label %exit446 447exit:448 %i0 = invoke i32 @user_of_alloca(ptr %retval) to label %end unwind label %uw449 450uw:451 %i1 = landingpad { ptr, i32 } catch ptr null452 br label %end453 454end:455 %i2 = load i32, ptr %retval, align 4456 ret i32 %i2457}458 459define [2 x i32] @part_of_alloca_used_in_call(ptr %data, i64 %n) {460; CHECK-LABEL: @part_of_alloca_used_in_call(461; CHECK-NEXT: entry:462; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4463; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0464; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4465; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1466; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4467; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1468; CHECK-NEXT: br label [[LOOP:%.*]]469; CHECK: loop:470; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]471; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]472; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]473; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4474; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]475; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4476; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1477; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]478; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]479; CHECK: exit:480; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])481; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0482; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0483; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1484; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1485; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]]486;487entry:488 %retval.full = alloca [2 x i32], align 4489 store [2 x i32] zeroinitializer, ptr %retval.full, align 4490 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1491 br label %loop492 493loop:494 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]495 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv496 %ld = load i32, ptr %arrayidx, align 4497 %rdx = load i32, ptr %retval, align 4498 %rdx.inc = add nsw i32 %rdx, %ld499 store i32 %rdx.inc, ptr %retval, align 4500 %indvars.iv.next = add nsw i64 %indvars.iv, 1501 %exitcond = icmp ne i64 %indvars.iv.next, %n502 br i1 %exitcond, label %loop, label %exit503 504exit:505 %i0 = call i32 @user_of_alloca(ptr %retval)506 %i1 = load [2 x i32], ptr %retval.full, align 4507 ret [2 x i32] %i1508}509 510define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args(ptr %data, i64 %n) {511; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args(512; CHECK-NEXT: entry:513; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4514; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0515; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4516; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1517; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4518; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1519; CHECK-NEXT: br label [[LOOP:%.*]]520; CHECK: loop:521; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]522; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]523; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]524; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4525; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]526; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4527; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1528; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]529; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]530; CHECK: exit:531; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])532; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0533; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0534; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1535; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1536; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]]537;538entry:539 %retval.full = alloca [2 x i32], align 4540 store [2 x i32] zeroinitializer, ptr %retval.full, align 4541 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1542 br label %loop543 544loop:545 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]546 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv547 %ld = load i32, ptr %arrayidx, align 4548 %rdx = load i32, ptr %retval, align 4549 %rdx.inc = add nsw i32 %rdx, %ld550 store i32 %rdx.inc, ptr %retval, align 4551 %indvars.iv.next = add nsw i64 %indvars.iv, 1552 %exitcond = icmp ne i64 %indvars.iv.next, %n553 br i1 %exitcond, label %loop, label %exit554 555exit:556 %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)557 %i1 = load [2 x i32], ptr %retval.full, align 4558 ret [2 x i32] %i1559}560 561define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_before_call(ptr %data, i64 %n) {562; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_before_call(563; CHECK-NEXT: entry:564; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4565; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0566; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4567; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1568; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4569; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1570; CHECK-NEXT: br label [[LOOP:%.*]]571; CHECK: loop:572; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]573; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]574; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4575; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4576; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]577; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4578; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1579; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]580; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]581; CHECK: exit:582; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[RETVAL_FULL]], ptr [[RETVAL]], i32 4, i1 false)583; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])584; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0585; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4586; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0587; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1588; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4589; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1590; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]]591;592entry:593 %retval.full = alloca [2 x i32], align 4594 store [2 x i32] zeroinitializer, ptr %retval.full, align 4595 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1596 br label %loop597 598loop:599 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]600 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv601 %ld = load i32, ptr %arrayidx, align 4602 %rdx = load i32, ptr %retval, align 4603 %rdx.inc = add nsw i32 %rdx, %ld604 store i32 %rdx.inc, ptr %retval, align 4605 %indvars.iv.next = add nsw i64 %indvars.iv, 1606 %exitcond = icmp ne i64 %indvars.iv.next, %n607 br i1 %exitcond, label %loop, label %exit608 609exit:610 call void @llvm.memcpy.p0.p0.i32(ptr %retval.full, ptr %retval, i32 4, i1 false)611 %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)612 %i1 = load [2 x i32], ptr %retval.full, align 4613 ret [2 x i32] %i1614}615 616define [2 x i32] @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_after_call(ptr %data, i64 %n) {617; CHECK-LABEL: @all_parts_of_alloca_used_in_call_with_multiple_args_with_memcpy_after_call(618; CHECK-NEXT: entry:619; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4620; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0621; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4622; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1623; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4624; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1625; CHECK-NEXT: br label [[LOOP:%.*]]626; CHECK: loop:627; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]628; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]629; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4630; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4631; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]]632; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4633; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1634; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]635; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]636; CHECK: exit:637; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])638; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[RETVAL_FULL]], ptr [[RETVAL]], i32 4, i1 false)639; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0640; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4641; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0642; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1643; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4644; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1645; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]]646;647entry:648 %retval.full = alloca [2 x i32], align 4649 store [2 x i32] zeroinitializer, ptr %retval.full, align 4650 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1651 br label %loop652 653loop:654 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]655 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv656 %ld = load i32, ptr %arrayidx, align 4657 %rdx = load i32, ptr %retval, align 4658 %rdx.inc = add nsw i32 %rdx, %ld659 store i32 %rdx.inc, ptr %retval, align 4660 %indvars.iv.next = add nsw i64 %indvars.iv, 1661 %exitcond = icmp ne i64 %indvars.iv.next, %n662 br i1 %exitcond, label %loop, label %exit663 664exit:665 %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)666 call void @llvm.memcpy.p0.p0.i32(ptr %retval.full, ptr %retval, i32 4, i1 false)667 %i1 = load [2 x i32], ptr %retval.full, align 4668 ret [2 x i32] %i1669}670 671define [2 x i32] @part_of_alloca_used_in_call_with_multiple_args(ptr %data, i64 %n) {672; CHECK-LABEL: @part_of_alloca_used_in_call_with_multiple_args(673; CHECK-NEXT: entry:674; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4675; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0676; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4677; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1678; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4679; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1680; CHECK-NEXT: br label [[LOOP:%.*]]681; CHECK: loop:682; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]683; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]684; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]685; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4686; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]687; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4688; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1689; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]690; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]691; CHECK: exit:692; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL]])693; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0694; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0695; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1696; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1697; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]]698;699entry:700 %retval.full = alloca [2 x i32], align 4701 store [2 x i32] zeroinitializer, ptr %retval.full, align 4702 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1703 br label %loop704 705loop:706 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]707 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv708 %ld = load i32, ptr %arrayidx, align 4709 %rdx = load i32, ptr %retval, align 4710 %rdx.inc = add nsw i32 %rdx, %ld711 store i32 %rdx.inc, ptr %retval, align 4712 %indvars.iv.next = add nsw i64 %indvars.iv, 1713 %exitcond = icmp ne i64 %indvars.iv.next, %n714 br i1 %exitcond, label %loop, label %exit715 716exit:717 %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval)718 %i1 = load [2 x i32], ptr %retval.full, align 4719 ret [2 x i32] %i1720}721 722define [2 x i32] @all_parts_of_alloca_used_in_calls_with_multiple_args(ptr %data, i64 %n) {723; CHECK-LABEL: @all_parts_of_alloca_used_in_calls_with_multiple_args(724; CHECK-NEXT: entry:725; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4726; CHECK-NEXT: [[SOME_ANOTHER_ALLOCA_FULL:%.*]] = alloca [42 x i32], align 4727; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0728; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4729; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1730; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4731; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1732; CHECK-NEXT: br label [[LOOP:%.*]]733; CHECK: loop:734; CHECK-NEXT: [[RDX:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[RDX_INC:%.*]], [[LOOP]] ]735; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ]736; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[DATA:%.*]], i64 [[INDVARS_IV]]737; CHECK-NEXT: [[LD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4738; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]]739; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4740; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1741; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[N:%.*]]742; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]]743; CHECK: exit:744; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL]], ptr [[RETVAL_FULL]])745; CHECK-NEXT: [[I1:%.*]] = call i32 @user_of_alloca_with_multiple_args(ptr [[RETVAL_FULL]], ptr [[RETVAL]])746; CHECK-NEXT: [[I2:%.*]] = call i32 @capture_of_alloca(ptr [[SOME_ANOTHER_ALLOCA_FULL]])747; CHECK-NEXT: [[I3_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0748; CHECK-NEXT: [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0749; CHECK-NEXT: [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1750; CHECK-NEXT: [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[RDX_INC]], 1751; CHECK-NEXT: ret [2 x i32] [[I3_FCA_1_INSERT]]752;753entry:754 %retval.full = alloca [2 x i32], align 4755 %some.another.alloca.full = alloca [42 x i32], align 4756 store [2 x i32] zeroinitializer, ptr %retval.full, align 4757 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1758 br label %loop759 760loop:761 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ]762 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv763 %ld = load i32, ptr %arrayidx, align 4764 %rdx = load i32, ptr %retval, align 4765 %rdx.inc = add nsw i32 %rdx, %ld766 store i32 %rdx.inc, ptr %retval, align 4767 %indvars.iv.next = add nsw i64 %indvars.iv, 1768 %exitcond = icmp ne i64 %indvars.iv.next, %n769 br i1 %exitcond, label %loop, label %exit770 771exit:772 %i0 = call i32 @user_of_alloca_with_multiple_args(ptr %retval, ptr %retval.full)773 %i1 = call i32 @user_of_alloca_with_multiple_args(ptr %retval.full, ptr %retval)774 %i2 = call i32 @capture_of_alloca(ptr %some.another.alloca.full)775 %i3 = load [2 x i32], ptr %retval.full, align 4776 ret [2 x i32] %i3777}778 779define i32 @all_uses_of_alloca_are_calls(ptr %data, i64 %n) {780; CHECK-LABEL: @all_uses_of_alloca_are_calls(781; CHECK-NEXT: entry:782; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4783; CHECK-NEXT: [[TMP0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])784; CHECK-NEXT: [[TMP1:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL]])785; CHECK-NEXT: ret i32 0786;787entry:788 %retval = alloca i32, align 4789 call i32 @user_of_alloca(ptr %retval)790 call i32 @user_of_alloca(ptr %retval)791 ret i32 0792}793 794declare void @llvm.lifetime.start.p0(ptr)795 796define i64 @do_schedule_instrs_for_dce_after_fixups() {797; CHECK-LABEL: @do_schedule_instrs_for_dce_after_fixups(798; CHECK-NEXT: entry:799; CHECK-NEXT: [[C:%.*]] = alloca i64, align 2800; CHECK-NEXT: call void @llvm.lifetime.start.p0(ptr [[C]])801; CHECK-NEXT: store i64 0, ptr [[C]], align 4802; CHECK-NEXT: br label [[IF_END:%.*]]803; CHECK: if.end:804; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 1805; CHECK-NEXT: [[TMP0:%.*]] = call i32 @user_of_alloca(ptr [[ADD_PTR]])806; CHECK-NEXT: ret i64 0807;808entry:809 %c = alloca i64, align 2810 call void @llvm.lifetime.start.p0(ptr %c)811 store i64 0, ptr %c812 br label %if.end813 814if.end: ; preds = %entry815 %add.ptr = getelementptr inbounds i32, ptr %c, i64 1816 call i32 @user_of_alloca(ptr %add.ptr)817 %ld = load i64, ptr %c818 ret i64 %ld819}820 821define void @dont_transform_store_only() {822; CHECK-LABEL: @dont_transform_store_only(823; CHECK-NEXT: entry:824; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1825; CHECK-NEXT: store i8 0, ptr [[A]], align 1826; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]])827; CHECK-NEXT: ret void828;829entry:830 %a = alloca i8831 store i8 0, ptr %a832 call void @byte_user_of_alloca(ptr %a)833 ret void834}835define i8 @dont_transform_load_only() {836; CHECK-LABEL: @dont_transform_load_only(837; CHECK-NEXT: entry:838; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1839; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]])840; CHECK-NEXT: ret i8 undef841;842entry:843 %a = alloca i8844 call void @byte_user_of_alloca(ptr %a)845 %r = load i8, ptr %a846 ret i8 %r847}848define i8 @transform_load_and_store() {849; CHECK-LABEL: @transform_load_and_store(850; CHECK-NEXT: entry:851; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1852; CHECK-NEXT: store i8 0, ptr [[A]], align 1853; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]])854; CHECK-NEXT: ret i8 0855;856entry:857 %a = alloca i8858 store i8 0, ptr %a859 call void @byte_user_of_alloca(ptr %a)860 %r = load i8, ptr %a861 ret i8 %r862}863 864define [2 x i32] @select_of_ptrs(ptr %data, i1 %c, i32 %v) {865; CHECK-LABEL: @select_of_ptrs(866; CHECK-NEXT: entry:867; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4868; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0869; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4870; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1871; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4872; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1873; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr [[RETVAL_FULL]], ptr [[RETVAL]]874; CHECK-NEXT: store i32 [[V:%.*]], ptr [[PTR]], align 4875; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL_FULL]])876; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0877; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4878; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0879; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1880; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4881; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1882; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]]883;884entry:885 %retval.full = alloca [2 x i32], align 4886 store [2 x i32] zeroinitializer, ptr %retval.full, align 4887 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1888 %ptr = select i1 %c, ptr %retval.full, ptr %retval889 store i32 %v, ptr %ptr890 %i0 = call i32 @user_of_alloca(ptr %retval.full)891 %i1 = load [2 x i32], ptr %retval.full, align 4892 ret [2 x i32] %i1893}894 895declare dso_local i32 @user_of_alloca(ptr nocapture readonly)896declare dso_local i32 @user_of_alloca_with_multiple_args(ptr nocapture readonly, ptr nocapture readonly)897declare dso_local i32 @capture_of_alloca(ptr)898declare dso_local i32 @capture_with_multiple_args(ptr nocapture readonly, ptr)899 900declare dso_local void @byte_user_of_alloca(ptr nocapture readonly)901 902declare dso_local i32 @__gxx_personality_v0(...)903 904declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1)905;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:906; CHECK-MODIFY-CFG: {{.*}}907; CHECK-PRESERVE-CFG: {{.*}}908