| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt -passes="loop-mssa(indvars,simple-loop-unswitch<nontrivial>)" -verify-scev -S %s | FileCheck %s |
| target datalayout = "n16:32" |
| |
| @glob = external global i16, align 1 |
| |
| ; Test case for PR58136. |
| define void @test_pr58136(i1 %c.1, i1 %c.2) { |
| ; CHECK-LABEL: @test_pr58136( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[SRC1:%.*]] = alloca i16, align 2 |
| ; CHECK-NEXT: [[L_3:%.*]] = load i16, ptr [[SRC1]], align 2 |
| ; CHECK-NEXT: [[GLOB_PROMOTED:%.*]] = load i16, ptr @glob, align 2 |
| ; CHECK-NEXT: [[C_1_FR:%.*]] = freeze i1 [[C_1:%.*]] |
| ; CHECK-NEXT: br i1 [[C_1_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] |
| ; CHECK: entry.split.us: |
| ; CHECK-NEXT: [[C_2_FR:%.*]] = freeze i1 [[C_2:%.*]] |
| ; CHECK-NEXT: br i1 [[C_2_FR]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]] |
| ; CHECK: entry.split.us.split.us: |
| ; CHECK-NEXT: br label [[LOOP_HEADER_US_US:%.*]] |
| ; CHECK: loop.header.us.us: |
| ; CHECK-NEXT: [[MUL1_US_US:%.*]] = phi i16 [ [[MUL_US_US:%.*]], [[LOOP_LATCH_US_US:%.*]] ], [ [[GLOB_PROMOTED]], [[ENTRY_SPLIT_US_SPLIT_US]] ] |
| ; CHECK-NEXT: [[CALL2_US_US:%.*]] = call i16 @foo() |
| ; CHECK-NEXT: br label [[THEN_BB_US_US:%.*]] |
| ; CHECK: then.bb.us.us: |
| ; CHECK-NEXT: br label [[LOOP_LATCH_US_US]] |
| ; CHECK: loop.latch.us.us: |
| ; CHECK-NEXT: [[MUL_US_US]] = mul nsw i16 [[MUL1_US_US]], [[L_3]] |
| ; CHECK-NEXT: store i16 [[MUL_US_US]], ptr @glob, align 2 |
| ; CHECK-NEXT: br label [[LOOP_HEADER_US_US]] |
| ; CHECK: entry.split.us.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] |
| ; CHECK: loop.header.us: |
| ; CHECK-NEXT: [[CALL2_US:%.*]] = call i16 @foo() |
| ; CHECK-NEXT: br label [[THEN_BB_US:%.*]] |
| ; CHECK: then.bb.us: |
| ; CHECK-NEXT: br label [[EXIT_SPLIT_US:%.*]] |
| ; CHECK: exit.split.us: |
| ; CHECK-NEXT: br label [[EXIT:%.*]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] |
| ; CHECK: loop.header: |
| ; CHECK-NEXT: [[CALL2:%.*]] = call i16 @foo() |
| ; CHECK-NEXT: br label [[EXIT_SPLIT:%.*]] |
| ; CHECK: exit.split: |
| ; CHECK-NEXT: br label [[EXIT]] |
| ; CHECK: exit: |
| ; CHECK-NEXT: ret void |
| ; |
| entry: |
| %src1 = alloca i16, align 2 |
| %l.3 = load i16, ptr %src1, align 2 |
| %glob.promoted = load i16, ptr @glob, align 2 |
| br label %loop.header |
| |
| loop.header: ; preds = %loop.latch, %entry |
| %mul1 = phi i16 [ %mul, %loop.latch ], [ %glob.promoted, %entry ] |
| %call2 = call i16 @foo() |
| br i1 %c.1, label %then.bb, label %exit |
| |
| then.bb: ; preds = %loop.header |
| br i1 %c.2, label %loop.latch, label %exit |
| |
| loop.latch: ; preds = %then.bb |
| %mul = mul nsw i16 %mul1, %l.3 |
| store i16 %mul, ptr @glob, align 2 |
| br label %loop.header |
| |
| exit: ; preds = %then.bb, %loop.header |
| ret void |
| } |
| |
| declare i16 @foo() nounwind readnone |
| |
| define void @test_pr58158(i1 %c.1) { |
| ; CHECK-LABEL: @test_pr58158( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: [[CALL:%.*]] = tail call i16 @bar() |
| ; CHECK-NEXT: br i1 [[C_1:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] |
| ; CHECK: entry.split.us: |
| ; CHECK-NEXT: br label [[OUTER_US:%.*]] |
| ; CHECK: outer.us: |
| ; CHECK-NEXT: br label [[INNER_PREHEADER_US:%.*]] |
| ; CHECK: inner.us: |
| ; CHECK-NEXT: [[C_2_US:%.*]] = icmp eq i16 0, [[CALL]] |
| ; CHECK-NEXT: br i1 [[C_2_US]], label [[OUTER_LOOPEXIT_US:%.*]], label [[INNER_US:%.*]] |
| ; CHECK: inner.preheader.us: |
| ; CHECK-NEXT: br label [[INNER_US]] |
| ; CHECK: outer.loopexit.us: |
| ; CHECK-NEXT: br label [[OUTER_BACKEDGE_US:%.*]] |
| ; CHECK: outer.backedge.us: |
| ; CHECK-NEXT: br label [[OUTER_US]] |
| ; CHECK: entry.split: |
| ; CHECK-NEXT: br label [[OUTER:%.*]] |
| ; CHECK: outer: |
| ; CHECK-NEXT: br label [[OUTER_BACKEDGE:%.*]] |
| ; CHECK: outer.backedge: |
| ; CHECK-NEXT: br label [[OUTER]] |
| ; |
| entry: |
| %call = tail call i16 @bar() |
| br label %outer |
| |
| outer: |
| br i1 %c.1, label %inner, label %outer |
| |
| inner: |
| %c.2 = icmp eq i16 0, %call |
| br i1 %c.2, label %outer, label %inner |
| } |
| |
| declare i16 @bar() |
| |
| define void @pr58751(i16 %a, ptr %dst) { |
| entry: |
| %c.1 = icmp eq i16 %a, 0 |
| br label %outer.header |
| |
| outer.header: |
| %outer.iv = phi i16 [ %a, %entry ], [ %outer.iv.next, %outer.latch ] |
| br label %inner.header |
| |
| inner.header: |
| %inner.iv = phi i16 [ %outer.iv, %outer.header ], [ %inner.iv.next, %inner.latch ] |
| br i1 %c.1, label %outer.latch, label %inner.latch |
| |
| inner.latch: |
| %inner.iv.next = add nsw i16 %inner.iv, 1 |
| store i16 %inner.iv.next, ptr %dst, align 1 |
| %c.2 = icmp eq i16 %inner.iv.next, 0 |
| br i1 %c.2, label %exit, label %inner.header |
| |
| outer.latch: |
| %outer.iv.next = add nsw i16 %outer.iv, 1 |
| br label %outer.header |
| |
| exit: |
| ret void |
| } |
| |