brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.2 KiB · e94a368 Raw
686 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -p loop-unroll -unroll-add-parallel-reductions -unroll-allow-partial -unroll-max-count=4 -S %s | FileCheck %s3 4define i32 @test_add(ptr %src, i64 %n, i32 %start) {5; CHECK-LABEL: define i32 @test_add(6; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], i32 [[START:%.*]]) {7; CHECK-NEXT:  [[ENTRY:.*]]:8; CHECK-NEXT:    br label %[[LOOP:.*]]9; CHECK:       [[LOOP]]:10; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]11; CHECK-NEXT:    [[RDX_1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]12; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_2:%.*]], %[[LOOP]] ]13; CHECK-NEXT:    [[RDX_3:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_24:%.*]], %[[LOOP]] ]14; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT:%.*]], %[[LOOP]] ]15; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 116; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]17; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 118; CHECK-NEXT:    [[RDX_NEXT]] = add i32 [[RDX]], [[L]]19; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 220; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT]]21; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 122; CHECK-NEXT:    [[RDX_NEXT_3]] = add i32 [[RDX_1]], [[L_1]]23; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 324; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_1]]25; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 126; CHECK-NEXT:    [[RDX_NEXT_2]] = add i32 [[RDX_NEXT_1]], [[L_2]]27; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 428; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_2]]29; CHECK-NEXT:    [[L_24:%.*]] = load i32, ptr [[GEP_SRC_24]], align 130; CHECK-NEXT:    [[RDX_NEXT_24]] = add i32 [[RDX_3]], [[L_24]]31; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 100032; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]33; CHECK:       [[EXIT]]:34; CHECK-NEXT:    [[RDX_NEXT_LCSSA1:%.*]] = phi i32 [ [[RDX_NEXT_24]], %[[LOOP]] ]35; CHECK-NEXT:    [[BIN_RDX:%.*]] = add i32 [[RDX_NEXT_3]], [[RDX_NEXT]]36; CHECK-NEXT:    [[BIN_RDX1:%.*]] = add i32 [[RDX_NEXT_2]], [[BIN_RDX]]37; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = add i32 [[RDX_NEXT_24]], [[BIN_RDX1]]38; CHECK-NEXT:    ret i32 [[RDX_NEXT_LCSSA]]39;40entry:41  br label %loop42 43loop:44  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]45  %rdx = phi i32 [ %start, %entry ], [ %rdx.next, %loop ]46  %iv.next = add i64 %iv, 147  %gep.src = getelementptr i32, ptr %src, i64 %iv48  %l = load i32 , ptr %gep.src, align 149  %rdx.next = add i32 %rdx, %l50  %ec = icmp ne i64 %iv.next, 100051  br i1 %ec, label %loop, label %exit52 53exit:54  ret i32 %rdx.next55}56 57define i32 @test_add_tc_not_multiple_of_4(ptr %src, i64 %n, i32 %start) {58; CHECK-LABEL: define i32 @test_add_tc_not_multiple_of_4(59; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], i32 [[START:%.*]]) {60; CHECK-NEXT:  [[ENTRY:.*]]:61; CHECK-NEXT:    br label %[[LOOP:.*]]62; CHECK:       [[LOOP]]:63; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP_1:.*]] ]64; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP_1]] ]65; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 166; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]67; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 168; CHECK-NEXT:    [[RDX_NEXT:%.*]] = add i32 [[RDX]], [[L]]69; CHECK-NEXT:    [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 100170; CHECK-NEXT:    br i1 [[EC]], label %[[LOOP_1]], label %[[EXIT:.*]]71; CHECK:       [[LOOP_1]]:72; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 273; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT]]74; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 175; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = add i32 [[RDX_NEXT]], [[L_1]]76; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 377; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_1]]78; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 179; CHECK-NEXT:    [[RDX_NEXT_2:%.*]] = add i32 [[RDX_NEXT_1]], [[L_2]]80; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 481; CHECK-NEXT:    [[GEP_SRC_12:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_2]]82; CHECK-NEXT:    [[L_12:%.*]] = load i32, ptr [[GEP_SRC_12]], align 183; CHECK-NEXT:    [[RDX_NEXT_3]] = add i32 [[RDX_NEXT_2]], [[L_12]]84; CHECK-NEXT:    br label %[[LOOP]]85; CHECK:       [[EXIT]]:86; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi i32 [ [[RDX_NEXT]], %[[LOOP]] ]87; CHECK-NEXT:    ret i32 [[RDX_NEXT_LCSSA]]88;89entry:90  br label %loop91 92loop:93  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]94  %rdx = phi i32 [ %start, %entry ], [ %rdx.next, %loop ]95  %iv.next = add i64 %iv, 196  %gep.src = getelementptr i32, ptr %src, i64 %iv97  %l = load i32 , ptr %gep.src, align 198  %rdx.next = add i32 %rdx, %l99  %ec = icmp ne i64 %iv.next, 1001100  br i1 %ec, label %loop, label %exit101 102exit:103  ret i32 %rdx.next104}105 106define i32 @test_add_rdx_used_in_loop(ptr %src, i64 %n, i32 %start) {107; CHECK-LABEL: define i32 @test_add_rdx_used_in_loop(108; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], i32 [[START:%.*]]) {109; CHECK-NEXT:  [[ENTRY:.*]]:110; CHECK-NEXT:    br label %[[LOOP:.*]]111; CHECK:       [[LOOP]]:112; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]113; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT_24:%.*]], %[[LOOP]] ]114; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1115; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]116; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 1117; CHECK-NEXT:    [[RDX_NEXT:%.*]] = add i32 [[RDX]], [[L]]118; CHECK-NEXT:    store i32 [[RDX_NEXT]], ptr [[GEP_SRC]], align 4119; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2120; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT]]121; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 1122; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = add i32 [[RDX_NEXT]], [[L_1]]123; CHECK-NEXT:    store i32 [[RDX_NEXT_1]], ptr [[GEP_SRC_1]], align 4124; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3125; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_1]]126; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 1127; CHECK-NEXT:    [[RDX_NEXT_2:%.*]] = add i32 [[RDX_NEXT_1]], [[L_2]]128; CHECK-NEXT:    store i32 [[RDX_NEXT_2]], ptr [[GEP_SRC_2]], align 4129; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4130; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_2]]131; CHECK-NEXT:    [[L_24:%.*]] = load i32, ptr [[GEP_SRC_24]], align 1132; CHECK-NEXT:    [[RDX_NEXT_24]] = add i32 [[RDX_NEXT_2]], [[L_24]]133; CHECK-NEXT:    store i32 [[RDX_NEXT_24]], ptr [[GEP_SRC_24]], align 4134; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000135; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]136; CHECK:       [[EXIT]]:137; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi i32 [ [[RDX_NEXT_24]], %[[LOOP]] ]138; CHECK-NEXT:    ret i32 [[RDX_NEXT_LCSSA]]139;140entry:141  br label %loop142 143loop:144  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]145  %rdx = phi i32 [ %start, %entry ], [ %rdx.next, %loop ]146  %iv.next = add i64 %iv, 1147  %gep.src = getelementptr i32, ptr %src, i64 %iv148  %l = load i32 , ptr %gep.src, align 1149  %rdx.next = add i32 %rdx, %l150  store i32 %rdx.next, ptr %gep.src151  %ec = icmp ne i64 %iv.next, 1000152  br i1 %ec, label %loop, label %exit153 154exit:155  ret i32 %rdx.next156}157 158define i32 @test_add_phi_used_outside_loop(ptr %src, i64 %n, i32 %start) {159; CHECK-LABEL: define i32 @test_add_phi_used_outside_loop(160; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], i32 [[START:%.*]]) {161; CHECK-NEXT:  [[ENTRY:.*]]:162; CHECK-NEXT:    br label %[[LOOP:.*]]163; CHECK:       [[LOOP]]:164; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]165; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]166; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1167; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]168; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 1169; CHECK-NEXT:    [[RDX_NEXT:%.*]] = add i32 [[RDX]], [[L]]170; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2171; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT]]172; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 1173; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = add i32 [[RDX_NEXT]], [[L_1]]174; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3175; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_1]]176; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 1177; CHECK-NEXT:    [[RDX_NEXT_2:%.*]] = add i32 [[RDX_NEXT_1]], [[L_2]]178; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4179; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_2]]180; CHECK-NEXT:    [[L_24:%.*]] = load i32, ptr [[GEP_SRC_24]], align 1181; CHECK-NEXT:    [[RDX_NEXT_3]] = add i32 [[RDX_NEXT_2]], [[L_24]]182; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000183; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]184; CHECK:       [[EXIT]]:185; CHECK-NEXT:    [[RDX_LCSSA:%.*]] = phi i32 [ [[RDX_NEXT_2]], %[[LOOP]] ]186; CHECK-NEXT:    ret i32 [[RDX_LCSSA]]187;188entry:189  br label %loop190 191loop:192  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]193  %rdx = phi i32 [ %start, %entry ], [ %rdx.next, %loop ]194  %iv.next = add i64 %iv, 1195  %gep.src = getelementptr i32, ptr %src, i64 %iv196  %l = load i32 , ptr %gep.src, align 1197  %rdx.next = add i32 %rdx, %l198  %ec = icmp ne i64 %iv.next, 1000199  br i1 %ec, label %loop, label %exit200 201exit:202  ret i32 %rdx203}204 205define i32 @test_add_and_mul_reduction(ptr %src, i64 %n, i32 %start) {206; CHECK-LABEL: define i32 @test_add_and_mul_reduction(207; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], i32 [[START:%.*]]) {208; CHECK-NEXT:  [[ENTRY:.*]]:209; CHECK-NEXT:    br label %[[LOOP:.*]]210; CHECK:       [[LOOP]]:211; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]212; CHECK-NEXT:    [[RDX_1_1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_1_NEXT_1:%.*]], %[[LOOP]] ]213; CHECK-NEXT:    [[RDX_1_2:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_1_NEXT_2:%.*]], %[[LOOP]] ]214; CHECK-NEXT:    [[RDX_1_3:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_1_NEXT_24:%.*]], %[[LOOP]] ]215; CHECK-NEXT:    [[RDX_1:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_1_NEXT:%.*]], %[[LOOP]] ]216; CHECK-NEXT:    [[RDX_2:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_2_NEXT_3:%.*]], %[[LOOP]] ]217; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1218; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]219; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 1220; CHECK-NEXT:    [[RDX_1_NEXT]] = add i32 [[RDX_1]], [[L]]221; CHECK-NEXT:    [[RDX_2_NEXT:%.*]] = mul i32 [[RDX_2]], [[L]]222; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2223; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT]]224; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 1225; CHECK-NEXT:    [[RDX_1_NEXT_1]] = add i32 [[RDX_1_1]], [[L_1]]226; CHECK-NEXT:    [[RDX_2_2:%.*]] = mul i32 [[RDX_2_NEXT]], [[L_1]]227; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3228; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_1]]229; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 1230; CHECK-NEXT:    [[RDX_1_NEXT_2]] = add i32 [[RDX_1_2]], [[L_2]]231; CHECK-NEXT:    [[RDX_2_NEXT_2:%.*]] = mul i32 [[RDX_2_2]], [[L_2]]232; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4233; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_2]]234; CHECK-NEXT:    [[L_24:%.*]] = load i32, ptr [[GEP_SRC_24]], align 1235; CHECK-NEXT:    [[RDX_1_NEXT_24]] = add i32 [[RDX_1_3]], [[L_24]]236; CHECK-NEXT:    [[RDX_2_NEXT_3]] = mul i32 [[RDX_2_NEXT_2]], [[L_24]]237; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000238; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]239; CHECK:       [[EXIT]]:240; CHECK-NEXT:    [[RDX_1_NEXT_LCSSA1:%.*]] = phi i32 [ [[RDX_1_NEXT_24]], %[[LOOP]] ]241; CHECK-NEXT:    [[BIN_RDX5:%.*]] = phi i32 [ [[RDX_2_NEXT_3]], %[[LOOP]] ]242; CHECK-NEXT:    [[BIN_RDX:%.*]] = add i32 [[RDX_1_NEXT_1]], [[RDX_1_NEXT]]243; CHECK-NEXT:    [[BIN_RDX1:%.*]] = add i32 [[RDX_1_NEXT_2]], [[BIN_RDX]]244; CHECK-NEXT:    [[RDX_1_NEXT_LCSSA:%.*]] = add i32 [[RDX_1_NEXT_24]], [[BIN_RDX1]]245; CHECK-NEXT:    [[RES:%.*]] = add i32 [[RDX_1_NEXT_LCSSA]], [[BIN_RDX5]]246; CHECK-NEXT:    ret i32 [[RES]]247;248entry:249  br label %loop250 251loop:252  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]253  %rdx.1 = phi i32 [ %start, %entry ], [ %rdx.1.next, %loop ]254  %rdx.2 = phi i32 [ %start, %entry ], [ %rdx.2.next, %loop ]255  %iv.next = add i64 %iv, 1256  %gep.src = getelementptr i32, ptr %src, i64 %iv257  %l = load i32 , ptr %gep.src, align 1258  %rdx.1.next = add i32 %rdx.1, %l259  %rdx.2.next = mul i32 %rdx.2, %l260  %ec = icmp ne i64 %iv.next, 1000261  br i1 %ec, label %loop, label %exit262 263exit:264  %res = add i32 %rdx.1.next, %rdx.2.next265  ret i32 %res266}267 268define float @test_fadd_no_fmfs(ptr %src, i64 %n, float %start) {269; CHECK-LABEL: define float @test_fadd_no_fmfs(270; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], float [[START:%.*]]) {271; CHECK-NEXT:  [[ENTRY:.*]]:272; CHECK-NEXT:    br label %[[LOOP:.*]]273; CHECK:       [[LOOP]]:274; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]275; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]276; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1277; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV]]278; CHECK-NEXT:    [[L:%.*]] = load float, ptr [[GEP_SRC]], align 1279; CHECK-NEXT:    [[RDX_NEXT:%.*]] = fadd float [[RDX]], [[L]]280; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2281; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV_NEXT]]282; CHECK-NEXT:    [[L_1:%.*]] = load float, ptr [[GEP_SRC_1]], align 1283; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = fadd float [[RDX_NEXT]], [[L_1]]284; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3285; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV_NEXT_1]]286; CHECK-NEXT:    [[L_2:%.*]] = load float, ptr [[GEP_SRC_2]], align 1287; CHECK-NEXT:    [[RDX_NEXT_2:%.*]] = fadd float [[RDX_NEXT_1]], [[L_2]]288; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4289; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV_NEXT_2]]290; CHECK-NEXT:    [[L_24:%.*]] = load float, ptr [[GEP_SRC_24]], align 1291; CHECK-NEXT:    [[RDX_NEXT_3]] = fadd float [[RDX_NEXT_2]], [[L_24]]292; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000293; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]294; CHECK:       [[EXIT]]:295; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi float [ [[RDX_NEXT_3]], %[[LOOP]] ]296; CHECK-NEXT:    ret float [[RDX_NEXT_LCSSA]]297;298entry:299  br label %loop300 301loop:302  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]303  %rdx = phi float [ %start, %entry ], [ %rdx.next, %loop ]304  %iv.next = add i64 %iv, 1305  %gep.src = getelementptr float, ptr %src, i64 %iv306  %l = load float, ptr %gep.src, align 1307  %rdx.next = fadd float %rdx, %l308  %ec = icmp ne i64 %iv.next, 1000309  br i1 %ec, label %loop, label %exit310 311exit:312  ret float %rdx.next313}314 315define float @test_fadd_with_ressaoc(ptr %src, i64 %n, float %start) {316; CHECK-LABEL: define float @test_fadd_with_ressaoc(317; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]], float [[START:%.*]]) {318; CHECK-NEXT:  [[ENTRY:.*]]:319; CHECK-NEXT:    br label %[[LOOP:.*]]320; CHECK:       [[LOOP]]:321; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]322; CHECK-NEXT:    [[RDX_1:%.*]] = phi float [ -0.000000e+00, %[[ENTRY]] ], [ [[RDX_NEXT_1:%.*]], %[[LOOP]] ]323; CHECK-NEXT:    [[RDX_2:%.*]] = phi float [ -0.000000e+00, %[[ENTRY]] ], [ [[RDX_NEXT_2:%.*]], %[[LOOP]] ]324; CHECK-NEXT:    [[RDX_3:%.*]] = phi float [ -0.000000e+00, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]325; CHECK-NEXT:    [[RDX:%.*]] = phi float [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT:%.*]], %[[LOOP]] ]326; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1327; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV]]328; CHECK-NEXT:    [[L:%.*]] = load float, ptr [[GEP_SRC]], align 1329; CHECK-NEXT:    [[RDX_NEXT]] = fadd reassoc float [[RDX]], [[L]]330; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2331; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV_NEXT]]332; CHECK-NEXT:    [[L_1:%.*]] = load float, ptr [[GEP_SRC_1]], align 1333; CHECK-NEXT:    [[RDX_NEXT_1]] = fadd reassoc float [[RDX_1]], [[L_1]]334; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3335; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV_NEXT_1]]336; CHECK-NEXT:    [[L_2:%.*]] = load float, ptr [[GEP_SRC_2]], align 1337; CHECK-NEXT:    [[RDX_NEXT_2]] = fadd reassoc float [[RDX_2]], [[L_2]]338; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4339; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr float, ptr [[SRC]], i64 [[IV_NEXT_2]]340; CHECK-NEXT:    [[L_24:%.*]] = load float, ptr [[GEP_SRC_24]], align 1341; CHECK-NEXT:    [[RDX_NEXT_3]] = fadd reassoc float [[RDX_3]], [[L_24]]342; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000343; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]344; CHECK:       [[EXIT]]:345; CHECK-NEXT:    [[RDX_NEXT_LCSSA1:%.*]] = phi float [ [[RDX_NEXT_3]], %[[LOOP]] ]346; CHECK-NEXT:    [[BIN_RDX:%.*]] = fadd reassoc float [[RDX_NEXT_1]], [[RDX_NEXT]]347; CHECK-NEXT:    [[BIN_RDX1:%.*]] = fadd reassoc float [[RDX_NEXT_2]], [[BIN_RDX]]348; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = fadd reassoc float [[RDX_NEXT_3]], [[BIN_RDX1]]349; CHECK-NEXT:    ret float [[RDX_NEXT_LCSSA]]350;351entry:352  br label %loop353 354loop:355  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]356  %rdx = phi float [ %start, %entry ], [ %rdx.next, %loop ]357  %iv.next = add i64 %iv, 1358  %gep.src = getelementptr float, ptr %src, i64 %iv359  %l = load float, ptr %gep.src, align 1360  %rdx.next = fadd reassoc float %rdx, %l361  %ec = icmp ne i64 %iv.next, 1000362  br i1 %ec, label %loop, label %exit363 364exit:365  ret float %rdx.next366}367 368define i32 @test_smin(ptr %src, i64 %n) {369; CHECK-LABEL: define i32 @test_smin(370; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {371; CHECK-NEXT:  [[ENTRY:.*]]:372; CHECK-NEXT:    br label %[[LOOP:.*]]373; CHECK:       [[LOOP]]:374; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]375; CHECK-NEXT:    [[MIN:%.*]] = phi i32 [ 1000, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]376; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1377; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV]]378; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 1379; CHECK-NEXT:    [[RDX_NEXT:%.*]] = call i32 @llvm.smin.i32(i32 [[MIN]], i32 [[L]])380; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2381; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT]]382; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 1383; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = call i32 @llvm.smin.i32(i32 [[RDX_NEXT]], i32 [[L_1]])384; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3385; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_1]]386; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 1387; CHECK-NEXT:    [[RDX_NEXT_2:%.*]] = call i32 @llvm.smin.i32(i32 [[RDX_NEXT_1]], i32 [[L_2]])388; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4389; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IV_NEXT_2]]390; CHECK-NEXT:    [[L_24:%.*]] = load i32, ptr [[GEP_SRC_24]], align 1391; CHECK-NEXT:    [[RDX_NEXT_3]] = call i32 @llvm.smin.i32(i32 [[RDX_NEXT_2]], i32 [[L_24]])392; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000393; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]394; CHECK:       [[EXIT]]:395; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi i32 [ [[RDX_NEXT_3]], %[[LOOP]] ]396; CHECK-NEXT:    ret i32 [[RDX_NEXT_LCSSA]]397;398entry:399  br label %loop400 401loop:402  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]403  %min = phi i32 [ 1000, %entry ], [ %rdx.next, %loop ]404  %iv.next = add i64 %iv, 1405  %gep.src = getelementptr i32, ptr %src, i64 %iv406  %l = load i32 , ptr %gep.src, align 1407  %rdx.next = call i32 @llvm.smin(i32 %min, i32 %l)408  %ec = icmp ne i64 %iv.next, 1000409  br i1 %ec, label %loop, label %exit410 411exit:412  ret i32 %rdx.next413}414 415define i64 @test_any_of_reduction(ptr %src, i64 %n) {416; CHECK-LABEL: define i64 @test_any_of_reduction(417; CHECK-SAME: ptr [[SRC:%.*]], i64 [[N:%.*]]) {418; CHECK-NEXT:  [[ENTRY:.*]]:419; CHECK-NEXT:    br label %[[LOOP:.*]]420; CHECK:       [[LOOP]]:421; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]422; CHECK-NEXT:    [[ANY_OF_RDX:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]423; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1424; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[IV]]425; CHECK-NEXT:    [[L:%.*]] = load i8, ptr [[GEP_SRC]], align 1426; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 [[L]], 0427; CHECK-NEXT:    [[RDX_NEXT:%.*]] = select i1 [[C]], i64 [[ANY_OF_RDX]], i64 0428; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2429; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[IV_NEXT]]430; CHECK-NEXT:    [[L_1:%.*]] = load i8, ptr [[GEP_SRC_1]], align 1431; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i8 [[L_1]], 0432; CHECK-NEXT:    [[RDX_NEXT_1:%.*]] = select i1 [[C_1]], i64 [[RDX_NEXT]], i64 0433; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3434; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[IV_NEXT_1]]435; CHECK-NEXT:    [[L_2:%.*]] = load i8, ptr [[GEP_SRC_2]], align 1436; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i8 [[L_2]], 0437; CHECK-NEXT:    [[RDX_NEXT_2:%.*]] = select i1 [[C_2]], i64 [[RDX_NEXT_1]], i64 0438; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4439; CHECK-NEXT:    [[GEP_SRC_24:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[IV_NEXT_2]]440; CHECK-NEXT:    [[L_24:%.*]] = load i8, ptr [[GEP_SRC_24]], align 1441; CHECK-NEXT:    [[C_24:%.*]] = icmp eq i8 [[L_24]], 0442; CHECK-NEXT:    [[RDX_NEXT_3]] = select i1 [[C_24]], i64 [[RDX_NEXT_2]], i64 0443; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000444; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]445; CHECK:       [[EXIT]]:446; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi i64 [ [[RDX_NEXT_3]], %[[LOOP]] ]447; CHECK-NEXT:    ret i64 [[RDX_NEXT_LCSSA]]448;449entry:450  br label %loop451 452loop:453  %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]454  %any.of.rdx = phi i64 [ %rdx.next, %loop ], [ 0, %entry ]455  %iv.next = add i64 %iv, 1456  %gep.src = getelementptr i8, ptr %src, i64 %iv457  %l = load i8, ptr %gep.src, align 1458  %c = icmp eq i8 %l, 0459  %rdx.next = select i1 %c, i64 %any.of.rdx, i64 0460  %ec = icmp ne i64 %iv.next, 1000461  br i1 %ec, label %loop, label %exit462 463exit:464  ret i64 %rdx.next465}466 467define void @reduction_with_intermediate_store(ptr %src, ptr %sum) {468; CHECK-LABEL: define void @reduction_with_intermediate_store(469; CHECK-SAME: ptr [[SRC:%.*]], ptr [[SUM:%.*]]) {470; CHECK-NEXT:  [[ENTRY:.*]]:471; CHECK-NEXT:    [[SUM_PROMOTED:%.*]] = load i32, ptr [[SUM]], align 4472; CHECK-NEXT:    br label %[[LOOP:.*]]473; CHECK:       [[LOOP]]:474; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]475; CHECK-NEXT:    [[RED:%.*]] = phi i32 [ [[SUM_PROMOTED]], %[[ENTRY]] ], [ [[RED_NEXT_3:%.*]], %[[LOOP]] ]476; CHECK-NEXT:    [[GEP_SRC:%.*]] = getelementptr inbounds nuw i32, ptr [[SRC]], i64 [[IV]]477; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 4478; CHECK-NEXT:    [[RED_NEXT:%.*]] = add nsw i32 [[RED]], [[L]]479; CHECK-NEXT:    store i32 [[RED_NEXT]], ptr [[SUM]], align 4480; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1481; CHECK-NEXT:    [[GEP_SRC_1:%.*]] = getelementptr inbounds nuw i32, ptr [[SRC]], i64 [[IV_NEXT]]482; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_SRC_1]], align 4483; CHECK-NEXT:    [[RED_NEXT_1:%.*]] = add nsw i32 [[RED_NEXT]], [[L_1]]484; CHECK-NEXT:    store i32 [[RED_NEXT_1]], ptr [[SUM]], align 4485; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2486; CHECK-NEXT:    [[GEP_SRC_2:%.*]] = getelementptr inbounds nuw i32, ptr [[SRC]], i64 [[IV_NEXT_1]]487; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_SRC_2]], align 4488; CHECK-NEXT:    [[RED_NEXT_2:%.*]] = add nsw i32 [[RED_NEXT_1]], [[L_2]]489; CHECK-NEXT:    store i32 [[RED_NEXT_2]], ptr [[SUM]], align 4490; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3491; CHECK-NEXT:    [[GEP_SRC_3:%.*]] = getelementptr inbounds nuw i32, ptr [[SRC]], i64 [[IV_NEXT_2]]492; CHECK-NEXT:    [[L_3:%.*]] = load i32, ptr [[GEP_SRC_3]], align 4493; CHECK-NEXT:    [[RED_NEXT_3]] = add nsw i32 [[RED_NEXT_2]], [[L_3]]494; CHECK-NEXT:    store i32 [[RED_NEXT_3]], ptr [[SUM]], align 4495; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4496; CHECK-NEXT:    [[EC_3:%.*]] = icmp eq i64 [[IV_NEXT_3]], 10000497; CHECK-NEXT:    br i1 [[EC_3]], label %[[EXIT:.*]], label %[[LOOP]]498; CHECK:       [[EXIT]]:499; CHECK-NEXT:    ret void500;501entry:502  %sum.promoted = load i32, ptr %sum, align 4503  br label %loop504 505loop:506  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]507  %red = phi i32 [ %sum.promoted, %entry ], [ %red.next, %loop ]508  %gep.src = getelementptr inbounds nuw i32, ptr %src, i64 %iv509  %l = load i32, ptr %gep.src, align 4510  %red.next = add nsw i32 %red, %l511  store i32 %red.next, ptr %sum, align 4512  %iv.next = add nuw nsw i64 %iv, 1513  %ec = icmp eq i64 %iv.next, 10000514  br i1 %ec, label %exit, label %loop515 516exit:517  ret void518}519 520declare i32 @foo()521 522; Loop with a call cannot be handled by LoopVectorize, introducing additional523; accumulators when unrolling increases throughput.524define i32 @test_add_with_call(i64 %n, i32 %start) {525; CHECK-LABEL: define i32 @test_add_with_call(526; CHECK-SAME: i64 [[N:%.*]], i32 [[START:%.*]]) {527; CHECK-NEXT:  [[ENTRY:.*]]:528; CHECK-NEXT:    br label %[[LOOP:.*]]529; CHECK:       [[LOOP]]:530; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]531; CHECK-NEXT:    [[RDX_1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_1:%.*]], %[[LOOP]] ]532; CHECK-NEXT:    [[RDX_2:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_2:%.*]], %[[LOOP]] ]533; CHECK-NEXT:    [[RDX_3:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]534; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT:%.*]], %[[LOOP]] ]535; CHECK-NEXT:    [[L:%.*]] = call i32 @foo()536; CHECK-NEXT:    [[RDX_NEXT]] = add i32 [[RDX]], [[L]]537; CHECK-NEXT:    [[L_1:%.*]] = call i32 @foo()538; CHECK-NEXT:    [[RDX_NEXT_1]] = add i32 [[RDX_1]], [[L_1]]539; CHECK-NEXT:    [[L_2:%.*]] = call i32 @foo()540; CHECK-NEXT:    [[RDX_NEXT_2]] = add i32 [[RDX_2]], [[L_2]]541; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4542; CHECK-NEXT:    [[L_3:%.*]] = call i32 @foo()543; CHECK-NEXT:    [[RDX_NEXT_3]] = add i32 [[RDX_3]], [[L_3]]544; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000545; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]546; CHECK:       [[EXIT]]:547; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi i32 [ [[RDX_NEXT_3]], %[[LOOP]] ]548; CHECK-NEXT:    [[BIN_RDX:%.*]] = add i32 [[RDX_NEXT_1]], [[RDX_NEXT]]549; CHECK-NEXT:    [[BIN_RDX1:%.*]] = add i32 [[RDX_NEXT_2]], [[BIN_RDX]]550; CHECK-NEXT:    [[BIN_RDX2:%.*]] = add i32 [[RDX_NEXT_3]], [[BIN_RDX1]]551; CHECK-NEXT:    ret i32 [[BIN_RDX2]]552;553entry:554  br label %loop555 556loop:557  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]558  %rdx = phi i32 [ %start, %entry ], [ %rdx.next, %loop ]559  %iv.next = add i64 %iv, 1560  %l = call i32 @foo()561  %rdx.next = add i32 %rdx, %l562  %ec = icmp ne i64 %iv.next, 1000563  br i1 %ec, label %loop, label %exit564 565exit:566  ret i32 %rdx.next567}568 569; Loop with backward dependence cannot be handled LoopVectorize, introducing additional570; accumulators when unrolling increases throughput.571define i32 @test_add_with_backward_dep(ptr %p, i64 %n, i32 %start) {572; CHECK-LABEL: define i32 @test_add_with_backward_dep(573; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]], i32 [[START:%.*]]) {574; CHECK-NEXT:  [[ENTRY:.*]]:575; CHECK-NEXT:    br label %[[LOOP:.*]]576; CHECK:       [[LOOP]]:577; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]578; CHECK-NEXT:    [[RDX_1:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_1:%.*]], %[[LOOP]] ]579; CHECK-NEXT:    [[RDX_2:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_2:%.*]], %[[LOOP]] ]580; CHECK-NEXT:    [[RDX_3:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]581; CHECK-NEXT:    [[RDX:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT:%.*]], %[[LOOP]] ]582; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1583; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV]]584; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[GEP]], align 4585; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT]]586; CHECK-NEXT:    store i32 0, ptr [[GEP_1]], align 4587; CHECK-NEXT:    [[RDX_NEXT]] = add i32 [[RDX]], [[L]]588; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2589; CHECK-NEXT:    [[GEP_11:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT]]590; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[GEP_11]], align 4591; CHECK-NEXT:    [[GEP_1_1:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT_1]]592; CHECK-NEXT:    store i32 0, ptr [[GEP_1_1]], align 4593; CHECK-NEXT:    [[RDX_NEXT_1]] = add i32 [[RDX_1]], [[L_1]]594; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3595; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT_1]]596; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[GEP_2]], align 4597; CHECK-NEXT:    [[GEP_1_2:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT_2]]598; CHECK-NEXT:    store i32 0, ptr [[GEP_1_2]], align 4599; CHECK-NEXT:    [[RDX_NEXT_2]] = add i32 [[RDX_2]], [[L_2]]600; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4601; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT_2]]602; CHECK-NEXT:    [[L_3:%.*]] = load i32, ptr [[GEP_3]], align 4603; CHECK-NEXT:    [[GEP_1_3:%.*]] = getelementptr inbounds nuw i32, ptr [[P]], i64 [[IV_NEXT_3]]604; CHECK-NEXT:    store i32 0, ptr [[GEP_1_3]], align 4605; CHECK-NEXT:    [[RDX_NEXT_3]] = add i32 [[RDX_3]], [[L_3]]606; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000607; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]608; CHECK:       [[EXIT]]:609; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi i32 [ [[RDX_NEXT_3]], %[[LOOP]] ]610; CHECK-NEXT:    [[BIN_RDX:%.*]] = add i32 [[RDX_NEXT_1]], [[RDX_NEXT]]611; CHECK-NEXT:    [[BIN_RDX2:%.*]] = add i32 [[RDX_NEXT_2]], [[BIN_RDX]]612; CHECK-NEXT:    [[BIN_RDX3:%.*]] = add i32 [[RDX_NEXT_3]], [[BIN_RDX2]]613; CHECK-NEXT:    ret i32 [[BIN_RDX3]]614;615entry:616  br label %loop617 618loop:619  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]620  %rdx = phi i32 [ %start, %entry ], [ %rdx.next, %loop ]621  %iv.next = add i64 %iv, 1622  %gep = getelementptr inbounds nuw i32, ptr %p, i64 %iv623  %l = load i32, ptr %gep624  %gep.1 = getelementptr inbounds nuw i32, ptr %p, i64 %iv.next625  store i32 0, ptr %gep.1626  %rdx.next = add i32 %rdx, %l627  %ec = icmp ne i64 %iv.next, 1000628  br i1 %ec, label %loop, label %exit629 630exit:631  ret i32 %rdx.next632}633 634define <4 x i32> @test_vector_add(ptr %p, i64 %n, <4 x i32> %start) {635; CHECK-LABEL: define <4 x i32> @test_vector_add(636; CHECK-SAME: ptr [[P:%.*]], i64 [[N:%.*]], <4 x i32> [[START:%.*]]) {637; CHECK-NEXT:  [[ENTRY:.*]]:638; CHECK-NEXT:    br label %[[LOOP:.*]]639; CHECK:       [[LOOP]]:640; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT_3:%.*]], %[[LOOP]] ]641; CHECK-NEXT:    [[RDX_1:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[RDX_NEXT_1:%.*]], %[[LOOP]] ]642; CHECK-NEXT:    [[RDX_2:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[RDX_NEXT_2:%.*]], %[[LOOP]] ]643; CHECK-NEXT:    [[RDX_3:%.*]] = phi <4 x i32> [ zeroinitializer, %[[ENTRY]] ], [ [[RDX_NEXT_3:%.*]], %[[LOOP]] ]644; CHECK-NEXT:    [[RDX:%.*]] = phi <4 x i32> [ [[START]], %[[ENTRY]] ], [ [[RDX_NEXT:%.*]], %[[LOOP]] ]645; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1646; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[P]], i64 [[IV]]647; CHECK-NEXT:    [[L:%.*]] = load <4 x i32>, ptr [[GEP]], align 16648; CHECK-NEXT:    [[RDX_NEXT]] = add <4 x i32> [[RDX]], [[L]]649; CHECK-NEXT:    [[IV_NEXT_1:%.*]] = add nuw nsw i64 [[IV]], 2650; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[P]], i64 [[IV_NEXT]]651; CHECK-NEXT:    [[L_1:%.*]] = load <4 x i32>, ptr [[GEP_1]], align 16652; CHECK-NEXT:    [[RDX_NEXT_1]] = add <4 x i32> [[RDX_1]], [[L_1]]653; CHECK-NEXT:    [[IV_NEXT_2:%.*]] = add nuw nsw i64 [[IV]], 3654; CHECK-NEXT:    [[GEP_2:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[P]], i64 [[IV_NEXT_1]]655; CHECK-NEXT:    [[L_2:%.*]] = load <4 x i32>, ptr [[GEP_2]], align 16656; CHECK-NEXT:    [[RDX_NEXT_2]] = add <4 x i32> [[RDX_2]], [[L_2]]657; CHECK-NEXT:    [[IV_NEXT_3]] = add nuw nsw i64 [[IV]], 4658; CHECK-NEXT:    [[GEP_3:%.*]] = getelementptr inbounds nuw <4 x i32>, ptr [[P]], i64 [[IV_NEXT_2]]659; CHECK-NEXT:    [[L_3:%.*]] = load <4 x i32>, ptr [[GEP_3]], align 16660; CHECK-NEXT:    [[RDX_NEXT_3]] = add <4 x i32> [[RDX_3]], [[L_3]]661; CHECK-NEXT:    [[EC_3:%.*]] = icmp ne i64 [[IV_NEXT_3]], 1000662; CHECK-NEXT:    br i1 [[EC_3]], label %[[LOOP]], label %[[EXIT:.*]]663; CHECK:       [[EXIT]]:664; CHECK-NEXT:    [[RDX_NEXT_LCSSA:%.*]] = phi <4 x i32> [ [[RDX_NEXT_3]], %[[LOOP]] ]665; CHECK-NEXT:    [[BIN_RDX:%.*]] = add <4 x i32> [[RDX_NEXT_1]], [[RDX_NEXT]]666; CHECK-NEXT:    [[BIN_RDX1:%.*]] = add <4 x i32> [[RDX_NEXT_2]], [[BIN_RDX]]667; CHECK-NEXT:    [[BIN_RDX2:%.*]] = add <4 x i32> [[RDX_NEXT_3]], [[BIN_RDX1]]668; CHECK-NEXT:    ret <4 x i32> [[BIN_RDX2]]669;670entry:671  br label %loop672 673loop:674  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]675  %rdx = phi <4 x i32> [ %start, %entry ], [ %rdx.next, %loop ]676  %iv.next = add i64 %iv, 1677  %gep = getelementptr inbounds nuw <4 x i32>, ptr %p, i64 %iv678  %l = load <4 x i32>, ptr %gep, align 16679  %rdx.next = add <4 x i32> %rdx, %l680  %ec = icmp ne i64 %iv.next, 1000681  br i1 %ec, label %loop, label %exit682 683exit:684  ret <4 x i32> %rdx.next685}686