[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / Util / PredicateInfo / testandor.ll
blobc84562cc5ef5365428069c19e900b695aca64b8d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -print-predicateinfo < %s 2>&1 | FileCheck %s
4 declare void @foo(i1)
5 declare void @bar(i32)
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:%.*]]
19 ; CHECK:       oneof:
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
25 ; CHECK:       neither:
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
35   %z = or i1 %xz, %yz
36   br i1 %z, label %oneof, label %neither
37 oneof:
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)
43   ret void
44 neither:
45   call void @foo(i1 %xz)
46   call void @foo(i1 %yz)
47   call void @bar(i32 %x)
48   call void @bar(i32 %y)
49   call void @foo(i1 %z)
50   ret void
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:%.*]]
63 ; CHECK:       both:
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
69 ; CHECK:       nope:
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
79   %z = and i1 %xz, %yz
80   br i1 %z, label %both, label %nope
81 both:
82   call void @foo(i1 %xz)
83   call void @foo(i1 %yz)
84   call void @bar(i32 %x)
85   call void @bar(i32 %y)
86   ret void
87 nope:
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)
93   call void @foo(i1 %z)
94   ret void
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:%.*]]
107 ; CHECK:       both:
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
112 ; CHECK:       nope:
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
122 both:
123   call void @foo(i1 %xgt)
124   call void @foo(i1 %xlt)
125   call void @bar(i32 %x)
126   ret void
127 nope:
128   call void @foo(i1 %xgt)
129   call void @foo(i1 %xlt)
130   call void @foo(i1 %z)
131   ret void
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:%.*]]
151 ; CHECK:       both:
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
157 ; CHECK:       nope:
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
163   %z = and i1 %xz, %yz
164   call void @llvm.assume(i1 %z)
165   br i1 %z, label %both, label %nope
166 both:
167   call void @foo(i1 %xz)
168   call void @foo(i1 %yz)
169   call void @bar(i32 %x)
170   call void @bar(i32 %y)
171   ret void
172 nope:
173   call void @foo(i1 %z)
174   ret void
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:%.*]]
187 ; CHECK:       both:
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
193 ; CHECK:       nope:
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
199   %z = or i1 %xz, %yz
200   call void @llvm.assume(i1 %z)
201   br i1 %z, label %both, label %nope
202 both:
203   call void @foo(i1 %xz)
204   call void @foo(i1 %yz)
205   call void @bar(i32 %x)
206   call void @bar(i32 %y)
207   ret void
208 nope:
209   call void @foo(i1 %z)
210   ret void