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
}
|