1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -print-predicateinfo < %s 2>&1 | FileCheck %s
6 declare void @llvm.assume(i1)
8 define void @testor(i32 %x, i32 %y) {
9 ; CHECK-LABEL: @testor(
10 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
11 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
12 ; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
13 ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
14 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
15 ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
16 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
17 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
18 ; CHECK-NEXT: br i1 [[Z]], label [[ONEOF:%.*]], label [[NEITHER:%.*]]
20 ; CHECK-NEXT: call void @foo(i1 [[XZ]])
21 ; CHECK-NEXT: call void @foo(i1 [[YZ]])
22 ; CHECK-NEXT: call void @bar(i32 [[X]])
23 ; CHECK-NEXT: call void @bar(i32 [[Y]])
24 ; CHECK-NEXT: ret void
26 ; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
27 ; CHECK-NEXT: call void @foo(i1 [[YZ_0]])
28 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
29 ; CHECK-NEXT: call void @bar(i32 [[Y_0]])
30 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
31 ; CHECK-NEXT: ret void
33 %xz = icmp eq i32 %x, 0
34 %yz = icmp eq i32 %y, 0
36 br i1 %z, label %oneof, label %neither
38 ;; Should not insert on the true edge for or
39 call void @foo(i1 %xz)
40 call void @foo(i1 %yz)
41 call void @bar(i32 %x)
42 call void @bar(i32 %y)
45 call void @foo(i1 %xz)
46 call void @foo(i1 %yz)
47 call void @bar(i32 %x)
48 call void @bar(i32 %y)
52 define void @testand(i32 %x, i32 %y) {
53 ; CHECK-LABEL: @testand(
54 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
55 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
56 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
57 ; CHECK: [[XZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
58 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
59 ; CHECK: [[YZ_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
60 ; CHECK: [[Y_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
61 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
62 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
64 ; CHECK-NEXT: call void @foo(i1 [[XZ_0]])
65 ; CHECK-NEXT: call void @foo(i1 [[YZ_0]])
66 ; CHECK-NEXT: call void @bar(i32 [[X_0]])
67 ; CHECK-NEXT: call void @bar(i32 [[Y_0]])
68 ; CHECK-NEXT: ret void
70 ; CHECK-NEXT: call void @foo(i1 [[XZ]])
71 ; CHECK-NEXT: call void @foo(i1 [[YZ]])
72 ; CHECK-NEXT: call void @bar(i32 [[X]])
73 ; CHECK-NEXT: call void @bar(i32 [[Y]])
74 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
75 ; CHECK-NEXT: ret void
77 %xz = icmp eq i32 %x, 0
78 %yz = icmp eq i32 %y, 0
80 br i1 %z, label %both, label %nope
82 call void @foo(i1 %xz)
83 call void @foo(i1 %yz)
84 call void @bar(i32 %x)
85 call void @bar(i32 %y)
88 ;; Should not insert on the false edge for and
89 call void @foo(i1 %xz)
90 call void @foo(i1 %yz)
91 call void @bar(i32 %x)
92 call void @bar(i32 %y)
96 define void @testandsame(i32 %x, i32 %y) {
97 ; CHECK-LABEL: @testandsame(
98 ; CHECK-NEXT: [[XGT:%.*]] = icmp sgt i32 [[X:%.*]], 0
99 ; CHECK-NEXT: [[XLT:%.*]] = icmp slt i32 [[X]], 100
100 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XGT]], [[XLT]]
101 ; CHECK: [[XGT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XGT]])
102 ; CHECK: [[X_0:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
103 ; CHECK: [[X_0_1:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X_0]])
104 ; CHECK: [[XLT_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XLT]])
105 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
106 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
108 ; CHECK-NEXT: call void @foo(i1 [[XGT_0]])
109 ; CHECK-NEXT: call void @foo(i1 [[XLT_0]])
110 ; CHECK-NEXT: call void @bar(i32 [[X_0_1]])
111 ; CHECK-NEXT: ret void
113 ; CHECK-NEXT: call void @foo(i1 [[XGT]])
114 ; CHECK-NEXT: call void @foo(i1 [[XLT]])
115 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
116 ; CHECK-NEXT: ret void
118 %xgt = icmp sgt i32 %x, 0
119 %xlt = icmp slt i32 %x, 100
120 %z = and i1 %xgt, %xlt
121 br i1 %z, label %both, label %nope
123 call void @foo(i1 %xgt)
124 call void @foo(i1 %xlt)
125 call void @bar(i32 %x)
128 call void @foo(i1 %xgt)
129 call void @foo(i1 %xlt)
130 call void @foo(i1 %z)
134 define void @testandassume(i32 %x, i32 %y) {
135 ; CHECK-LABEL: @testandassume(
136 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
137 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
138 ; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]]
139 ; CHECK: [[TMP1:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[XZ]])
140 ; CHECK: [[TMP2:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[X]])
141 ; CHECK: [[TMP3:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[YZ]])
142 ; CHECK: [[TMP4:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[Y]])
143 ; CHECK: [[TMP5:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
144 ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP5]])
145 ; CHECK: [[DOT0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP1]])
146 ; CHECK: [[DOT01:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP2]])
147 ; CHECK: [[DOT02:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP3]])
148 ; CHECK: [[DOT03:%.*]] = call i32 @llvm.ssa.copy.{{.+}}(i32 [[TMP4]])
149 ; CHECK: [[DOT04:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[TMP5]])
150 ; CHECK-NEXT: br i1 [[TMP5]], label [[BOTH:%.*]], label [[NOPE:%.*]]
152 ; CHECK-NEXT: call void @foo(i1 [[DOT0]])
153 ; CHECK-NEXT: call void @foo(i1 [[DOT02]])
154 ; CHECK-NEXT: call void @bar(i32 [[DOT01]])
155 ; CHECK-NEXT: call void @bar(i32 [[DOT03]])
156 ; CHECK-NEXT: ret void
158 ; CHECK-NEXT: call void @foo(i1 [[DOT04]])
159 ; CHECK-NEXT: ret void
161 %xz = icmp eq i32 %x, 0
162 %yz = icmp eq i32 %y, 0
164 call void @llvm.assume(i1 %z)
165 br i1 %z, label %both, label %nope
167 call void @foo(i1 %xz)
168 call void @foo(i1 %yz)
169 call void @bar(i32 %x)
170 call void @bar(i32 %y)
173 call void @foo(i1 %z)
177 ;; Unlike and/or for branches, assume is *always* true, so we only match and for it
178 define void @testorassume(i32 %x, i32 %y) {
180 ; CHECK-LABEL: @testorassume(
181 ; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0
182 ; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0
183 ; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]]
184 ; CHECK-NEXT: call void @llvm.assume(i1 [[Z]])
185 ; CHECK: [[Z_0:%.*]] = call i1 @llvm.ssa.copy.{{.+}}(i1 [[Z]])
186 ; CHECK-NEXT: br i1 [[Z]], label [[BOTH:%.*]], label [[NOPE:%.*]]
188 ; CHECK-NEXT: call void @foo(i1 [[XZ]])
189 ; CHECK-NEXT: call void @foo(i1 [[YZ]])
190 ; CHECK-NEXT: call void @bar(i32 [[X]])
191 ; CHECK-NEXT: call void @bar(i32 [[Y]])
192 ; CHECK-NEXT: ret void
194 ; CHECK-NEXT: call void @foo(i1 [[Z_0]])
195 ; CHECK-NEXT: ret void
197 %xz = icmp eq i32 %x, 0
198 %yz = icmp eq i32 %y, 0
200 call void @llvm.assume(i1 %z)
201 br i1 %z, label %both, label %nope
203 call void @foo(i1 %xz)
204 call void @foo(i1 %yz)
205 call void @bar(i32 %x)
206 call void @bar(i32 %y)
209 call void @foo(i1 %z)