1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
; 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
}
|