brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.7 KiB · 433b0f0 Raw
958 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-bound-split -S < %s | FileCheck %s3 4; The transformation is failed with this test because we can not guarantee the5; split condition is always true in pre-loop after transformation.6define void @variable_split_loop_bound_and_exit_cond_inc_with_sgt(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {7; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_sgt(8; CHECK-NEXT:  loop.ph:9; CHECK-NEXT:    br label [[LOOP:%.*]]10; CHECK:       loop:11; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]12; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]13; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]14; CHECK:       if.then:15; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]16; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 417; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]18; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 419; CHECK-NEXT:    br label [[FOR_INC]]20; CHECK:       if.else:21; CHECK-NEXT:    br label [[FOR_INC]]22; CHECK:       for.inc:23; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 124; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[N:%.*]]25; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]26; CHECK:       exit:27; CHECK-NEXT:    ret void28;29loop.ph:30  br label %loop31 32loop:33  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]34  %cmp = icmp ult i64 %iv, %a35  br i1 %cmp, label %if.then, label %if.else36 37if.then:38  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv39  %val = load i64, ptr %src.arrayidx40  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv41  store i64 %val, ptr %dst.arrayidx42  br label %for.inc43 44if.else:45  br label %for.inc46 47for.inc:48  %inc = add nuw nsw i64 %iv, 149  %cond = icmp sgt i64 %inc, %n50  br i1 %cond, label %exit, label %loop51 52exit:53  ret void54}55 56; The transformation works with this test because we can guarantee the split57; condition is always true in pre-loop after transformation.58define void @umax_variable_split_loop_bound_and_exit_cond_inc_with_sgt(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {59; CHECK-LABEL: @umax_variable_split_loop_bound_and_exit_cond_inc_with_sgt(60; CHECK-NEXT:  loop.ph:61; CHECK-NEXT:    [[B:%.*]] = call i64 @llvm.umax.i64(i64 [[A:%.*]], i64 1)62; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]63; CHECK:       loop.ph.split:64; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0)65; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 [[B]])66; CHECK-NEXT:    br label [[LOOP:%.*]]67; CHECK:       loop:68; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]69; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[B]]70; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]71; CHECK:       if.then:72; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]73; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 474; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]75; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 476; CHECK-NEXT:    br label [[FOR_INC]]77; CHECK:       if.else:78; CHECK-NEXT:    br label [[FOR_INC]]79; CHECK:       for.inc:80; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 181; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]82; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]83; CHECK:       loop.ph.split.split:84; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]85; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]]86; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]87; CHECK:       loop.split.preheader:88; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]89; CHECK:       loop.split:90; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]91; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], [[B]]92; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]93; CHECK:       if.else.split:94; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]95; CHECK:       if.then.split:96; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]]97; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 498; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]]99; CHECK-NEXT:    store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4100; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]101; CHECK:       for.inc.split:102; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1103; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]104; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]105; CHECK:       exit.loopexit:106; CHECK-NEXT:    br label [[EXIT]]107; CHECK:       exit:108; CHECK-NEXT:    ret void109;110loop.ph:111  %b = call i64 @llvm.umax.i64(i64 %a, i64 1)112  br label %loop113 114loop:115  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]116  %cmp = icmp ult i64 %iv, %b117  br i1 %cmp, label %if.then, label %if.else118 119if.then:120  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv121  %val = load i64, ptr %src.arrayidx122  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv123  store i64 %val, ptr %dst.arrayidx124  br label %for.inc125 126if.else:127  br label %for.inc128 129for.inc:130  %inc = add nuw nsw i64 %iv, 1131  %cond = icmp sgt i64 %inc, %n132  br i1 %cond, label %exit, label %loop133 134exit:135  ret void136}137 138; The transformation works with this test because we can guarantee the split139; condition is always true in pre-loop after transformation.140define void @constant_split_loop_bound_and_exit_cond_inc_with_sgt(ptr noalias %src, ptr noalias %dst, i64 %n) {141; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_sgt(142; CHECK-NEXT:  loop.ph:143; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]144; CHECK:       loop.ph.split:145; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0)146; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 10)147; CHECK-NEXT:    br label [[LOOP:%.*]]148; CHECK:       loop:149; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]150; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10151; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]152; CHECK:       if.then:153; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]154; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4155; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]156; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4157; CHECK-NEXT:    br label [[FOR_INC]]158; CHECK:       if.else:159; CHECK-NEXT:    br label [[FOR_INC]]160; CHECK:       for.inc:161; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1162; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]163; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]164; CHECK:       loop.ph.split.split:165; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]166; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]]167; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]168; CHECK:       loop.split.preheader:169; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]170; CHECK:       loop.split:171; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]172; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10173; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]174; CHECK:       if.else.split:175; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]176; CHECK:       if.then.split:177; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]]178; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4179; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]]180; CHECK-NEXT:    store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4181; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]182; CHECK:       for.inc.split:183; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1184; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]185; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]186; CHECK:       exit.loopexit:187; CHECK-NEXT:    br label [[EXIT]]188; CHECK:       exit:189; CHECK-NEXT:    ret void190;191loop.ph:192  br label %loop193 194loop:195  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]196  %cmp = icmp ult i64 %iv, 10197  br i1 %cmp, label %if.then, label %if.else198 199if.then:200  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv201  %val = load i64, ptr %src.arrayidx202  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv203  store i64 %val, ptr %dst.arrayidx204  br label %for.inc205 206if.else:207  br label %for.inc208 209for.inc:210  %inc = add nuw nsw i64 %iv, 1211  %cond = icmp sgt i64 %inc, %n212  br i1 %cond, label %exit, label %loop213 214exit:215  ret void216}217 218define void @variable_split_loop_bound_and_exit_cond_inc_with_eq(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {219; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_eq(220; CHECK-NEXT:  loop.ph:221; CHECK-NEXT:    br label [[LOOP:%.*]]222; CHECK:       loop:223; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]224; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]225; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]226; CHECK:       if.then:227; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]228; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4229; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]230; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4231; CHECK-NEXT:    br label [[FOR_INC]]232; CHECK:       if.else:233; CHECK-NEXT:    br label [[FOR_INC]]234; CHECK:       for.inc:235; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1236; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INC]], [[N:%.*]]237; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]238; CHECK:       exit:239; CHECK-NEXT:    ret void240;241loop.ph:242  br label %loop243 244loop:245  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]246  %cmp = icmp ult i64 %iv, %a247  br i1 %cmp, label %if.then, label %if.else248 249if.then:250  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv251  %val = load i64, ptr %src.arrayidx252  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv253  store i64 %val, ptr %dst.arrayidx254  br label %for.inc255 256if.else:257  br label %for.inc258 259for.inc:260  %inc = add nuw nsw i64 %iv, 1261  %cond = icmp eq i64 %inc, %n262  br i1 %cond, label %exit, label %loop263 264exit:265  ret void266}267 268define void @constant_split_loop_bound_and_exit_cond_inc_with_eq(ptr noalias %src, ptr noalias %dst, i64 %n) {269; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_eq(270; CHECK-NEXT:  loop.ph:271; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]272; CHECK:       loop.ph.split:273; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N:%.*]], -1274; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP0]], i64 10)275; CHECK-NEXT:    br label [[LOOP:%.*]]276; CHECK:       loop:277; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]278; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10279; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]280; CHECK:       if.then:281; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]282; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4283; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]284; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4285; CHECK-NEXT:    br label [[FOR_INC]]286; CHECK:       if.else:287; CHECK-NEXT:    br label [[FOR_INC]]288; CHECK:       for.inc:289; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1290; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[INC]], [[NEW_BOUND]]291; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]292; CHECK:       loop.ph.split.split:293; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]294; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]]295; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]296; CHECK:       loop.split.preheader:297; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]298; CHECK:       loop.split:299; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]300; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10301; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]302; CHECK:       if.else.split:303; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]304; CHECK:       if.then.split:305; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]]306; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4307; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]]308; CHECK-NEXT:    store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4309; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]310; CHECK:       for.inc.split:311; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1312; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp eq i64 [[INC_SPLIT]], [[N]]313; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]314; CHECK:       exit.loopexit:315; CHECK-NEXT:    br label [[EXIT]]316; CHECK:       exit:317; CHECK-NEXT:    ret void318;319loop.ph:320  br label %loop321 322loop:323  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]324  %cmp = icmp ult i64 %iv, 10325  br i1 %cmp, label %if.then, label %if.else326 327if.then:328  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv329  %val = load i64, ptr %src.arrayidx330  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv331  store i64 %val, ptr %dst.arrayidx332  br label %for.inc333 334if.else:335  br label %for.inc336 337for.inc:338  %inc = add nuw nsw i64 %iv, 1339  %cond = icmp eq i64 %inc, %n340  br i1 %cond, label %exit, label %loop341 342exit:343  ret void344}345 346define void @variable_split_loop_bound_and_exit_cond_inc_with_sge(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {347; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_sge(348; CHECK-NEXT:  loop.ph:349; CHECK-NEXT:    br label [[LOOP:%.*]]350; CHECK:       loop:351; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]352; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]353; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]354; CHECK:       if.then:355; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]356; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4357; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]358; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4359; CHECK-NEXT:    br label [[FOR_INC]]360; CHECK:       if.else:361; CHECK-NEXT:    br label [[FOR_INC]]362; CHECK:       for.inc:363; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1364; CHECK-NEXT:    [[COND:%.*]] = icmp sge i64 [[INC]], [[N:%.*]]365; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]366; CHECK:       exit:367; CHECK-NEXT:    ret void368;369loop.ph:370  br label %loop371 372loop:373  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]374  %cmp = icmp ult i64 %iv, %a375  br i1 %cmp, label %if.then, label %if.else376 377if.then:378  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv379  %val = load i64, ptr %src.arrayidx380  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv381  store i64 %val, ptr %dst.arrayidx382  br label %for.inc383 384if.else:385  br label %for.inc386 387for.inc:388  %inc = add nuw nsw i64 %iv, 1389  %cond = icmp sge i64 %inc, %n390  br i1 %cond, label %exit, label %loop391 392exit:393  ret void394}395 396define void @constant_split_loop_bound_and_exit_cond_inc_with_sge(ptr noalias %src, ptr noalias %dst, i64 %n) {397; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_sge(398; CHECK-NEXT:  loop.ph:399; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]400; CHECK:       loop.ph.split:401; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 1)402; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i64 [[SMAX]], -1403; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 10)404; CHECK-NEXT:    br label [[LOOP:%.*]]405; CHECK:       loop:406; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]407; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10408; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]409; CHECK:       if.then:410; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]411; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4412; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]413; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4414; CHECK-NEXT:    br label [[FOR_INC]]415; CHECK:       if.else:416; CHECK-NEXT:    br label [[FOR_INC]]417; CHECK:       for.inc:418; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1419; CHECK-NEXT:    [[COND:%.*]] = icmp sge i64 [[INC]], [[NEW_BOUND]]420; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]421; CHECK:       loop.ph.split.split:422; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]423; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]]424; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]425; CHECK:       loop.split.preheader:426; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]427; CHECK:       loop.split:428; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]429; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10430; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]431; CHECK:       if.else.split:432; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]433; CHECK:       if.then.split:434; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]]435; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4436; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]]437; CHECK-NEXT:    store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4438; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]439; CHECK:       for.inc.split:440; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1441; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sge i64 [[INC_SPLIT]], [[N]]442; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]443; CHECK:       exit.loopexit:444; CHECK-NEXT:    br label [[EXIT]]445; CHECK:       exit:446; CHECK-NEXT:    ret void447;448loop.ph:449  br label %loop450 451loop:452  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]453  %cmp = icmp ult i64 %iv, 10454  br i1 %cmp, label %if.then, label %if.else455 456if.then:457  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv458  %val = load i64, ptr %src.arrayidx459  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv460  store i64 %val, ptr %dst.arrayidx461  br label %for.inc462 463if.else:464  br label %for.inc465 466for.inc:467  %inc = add nuw nsw i64 %iv, 1468  %cond = icmp sge i64 %inc, %n469  br i1 %cond, label %exit, label %loop470 471exit:472  ret void473}474 475define void @variable_split_loop_bound_and_exit_cond_inc_with_step_is_not_one(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {476; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_step_is_not_one(477; CHECK-NEXT:  loop.ph:478; CHECK-NEXT:    br label [[LOOP:%.*]]479; CHECK:       loop:480; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]481; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]482; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]483; CHECK:       if.then:484; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]485; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4486; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]487; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4488; CHECK-NEXT:    br label [[FOR_INC]]489; CHECK:       if.else:490; CHECK-NEXT:    br label [[FOR_INC]]491; CHECK:       for.inc:492; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 2493; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[N:%.*]]494; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]495; CHECK:       exit:496; CHECK-NEXT:    ret void497;498loop.ph:499  br label %loop500 501loop:502  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]503  %cmp = icmp ult i64 %iv, %a504  br i1 %cmp, label %if.then, label %if.else505 506if.then:507  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv508  %val = load i64, ptr %src.arrayidx509  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv510  store i64 %val, ptr %dst.arrayidx511  br label %for.inc512 513if.else:514  br label %for.inc515 516for.inc:517  %inc = add nuw nsw i64 %iv, 2518  %cond = icmp sgt i64 %inc, %n519  br i1 %cond, label %exit, label %loop520 521exit:522  ret void523}524 525define void @constant_split_loop_bound_and_exit_cond_inc_with_step_is_not_one(ptr noalias %src, ptr noalias %dst, i64 %n) {526; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_step_is_not_one(527; CHECK-NEXT:  loop.ph:528; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]529; CHECK:       loop.ph.split:530; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 1)531; CHECK-NEXT:    [[TMP0:%.*]] = lshr i64 [[SMAX]], 1532; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP0]], i64 10)533; CHECK-NEXT:    br label [[LOOP:%.*]]534; CHECK:       loop:535; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH_SPLIT]] ]536; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10537; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]538; CHECK:       if.then:539; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]540; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4541; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]542; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4543; CHECK-NEXT:    br label [[FOR_INC]]544; CHECK:       if.else:545; CHECK-NEXT:    br label [[FOR_INC]]546; CHECK:       for.inc:547; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 2548; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]549; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]550; CHECK:       loop.ph.split.split:551; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]552; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]]553; CHECK-NEXT:    br i1 [[TMP1]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]554; CHECK:       loop.split.preheader:555; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]556; CHECK:       loop.split:557; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT:%.*]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]558; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10559; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]560; CHECK:       if.else.split:561; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]562; CHECK:       if.then.split:563; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]]564; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4565; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]]566; CHECK-NEXT:    store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4567; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]568; CHECK:       for.inc.split:569; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 2570; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]571; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]572; CHECK:       exit.loopexit:573; CHECK-NEXT:    br label [[EXIT]]574; CHECK:       exit:575; CHECK-NEXT:    ret void576;577loop.ph:578  br label %loop579 580loop:581  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]582  %cmp = icmp ult i64 %iv, 10583  br i1 %cmp, label %if.then, label %if.else584 585if.then:586  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv587  %val = load i64, ptr %src.arrayidx588  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv589  store i64 %val, ptr %dst.arrayidx590  br label %for.inc591 592if.else:593  br label %for.inc594 595for.inc:596  %inc = add nuw nsw i64 %iv, 2597  %cond = icmp sgt i64 %inc, %n598  br i1 %cond, label %exit, label %loop599 600exit:601  ret void602}603 604define void @variable_split_loop_bound_and_exit_cond_inc_with_ne(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {605; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_inc_with_ne(606; CHECK-NEXT:  loop.ph:607; CHECK-NEXT:    br label [[LOOP:%.*]]608; CHECK:       loop:609; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]610; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]611; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_INC]]612; CHECK:       if.then:613; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]614; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4615; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]616; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4617; CHECK-NEXT:    br label [[FOR_INC]]618; CHECK:       for.inc:619; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1620; CHECK-NEXT:    [[COND:%.*]] = icmp ne i64 [[INC]], [[N:%.*]]621; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]622; CHECK:       exit:623; CHECK-NEXT:    ret void624;625loop.ph:626  br label %loop627 628loop:629  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]630  %cmp = icmp ult i64 %iv, %a631  br i1 %cmp, label %if.then, label %for.inc632 633if.then:634  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv635  %val = load i64, ptr %src.arrayidx636  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv637  store i64 %val, ptr %dst.arrayidx638  br label %for.inc639 640for.inc:641  %inc = add nuw nsw i64 %iv, 1642  %cond = icmp ne i64 %inc, %n643  br i1 %cond, label %exit, label %loop644 645exit:646  ret void647}648 649define void @constant_split_loop_bound_and_exit_cond_inc_with_ne(ptr noalias %src, ptr noalias %dst, i64 %n) {650; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_ne(651; CHECK-NEXT:  loop.ph:652; CHECK-NEXT:    br label [[LOOP:%.*]]653; CHECK:       loop:654; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]655; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10656; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_INC]]657; CHECK:       if.then:658; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]659; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4660; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]661; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4662; CHECK-NEXT:    br label [[FOR_INC]]663; CHECK:       for.inc:664; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1665; CHECK-NEXT:    [[COND:%.*]] = icmp ne i64 [[INC]], [[N:%.*]]666; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]667; CHECK:       exit:668; CHECK-NEXT:    ret void669;670loop.ph:671  br label %loop672 673loop:674  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]675  %cmp = icmp ult i64 %iv, 10676  br i1 %cmp, label %if.then, label %for.inc677 678if.then:679  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv680  %val = load i64, ptr %src.arrayidx681  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv682  store i64 %val, ptr %dst.arrayidx683  br label %for.inc684 685for.inc:686  %inc = add nuw nsw i64 %iv, 1687  %cond = icmp ne i64 %inc, %n688  br i1 %cond, label %exit, label %loop689 690exit:691  ret void692}693 694define void @varialbe_split_loop_bound_and_exit_cond_dec_with_slt(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {695; CHECK-LABEL: @varialbe_split_loop_bound_and_exit_cond_dec_with_slt(696; CHECK-NEXT:  loop.ph:697; CHECK-NEXT:    br label [[LOOP:%.*]]698; CHECK:       loop:699; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]700; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]701; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]]702; CHECK:       if.then:703; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]704; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4705; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]706; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4707; CHECK-NEXT:    br label [[FOR_DEC]]708; CHECK:       for.dec:709; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1710; CHECK-NEXT:    [[COND:%.*]] = icmp slt i64 [[DEC]], [[N:%.*]]711; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]712; CHECK:       exit:713; CHECK-NEXT:    ret void714;715loop.ph:716  br label %loop717 718loop:719  %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ]720  %cmp = icmp ult i64 %iv, %a721  br i1 %cmp, label %if.then, label %for.dec722 723if.then:724  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv725  %val = load i64, ptr %src.arrayidx726  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv727  store i64 %val, ptr %dst.arrayidx728  br label %for.dec729 730for.dec:731  %dec = sub nuw nsw i64 %iv, 1732  %cond = icmp slt i64 %dec, %n733  br i1 %cond, label %exit, label %loop734 735exit:736  ret void737}738 739define void @constant_split_loop_bound_and_exit_cond_dec_with_slt(ptr noalias %src, ptr noalias %dst, i64 %n) {740; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_dec_with_slt(741; CHECK-NEXT:  loop.ph:742; CHECK-NEXT:    br label [[LOOP:%.*]]743; CHECK:       loop:744; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]745; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10746; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]]747; CHECK:       if.then:748; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]749; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4750; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]751; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4752; CHECK-NEXT:    br label [[FOR_DEC]]753; CHECK:       for.dec:754; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1755; CHECK-NEXT:    [[COND:%.*]] = icmp slt i64 [[DEC]], [[N:%.*]]756; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]757; CHECK:       exit:758; CHECK-NEXT:    ret void759;760loop.ph:761  br label %loop762 763loop:764  %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ]765  %cmp = icmp ult i64 %iv, 10766  br i1 %cmp, label %if.then, label %for.dec767 768if.then:769  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv770  %val = load i64, ptr %src.arrayidx771  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv772  store i64 %val, ptr %dst.arrayidx773  br label %for.dec774 775for.dec:776  %dec = sub nuw nsw i64 %iv, 1777  %cond = icmp slt i64 %dec, %n778  br i1 %cond, label %exit, label %loop779 780exit:781  ret void782}783 784define void @variable_split_loop_bound_and_exit_cond_dec_with_sle(i64 %a, ptr noalias %src, ptr noalias %dst, i64 %n) {785; CHECK-LABEL: @variable_split_loop_bound_and_exit_cond_dec_with_sle(786; CHECK-NEXT:  loop.ph:787; CHECK-NEXT:    br label [[LOOP:%.*]]788; CHECK:       loop:789; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]790; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], [[A:%.*]]791; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]]792; CHECK:       if.then:793; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]794; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4795; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]796; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4797; CHECK-NEXT:    br label [[FOR_DEC]]798; CHECK:       for.dec:799; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1800; CHECK-NEXT:    [[COND:%.*]] = icmp sle i64 [[DEC]], [[N:%.*]]801; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]802; CHECK:       exit:803; CHECK-NEXT:    ret void804;805loop.ph:806  br label %loop807 808loop:809  %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ]810  %cmp = icmp ult i64 %iv, %a811  br i1 %cmp, label %if.then, label %for.dec812 813if.then:814  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv815  %val = load i64, ptr %src.arrayidx816  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv817  store i64 %val, ptr %dst.arrayidx818  br label %for.dec819 820for.dec:821  %dec = sub nuw nsw i64 %iv, 1822  %cond = icmp sle i64 %dec, %n823  br i1 %cond, label %exit, label %loop824 825exit:826  ret void827}828 829define void @constant_split_loop_bound_and_exit_cond_dec_with_sle(ptr noalias %src, ptr noalias %dst, i64 %n) {830; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_dec_with_sle(831; CHECK-NEXT:  loop.ph:832; CHECK-NEXT:    br label [[LOOP:%.*]]833; CHECK:       loop:834; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[DEC:%.*]], [[FOR_DEC:%.*]] ], [ 0, [[LOOP_PH:%.*]] ]835; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10836; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[FOR_DEC]]837; CHECK:       if.then:838; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]839; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4840; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]841; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4842; CHECK-NEXT:    br label [[FOR_DEC]]843; CHECK:       for.dec:844; CHECK-NEXT:    [[DEC]] = sub nuw nsw i64 [[IV]], 1845; CHECK-NEXT:    [[COND:%.*]] = icmp sle i64 [[DEC]], [[N:%.*]]846; CHECK-NEXT:    br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]]847; CHECK:       exit:848; CHECK-NEXT:    ret void849;850loop.ph:851  br label %loop852 853loop:854  %iv = phi i64 [ %dec, %for.dec ], [ 0, %loop.ph ]855  %cmp = icmp ult i64 %iv, 10856  br i1 %cmp, label %if.then, label %for.dec857 858if.then:859  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv860  %val = load i64, ptr %src.arrayidx861  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv862  store i64 %val, ptr %dst.arrayidx863  br label %for.dec864 865for.dec:866  %dec = sub nuw nsw i64 %iv, 1867  %cond = icmp sle i64 %dec, %n868  br i1 %cond, label %exit, label %loop869 870exit:871  ret void872}873 874; LoopBoundSplit pass should ignore phi which is not scevable phi.875define void @constant_split_loop_bound_and_exit_cond_inc_with_sgt_and_is_not_scevable_phi(ptr noalias %src, ptr noalias %dst, i64 %n) {876; CHECK-LABEL: @constant_split_loop_bound_and_exit_cond_inc_with_sgt_and_is_not_scevable_phi(877; CHECK-NEXT:  loop.ph:878; CHECK-NEXT:    br label [[LOOP_PH_SPLIT:%.*]]879; CHECK:       loop.ph.split:880; CHECK-NEXT:    [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[N:%.*]], i64 0)881; CHECK-NEXT:    [[NEW_BOUND:%.*]] = call i64 @llvm.smin.i64(i64 [[SMAX]], i64 10)882; CHECK-NEXT:    br label [[LOOP:%.*]]883; CHECK:       loop:884; CHECK-NEXT:    [[IS_NOT_SCEVABLE_PHI:%.*]] = phi double [ 1.000000e+00, [[FOR_INC:%.*]] ], [ 2.000000e+00, [[LOOP_PH_SPLIT]] ]885; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC]] ], [ 0, [[LOOP_PH_SPLIT]] ]886; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[IV]], 10887; CHECK-NEXT:    br i1 true, label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]888; CHECK:       if.then:889; CHECK-NEXT:    [[SRC_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[SRC:%.*]], i64 [[IV]]890; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[SRC_ARRAYIDX]], align 4891; CHECK-NEXT:    [[DST_ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[DST:%.*]], i64 [[IV]]892; CHECK-NEXT:    store i64 [[VAL]], ptr [[DST_ARRAYIDX]], align 4893; CHECK-NEXT:    br label [[FOR_INC]]894; CHECK:       if.else:895; CHECK-NEXT:    br label [[FOR_INC]]896; CHECK:       for.inc:897; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[IV]], 1898; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i64 [[INC]], [[NEW_BOUND]]899; CHECK-NEXT:    br i1 [[COND]], label [[LOOP_PH_SPLIT_SPLIT:%.*]], label [[LOOP]]900; CHECK:       loop.ph.split.split:901; CHECK-NEXT:    [[IS_NOT_SCEVABLE_PHI_LCSSA:%.*]] = phi double [ 1.000000e+00, [[FOR_INC]] ]902; CHECK-NEXT:    [[IV_LCSSA:%.*]] = phi i64 [ [[INC]], [[FOR_INC]] ]903; CHECK-NEXT:    [[TMP0:%.*]] = icmp ne i64 [[IV_LCSSA]], [[N]]904; CHECK-NEXT:    br i1 [[TMP0]], label [[LOOP_SPLIT_PREHEADER:%.*]], label [[EXIT:%.*]]905; CHECK:       loop.split.preheader:906; CHECK-NEXT:    br label [[LOOP_SPLIT:%.*]]907; CHECK:       loop.split:908; CHECK-NEXT:    [[IS_NOT_SCEVABLE_PHI_SPLIT:%.*]] = phi double [ 1.000000e+00, [[FOR_INC_SPLIT:%.*]] ], [ [[IS_NOT_SCEVABLE_PHI_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]909; CHECK-NEXT:    [[IV_SPLIT:%.*]] = phi i64 [ [[INC_SPLIT:%.*]], [[FOR_INC_SPLIT]] ], [ [[IV_LCSSA]], [[LOOP_SPLIT_PREHEADER]] ]910; CHECK-NEXT:    [[CMP_SPLIT:%.*]] = icmp ult i64 [[IV_SPLIT]], 10911; CHECK-NEXT:    br i1 false, label [[IF_THEN_SPLIT:%.*]], label [[IF_ELSE_SPLIT:%.*]]912; CHECK:       if.else.split:913; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]914; CHECK:       if.then.split:915; CHECK-NEXT:    [[SRC_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[IV_SPLIT]]916; CHECK-NEXT:    [[VAL_SPLIT:%.*]] = load i64, ptr [[SRC_ARRAYIDX_SPLIT]], align 4917; CHECK-NEXT:    [[DST_ARRAYIDX_SPLIT:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[IV_SPLIT]]918; CHECK-NEXT:    store i64 [[VAL_SPLIT]], ptr [[DST_ARRAYIDX_SPLIT]], align 4919; CHECK-NEXT:    br label [[FOR_INC_SPLIT]]920; CHECK:       for.inc.split:921; CHECK-NEXT:    [[INC_SPLIT]] = add nuw nsw i64 [[IV_SPLIT]], 1922; CHECK-NEXT:    [[COND_SPLIT:%.*]] = icmp sgt i64 [[INC_SPLIT]], [[N]]923; CHECK-NEXT:    br i1 [[COND_SPLIT]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_SPLIT]]924; CHECK:       exit.loopexit:925; CHECK-NEXT:    br label [[EXIT]]926; CHECK:       exit:927; CHECK-NEXT:    ret void928;929loop.ph:930  br label %loop931 932loop:933  %is_not_scevable_phi = phi double [ 1.0, %for.inc ], [ 2.0, %loop.ph ]934  %iv = phi i64 [ %inc, %for.inc ], [ 0, %loop.ph ]935  %cmp = icmp ult i64 %iv, 10936  br i1 %cmp, label %if.then, label %if.else937 938if.then:939  %src.arrayidx = getelementptr inbounds i64, ptr %src, i64 %iv940  %val = load i64, ptr %src.arrayidx941  %dst.arrayidx = getelementptr inbounds i64, ptr %dst, i64 %iv942  store i64 %val, ptr %dst.arrayidx943  br label %for.inc944 945if.else:946  br label %for.inc947 948for.inc:949  %inc = add nuw nsw i64 %iv, 1950  %cond = icmp sgt i64 %inc, %n951  br i1 %cond, label %exit, label %loop952 953exit:954  ret void955}956 957declare i64 @llvm.umax.i64(i64, i64)958