1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG 3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG 4 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 4 9; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 10; 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 4 16; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 17; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 18; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 19; 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 4 27 store i32 0, ptr %retval, align 4 28 br label %loop 29 30loop: 31 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 32 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 33 %ld = load i32, ptr %arrayidx, align 4 34 %rdx = load i32, ptr %retval, align 4 35 %rdx.inc = add nsw i32 %rdx, %ld 36 store i32 %rdx.inc, ptr %retval, align 4 37 %indvars.iv.next = add nsw i64 %indvars.iv, 1 38 %exitcond = icmp ne i64 %indvars.iv.next, %n 39 br i1 %exitcond, label %loop, label %exit 40 41exit: 42 %i0 = call i32 @user_of_alloca(ptr %retval) 43 %i1 = load i32, ptr %retval, align 4 44 ret i32 %i1 45} 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 4 51; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 52; 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 4 57; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 58; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 59; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 60; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 61; 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 4 66; CHECK-NEXT: ret i32 [[I1]] 67; 68entry: 69 %retval = alloca i32, align 4 70 store i32 0, ptr %retval, align 4 71 br label %loop 72 73loop: 74 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 75 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 76 %ld = load i32, ptr %arrayidx, align 4 77 %rdx = load i32, ptr %retval, align 4 78 %rdx.inc = add nsw i32 %rdx, %ld 79 store i32 %rdx.inc, ptr %retval, align 4 80 %indvars.iv.next = add nsw i64 %indvars.iv, 1 81 %exitcond = icmp ne i64 %indvars.iv.next, %n 82 br i1 %exitcond, label %loop, label %exit 83 84exit: 85 %i0 = call i32 @capture_of_alloca(ptr %retval) 86 %i1 = load i32, ptr %retval, align 4 87 ret i32 %i1 88} 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 4 94; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 95; 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 4 100; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 101; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 102; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 103; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 104; 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 4 109; CHECK-NEXT: ret i32 [[I1]] 110; 111entry: 112 %retval = alloca i32, align 4 113 store i32 0, ptr %retval, align 4 114 br label %loop 115 116loop: 117 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 118 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 119 %ld = load i32, ptr %arrayidx, align 4 120 %rdx = load i32, ptr %retval, align 4 121 %rdx.inc = add nsw i32 %rdx, %ld 122 store i32 %rdx.inc, ptr %retval, align 4 123 %indvars.iv.next = add nsw i64 %indvars.iv, 1 124 %exitcond = icmp ne i64 %indvars.iv.next, %n 125 br i1 %exitcond, label %loop, label %exit 126 127exit: 128 %i0 = call i32 @capture_of_alloca(ptr nocapture %retval) 129 %i1 = load i32, ptr %retval, align 4 130 ret i32 %i1 131} 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 4 137; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 138; 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 4 144; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 145; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 146; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 147; 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 4 155 store i32 0, ptr %retval, align 4 156 br label %loop 157 158loop: 159 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 160 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 161 %ld = load i32, ptr %arrayidx, align 4 162 %rdx = load i32, ptr %retval, align 4 163 %rdx.inc = add nsw i32 %rdx, %ld 164 store i32 %rdx.inc, ptr %retval, align 4 165 %indvars.iv.next = add nsw i64 %indvars.iv, 1 166 %exitcond = icmp ne i64 %indvars.iv.next, %n 167 br i1 %exitcond, label %loop, label %exit 168 169exit: 170 %i0 = call i32 @capture_of_alloca(ptr nocapture readonly %retval) 171 %i1 = load i32, ptr %retval, align 4 172 ret i32 %i1 173} 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 4 179; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 180; 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 4 185; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 186; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 187; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 188; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 189; 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 4 194; CHECK-NEXT: ret i32 [[I1]] 195; 196entry: 197 %retval = alloca i32, align 4 198 store i32 0, ptr %retval, align 4 199 br label %loop 200 201loop: 202 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 203 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 204 %ld = load i32, ptr %arrayidx, align 4 205 %rdx = load i32, ptr %retval, align 4 206 %rdx.inc = add nsw i32 %rdx, %ld 207 store i32 %rdx.inc, ptr %retval, align 4 208 %indvars.iv.next = add nsw i64 %indvars.iv, 1 209 %exitcond = icmp ne i64 %indvars.iv.next, %n 210 br i1 %exitcond, label %loop, label %exit 211 212exit: 213 %i0 = call i32 @capture_of_alloca(ptr nocapture %retval) readonly 214 %i1 = load i32, ptr %retval, align 4 215 ret i32 %i1 216} 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 4 222; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 223; 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 4 228; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 229; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 230; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 231; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 232; 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 4 237; CHECK-NEXT: ret i32 [[I1]] 238; 239entry: 240 %retval = alloca i32, align 4 241 store i32 0, ptr %retval, align 4 242 br label %loop 243 244loop: 245 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 246 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 247 %ld = load i32, ptr %arrayidx, align 4 248 %rdx = load i32, ptr %retval, align 4 249 %rdx.inc = add nsw i32 %rdx, %ld 250 store i32 %rdx.inc, ptr %retval, align 4 251 %indvars.iv.next = add nsw i64 %indvars.iv, 1 252 %exitcond = icmp ne i64 %indvars.iv.next, %n 253 br i1 %exitcond, label %loop, label %exit 254 255exit: 256 %i0 = call i32 @capture_of_alloca(ptr readonly %retval) 257 %i1 = load i32, ptr %retval, align 4 258 ret i32 %i1 259} 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 4 265; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 266; 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 4 272; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 273; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 274; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 275; 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 4 283 store i32 0, ptr %retval, align 4 284 br label %loop 285 286loop: 287 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 288 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 289 %ld = load i32, ptr %arrayidx, align 4 290 %rdx = load i32, ptr %retval, align 4 291 %rdx.inc = add nsw i32 %rdx, %ld 292 store i32 %rdx.inc, ptr %retval, align 4 293 %indvars.iv.next = add nsw i64 %indvars.iv, 1 294 %exitcond = icmp ne i64 %indvars.iv.next, %n 295 br i1 %exitcond, label %loop, label %exit 296 297exit: 298 %i0 = call i32 @user_of_alloca(ptr %retval) 299 %i1 = load i32, ptr %retval, align 4 300 ret i32 %i1 301} 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 4 307; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 308; 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 4 313; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 314; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 315; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 316; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 317; 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 4 322; CHECK-NEXT: ret i32 [[I1]] 323; 324entry: 325 %retval = alloca i32, align 4 326 store i32 0, ptr %retval, align 4 327 br label %loop 328 329loop: 330 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 331 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 332 %ld = load i32, ptr %arrayidx, align 4 333 %rdx = load i32, ptr %retval, align 4 334 %rdx.inc = add nsw i32 %rdx, %ld 335 store i32 %rdx.inc, ptr %retval, align 4 336 %indvars.iv.next = add nsw i64 %indvars.iv, 1 337 %exitcond = icmp ne i64 %indvars.iv.next, %n 338 br i1 %exitcond, label %loop, label %exit 339 340exit: 341 %i0 = call i32 @capture_with_multiple_args(ptr %retval, ptr %retval) 342 %i1 = load i32, ptr %retval, align 4 343 ret i32 %i1 344} 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 4 350; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 351; 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 4 357; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 358; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 359; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 360; 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 null 370; CHECK-NEXT: br label [[END]] 371; CHECK: end: 372; CHECK-NEXT: ret i32 [[RDX_INC]] 373; 374entry: 375 %retval = alloca i32, align 4 376 store i32 0, ptr %retval, align 4 377 br label %loop 378 379loop: 380 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 381 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 382 %ld = load i32, ptr %arrayidx, align 4 383 %rdx = load i32, ptr %retval, align 4 384 %rdx.inc = add nsw i32 %rdx, %ld 385 store i32 %rdx.inc, ptr %retval, align 4 386 %indvars.iv.next = add nsw i64 %indvars.iv, 1 387 %exitcond = icmp ne i64 %indvars.iv.next, %n 388 br i1 %exitcond, label %loop, label %exit 389 390exit: 391 %i0 = invoke i32 @user_of_alloca(ptr %retval) to label %cont unwind label %uw 392 393cont: 394 br label %end 395 396uw: 397 %i1 = landingpad { ptr, i32 } catch ptr null 398 br label %end 399 400end: 401 %i2 = load i32, ptr %retval, align 4 402 ret i32 %i2 403} 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 4 409; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4 410; 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 4 416; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 417; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 418; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 419; 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 null 427; CHECK-NEXT: br label [[END]] 428; CHECK: end: 429; CHECK-NEXT: ret i32 [[RDX_INC]] 430; 431entry: 432 %retval = alloca i32, align 4 433 store i32 0, ptr %retval, align 4 434 br label %loop 435 436loop: 437 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 438 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 439 %ld = load i32, ptr %arrayidx, align 4 440 %rdx = load i32, ptr %retval, align 4 441 %rdx.inc = add nsw i32 %rdx, %ld 442 store i32 %rdx.inc, ptr %retval, align 4 443 %indvars.iv.next = add nsw i64 %indvars.iv, 1 444 %exitcond = icmp ne i64 %indvars.iv.next, %n 445 br i1 %exitcond, label %loop, label %exit 446 447exit: 448 %i0 = invoke i32 @user_of_alloca(ptr %retval) to label %end unwind label %uw 449 450uw: 451 %i1 = landingpad { ptr, i32 } catch ptr null 452 br label %end 453 454end: 455 %i2 = load i32, ptr %retval, align 4 456 ret i32 %i2 457} 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 4 463; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 464; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 465; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 466; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 467; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 468; 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 4 474; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 475; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 476; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 477; 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 0 482; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 483; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 484; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 485; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] 486; 487entry: 488 %retval.full = alloca [2 x i32], align 4 489 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 490 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 491 br label %loop 492 493loop: 494 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 495 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 496 %ld = load i32, ptr %arrayidx, align 4 497 %rdx = load i32, ptr %retval, align 4 498 %rdx.inc = add nsw i32 %rdx, %ld 499 store i32 %rdx.inc, ptr %retval, align 4 500 %indvars.iv.next = add nsw i64 %indvars.iv, 1 501 %exitcond = icmp ne i64 %indvars.iv.next, %n 502 br i1 %exitcond, label %loop, label %exit 503 504exit: 505 %i0 = call i32 @user_of_alloca(ptr %retval) 506 %i1 = load [2 x i32], ptr %retval.full, align 4 507 ret [2 x i32] %i1 508} 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 4 514; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 515; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 516; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 517; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 518; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 519; 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 4 525; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 526; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 527; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 528; 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 0 533; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 534; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 535; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 536; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] 537; 538entry: 539 %retval.full = alloca [2 x i32], align 4 540 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 541 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 542 br label %loop 543 544loop: 545 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 546 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 547 %ld = load i32, ptr %arrayidx, align 4 548 %rdx = load i32, ptr %retval, align 4 549 %rdx.inc = add nsw i32 %rdx, %ld 550 store i32 %rdx.inc, ptr %retval, align 4 551 %indvars.iv.next = add nsw i64 %indvars.iv, 1 552 %exitcond = icmp ne i64 %indvars.iv.next, %n 553 br i1 %exitcond, label %loop, label %exit 554 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 4 558 ret [2 x i32] %i1 559} 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 4 565; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 566; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 567; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 568; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 569; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 570; 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 4 575; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 576; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 577; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 578; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 579; 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 0 585; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 586; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 587; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 588; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 589; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 590; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] 591; 592entry: 593 %retval.full = alloca [2 x i32], align 4 594 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 595 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 596 br label %loop 597 598loop: 599 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 600 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 601 %ld = load i32, ptr %arrayidx, align 4 602 %rdx = load i32, ptr %retval, align 4 603 %rdx.inc = add nsw i32 %rdx, %ld 604 store i32 %rdx.inc, ptr %retval, align 4 605 %indvars.iv.next = add nsw i64 %indvars.iv, 1 606 %exitcond = icmp ne i64 %indvars.iv.next, %n 607 br i1 %exitcond, label %loop, label %exit 608 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 4 613 ret [2 x i32] %i1 614} 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 4 620; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 621; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 622; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 623; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 624; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 625; 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 4 630; CHECK-NEXT: [[RDX:%.*]] = load i32, ptr [[RETVAL]], align 4 631; CHECK-NEXT: [[RDX_INC:%.*]] = add nsw i32 [[RDX]], [[LD]] 632; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 633; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 634; 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 0 640; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 641; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 642; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 643; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 644; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 645; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] 646; 647entry: 648 %retval.full = alloca [2 x i32], align 4 649 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 650 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 651 br label %loop 652 653loop: 654 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 655 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 656 %ld = load i32, ptr %arrayidx, align 4 657 %rdx = load i32, ptr %retval, align 4 658 %rdx.inc = add nsw i32 %rdx, %ld 659 store i32 %rdx.inc, ptr %retval, align 4 660 %indvars.iv.next = add nsw i64 %indvars.iv, 1 661 %exitcond = icmp ne i64 %indvars.iv.next, %n 662 br i1 %exitcond, label %loop, label %exit 663 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 4 668 ret [2 x i32] %i1 669} 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 4 675; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 676; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 677; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 678; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 679; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 680; 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 4 686; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 687; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 688; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 689; 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 0 694; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 695; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 696; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[RDX_INC]], 1 697; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] 698; 699entry: 700 %retval.full = alloca [2 x i32], align 4 701 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 702 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 703 br label %loop 704 705loop: 706 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 707 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 708 %ld = load i32, ptr %arrayidx, align 4 709 %rdx = load i32, ptr %retval, align 4 710 %rdx.inc = add nsw i32 %rdx, %ld 711 store i32 %rdx.inc, ptr %retval, align 4 712 %indvars.iv.next = add nsw i64 %indvars.iv, 1 713 %exitcond = icmp ne i64 %indvars.iv.next, %n 714 br i1 %exitcond, label %loop, label %exit 715 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 4 719 ret [2 x i32] %i1 720} 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 4 726; CHECK-NEXT: [[SOME_ANOTHER_ALLOCA_FULL:%.*]] = alloca [42 x i32], align 4 727; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 728; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 729; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 730; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 731; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 732; 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 4 738; CHECK-NEXT: [[RDX_INC]] = add nsw i32 [[RDX]], [[LD]] 739; CHECK-NEXT: store i32 [[RDX_INC]], ptr [[RETVAL]], align 4 740; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1 741; 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 0 748; CHECK-NEXT: [[I3_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 0, 0 749; CHECK-NEXT: [[I3_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 750; CHECK-NEXT: [[I3_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I3_FCA_0_INSERT]], i32 [[RDX_INC]], 1 751; CHECK-NEXT: ret [2 x i32] [[I3_FCA_1_INSERT]] 752; 753entry: 754 %retval.full = alloca [2 x i32], align 4 755 %some.another.alloca.full = alloca [42 x i32], align 4 756 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 757 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 758 br label %loop 759 760loop: 761 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %loop ] 762 %arrayidx = getelementptr inbounds i32, ptr %data, i64 %indvars.iv 763 %ld = load i32, ptr %arrayidx, align 4 764 %rdx = load i32, ptr %retval, align 4 765 %rdx.inc = add nsw i32 %rdx, %ld 766 store i32 %rdx.inc, ptr %retval, align 4 767 %indvars.iv.next = add nsw i64 %indvars.iv, 1 768 %exitcond = icmp ne i64 %indvars.iv.next, %n 769 br i1 %exitcond, label %loop, label %exit 770 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 4 776 ret [2 x i32] %i3 777} 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 4 783; 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 0 786; 787entry: 788 %retval = alloca i32, align 4 789 call i32 @user_of_alloca(ptr %retval) 790 call i32 @user_of_alloca(ptr %retval) 791 ret i32 0 792} 793 794declare void @llvm.lifetime.start.p0(i64 immarg, 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 2 800; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 1, ptr [[C]]) 801; CHECK-NEXT: store i64 0, ptr [[C]], align 4 802; CHECK-NEXT: br label [[IF_END:%.*]] 803; CHECK: if.end: 804; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 1 805; CHECK-NEXT: [[TMP0:%.*]] = call i32 @user_of_alloca(ptr [[ADD_PTR]]) 806; CHECK-NEXT: [[LD:%.*]] = load i64, ptr [[C]], align 4 807; CHECK-NEXT: ret i64 [[LD]] 808; 809entry: 810 %c = alloca i64, align 2 811 call void @llvm.lifetime.start.p0(i64 1, ptr %c) 812 store i64 0, ptr %c 813 br label %if.end 814 815if.end: ; preds = %entry 816 %add.ptr = getelementptr inbounds i32, ptr %c, i64 1 817 call i32 @user_of_alloca(ptr %add.ptr) 818 %ld = load i64, ptr %c 819 ret i64 %ld 820} 821 822define void @dont_transform_store_only() { 823; CHECK-LABEL: @dont_transform_store_only( 824; CHECK-NEXT: entry: 825; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 826; CHECK-NEXT: store i8 0, ptr [[A]], align 1 827; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]]) 828; CHECK-NEXT: ret void 829; 830entry: 831 %a = alloca i8 832 store i8 0, ptr %a 833 call void @byte_user_of_alloca(ptr %a) 834 ret void 835} 836define i8 @dont_transform_load_only() { 837; CHECK-LABEL: @dont_transform_load_only( 838; CHECK-NEXT: entry: 839; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 840; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]]) 841; CHECK-NEXT: ret i8 undef 842; 843entry: 844 %a = alloca i8 845 call void @byte_user_of_alloca(ptr %a) 846 %r = load i8, ptr %a 847 ret i8 %r 848} 849define i8 @transform_load_and_store() { 850; CHECK-LABEL: @transform_load_and_store( 851; CHECK-NEXT: entry: 852; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1 853; CHECK-NEXT: store i8 0, ptr [[A]], align 1 854; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]]) 855; CHECK-NEXT: ret i8 0 856; 857entry: 858 %a = alloca i8 859 store i8 0, ptr %a 860 call void @byte_user_of_alloca(ptr %a) 861 %r = load i8, ptr %a 862 ret i8 %r 863} 864 865define [2 x i32] @select_of_ptrs(ptr %data, i1 %c, i32 %v) { 866; CHECK-LABEL: @select_of_ptrs( 867; CHECK-NEXT: entry: 868; CHECK-NEXT: [[RETVAL_FULL:%.*]] = alloca [2 x i32], align 4 869; CHECK-NEXT: [[DOTFCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 870; CHECK-NEXT: store i32 0, ptr [[DOTFCA_0_GEP]], align 4 871; CHECK-NEXT: [[DOTFCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 872; CHECK-NEXT: store i32 0, ptr [[DOTFCA_1_GEP]], align 4 873; CHECK-NEXT: [[RETVAL:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i64 0, i64 1 874; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr [[RETVAL_FULL]], ptr [[RETVAL]] 875; CHECK-NEXT: store i32 [[V:%.*]], ptr [[PTR]], align 4 876; CHECK-NEXT: [[I0:%.*]] = call i32 @user_of_alloca(ptr [[RETVAL_FULL]]) 877; CHECK-NEXT: [[I1_FCA_0_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 0 878; CHECK-NEXT: [[I1_FCA_0_LOAD:%.*]] = load i32, ptr [[I1_FCA_0_GEP]], align 4 879; CHECK-NEXT: [[I1_FCA_0_INSERT:%.*]] = insertvalue [2 x i32] poison, i32 [[I1_FCA_0_LOAD]], 0 880; CHECK-NEXT: [[I1_FCA_1_GEP:%.*]] = getelementptr inbounds [2 x i32], ptr [[RETVAL_FULL]], i32 0, i32 1 881; CHECK-NEXT: [[I1_FCA_1_LOAD:%.*]] = load i32, ptr [[I1_FCA_1_GEP]], align 4 882; CHECK-NEXT: [[I1_FCA_1_INSERT:%.*]] = insertvalue [2 x i32] [[I1_FCA_0_INSERT]], i32 [[I1_FCA_1_LOAD]], 1 883; CHECK-NEXT: ret [2 x i32] [[I1_FCA_1_INSERT]] 884; 885entry: 886 %retval.full = alloca [2 x i32], align 4 887 store [2 x i32] zeroinitializer, ptr %retval.full, align 4 888 %retval = getelementptr inbounds [2 x i32], ptr %retval.full, i64 0, i64 1 889 %ptr = select i1 %c, ptr %retval.full, ptr %retval 890 store i32 %v, ptr %ptr 891 %i0 = call i32 @user_of_alloca(ptr %retval.full) 892 %i1 = load [2 x i32], ptr %retval.full, align 4 893 ret [2 x i32] %i1 894} 895 896declare dso_local i32 @user_of_alloca(ptr nocapture readonly) 897declare dso_local i32 @user_of_alloca_with_multiple_args(ptr nocapture readonly, ptr nocapture readonly) 898declare dso_local i32 @capture_of_alloca(ptr) 899declare dso_local i32 @capture_with_multiple_args(ptr nocapture readonly, ptr) 900 901declare dso_local void @byte_user_of_alloca(ptr nocapture readonly) 902 903declare dso_local i32 @__gxx_personality_v0(...) 904 905declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1) 906;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 907; CHECK-MODIFY-CFG: {{.*}} 908; CHECK-PRESERVE-CFG: {{.*}} 909