134 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=loop-unroll %s | FileCheck %s3 4; In both cases, we have one unpredictable exit and one IV-based exit with5; known trip count. We can fully unroll against the latter. In one of the6; examples the IV-based exit is the latch exit, in the other the non-latch7; exit. After full unrolling, the functions fold to ret i1 true.8 9define i1 @test_latch() {10; CHECK-LABEL: @test_latch(11; CHECK-NEXT: start:12; CHECK-NEXT: [[A1:%.*]] = alloca [2 x i64], align 813; CHECK-NEXT: [[A2:%.*]] = alloca [2 x i64], align 814; CHECK-NEXT: store i64 -5015437470765251660, ptr [[A1]], align 815; CHECK-NEXT: [[A1_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A1]], i64 0, i64 116; CHECK-NEXT: store i64 -8661621401413125213, ptr [[A1_1]], align 817; CHECK-NEXT: store i64 -5015437470765251660, ptr [[A2]], align 818; CHECK-NEXT: [[A2_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A2]], i64 0, i64 119; CHECK-NEXT: store i64 -8661621401413125213, ptr [[A2_1]], align 820; CHECK-NEXT: br label [[LOOP:%.*]]21; CHECK: loop:22; CHECK-NEXT: [[LOAD1:%.*]] = load i64, ptr [[A1]], align 823; CHECK-NEXT: [[LOAD2:%.*]] = load i64, ptr [[A2]], align 824; CHECK-NEXT: [[EXITCOND2:%.*]] = icmp eq i64 [[LOAD1]], [[LOAD2]]25; CHECK-NEXT: br i1 [[EXITCOND2]], label [[LATCH:%.*]], label [[EXIT:%.*]]26; CHECK: latch:27; CHECK-NEXT: [[GEP1_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A1]], i64 0, i64 128; CHECK-NEXT: [[GEP2_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A2]], i64 0, i64 129; CHECK-NEXT: [[LOAD1_1:%.*]] = load i64, ptr [[GEP1_1]], align 830; CHECK-NEXT: [[LOAD2_1:%.*]] = load i64, ptr [[GEP2_1]], align 831; CHECK-NEXT: [[EXITCOND2_1:%.*]] = icmp eq i64 [[LOAD1_1]], [[LOAD2_1]]32; CHECK-NEXT: br i1 [[EXITCOND2_1]], label [[LATCH_1:%.*]], label [[EXIT]]33; CHECK: latch.1:34; CHECK-NEXT: br label [[EXIT]]35; CHECK: exit:36; CHECK-NEXT: [[EXIT_VAL:%.*]] = phi i1 [ false, [[LOOP]] ], [ false, [[LATCH]] ], [ true, [[LATCH_1]] ]37; CHECK-NEXT: ret i1 [[EXIT_VAL]]38;39start:40 %a1 = alloca [2 x i64], align 841 %a2 = alloca [2 x i64], align 842 store i64 -5015437470765251660, ptr %a1, align 843 %a1.1 = getelementptr inbounds [2 x i64], ptr %a1, i64 0, i64 144 store i64 -8661621401413125213, ptr %a1.1, align 845 store i64 -5015437470765251660, ptr %a2, align 846 %a2.1 = getelementptr inbounds [2 x i64], ptr %a2, i64 0, i64 147 store i64 -8661621401413125213, ptr %a2.1, align 848 br label %loop49 50loop:51 %iv = phi i64 [ 0, %start ], [ %iv.next, %latch ]52 %gep1 = getelementptr inbounds [2 x i64], ptr %a1, i64 0, i64 %iv53 %gep2 = getelementptr inbounds [2 x i64], ptr %a2, i64 0, i64 %iv54 %load1 = load i64, ptr %gep1, align 855 %load2 = load i64, ptr %gep2, align 856 %exitcond2 = icmp eq i64 %load1, %load257 br i1 %exitcond2, label %latch, label %exit58 59latch:60 %iv.next = add nuw nsw i64 %iv, 161 %exitcond = icmp eq i64 %iv.next, 262 br i1 %exitcond, label %exit, label %loop63 64exit:65 %exit.val = phi i1 [ true, %latch ], [ false, %loop ]66 ret i1 %exit.val67}68 69define i1 @test_non_latch() {70; CHECK-LABEL: @test_non_latch(71; CHECK-NEXT: start:72; CHECK-NEXT: [[A1:%.*]] = alloca [2 x i64], align 873; CHECK-NEXT: [[A2:%.*]] = alloca [2 x i64], align 874; CHECK-NEXT: store i64 -5015437470765251660, ptr [[A1]], align 875; CHECK-NEXT: [[A1_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A1]], i64 0, i64 176; CHECK-NEXT: store i64 -8661621401413125213, ptr [[A1_1]], align 877; CHECK-NEXT: store i64 -5015437470765251660, ptr [[A2]], align 878; CHECK-NEXT: [[A2_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A2]], i64 0, i64 179; CHECK-NEXT: store i64 -8661621401413125213, ptr [[A2_1]], align 880; CHECK-NEXT: br label [[LOOP:%.*]]81; CHECK: loop:82; CHECK-NEXT: br label [[LATCH:%.*]]83; CHECK: latch:84; CHECK-NEXT: [[LOAD1:%.*]] = load i64, ptr [[A1]], align 885; CHECK-NEXT: [[LOAD2:%.*]] = load i64, ptr [[A2]], align 886; CHECK-NEXT: [[EXITCOND2:%.*]] = icmp eq i64 [[LOAD1]], [[LOAD2]]87; CHECK-NEXT: br i1 [[EXITCOND2]], label [[LOOP_1:%.*]], label [[EXIT:%.*]]88; CHECK: loop.1:89; CHECK-NEXT: br label [[LATCH_1:%.*]]90; CHECK: latch.1:91; CHECK-NEXT: [[GEP1_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A1]], i64 0, i64 192; CHECK-NEXT: [[GEP2_1:%.*]] = getelementptr inbounds [2 x i64], ptr [[A2]], i64 0, i64 193; CHECK-NEXT: [[LOAD1_1:%.*]] = load i64, ptr [[GEP1_1]], align 894; CHECK-NEXT: [[LOAD2_1:%.*]] = load i64, ptr [[GEP2_1]], align 895; CHECK-NEXT: [[EXITCOND2_1:%.*]] = icmp eq i64 [[LOAD1_1]], [[LOAD2_1]]96; CHECK-NEXT: br i1 [[EXITCOND2_1]], label [[LOOP_2:%.*]], label [[EXIT]]97; CHECK: loop.2:98; CHECK-NEXT: br i1 true, label [[EXIT]], label [[LATCH_2:%.*]]99; CHECK: latch.2:100; CHECK-NEXT: br label [[EXIT]]101; CHECK: exit:102; CHECK-NEXT: [[EXIT_VAL:%.*]] = phi i1 [ false, [[LATCH]] ], [ false, [[LATCH_1]] ], [ true, [[LOOP_2]] ], [ false, [[LATCH_2]] ]103; CHECK-NEXT: ret i1 [[EXIT_VAL]]104;105start:106 %a1 = alloca [2 x i64], align 8107 %a2 = alloca [2 x i64], align 8108 store i64 -5015437470765251660, ptr %a1, align 8109 %a1.1 = getelementptr inbounds [2 x i64], ptr %a1, i64 0, i64 1110 store i64 -8661621401413125213, ptr %a1.1, align 8111 store i64 -5015437470765251660, ptr %a2, align 8112 %a2.1 = getelementptr inbounds [2 x i64], ptr %a2, i64 0, i64 1113 store i64 -8661621401413125213, ptr %a2.1, align 8114 br label %loop115 116loop:117 %iv = phi i64 [ 0, %start ], [ %iv.next, %latch ]118 %exitcond = icmp eq i64 %iv, 2119 br i1 %exitcond, label %exit, label %latch120 121latch:122 %iv.next = add nuw nsw i64 %iv, 1123 %gep1 = getelementptr inbounds [2 x i64], ptr %a1, i64 0, i64 %iv124 %gep2 = getelementptr inbounds [2 x i64], ptr %a2, i64 0, i64 %iv125 %load1 = load i64, ptr %gep1, align 8126 %load2 = load i64, ptr %gep2, align 8127 %exitcond2 = icmp eq i64 %load1, %load2128 br i1 %exitcond2, label %loop, label %exit129 130exit:131 %exit.val = phi i1 [ false, %latch ], [ true, %loop ]132 ret i1 %exit.val133}134