xref: /llvm-project/llvm/test/Transforms/LoopUnroll/unroll-loads-cse.ll (revision 175d2971020ceaad3e1adcf9bb92e4ebaaa449ee)
101f8da90SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
201f8da90SFlorian Hahn; RUN: opt -p loop-unroll -S %s | FileCheck %s
301f8da90SFlorian Hahn
401f8da90SFlorian Hahntarget datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
501f8da90SFlorian Hahn
601f8da90SFlorian Hahndefine void @cse_matching_load_from_previous_unrolled_iteration(ptr %src, ptr noalias %dst, i64 %N) {
701f8da90SFlorian Hahn; CHECK-LABEL: define void @cse_matching_load_from_previous_unrolled_iteration(
801f8da90SFlorian Hahn; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) {
901f8da90SFlorian Hahn; CHECK-NEXT:  entry:
1001f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_4:%.*]] = getelementptr i8, ptr [[SRC]], i64 4
1101f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_12:%.*]] = getelementptr i8, ptr [[SRC]], i64 12
1201f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], -1
1301f8da90SFlorian Hahn; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[N]], 1
1401f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 1
1501f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP1]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
1601f8da90SFlorian Hahn; CHECK:       entry.new:
1701f8da90SFlorian Hahn; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]]
1801f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
1901f8da90SFlorian Hahn; CHECK:       loop:
2001f8da90SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_1:%.*]], [[LOOP]] ]
2101f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[LOOP]] ]
2201f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV]]
2301f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12:%.*]] = load i64, ptr [[GEP_SRC_12]], align 8
2401f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV]]
2501f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4:%.*]] = load i64, ptr [[GEP_SRC_4]], align 8
2601f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[L_12]], [[L_4]]
2701f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV]]
2801f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL]], ptr [[GEP_DST]], align 8
2901f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1
3001f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_1:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_NEXT]]
3101f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_1:%.*]] = load i64, ptr [[GEP_SRC_12_1]], align 8
32*175d2971SFlorian Hahn; CHECK-NEXT:    [[MUL_1:%.*]] = mul i64 [[L_12_1]], [[L_12]]
3301f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_1:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_NEXT]]
3401f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_1]], ptr [[GEP_DST_1]], align 8
3501f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT_1]] = add nuw nsw i64 [[IV]], 2
3601f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NEXT_1]] = add i64 [[NITER]], 2
3701f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i64 [[NITER_NEXT_1]], [[UNROLL_ITER]]
3801f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[EXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP0:![0-9]+]]
3901f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa.loopexit:
4001f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_1]], [[LOOP]] ]
4101f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT_UNR_LCSSA]]
4201f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa:
4301f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT_UNR_LCSSA_LOOPEXIT]] ]
4401f8da90SFlorian Hahn; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
4501f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[LOOP_EPIL_PREHEADER:%.*]], label [[EXIT:%.*]]
4601f8da90SFlorian Hahn; CHECK:       loop.epil.preheader:
4701f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_EPIL:%.*]]
4801f8da90SFlorian Hahn; CHECK:       loop.epil:
4901f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_EPIL:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_UNR]]
5001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EPIL:%.*]] = load i64, ptr [[GEP_SRC_12_EPIL]], align 8
5101f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_EPIL:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_UNR]]
5201f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_EPIL:%.*]] = load i64, ptr [[GEP_SRC_4_EPIL]], align 8
5301f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_EPIL:%.*]] = mul i64 [[L_12_EPIL]], [[L_4_EPIL]]
5401f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_EPIL:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_UNR]]
5501f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_EPIL]], ptr [[GEP_DST_EPIL]], align 8
5601f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
5701f8da90SFlorian Hahn; CHECK:       exit:
5801f8da90SFlorian Hahn; CHECK-NEXT:    ret void
5901f8da90SFlorian Hahn;
6001f8da90SFlorian Hahnentry:
6101f8da90SFlorian Hahn  %src.4 = getelementptr i8, ptr %src, i64 4
6201f8da90SFlorian Hahn  %src.12 = getelementptr i8, ptr %src, i64 12
6301f8da90SFlorian Hahn  br label %loop
6401f8da90SFlorian Hahn
6501f8da90SFlorian Hahnloop:
6601f8da90SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
6701f8da90SFlorian Hahn  %gep.src.12 = getelementptr i64, ptr %src.12, i64 %iv
6801f8da90SFlorian Hahn  %l.12 = load i64, ptr %gep.src.12, align 8
6901f8da90SFlorian Hahn  %gep.src.4 = getelementptr i64, ptr %src.4, i64 %iv
7001f8da90SFlorian Hahn  %l.4 = load i64, ptr %gep.src.4, align 8
7101f8da90SFlorian Hahn  %mul = mul i64 %l.12, %l.4
7201f8da90SFlorian Hahn  %gep.dst = getelementptr i64, ptr %dst, i64 %iv
7301f8da90SFlorian Hahn  store i64 %mul, ptr %gep.dst
7401f8da90SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
7501f8da90SFlorian Hahn  %c = icmp eq i64 %iv.next, %N
7601f8da90SFlorian Hahn  br i1 %c, label %exit, label %loop, !llvm.loop !1
7701f8da90SFlorian Hahn
7801f8da90SFlorian Hahnexit:
7901f8da90SFlorian Hahn  ret void
8001f8da90SFlorian Hahn}
8101f8da90SFlorian Hahn
8201f8da90SFlorian Hahndefine void @cse_different_load_types(ptr %src, ptr noalias %dst, i64 %N) {
8301f8da90SFlorian Hahn; CHECK-LABEL: define void @cse_different_load_types(
8401f8da90SFlorian Hahn; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) {
8501f8da90SFlorian Hahn; CHECK-NEXT:  entry:
8601f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_4:%.*]] = getelementptr i8, ptr [[SRC]], i64 4
8701f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_12:%.*]] = getelementptr i8, ptr [[SRC]], i64 12
8801f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], -1
8901f8da90SFlorian Hahn; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[N]], 1
9001f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 1
9101f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP1]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
9201f8da90SFlorian Hahn; CHECK:       entry.new:
9301f8da90SFlorian Hahn; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]]
9401f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
9501f8da90SFlorian Hahn; CHECK:       loop:
9601f8da90SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_1:%.*]], [[LOOP]] ]
9701f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[LOOP]] ]
9801f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV]]
9901f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12:%.*]] = load i32, ptr [[GEP_SRC_12]], align 8
10001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EXT:%.*]] = zext i32 [[L_12]] to i64
10101f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV]]
10201f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4:%.*]] = load i64, ptr [[GEP_SRC_4]], align 8
10301f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[L_12_EXT]], [[L_4]]
10401f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV]]
10501f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL]], ptr [[GEP_DST]], align 8
10601f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1
10701f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_1:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_NEXT]]
10801f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_1:%.*]] = load i32, ptr [[GEP_SRC_12_1]], align 8
10901f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EXT_1:%.*]] = zext i32 [[L_12_1]] to i64
11001f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_1:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_NEXT]]
11101f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_1:%.*]] = load i64, ptr [[GEP_SRC_4_1]], align 8
11201f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_1:%.*]] = mul i64 [[L_12_EXT_1]], [[L_4_1]]
11301f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_1:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_NEXT]]
11401f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_1]], ptr [[GEP_DST_1]], align 8
11501f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT_1]] = add nuw nsw i64 [[IV]], 2
11601f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NEXT_1]] = add i64 [[NITER]], 2
11701f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i64 [[NITER_NEXT_1]], [[UNROLL_ITER]]
11801f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[EXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
11901f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa.loopexit:
12001f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_1]], [[LOOP]] ]
12101f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT_UNR_LCSSA]]
12201f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa:
12301f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT_UNR_LCSSA_LOOPEXIT]] ]
12401f8da90SFlorian Hahn; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
12501f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[LOOP_EPIL_PREHEADER:%.*]], label [[EXIT:%.*]]
12601f8da90SFlorian Hahn; CHECK:       loop.epil.preheader:
12701f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_EPIL:%.*]]
12801f8da90SFlorian Hahn; CHECK:       loop.epil:
12901f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_EPIL:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_UNR]]
13001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EPIL:%.*]] = load i32, ptr [[GEP_SRC_12_EPIL]], align 8
13101f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EXT_EPIL:%.*]] = zext i32 [[L_12_EPIL]] to i64
13201f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_EPIL:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_UNR]]
13301f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_EPIL:%.*]] = load i64, ptr [[GEP_SRC_4_EPIL]], align 8
13401f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_EPIL:%.*]] = mul i64 [[L_12_EXT_EPIL]], [[L_4_EPIL]]
13501f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_EPIL:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_UNR]]
13601f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_EPIL]], ptr [[GEP_DST_EPIL]], align 8
13701f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
13801f8da90SFlorian Hahn; CHECK:       exit:
13901f8da90SFlorian Hahn; CHECK-NEXT:    ret void
14001f8da90SFlorian Hahn;
14101f8da90SFlorian Hahnentry:
14201f8da90SFlorian Hahn  %src.4 = getelementptr i8, ptr %src, i64 4
14301f8da90SFlorian Hahn  %src.12 = getelementptr i8, ptr %src, i64 12
14401f8da90SFlorian Hahn  br label %loop
14501f8da90SFlorian Hahn
14601f8da90SFlorian Hahnloop:
14701f8da90SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
14801f8da90SFlorian Hahn  %gep.src.12 = getelementptr i64, ptr %src.12, i64 %iv
14901f8da90SFlorian Hahn  %l.12 = load i32, ptr %gep.src.12, align 8
15001f8da90SFlorian Hahn  %l.12.ext = zext i32 %l.12 to i64
15101f8da90SFlorian Hahn  %gep.src.4 = getelementptr i64, ptr %src.4, i64 %iv
15201f8da90SFlorian Hahn  %l.4 = load i64, ptr %gep.src.4, align 8
15301f8da90SFlorian Hahn  %mul = mul i64 %l.12.ext, %l.4
15401f8da90SFlorian Hahn  %gep.dst = getelementptr i64, ptr %dst, i64 %iv
15501f8da90SFlorian Hahn  store i64 %mul, ptr %gep.dst
15601f8da90SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
15701f8da90SFlorian Hahn  %c = icmp eq i64 %iv.next, %N
15801f8da90SFlorian Hahn  br i1 %c, label %exit, label %loop, !llvm.loop !1
15901f8da90SFlorian Hahn
16001f8da90SFlorian Hahnexit:
16101f8da90SFlorian Hahn  ret void
16201f8da90SFlorian Hahn}
16301f8da90SFlorian Hahn
16401f8da90SFlorian Hahndefine void @cse_volatile_loads(ptr %src, ptr noalias %dst, i64 %N) {
16501f8da90SFlorian Hahn; CHECK-LABEL: define void @cse_volatile_loads(
16601f8da90SFlorian Hahn; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) {
16701f8da90SFlorian Hahn; CHECK-NEXT:  entry:
16801f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_4:%.*]] = getelementptr i8, ptr [[SRC]], i64 4
16901f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_12:%.*]] = getelementptr i8, ptr [[SRC]], i64 12
17001f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], -1
17101f8da90SFlorian Hahn; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[N]], 1
17201f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 1
17301f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP1]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
17401f8da90SFlorian Hahn; CHECK:       entry.new:
17501f8da90SFlorian Hahn; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]]
17601f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
17701f8da90SFlorian Hahn; CHECK:       loop:
17801f8da90SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_1:%.*]], [[LOOP]] ]
17901f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[LOOP]] ]
18001f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV]]
18101f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12:%.*]] = load i64, ptr [[GEP_SRC_12]], align 8
18201f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV]]
18301f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4:%.*]] = load volatile i64, ptr [[GEP_SRC_4]], align 8
18401f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[L_12]], [[L_4]]
18501f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV]]
18601f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL]], ptr [[GEP_DST]], align 8
18701f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1
18801f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_1:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_NEXT]]
18901f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_1:%.*]] = load i64, ptr [[GEP_SRC_12_1]], align 8
19001f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_1:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_NEXT]]
19101f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_1:%.*]] = load volatile i64, ptr [[GEP_SRC_4_1]], align 8
19201f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_1:%.*]] = mul i64 [[L_12_1]], [[L_4_1]]
19301f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_1:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_NEXT]]
19401f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_1]], ptr [[GEP_DST_1]], align 8
19501f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT_1]] = add nuw nsw i64 [[IV]], 2
19601f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NEXT_1]] = add i64 [[NITER]], 2
19701f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i64 [[NITER_NEXT_1]], [[UNROLL_ITER]]
19801f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[EXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP4:![0-9]+]]
19901f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa.loopexit:
20001f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_1]], [[LOOP]] ]
20101f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT_UNR_LCSSA]]
20201f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa:
20301f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT_UNR_LCSSA_LOOPEXIT]] ]
20401f8da90SFlorian Hahn; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
20501f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[LOOP_EPIL_PREHEADER:%.*]], label [[EXIT:%.*]]
20601f8da90SFlorian Hahn; CHECK:       loop.epil.preheader:
20701f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_EPIL:%.*]]
20801f8da90SFlorian Hahn; CHECK:       loop.epil:
20901f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_EPIL:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_UNR]]
21001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EPIL:%.*]] = load i64, ptr [[GEP_SRC_12_EPIL]], align 8
21101f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_EPIL:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_UNR]]
21201f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_EPIL:%.*]] = load volatile i64, ptr [[GEP_SRC_4_EPIL]], align 8
21301f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_EPIL:%.*]] = mul i64 [[L_12_EPIL]], [[L_4_EPIL]]
21401f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_EPIL:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_UNR]]
21501f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_EPIL]], ptr [[GEP_DST_EPIL]], align 8
21601f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
21701f8da90SFlorian Hahn; CHECK:       exit:
21801f8da90SFlorian Hahn; CHECK-NEXT:    ret void
21901f8da90SFlorian Hahn;
22001f8da90SFlorian Hahnentry:
22101f8da90SFlorian Hahn  %src.4 = getelementptr i8, ptr %src, i64 4
22201f8da90SFlorian Hahn  %src.12 = getelementptr i8, ptr %src, i64 12
22301f8da90SFlorian Hahn  br label %loop
22401f8da90SFlorian Hahn
22501f8da90SFlorian Hahnloop:
22601f8da90SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
22701f8da90SFlorian Hahn  %gep.src.12 = getelementptr i64, ptr %src.12, i64 %iv
22801f8da90SFlorian Hahn  %l.12 = load i64, ptr %gep.src.12, align 8
22901f8da90SFlorian Hahn  %gep.src.4 = getelementptr i64, ptr %src.4, i64 %iv
23001f8da90SFlorian Hahn  %l.4 = load volatile i64, ptr %gep.src.4, align 8
23101f8da90SFlorian Hahn  %mul = mul i64 %l.12, %l.4
23201f8da90SFlorian Hahn  %gep.dst = getelementptr i64, ptr %dst, i64 %iv
23301f8da90SFlorian Hahn  store i64 %mul, ptr %gep.dst
23401f8da90SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
23501f8da90SFlorian Hahn  %c = icmp eq i64 %iv.next, %N
23601f8da90SFlorian Hahn  br i1 %c, label %exit, label %loop, !llvm.loop !1
23701f8da90SFlorian Hahn
23801f8da90SFlorian Hahnexit:
23901f8da90SFlorian Hahn  ret void
24001f8da90SFlorian Hahn}
24101f8da90SFlorian Hahn
24201f8da90SFlorian Hahndefine void @cse_atomic_loads(ptr %src, ptr noalias %dst, i64 %N) {
24301f8da90SFlorian Hahn; CHECK-LABEL: define void @cse_atomic_loads(
24401f8da90SFlorian Hahn; CHECK-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) {
24501f8da90SFlorian Hahn; CHECK-NEXT:  entry:
24601f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_4:%.*]] = getelementptr i8, ptr [[SRC]], i64 4
24701f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_12:%.*]] = getelementptr i8, ptr [[SRC]], i64 12
24801f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], -1
24901f8da90SFlorian Hahn; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[N]], 1
25001f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 1
25101f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP1]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
25201f8da90SFlorian Hahn; CHECK:       entry.new:
25301f8da90SFlorian Hahn; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]]
25401f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
25501f8da90SFlorian Hahn; CHECK:       loop:
25601f8da90SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_1:%.*]], [[LOOP]] ]
25701f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[LOOP]] ]
25801f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV]]
25901f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12:%.*]] = load i64, ptr [[GEP_SRC_12]], align 8
26001f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV]]
26101f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4:%.*]] = load atomic i64, ptr [[GEP_SRC_4]] unordered, align 8
26201f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[L_12]], [[L_4]]
26301f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV]]
26401f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL]], ptr [[GEP_DST]], align 8
26501f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1
26601f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_1:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_NEXT]]
26701f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_1:%.*]] = load i64, ptr [[GEP_SRC_12_1]], align 8
26801f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_1:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_NEXT]]
26901f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_1:%.*]] = load atomic i64, ptr [[GEP_SRC_4_1]] unordered, align 8
27001f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_1:%.*]] = mul i64 [[L_12_1]], [[L_4_1]]
27101f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_1:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_NEXT]]
27201f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_1]], ptr [[GEP_DST_1]], align 8
27301f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT_1]] = add nuw nsw i64 [[IV]], 2
27401f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NEXT_1]] = add i64 [[NITER]], 2
27501f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i64 [[NITER_NEXT_1]], [[UNROLL_ITER]]
27601f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[EXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
27701f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa.loopexit:
27801f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_1]], [[LOOP]] ]
27901f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT_UNR_LCSSA]]
28001f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa:
28101f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT_UNR_LCSSA_LOOPEXIT]] ]
28201f8da90SFlorian Hahn; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
28301f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[LOOP_EPIL_PREHEADER:%.*]], label [[EXIT:%.*]]
28401f8da90SFlorian Hahn; CHECK:       loop.epil.preheader:
28501f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_EPIL:%.*]]
28601f8da90SFlorian Hahn; CHECK:       loop.epil:
28701f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_EPIL:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_UNR]]
28801f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EPIL:%.*]] = load i64, ptr [[GEP_SRC_12_EPIL]], align 8
28901f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_EPIL:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_UNR]]
29001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_EPIL:%.*]] = load atomic i64, ptr [[GEP_SRC_4_EPIL]] unordered, align 8
29101f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_EPIL:%.*]] = mul i64 [[L_12_EPIL]], [[L_4_EPIL]]
29201f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_EPIL:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_UNR]]
29301f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_EPIL]], ptr [[GEP_DST_EPIL]], align 8
29401f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
29501f8da90SFlorian Hahn; CHECK:       exit:
29601f8da90SFlorian Hahn; CHECK-NEXT:    ret void
29701f8da90SFlorian Hahn;
29801f8da90SFlorian Hahnentry:
29901f8da90SFlorian Hahn  %src.4 = getelementptr i8, ptr %src, i64 4
30001f8da90SFlorian Hahn  %src.12 = getelementptr i8, ptr %src, i64 12
30101f8da90SFlorian Hahn  br label %loop
30201f8da90SFlorian Hahn
30301f8da90SFlorian Hahnloop:
30401f8da90SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
30501f8da90SFlorian Hahn  %gep.src.12 = getelementptr i64, ptr %src.12, i64 %iv
30601f8da90SFlorian Hahn  %l.12 = load i64, ptr %gep.src.12, align 8
30701f8da90SFlorian Hahn  %gep.src.4 = getelementptr i64, ptr %src.4, i64 %iv
30801f8da90SFlorian Hahn  %l.4 = load atomic i64, ptr %gep.src.4 unordered, align 8
30901f8da90SFlorian Hahn  %mul = mul i64 %l.12, %l.4
31001f8da90SFlorian Hahn  %gep.dst = getelementptr i64, ptr %dst, i64 %iv
31101f8da90SFlorian Hahn  store i64 %mul, ptr %gep.dst
31201f8da90SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
31301f8da90SFlorian Hahn  %c = icmp eq i64 %iv.next, %N
31401f8da90SFlorian Hahn  br i1 %c, label %exit, label %loop, !llvm.loop !1
31501f8da90SFlorian Hahn
31601f8da90SFlorian Hahnexit:
31701f8da90SFlorian Hahn  ret void
31801f8da90SFlorian Hahn}
31901f8da90SFlorian Hahn
32001f8da90SFlorian Hahndefine void @cse_load_may_be_clobbered(ptr %src, ptr %dst, i64 %N) {
32101f8da90SFlorian Hahn; CHECK-LABEL: define void @cse_load_may_be_clobbered(
32201f8da90SFlorian Hahn; CHECK-SAME: ptr [[SRC:%.*]], ptr [[DST:%.*]], i64 [[N:%.*]]) {
32301f8da90SFlorian Hahn; CHECK-NEXT:  entry:
32401f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_4:%.*]] = getelementptr i8, ptr [[SRC]], i64 4
32501f8da90SFlorian Hahn; CHECK-NEXT:    [[SRC_12:%.*]] = getelementptr i8, ptr [[SRC]], i64 12
32601f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], -1
32701f8da90SFlorian Hahn; CHECK-NEXT:    [[XTRAITER:%.*]] = and i64 [[N]], 1
32801f8da90SFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 1
32901f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[TMP1]], label [[EXIT_UNR_LCSSA:%.*]], label [[ENTRY_NEW:%.*]]
33001f8da90SFlorian Hahn; CHECK:       entry.new:
33101f8da90SFlorian Hahn; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = sub i64 [[N]], [[XTRAITER]]
33201f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP:%.*]]
33301f8da90SFlorian Hahn; CHECK:       loop:
33401f8da90SFlorian Hahn; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[IV_NEXT_1:%.*]], [[LOOP]] ]
33501f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER:%.*]] = phi i64 [ 0, [[ENTRY_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[LOOP]] ]
33601f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV]]
33701f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12:%.*]] = load i64, ptr [[GEP_SRC_12]], align 8
33801f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV]]
33901f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4:%.*]] = load i64, ptr [[GEP_SRC_4]], align 8
34001f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL:%.*]] = mul i64 [[L_12]], [[L_4]]
34101f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV]]
34201f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL]], ptr [[GEP_DST]], align 8
34301f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT:%.*]] = add nuw nsw i64 [[IV]], 1
34401f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_1:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_NEXT]]
34501f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_1:%.*]] = load i64, ptr [[GEP_SRC_12_1]], align 8
34601f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_1:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_NEXT]]
34701f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_1:%.*]] = load i64, ptr [[GEP_SRC_4_1]], align 8
34801f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_1:%.*]] = mul i64 [[L_12_1]], [[L_4_1]]
34901f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_1:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_NEXT]]
35001f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_1]], ptr [[GEP_DST_1]], align 8
35101f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_NEXT_1]] = add nuw nsw i64 [[IV]], 2
35201f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NEXT_1]] = add i64 [[NITER]], 2
35301f8da90SFlorian Hahn; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i64 [[NITER_NEXT_1]], [[UNROLL_ITER]]
35401f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[EXIT_UNR_LCSSA_LOOPEXIT:%.*]], label [[LOOP]], !llvm.loop [[LOOP6:![0-9]+]]
35501f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa.loopexit:
35601f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR_PH:%.*]] = phi i64 [ [[IV_NEXT_1]], [[LOOP]] ]
35701f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT_UNR_LCSSA]]
35801f8da90SFlorian Hahn; CHECK:       exit.unr-lcssa:
35901f8da90SFlorian Hahn; CHECK-NEXT:    [[IV_UNR:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_UNR_PH]], [[EXIT_UNR_LCSSA_LOOPEXIT]] ]
36001f8da90SFlorian Hahn; CHECK-NEXT:    [[LCMP_MOD:%.*]] = icmp ne i64 [[XTRAITER]], 0
36101f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[LCMP_MOD]], label [[LOOP_EPIL_PREHEADER:%.*]], label [[EXIT:%.*]]
36201f8da90SFlorian Hahn; CHECK:       loop.epil.preheader:
36301f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_EPIL:%.*]]
36401f8da90SFlorian Hahn; CHECK:       loop.epil:
36501f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_12_EPIL:%.*]] = getelementptr i64, ptr [[SRC_12]], i64 [[IV_UNR]]
36601f8da90SFlorian Hahn; CHECK-NEXT:    [[L_12_EPIL:%.*]] = load i64, ptr [[GEP_SRC_12_EPIL]], align 8
36701f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_SRC_4_EPIL:%.*]] = getelementptr i64, ptr [[SRC_4]], i64 [[IV_UNR]]
36801f8da90SFlorian Hahn; CHECK-NEXT:    [[L_4_EPIL:%.*]] = load i64, ptr [[GEP_SRC_4_EPIL]], align 8
36901f8da90SFlorian Hahn; CHECK-NEXT:    [[MUL_EPIL:%.*]] = mul i64 [[L_12_EPIL]], [[L_4_EPIL]]
37001f8da90SFlorian Hahn; CHECK-NEXT:    [[GEP_DST_EPIL:%.*]] = getelementptr i64, ptr [[DST]], i64 [[IV_UNR]]
37101f8da90SFlorian Hahn; CHECK-NEXT:    store i64 [[MUL_EPIL]], ptr [[GEP_DST_EPIL]], align 8
37201f8da90SFlorian Hahn; CHECK-NEXT:    br label [[EXIT]]
37301f8da90SFlorian Hahn; CHECK:       exit:
37401f8da90SFlorian Hahn; CHECK-NEXT:    ret void
37501f8da90SFlorian Hahn;
37601f8da90SFlorian Hahnentry:
37701f8da90SFlorian Hahn  %src.4 = getelementptr i8, ptr %src, i64 4
37801f8da90SFlorian Hahn  %src.12 = getelementptr i8, ptr %src, i64 12
37901f8da90SFlorian Hahn  br label %loop
38001f8da90SFlorian Hahn
38101f8da90SFlorian Hahnloop:
38201f8da90SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
38301f8da90SFlorian Hahn  %gep.src.12 = getelementptr i64, ptr %src.12, i64 %iv
38401f8da90SFlorian Hahn  %l.12 = load i64, ptr %gep.src.12, align 8
38501f8da90SFlorian Hahn  %gep.src.4 = getelementptr i64, ptr %src.4, i64 %iv
38601f8da90SFlorian Hahn  %l.4 = load i64, ptr %gep.src.4, align 8
38701f8da90SFlorian Hahn  %mul = mul i64 %l.12, %l.4
38801f8da90SFlorian Hahn  %gep.dst = getelementptr i64, ptr %dst, i64 %iv
38901f8da90SFlorian Hahn  store i64 %mul, ptr %gep.dst
39001f8da90SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
39101f8da90SFlorian Hahn  %c = icmp eq i64 %iv.next, %N
39201f8da90SFlorian Hahn  br i1 %c, label %exit, label %loop, !llvm.loop !1
39301f8da90SFlorian Hahn
39401f8da90SFlorian Hahnexit:
39501f8da90SFlorian Hahn  ret void
39601f8da90SFlorian Hahn}
39701f8da90SFlorian Hahn
39801f8da90SFlorian Hahn
39901f8da90SFlorian Hahndeclare void @foo()
40001f8da90SFlorian Hahn
40101f8da90SFlorian Hahndefine void @loop_body_with_dead_blocks(ptr %src) {
40201f8da90SFlorian Hahn; CHECK-LABEL: define void @loop_body_with_dead_blocks(
40301f8da90SFlorian Hahn; CHECK-SAME: ptr [[SRC:%.*]]) {
40401f8da90SFlorian Hahn; CHECK-NEXT:  entry:
40501f8da90SFlorian Hahn; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
40601f8da90SFlorian Hahn; CHECK:       outer.header.loopexit:
40701f8da90SFlorian Hahn; CHECK-NEXT:    br label [[OUTER_HEADER]]
40801f8da90SFlorian Hahn; CHECK:       outer.header:
40901f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
41001f8da90SFlorian Hahn; CHECK:       loop.header:
41101f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_BB:%.*]]
41201f8da90SFlorian Hahn; CHECK:       loop.bb.dead:
41301f8da90SFlorian Hahn; CHECK-NEXT:    unreachable
41401f8da90SFlorian Hahn; CHECK:       loop.bb:
41501f8da90SFlorian Hahn; CHECK-NEXT:    [[L_1:%.*]] = load i32, ptr [[SRC]], align 8
41601f8da90SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = icmp eq i32 [[L_1]], 0
41701f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[OUTER_HEADER_LOOPEXIT:%.*]], label [[LOOP_LATCH:%.*]]
41801f8da90SFlorian Hahn; CHECK:       loop.latch:
41901f8da90SFlorian Hahn; CHECK-NEXT:    call void @foo()
42001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_2:%.*]] = load i32, ptr [[SRC]], align 8
42101f8da90SFlorian Hahn; CHECK-NEXT:    [[C_2:%.*]] = icmp eq i32 [[L_2]], 1
42201f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[C_2]], label [[EXIT:%.*]], label [[LOOP_HEADER_1:%.*]], !llvm.loop [[LOOP7:![0-9]+]]
42301f8da90SFlorian Hahn; CHECK:       loop.header.1:
42401f8da90SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_BB_1:%.*]]
42501f8da90SFlorian Hahn; CHECK:       loop.bb.1:
426*175d2971SFlorian Hahn; CHECK-NEXT:    [[C_1_1:%.*]] = icmp eq i32 [[L_2]], 0
42701f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1_1]], label [[OUTER_HEADER_LOOPEXIT]], label [[LOOP_LATCH_1:%.*]]
42801f8da90SFlorian Hahn; CHECK:       loop.latch.1:
42901f8da90SFlorian Hahn; CHECK-NEXT:    call void @foo()
43001f8da90SFlorian Hahn; CHECK-NEXT:    [[L_2_1:%.*]] = load i32, ptr [[SRC]], align 8
43101f8da90SFlorian Hahn; CHECK-NEXT:    [[C_2_1:%.*]] = icmp eq i32 [[L_2_1]], 1
43201f8da90SFlorian Hahn; CHECK-NEXT:    br i1 [[C_2_1]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP9:![0-9]+]]
43301f8da90SFlorian Hahn; CHECK:       exit:
43401f8da90SFlorian Hahn; CHECK-NEXT:    ret void
43501f8da90SFlorian Hahn;
43601f8da90SFlorian Hahnentry:
43701f8da90SFlorian Hahn  br label %outer.header
43801f8da90SFlorian Hahn
43901f8da90SFlorian Hahnouter.header:
44001f8da90SFlorian Hahn  br label %loop.header
44101f8da90SFlorian Hahn
44201f8da90SFlorian Hahnloop.header:
44301f8da90SFlorian Hahn  br label %loop.bb
44401f8da90SFlorian Hahn
44501f8da90SFlorian Hahnloop.bb.dead:
44601f8da90SFlorian Hahn  br label %loop.bb
44701f8da90SFlorian Hahn
44801f8da90SFlorian Hahnloop.bb:
44901f8da90SFlorian Hahn  %l.1 = load i32, ptr %src, align 8
45001f8da90SFlorian Hahn  %c.1 = icmp eq i32 %l.1, 0
45101f8da90SFlorian Hahn  br i1 %c.1, label %outer.header, label %loop.latch
45201f8da90SFlorian Hahn
45301f8da90SFlorian Hahnloop.latch:
45401f8da90SFlorian Hahn  call void @foo()
45501f8da90SFlorian Hahn  %l.2 = load i32, ptr %src, align 8
45601f8da90SFlorian Hahn  %c.2 = icmp eq i32 %l.2, 1
45701f8da90SFlorian Hahn  br i1 %c.2, label %exit, label %loop.header, !llvm.loop !1
45801f8da90SFlorian Hahn
45901f8da90SFlorian Hahnexit:
46001f8da90SFlorian Hahn  ret void
46101f8da90SFlorian Hahn}
46201f8da90SFlorian Hahn
46301f8da90SFlorian Hahn!0 = !{!"llvm.loop.mustprogress"}
46401f8da90SFlorian Hahn!1 = distinct !{!1, !0, !2}
46501f8da90SFlorian Hahn!2 = !{!"llvm.loop.unroll.count", i32 2}
46601f8da90SFlorian Hahn;.
46701f8da90SFlorian Hahn; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
46801f8da90SFlorian Hahn; CHECK: [[META1]] = !{!"llvm.loop.mustprogress"}
46901f8da90SFlorian Hahn; CHECK: [[META2]] = !{!"llvm.loop.unroll.disable"}
47001f8da90SFlorian Hahn; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]], [[META2]]}
47101f8da90SFlorian Hahn; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
47201f8da90SFlorian Hahn; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]], [[META2]]}
47301f8da90SFlorian Hahn; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
47401f8da90SFlorian Hahn; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META1]], [[META8:![0-9]+]]}
47501f8da90SFlorian Hahn; CHECK: [[META8]] = !{!"llvm.loop.unroll.count", i32 2}
47601f8da90SFlorian Hahn; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META1]], [[META2]]}
47701f8da90SFlorian Hahn;.
478