xref: /llvm-project/llvm/test/Transforms/InstSimplify/domcondition.ll (revision 2a7e1a132dff95ffe76ecb5cd8dea8d1f95e1046)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4define i32 @xor_domcondition(i32 %x, i32 %y) {
5; CHECK-LABEL: @xor_domcondition(
6; CHECK-NEXT:  entry:
7; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
8; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
9; CHECK:       cond.true:
10; CHECK-NEXT:    br label [[COND_END]]
11; CHECK:       cond.end:
12; CHECK-NEXT:    ret i32 0
13;
14entry:
15  %cmp = icmp eq i32 %x, %y
16  br i1 %cmp, label %cond.true, label %cond.end
17
18cond.true:
19  %xor = xor i32 %x, %y
20  br label %cond.end
21
22cond.end:
23  %cond = phi i32 [ %xor, %cond.true ], [ 0, %entry ]
24  ret i32 %cond
25}
26
27define i32 @sub_domcondition(i32 %x, i32 %y) {
28; CHECK-LABEL: @sub_domcondition(
29; CHECK-NEXT:  entry:
30; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
31; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
32; CHECK:       cond.true:
33; CHECK-NEXT:    br label [[COND_END]]
34; CHECK:       cond.end:
35; CHECK-NEXT:    ret i32 0
36;
37entry:
38  %cmp = icmp eq i32 %x, %y
39  br i1 %cmp, label %cond.true, label %cond.end
40
41cond.true:
42  %sub = sub i32 %x, %y
43  br label %cond.end
44
45cond.end:
46  %cond = phi i32 [ %sub, %cond.true ], [ 0, %entry ]
47  ret i32 %cond
48}
49
50define i32 @udiv_domcondition(i32 %x, i32 %y) {
51; CHECK-LABEL: @udiv_domcondition(
52; CHECK-NEXT:  entry:
53; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
54; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
55; CHECK:       cond.true:
56; CHECK-NEXT:    br label [[COND_END]]
57; CHECK:       cond.end:
58; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
59; CHECK-NEXT:    ret i32 [[COND]]
60;
61entry:
62  %cmp = icmp eq i32 %x, %y
63  br i1 %cmp, label %cond.true, label %cond.end
64
65cond.true:
66  %udiv = udiv i32 %x, %y
67  br label %cond.end
68
69cond.end:
70  %cond = phi i32 [ %udiv, %cond.true ], [ 0, %entry ]
71  ret i32 %cond
72}
73
74define i32 @sdiv_domcondition(i32 %x, i32 %y) {
75; CHECK-LABEL: @sdiv_domcondition(
76; CHECK-NEXT:  entry:
77; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
78; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
79; CHECK:       cond.true:
80; CHECK-NEXT:    br label [[COND_END]]
81; CHECK:       cond.end:
82; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ 1, [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
83; CHECK-NEXT:    ret i32 [[COND]]
84;
85entry:
86  %cmp = icmp eq i32 %x, %y
87  br i1 %cmp, label %cond.true, label %cond.end
88
89cond.true:
90  %sdiv = sdiv i32 %x, %y
91  br label %cond.end
92
93cond.end:
94  %cond = phi i32 [ %sdiv, %cond.true ], [ 0, %entry ]
95  ret i32 %cond
96}
97
98define i32 @urem_domcondition(i32 %x, i32 %y) {
99; CHECK-LABEL: @urem_domcondition(
100; CHECK-NEXT:  entry:
101; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
102; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
103; CHECK:       cond.true:
104; CHECK-NEXT:    br label [[COND_END]]
105; CHECK:       cond.end:
106; CHECK-NEXT:    ret i32 0
107;
108entry:
109  %cmp = icmp eq i32 %x, %y
110  br i1 %cmp, label %cond.true, label %cond.end
111
112cond.true:
113  %urem = urem i32 %x, %y
114  br label %cond.end
115
116cond.end:
117  %cond = phi i32 [ %urem, %cond.true ], [ 0, %entry ]
118  ret i32 %cond
119}
120
121define i32 @srem_domcondition(i32 %x, i32 %y) {
122; CHECK-LABEL: @srem_domcondition(
123; CHECK-NEXT:  entry:
124; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
125; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
126; CHECK:       cond.true:
127; CHECK-NEXT:    br label [[COND_END]]
128; CHECK:       cond.end:
129; CHECK-NEXT:    ret i32 0
130;
131entry:
132  %cmp = icmp eq i32 %x, %y
133  br i1 %cmp, label %cond.true, label %cond.end
134
135cond.true:
136  %srem = srem i32 %x, %y
137  br label %cond.end
138
139cond.end:
140  %cond = phi i32 [ %srem, %cond.true ], [ 0, %entry ]
141  ret i32 %cond
142}
143
144; TODO: %and can be one of %x, %y
145define i32 @and_domcondition(i32 %x, i32 %y) {
146; CHECK-LABEL: @and_domcondition(
147; CHECK-NEXT:  entry:
148; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
149; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
150; CHECK:       cond.true:
151; CHECK-NEXT:    br label [[COND_END]]
152; CHECK:       cond.end:
153; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[Y]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
154; CHECK-NEXT:    ret i32 [[COND]]
155;
156entry:
157  %cmp = icmp eq i32 %x, %y
158  br i1 %cmp, label %cond.true, label %cond.end
159
160cond.true:
161  %and = and i32 %x, %y
162  br label %cond.end
163
164cond.end:
165  %cond = phi i32 [ %and, %cond.true ], [ 0, %entry ]
166  ret i32 %cond
167}
168
169; TODO: %or can be one of %x, %y
170define i32 @or_domcondition(i32 %x, i32 %y) {
171; CHECK-LABEL: @or_domcondition(
172; CHECK-NEXT:  entry:
173; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
174; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
175; CHECK:       cond.true:
176; CHECK-NEXT:    br label [[COND_END]]
177; CHECK:       cond.end:
178; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[Y]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
179; CHECK-NEXT:    ret i32 [[COND]]
180;
181entry:
182  %cmp = icmp eq i32 %x, %y
183  br i1 %cmp, label %cond.true, label %cond.end
184
185cond.true:
186  %or = or i32 %x, %y
187  br label %cond.end
188
189cond.end:
190  %cond = phi i32 [ %or, %cond.true ], [ 0, %entry ]
191  ret i32 %cond
192}
193
194; negative test, dominate condtion is not eq
195define i32 @xor_domcondition_negative(i32 %x, i32 %y) {
196; CHECK-LABEL: @xor_domcondition_negative(
197; CHECK-NEXT:  entry:
198; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]
199; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
200; CHECK:       cond.true:
201; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
202; CHECK-NEXT:    br label [[COND_END]]
203; CHECK:       cond.end:
204; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[XOR]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
205; CHECK-NEXT:    ret i32 [[COND]]
206;
207entry:
208  %cmp = icmp uge i32 %x, %y
209  br i1 %cmp, label %cond.true, label %cond.end
210
211cond.true:
212  %xor = xor i32 %x, %y
213  br label %cond.end
214
215cond.end:
216  %cond = phi i32 [ %xor, %cond.true ], [ 0, %entry ]
217  ret i32 %cond
218}
219
220define i32 @xor_simplify_by_dci(i32 %x, i32 %y, i1 %c) {
221; CHECK-LABEL: @xor_simplify_by_dci(
222; CHECK-NEXT:  entry:
223; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
224; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
225; CHECK:       cond.true:
226; CHECK-NEXT:    br i1 [[C:%.*]], label [[XORBB:%.*]], label [[COND_END]]
227; CHECK:       xorbb:
228; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X]], [[Y]]
229; CHECK-NEXT:    br label [[COND_END]]
230; CHECK:       cond.end:
231; CHECK-NEXT:    [[COND:%.*]] = phi i32 [ [[XOR]], [[XORBB]] ], [ 0, [[ENTRY:%.*]] ], [ 0, [[COND_TRUE]] ]
232; CHECK-NEXT:    ret i32 [[COND]]
233;
234entry:
235  %cmp = icmp eq i32 %x, %y
236  br i1 %cmp, label %cond.true, label %cond.end
237
238cond.true:
239  br i1 %c, label %xorbb, label %cond.end
240
241xorbb:
242  %xor = xor i32 %x, %y
243  br label %cond.end
244
245cond.end:
246  %cond = phi i32 [ %xor, %xorbb ], [ 0, %entry ], [0, %cond.true]
247  ret i32 %cond
248}
249
250define void @icmp_simplify_by_dci(i32 %a, i32 %b, i1 %x) {
251; CHECK-LABEL: @icmp_simplify_by_dci(
252; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]
253; CHECK-NEXT:    br i1 [[CMP1]], label [[END:%.*]], label [[TAKEN:%.*]]
254; CHECK:       taken:
255; CHECK-NEXT:    br i1 [[X:%.*]], label [[SELBB:%.*]], label [[END]]
256; CHECK:       selbb:
257; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[A]], [[B]]
258; CHECK-NEXT:    [[C:%.*]] = select i1 [[CMP2]], i32 20, i32 0
259; CHECK-NEXT:    call void @foo(i32 [[C]])
260; CHECK-NEXT:    br label [[END]]
261; CHECK:       end:
262; CHECK-NEXT:    ret void
263;
264  %cmp1 = icmp eq i32 %a, %b
265  br i1 %cmp1, label %end, label %taken
266
267taken:
268  br i1 %x, label %selbb, label %end
269
270selbb:
271  %cmp2 = icmp ne i32 %a, %b
272  %c = select i1 %cmp2, i32 20, i32 0
273  call void @foo(i32 %c)
274  br label %end
275
276end:
277  ret void
278}
279
280declare void @foo(i32)
281