aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/SimpleLoopUnswitch/invalidate-block-and-loop-dispositions.ll
blob: fcef88667449f731cfe2d88fe4d3c8870683ca2d (plain)
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
}