| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt < %s -passes="loop-reduce" -S | FileCheck %s |
| |
| target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" |
| target triple = "x86_64-unknown-linux-gnu" |
| |
| define void @regression1() { |
| ; CHECK-LABEL: define void @regression1() { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: br label %[[LOOP1_HEADER:.*]] |
| ; CHECK: [[LOOP1_HEADER]]: |
| ; CHECK-NEXT: br label %[[LOOP1:.*]] |
| ; CHECK: [[LOOP1]]: |
| ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[LOOP1_HEADER]] ], [ 1, %[[LOOP1]] ] |
| ; CHECK-NEXT: br i1 false, label %[[LOOP2_HEADER:.*]], label %[[LOOP1]] |
| ; CHECK: [[LOOP2_HEADER]]: |
| ; CHECK-NEXT: [[PHI_LCSSA1:%.*]] = phi i32 [ [[PHI]], %[[LOOP1]] ] |
| ; CHECK-NEXT: [[TMP0:%.*]] = add nuw nsw i32 [[PHI_LCSSA1]], 1 |
| ; CHECK-NEXT: br label %[[LOOP2:.*]] |
| ; CHECK: [[LOOP2]]: |
| ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP2]] ], [ [[TMP0]], %[[LOOP2_HEADER]] ] |
| ; CHECK-NEXT: [[SELECT:%.*]] = select i1 false, i32 [[LSR_IV]], i32 0 |
| ; CHECK-NEXT: [[LSR_IV_NEXT]] = add i32 [[LSR_IV]], 1 |
| ; CHECK-NEXT: br i1 false, label %[[EXIT:.*]], label %[[LOOP2]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: br label %[[LOOP1_HEADER]] |
| ; |
| entry: |
| br label %loop1.header |
| |
| loop1.header: ; preds = %exit, %entry |
| br label %loop1 |
| |
| loop1: ; preds = %loop1, %loop1.header |
| %phi = phi i32 [ 0, %loop1.header ], [ 1, %loop1 ] |
| br i1 false, label %loop2.header, label %loop1 |
| |
| loop2.header: ; preds = %loop1 |
| br label %loop2 |
| |
| loop2: ; preds = %loop2.header, %loop2 |
| %phi5 = phi i32 [ %add, %loop2 ], [ %phi, %loop2.header ] |
| %add = add i32 %phi5, 1 |
| %select = select i1 false, i32 %add, i32 0 |
| br i1 false, label %exit, label %loop2 |
| |
| exit: ; preds = %loop2 |
| br label %loop1.header |
| } |
| |
| define void @regression2() { |
| ; CHECK-LABEL: define void @regression2() { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: br label %[[LOOP1_HEADER:.*]] |
| ; CHECK: [[LOOP1_HEADER]]: |
| ; CHECK-NEXT: switch i8 0, label %[[LOOP1_HEADER_BACKEDGE:.*]] [ |
| ; CHECK-NEXT: i8 63, label %[[LOOP1_LATCH1_PREHEADER:.*]] |
| ; CHECK-NEXT: i8 43, label %[[LOOP1_LATCH1_PREHEADER]] |
| ; CHECK-NEXT: i8 42, label %[[LOOP1_LATCH1_PREHEADER]] |
| ; CHECK-NEXT: ] |
| ; CHECK: [[LOOP1_HEADER_BACKEDGE]]: |
| ; CHECK-NEXT: br label %[[LOOP1_HEADER]] |
| ; CHECK: [[LOOP1_LATCH1_PREHEADER]]: |
| ; CHECK-NEXT: br label %[[LOOP1_LATCH1:.*]] |
| ; CHECK: [[LOOP1_LATCH1]]: |
| ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ADD4:%.*]], %[[LOOP1_LATCH2:.*]] ], [ 0, %[[LOOP1_LATCH1_PREHEADER]] ] |
| ; CHECK-NEXT: br i1 false, label %[[LOOP1_LATCH2]], label %[[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE:.*]] |
| ; CHECK: [[LOOP1_LATCH2]]: |
| ; CHECK-NEXT: [[ADD:%.*]] = add i32 0, 0 |
| ; CHECK-NEXT: [[ADD4]] = add i32 [[PHI]], 1 |
| ; CHECK-NEXT: br i1 false, label %[[LOOP1_LATCH1]], label %[[LOOP1_LATCH3SPLIT:.*]] |
| ; CHECK: [[LOOP1_LATCH3SPLIT]]: |
| ; CHECK-NEXT: [[PHI6_PH:%.*]] = phi i32 [ [[ADD]], %[[LOOP1_LATCH2]] ] |
| ; CHECK-NEXT: [[PHI7_PH:%.*]] = phi i32 [ 0, %[[LOOP1_LATCH2]] ] |
| ; CHECK-NEXT: br label %[[LOOP1_LATCH3:.*]] |
| ; CHECK: [[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE]]: |
| ; CHECK-NEXT: [[PHI_LCSSA:%.*]] = phi i32 [ [[PHI]], %[[LOOP1_LATCH1]] ] |
| ; CHECK-NEXT: [[SPLIT:%.*]] = phi i32 [ 0, %[[LOOP1_LATCH1]] ] |
| ; CHECK-NEXT: [[SPLIT1:%.*]] = phi i32 [ [[PHI]], %[[LOOP1_LATCH1]] ] |
| ; CHECK-NEXT: br label %[[LOOP1_LATCH3]] |
| ; CHECK: [[LOOP1_LATCH3]]: |
| ; CHECK-NEXT: [[PHI6:%.*]] = phi i32 [ [[SPLIT]], %[[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE]] ], [ [[PHI6_PH]], %[[LOOP1_LATCH3SPLIT]] ] |
| ; CHECK-NEXT: [[PHI7:%.*]] = phi i32 [ [[PHI_LCSSA]], %[[LOOP1_LATCH1_LOOP1_LATCH3_CRIT_EDGE]] ], [ [[PHI7_PH]], %[[LOOP1_LATCH3SPLIT]] ] |
| ; CHECK-NEXT: br label %[[LOOP1_HEADER_BACKEDGE]] |
| ; |
| entry: |
| br label %loop1.header |
| |
| loop1.header: ; preds = %loop1.latch3, %loop1.header, %entry |
| switch i8 0, label %loop1.header [ |
| i8 63, label %loop1.latch1 |
| i8 43, label %loop1.latch1 |
| i8 42, label %loop1.latch1 |
| ] |
| |
| loop1.latch1: ; preds = %loop1.latch2, %loop1.header, %loop1.header, %loop1.header |
| %phi = phi i32 [ %add4, %loop1.latch2 ], [ 0, %loop1.header ], [ 0, %loop1.header ], [ 0, %loop1.header ] |
| br i1 false, label %loop1.latch2, label %loop1.latch3 |
| |
| loop1.latch2: ; preds = %loop1.latch1 |
| %add = add i32 0, 0 |
| %add4 = add i32 %phi, 1 |
| br i1 false, label %loop1.latch1, label %loop1.latch3 |
| |
| loop1.latch3: ; preds = %loop1.latch2, %loop1.latch1 |
| %phi6 = phi i32 [ %add, %loop1.latch2 ], [ 0, %loop1.latch1 ] |
| %phi7 = phi i32 [ 0, %loop1.latch2 ], [ %phi, %loop1.latch1 ] |
| br label %loop1.header |
| } |
| |
| define i64 @regression3() { |
| ; CHECK-LABEL: define i64 @regression3() { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: [[ASHR:%.*]] = ashr i64 0, 1 |
| ; CHECK-NEXT: br label %[[LOOP2_HEADER:.*]] |
| ; CHECK: [[FUNCEXITSPLIT:.*]]: |
| ; CHECK-NEXT: [[PHI_PH:%.*]] = phi i64 [ [[PHI6:%.*]], %[[LOOP1_HEADER:.*]] ] |
| ; CHECK-NEXT: br label %[[FUNCEXIT:.*]] |
| ; CHECK: [[FUNCEXIT]]: |
| ; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[ASHR]], %[[LOOP1_LATCH_FUNCEXIT_CRIT_EDGE:.*]] ], [ [[PHI_PH]], %[[FUNCEXITSPLIT]] ] |
| ; CHECK-NEXT: ret i64 [[PHI]] |
| ; CHECK: [[LOOP2_HEADER]]: |
| ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], %[[LOOP2_LATCH:.*]] ], [ [[ASHR]], %[[ENTRY]] ] |
| ; CHECK-NEXT: br i1 false, label %[[LOOP2_LATCH]], label %[[LOOP1_HEADER_PREHEADER:.*]] |
| ; CHECK: [[LOOP1_HEADER_PREHEADER]]: |
| ; CHECK-NEXT: br label %[[LOOP1_HEADER]] |
| ; CHECK: [[LOOP2_LATCH]]: |
| ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[LSR_IV]], 0 |
| ; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i64 [[LSR_IV]], -1 |
| ; CHECK-NEXT: br label %[[LOOP2_HEADER]] |
| ; CHECK: [[LOOP1_HEADER]]: |
| ; CHECK-NEXT: [[PHI6]] = phi i64 [ 0, %[[LOOP1_LATCH:.*]] ], [ 1, %[[LOOP1_HEADER_PREHEADER]] ] |
| ; CHECK-NEXT: br i1 false, label %[[LOOP1_LATCH]], label %[[FUNCEXITSPLIT]] |
| ; CHECK: [[LOOP1_LATCH]]: |
| ; CHECK-NEXT: br i1 false, label %[[LOOP1_LATCH_FUNCEXIT_CRIT_EDGE]], label %[[LOOP1_HEADER]] |
| ; CHECK: [[LOOP1_LATCH_FUNCEXIT_CRIT_EDGE]]: |
| ; CHECK-NEXT: [[SPLIT:%.*]] = phi i64 [ [[ASHR]], %[[LOOP1_LATCH]] ] |
| ; CHECK-NEXT: br label %[[FUNCEXIT]] |
| ; |
| entry: |
| %ashr = ashr i64 0, 1 |
| br label %loop2.header |
| |
| funcexit: ; preds = %loop1.latch, %loop1.header |
| %phi = phi i64 [ %phi6, %loop1.header ], [ %ashr, %loop1.latch ] |
| ret i64 %phi |
| |
| loop2.header: ; preds = %loop2.latch, %entry |
| %phi3 = phi i64 [ 0, %entry ], [ %add, %loop2.latch ] |
| br i1 false, label %loop2.latch, label %loop1.header |
| |
| loop2.latch: ; preds = %loop2.header |
| %add = add i64 %phi3, 1 |
| %icmp = icmp eq i64 %phi3, %ashr |
| br label %loop2.header |
| |
| loop1.header: ; preds = %loop1.latch, %loop2.header |
| %phi6 = phi i64 [ 0, %loop1.latch ], [ 1, %loop2.header ] |
| br i1 false, label %loop1.latch, label %funcexit |
| |
| loop1.latch: ; preds = %loop1.header |
| br i1 false, label %funcexit, label %loop1.header |
| } |
| |
| define i32 @regression4() { |
| ; CHECK-LABEL: define i32 @regression4() { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: br label %[[WHILE_COND_OUTER:.*]] |
| ; CHECK: [[WHILE_COND_OUTER_LOOPEXIT:.*]]: |
| ; CHECK-NEXT: br label %[[WHILE_COND_OUTER]] |
| ; CHECK: [[WHILE_COND_OUTER]]: |
| ; CHECK-NEXT: br label %[[WHILE_COND:.*]] |
| ; CHECK: [[WHILE_COND]]: |
| ; CHECK-NEXT: br i1 false, label %[[WHILE_COND]], label %[[FOR_BODY_PREHEADER:.*]] |
| ; CHECK: [[FOR_BODY_PREHEADER]]: |
| ; CHECK-NEXT: br label %[[FOR_BODY:.*]] |
| ; CHECK: [[FOR_BODY]]: |
| ; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[LSR_IV_NEXT:%.*]], %[[FOR_BODY]] ] |
| ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[LSR_IV]], 0 |
| ; CHECK-NEXT: [[LSR_IV_NEXT]] = add i32 [[LSR_IV]], -1 |
| ; CHECK-NEXT: br i1 false, label %[[WHILE_COND_OUTER_LOOPEXIT]], label %[[FOR_BODY]] |
| ; |
| entry: |
| br label %while.cond.outer |
| |
| while.cond.outer: ; preds = %for.body, %entry |
| %phi = phi i32 [ 0, %entry ], [ %add, %for.body ] |
| br label %while.cond |
| |
| while.cond: ; preds = %while.cond, %while.cond.outer |
| %phi3 = phi i32 [ 0, %while.cond.outer ], [ %add5, %while.cond ] |
| %phi4 = phi i32 [ 0, %while.cond.outer ], [ %add, %while.cond ] |
| %add = add i32 %phi4, 1 |
| %add5 = add i32 %phi3, 1 |
| br i1 false, label %while.cond, label %for.body |
| |
| for.body: ; preds = %for.body, %while.cond |
| %phi7 = phi i32 [ %add8, %for.body ], [ 0, %while.cond ] |
| %add8 = add i32 %phi7, 1 |
| %sub = sub i32 0, %phi3 |
| %icmp = icmp eq i32 %phi7, %sub |
| br i1 false, label %while.cond.outer, label %for.body |
| } |