Jlm
Loading...
Searching...
No Matches
BitstringTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2010 2011 2012 2013 2014 2015 Helge Bahmann <hcb@chaoticmind.net>
3 * Copyright 2011 2012 2014 2015 2016 Nico Reißmann <nico.reissmann@gmail.com>
4 * See COPYING for terms of redistribution.
5 */
6
7#include <gtest/gtest.h>
8
11#include <jlm/rvsdg/view.hpp>
12
13TEST(bitstring, arithmetic_test_bitand)
14{
15 using namespace jlm::rvsdg;
16
17 // Arrange
18 Graph graph;
19 const auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
20 const auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
21
22 const auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
23 const auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
24
25 auto & and0 = CreateOpNode<bitand_op>({ s0, s1 }, 32);
26 auto & and1 = CreateOpNode<bitand_op>({ c0, c1 }, 32);
27
28 auto & ex0 = GraphExport::Create(*and0.output(0), "dummy");
29 auto & ex1 = GraphExport::Create(*and1.output(0), "dummy");
30
31 view(&graph.GetRootRegion(), stdout);
32
33 // Act
34 ReduceNode<bitand_op>(BitBinaryOperation::foldConstants, and0);
35 ReduceNode<bitand_op>(BitBinaryOperation::foldConstants, and1);
36 graph.PruneNodes();
37
38 view(&graph.GetRootRegion(), stdout);
39
40 // Assert
41 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitand_op(32));
42 EXPECT_EQ(
43 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
44 BitConstantOperation({ 32, +1 }));
45}
46
47TEST(bitstring, arithmetic_test_bitashr)
48{
49 using namespace jlm::rvsdg;
50
51 // Arrange
52 Graph graph;
53 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
54 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
55
56 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 16 });
57 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, -16 });
58 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 2 });
59 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 32 });
60
61 auto & ashr0 = CreateOpNode<bitashr_op>({ s0, s1 }, 32);
62 auto & ashr1 = CreateOpNode<bitashr_op>({ c0, c2 }, 32);
63 auto & ashr2 = CreateOpNode<bitashr_op>({ c0, c3 }, 32);
64 auto & ashr3 = CreateOpNode<bitashr_op>({ c1, c2 }, 32);
65 auto & ashr4 = CreateOpNode<bitashr_op>({ c1, c3 }, 32);
66
67 auto & ex0 = GraphExport::Create(*ashr0.output(0), "dummy");
68 auto & ex1 = GraphExport::Create(*ashr1.output(0), "dummy");
69 auto & ex2 = GraphExport::Create(*ashr2.output(0), "dummy");
70 auto & ex3 = GraphExport::Create(*ashr3.output(0), "dummy");
71 auto & ex4 = GraphExport::Create(*ashr4.output(0), "dummy");
72
73 view(&graph.GetRootRegion(), stdout);
74
75 // Act
76 ReduceNode<bitashr_op>(BitBinaryOperation::foldConstants, ashr0);
77 ReduceNode<bitashr_op>(BitBinaryOperation::foldConstants, ashr1);
78 ReduceNode<bitashr_op>(BitBinaryOperation::foldConstants, ashr2);
79 ReduceNode<bitashr_op>(BitBinaryOperation::foldConstants, ashr3);
80 ReduceNode<bitashr_op>(BitBinaryOperation::foldConstants, ashr4);
81 graph.PruneNodes();
82
83 view(&graph.GetRootRegion(), stdout);
84
85 // Assert
86 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitashr_op(32));
87 EXPECT_EQ(
88 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
89 BitConstantOperation({ 32, 4 }));
90 EXPECT_EQ(
91 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
92 BitConstantOperation({ 32, 0 }));
93 EXPECT_EQ(
94 TryGetOwnerNode<SimpleNode>(*ex3.origin())->GetOperation(),
95 BitConstantOperation({ 32, -4 }));
96 EXPECT_EQ(
97 TryGetOwnerNode<SimpleNode>(*ex4.origin())->GetOperation(),
98 BitConstantOperation({ 32, -1 }));
99}
100
101TEST(bitstring, arithmetic_test_bitdifference)
102{
103 using namespace jlm::rvsdg;
104
105 // Arrange
106 Graph graph;
107 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
108 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
109
110 auto & diff = CreateOpNode<bitsub_op>({ s0, s1 }, 32);
111
112 auto & ex0 = GraphExport::Create(*diff.output(0), "dummy");
113
114 view(&graph.GetRootRegion(), stdout);
115
116 // Act
117 ReduceNode<bitsub_op>(NormalizeBinaryOperation, diff);
118 graph.PruneNodes();
119
120 view(&graph.GetRootRegion(), stdout);
121
122 // Act
123 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsub_op(32));
124}
125
126TEST(bitstring, arithmetic_test_bitnegate)
127{
128 using namespace jlm::rvsdg;
129
130 // Arrange
131 Graph graph;
132 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
133 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
134
135 auto & neg0 = CreateOpNode<bitneg_op>({ s0 }, 32);
136 auto & neg1 = CreateOpNode<bitneg_op>({ c0 }, 32);
137 auto & neg2 = CreateOpNode<bitneg_op>({ neg1.output(0) }, 32);
138
139 auto & ex0 = GraphExport::Create(*neg0.output(0), "dummy");
140 auto & ex1 = GraphExport::Create(*neg1.output(0), "dummy");
141 auto & ex2 = GraphExport::Create(*neg2.output(0), "dummy");
142
143 view(&graph.GetRootRegion(), stdout);
144
145 // Act
146 ReduceNode<bitneg_op>(BitUnaryOperation::foldConstant, neg0);
147 ReduceNode<bitneg_op>(BitUnaryOperation::foldConstant, neg1);
148 ReduceNode<bitneg_op>(BitUnaryOperation::foldConstant, neg2);
149 graph.PruneNodes();
150
151 view(&graph.GetRootRegion(), stdout);
152
153 // Assert
154 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitneg_op(32));
155 EXPECT_EQ(
156 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
157 BitConstantOperation({ 32, -3 }));
158 EXPECT_EQ(
159 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
160 BitConstantOperation({ 32, 3 }));
161}
162
163TEST(bitstring, arithmetic_test_bitnot)
164{
165 using namespace jlm::rvsdg;
166
167 // Arrange
168 Graph graph;
169 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
170 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
171
172 auto & not0 = CreateOpNode<bitnot_op>({ s0 }, 32);
173 auto & not1 = CreateOpNode<bitnot_op>({ c0 }, 32);
174 auto & not2 = CreateOpNode<bitnot_op>({ not1.output(0) }, 32);
175
176 auto & ex0 = GraphExport::Create(*not0.output(0), "dummy");
177 auto & ex1 = GraphExport::Create(*not1.output(0), "dummy");
178 auto & ex2 = GraphExport::Create(*not2.output(0), "dummy");
179
180 view(&graph.GetRootRegion(), stdout);
181
182 // Act
183 ReduceNode<bitnot_op>(BitUnaryOperation::foldConstant, not0);
184 ReduceNode<bitnot_op>(BitUnaryOperation::foldConstant, not1);
185 ReduceNode<bitnot_op>(BitUnaryOperation::foldConstant, not2);
186 graph.PruneNodes();
187
188 view(&graph.GetRootRegion(), stdout);
189
190 // Assert
191 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitnot_op(32));
192 EXPECT_EQ(
193 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
194 BitConstantOperation({ 32, -4 }));
195 EXPECT_EQ(
196 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
197 BitConstantOperation({ 32, 3 }));
198}
199
200TEST(bitstring, arithmetic_test_bitor)
201{
202 using namespace jlm::rvsdg;
203
204 // Arrange
205 Graph graph;
206 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
207 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
208
209 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
210 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
211
212 auto & or0 = CreateOpNode<bitor_op>({ s0, s1 }, 32);
213 auto & or1 = CreateOpNode<bitor_op>({ c0, c1 }, 32);
214
215 auto & ex0 = GraphExport::Create(*or0.output(0), "dummy");
216 auto & ex1 = GraphExport::Create(*or1.output(0), "dummy");
217
218 view(&graph.GetRootRegion(), stdout);
219
220 // Act
221 ReduceNode<bitor_op>(BitBinaryOperation::foldConstants, or0);
222 ReduceNode<bitor_op>(BitBinaryOperation::foldConstants, or1);
223 graph.PruneNodes();
224
225 view(&graph.GetRootRegion(), stdout);
226
227 // Assert
228 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitor_op(32));
229 EXPECT_EQ(
230 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
231 BitConstantOperation({ 32, 7 }));
232}
233
234TEST(bitstring, arithmetic_test_bitproduct)
235{
236 using namespace jlm::rvsdg;
237
238 // Arrange
239 Graph graph;
240 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
241 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
242
243 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
244 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
245
246 auto & product0 = CreateOpNode<bitmul_op>({ s0, s1 }, 32);
247 auto & product1 = CreateOpNode<bitmul_op>({ c0, c1 }, 32);
248
249 auto & ex0 = GraphExport::Create(*product0.output(0), "dummy");
250 auto & ex1 = GraphExport::Create(*product1.output(0), "dummy");
251
252 view(&graph.GetRootRegion(), stdout);
253
254 // Act
255 ReduceNode<bitmul_op>(BitBinaryOperation::foldConstants, product0);
256 ReduceNode<bitmul_op>(BitBinaryOperation::foldConstants, product1);
257 graph.PruneNodes();
258
259 view(&graph.GetRootRegion(), stdout);
260
261 // Assert
262 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitmul_op(32));
263 EXPECT_EQ(
264 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
265 BitConstantOperation({ 32, 15 }));
266}
267
268TEST(bitstring, arithmetic_test_bitshiproduct)
269{
270 using namespace jlm::rvsdg;
271
272 // Arrange
273 Graph graph;
274 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
275 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
276
277 auto & shiproduct = CreateOpNode<bitsmulh_op>({ s0, s1 }, 32);
278
279 auto & ex0 = GraphExport::Create(*shiproduct.output(0), "dummy");
280
281 view(&graph.GetRootRegion(), stdout);
282
283 // Act
284 ReduceNode<bitsmulh_op>(NormalizeBinaryOperation, shiproduct);
285 graph.PruneNodes();
286
287 view(&graph.GetRootRegion(), stdout);
288
289 // Assert
290 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsmulh_op(32));
291}
292
293TEST(bitstring, arithmetic_test_bitshl)
294{
295 using namespace jlm::rvsdg;
296
297 // Arrange
298 Graph graph;
299 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
300 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
301
302 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 16 });
303 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 2 });
304 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 32 });
305
306 auto & shl0 = CreateOpNode<bitshl_op>({ s0, s1 }, 32);
307 auto & shl1 = CreateOpNode<bitshl_op>({ c0, c1 }, 32);
308 auto & shl2 = CreateOpNode<bitshl_op>({ c0, c2 }, 32);
309
310 auto & ex0 = GraphExport::Create(*shl0.output(0), "dummy");
311 auto & ex1 = GraphExport::Create(*shl1.output(0), "dummy");
312 auto & ex2 = GraphExport::Create(*shl2.output(0), "dummy");
313
314 view(&graph.GetRootRegion(), stdout);
315
316 // Act
317 ReduceNode<bitshl_op>(BitBinaryOperation::foldConstants, shl0);
318 ReduceNode<bitshl_op>(BitBinaryOperation::foldConstants, shl1);
319 ReduceNode<bitshl_op>(BitBinaryOperation::foldConstants, shl2);
320 graph.PruneNodes();
321
322 view(&graph.GetRootRegion(), stdout);
323
324 // Assert
325 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitshl_op(32));
326 EXPECT_EQ(
327 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
328 BitConstantOperation({ 32, 64 }));
329 EXPECT_EQ(
330 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
331 BitConstantOperation({ 32, 0 }));
332}
333
334TEST(bitstring, arithmetic_test_bitshr)
335{
336 using namespace jlm::rvsdg;
337
338 // Arrange
339 Graph graph;
340 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
341 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
342
343 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 16 });
344 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 2 });
345 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 32 });
346
347 auto & shr0 = CreateOpNode<bitshr_op>({ s0, s1 }, 32);
348 auto & shr1 = CreateOpNode<bitshr_op>({ c0, c1 }, 32);
349 auto & shr2 = CreateOpNode<bitshr_op>({ c0, c2 }, 32);
350
351 auto & ex0 = GraphExport::Create(*shr0.output(0), "dummy");
352 auto & ex1 = GraphExport::Create(*shr1.output(0), "dummy");
353 auto & ex2 = GraphExport::Create(*shr2.output(0), "dummy");
354
355 view(&graph.GetRootRegion(), stdout);
356
357 // Act
358 ReduceNode<bitshr_op>(BitBinaryOperation::foldConstants, shr0);
359 ReduceNode<bitshr_op>(BitBinaryOperation::foldConstants, shr1);
360 ReduceNode<bitshr_op>(BitBinaryOperation::foldConstants, shr2);
361 graph.PruneNodes();
362
363 view(&graph.GetRootRegion(), stdout);
364
365 // Assert
366 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitshr_op(32));
367 EXPECT_EQ(
368 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
369 BitConstantOperation({ 32, 4 }));
370 EXPECT_EQ(
371 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
372 BitConstantOperation({ 32, 0 }));
373}
374
375TEST(bitstring, arithmetic_test_bitsmod)
376{
377 using namespace jlm::rvsdg;
378
379 // Arrange
380 Graph graph;
381 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
382 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
383
384 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, -7 });
385 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
386
387 auto & smod0 = CreateOpNode<bitsmod_op>({ s0, s1 }, 32);
388 auto & smod1 = CreateOpNode<bitsmod_op>({ c0, c1 }, 32);
389
390 auto & ex0 = GraphExport::Create(*smod0.output(0), "dummy");
391 auto & ex1 = GraphExport::Create(*smod1.output(0), "dummy");
392
393 view(&graph.GetRootRegion(), stdout);
394
395 // Act
396 ReduceNode<bitsmod_op>(BitBinaryOperation::foldConstants, smod0);
397 ReduceNode<bitsmod_op>(BitBinaryOperation::foldConstants, smod1);
398 graph.PruneNodes();
399
400 view(&graph.GetRootRegion(), stdout);
401
402 // Assert
403 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsmod_op(32));
404 EXPECT_EQ(
405 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
406 BitConstantOperation({ 32, -1 }));
407}
408
409TEST(bitstring, arithmetic_test_bitsquotient)
410{
411 using namespace jlm::rvsdg;
412
413 // Arrange
414 Graph graph;
415 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
416 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
417
418 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 7 });
419 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, -3 });
420
421 auto & squot0 = CreateOpNode<bitsdiv_op>({ s0, s1 }, 32);
422 auto & squot1 = CreateOpNode<bitsdiv_op>({ c0, c1 }, 32);
423
424 auto & ex0 = GraphExport::Create(*squot0.output(0), "dummy");
425 auto & ex1 = GraphExport::Create(*squot1.output(0), "dummy");
426
427 view(&graph.GetRootRegion(), stdout);
428
429 // Act
430 ReduceNode<bitsdiv_op>(BitBinaryOperation::foldConstants, squot0);
431 ReduceNode<bitsdiv_op>(BitBinaryOperation::foldConstants, squot1);
432 graph.PruneNodes();
433
434 view(&graph.GetRootRegion(), stdout);
435
436 // Assert
437 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsdiv_op(32));
438 EXPECT_EQ(
439 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
440 BitConstantOperation({ 32, -2 }));
441}
442
443TEST(bitstring, arithmetic_test_bitsum)
444{
445 using namespace jlm::rvsdg;
446
447 // Arrange
448 Graph graph;
449 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
450 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
451
452 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
453 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
454
455 auto & sum0 = CreateOpNode<bitadd_op>({ s0, s1 }, 32);
456 auto & sum1 = CreateOpNode<bitadd_op>({ c0, c1 }, 32);
457
458 auto & ex0 = GraphExport::Create(*sum0.output(0), "dummy");
459 auto & ex1 = GraphExport::Create(*sum1.output(0), "dummy");
460
461 view(&graph.GetRootRegion(), stdout);
462
463 // Act
464 ReduceNode<bitadd_op>(BitBinaryOperation::foldConstants, sum0);
465 ReduceNode<bitadd_op>(BitBinaryOperation::foldConstants, sum1);
466 graph.PruneNodes();
467
468 view(&graph.GetRootRegion(), stdout);
469
470 // Assert
471 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitadd_op(32));
472 EXPECT_EQ(
473 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
474 BitConstantOperation({ 32, 8 }));
475}
476
477TEST(bitstring, arithmetic_test_bituhiproduct)
478{
479 using namespace jlm::rvsdg;
480
481 // Arrange
482 Graph graph;
483 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
484 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
485
486 auto & uhiproduct = CreateOpNode<bitumulh_op>({ s0, s1 }, 32);
487
488 auto & ex0 = GraphExport::Create(*uhiproduct.output(0), "dummy");
489
490 view(&graph.GetRootRegion(), stdout);
491
492 // Act
493 ReduceNode<bitumulh_op>(NormalizeBinaryOperation, uhiproduct);
494 graph.PruneNodes();
495
496 view(&graph.GetRootRegion(), stdout);
497
498 // Assert
499 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitumulh_op(32));
500}
501
502TEST(bitstring, arithmetic_test_bitumod)
503{
504 using namespace jlm::rvsdg;
505
506 // Arrange
507 Graph graph;
508 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
509 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
510
511 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 7 });
512 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
513
514 auto & umod0 = CreateOpNode<bitumod_op>({ s0, s1 }, 32);
515 auto & umod1 = CreateOpNode<bitumod_op>({ c0, c1 }, 32);
516
517 auto & ex0 = GraphExport::Create(*umod0.output(0), "dummy");
518 auto & ex1 = GraphExport::Create(*umod1.output(0), "dummy");
519
520 view(&graph.GetRootRegion(), stdout);
521
522 // Act
523 ReduceNode<bitumod_op>(BitBinaryOperation::foldConstants, umod0);
524 ReduceNode<bitumod_op>(BitBinaryOperation::foldConstants, umod1);
525 graph.PruneNodes();
526
527 view(&graph.GetRootRegion(), stdout);
528
529 // Assert
530 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitumod_op(32));
531 EXPECT_EQ(
532 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
533 BitConstantOperation({ 32, 1 }));
534}
535
536TEST(bitstring, arithmetic_test_bituquotient)
537{
538 using namespace jlm::rvsdg;
539
540 // Arrange
541 Graph graph;
542 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
543 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
544
545 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 7 });
546 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
547
548 auto & uquot0 = CreateOpNode<bitudiv_op>({ s0, s1 }, 32);
549 auto & uquot1 = CreateOpNode<bitudiv_op>({ c0, c1 }, 32);
550
551 auto & ex0 = GraphExport::Create(*uquot0.output(0), "dummy");
552 auto & ex1 = GraphExport::Create(*uquot1.output(0), "dummy");
553
554 view(&graph.GetRootRegion(), stdout);
555
556 // Act
557 ReduceNode<bitudiv_op>(BitBinaryOperation::foldConstants, uquot0);
558 ReduceNode<bitudiv_op>(BitBinaryOperation::foldConstants, uquot1);
559 graph.PruneNodes();
560
561 view(&graph.GetRootRegion(), stdout);
562
563 // Assert
564 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitudiv_op(32));
565 EXPECT_EQ(
566 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
567 BitConstantOperation({ 32, 2 }));
568}
569
570TEST(bitstring, arithmetic_test_bitxor)
571{
572 using namespace jlm::rvsdg;
573
574 // Arrange
575 Graph graph;
576 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
577 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
578
579 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
580 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
581
582 auto & xor0 = CreateOpNode<bitxor_op>({ s0, s1 }, 32);
583 auto & xor1 = CreateOpNode<bitxor_op>({ c0, c1 }, 32);
584
585 auto & ex0 = GraphExport::Create(*xor0.output(0), "dummy");
586 auto & ex1 = GraphExport::Create(*xor1.output(0), "dummy");
587
588 view(&graph.GetRootRegion(), stdout);
589
590 // Act
591 ReduceNode<bitxor_op>(BitBinaryOperation::foldConstants, xor0);
592 ReduceNode<bitxor_op>(BitBinaryOperation::foldConstants, xor1);
593 graph.PruneNodes();
594
595 view(&graph.GetRootRegion(), stdout);
596
597 // Arrange
598 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitxor_op(32));
599 EXPECT_EQ(
600 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
601 BitConstantOperation({ 32, 6 }));
602}
603
604static inline void
606{
608 auto op = dynamic_cast<const jlm::rvsdg::BitConstantOperation *>(&node->GetOperation());
609 ASSERT_TRUE(op);
610 EXPECT_EQ(op->value().nbits(), 1u);
611 EXPECT_EQ(op->value().str(), "1");
612}
613
614static inline void
616{
618 auto op = dynamic_cast<const jlm::rvsdg::BitConstantOperation *>(&node->GetOperation());
619 ASSERT_TRUE(op);
620 EXPECT_EQ(op->value().nbits(), 1u);
621 EXPECT_EQ(op->value().str(), "0");
622}
623
624TEST(bitstring, comparison_test_bitequal)
625{
626 using namespace jlm::rvsdg;
627
628 // Arrange
629 Graph graph;
630 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
631 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
632 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
633 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
634 auto c2 = &BitConstantOperation::createUndefined(graph.GetRootRegion(), 32);
635
636 auto & equal0 = CreateOpNode<biteq_op>({ s0, s1 }, 32);
637 auto & equal1 = CreateOpNode<biteq_op>({ c0, c0 }, 32);
638 auto & equal2 = CreateOpNode<biteq_op>({ c0, c1 }, 32);
639 auto & equal3 = CreateOpNode<biteq_op>({ c0, c2 }, 32);
640
641 auto & ex0 = GraphExport::Create(*equal0.output(0), "dummy");
642 auto & ex1 = GraphExport::Create(*equal1.output(0), "dummy");
643 auto & ex2 = GraphExport::Create(*equal2.output(0), "dummy");
644 auto & ex3 = GraphExport::Create(*equal3.output(0), "dummy");
645
646 view(&graph.GetRootRegion(), stdout);
647
648 // Act
649 ReduceNode<biteq_op>(BitCompareOperation::foldConstants, equal0);
650 ReduceNode<biteq_op>(BitCompareOperation::foldConstants, equal1);
651 ReduceNode<biteq_op>(BitCompareOperation::foldConstants, equal2);
652 ReduceNode<biteq_op>(BitCompareOperation::foldConstants, equal3);
653 graph.PruneNodes();
654
655 view(&graph.GetRootRegion(), stdout);
656
657 // Assert
658 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), biteq_op(32));
659 expect_static_true(ex1.origin());
660 expect_static_false(ex2.origin());
661 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex3.origin())->GetOperation(), biteq_op(32));
662}
663
664TEST(bitstring, comparison_test_bitnotequal)
665{
666 using namespace jlm::rvsdg;
667
668 // Arrange
669 Graph graph;
670 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
671 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
672 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
673 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
674 auto c2 = &BitConstantOperation::createUndefined(graph.GetRootRegion(), 32);
675
676 auto & nequal0 = CreateOpNode<bitne_op>({ s0, s1 }, 32);
677 auto & nequal1 = CreateOpNode<bitne_op>({ c0, c0 }, 32);
678 auto & nequal2 = CreateOpNode<bitne_op>({ c0, c1 }, 32);
679 auto & nequal3 = CreateOpNode<bitne_op>({ c0, c2 }, 32);
680
681 auto & ex0 = GraphExport::Create(*nequal0.output(0), "dummy");
682 auto & ex1 = GraphExport::Create(*nequal1.output(0), "dummy");
683 auto & ex2 = GraphExport::Create(*nequal2.output(0), "dummy");
684 auto & ex3 = GraphExport::Create(*nequal3.output(0), "dummy");
685
686 view(&graph.GetRootRegion(), stdout);
687
688 // Act
689 ReduceNode<bitne_op>(BitCompareOperation::foldConstants, nequal0);
690 ReduceNode<bitne_op>(BitCompareOperation::foldConstants, nequal1);
691 ReduceNode<bitne_op>(BitCompareOperation::foldConstants, nequal2);
692 ReduceNode<bitne_op>(BitCompareOperation::foldConstants, nequal3);
693 graph.PruneNodes();
694
695 view(&graph.GetRootRegion(), stdout);
696
697 // Assert
698 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitne_op(32));
699 expect_static_false(ex1.origin());
700 expect_static_true(ex2.origin());
701 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex3.origin())->GetOperation(), bitne_op(32));
702}
703
704TEST(bitstring, comparison_test_bitsgreater)
705{
706 using namespace jlm::rvsdg;
707
708 // Arrange
709 Graph graph;
710 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
711 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
712
713 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
714 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
715 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0x7fffffffL });
716 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (-0x7fffffffL - 1) });
717
718 auto & sgreater0 = CreateOpNode<bitsgt_op>({ s0, s1 }, 32);
719 auto & sgreater1 = CreateOpNode<bitsgt_op>({ c0, c1 }, 32);
720 auto & sgreater2 = CreateOpNode<bitsgt_op>({ c1, c0 }, 32);
721 auto & sgreater3 = CreateOpNode<bitsgt_op>({ s0, c2 }, 32);
722 auto & sgreater4 = CreateOpNode<bitsgt_op>({ c3, s1 }, 32);
723
724 auto & ex0 = GraphExport::Create(*sgreater0.output(0), "dummy");
725 auto & ex1 = GraphExport::Create(*sgreater1.output(0), "dummy");
726 auto & ex2 = GraphExport::Create(*sgreater2.output(0), "dummy");
727 auto & ex3 = GraphExport::Create(*sgreater3.output(0), "dummy");
728 auto & ex4 = GraphExport::Create(*sgreater4.output(0), "dummy");
729
730 view(&graph.GetRootRegion(), stdout);
731
732 // Act
733 ReduceNode<bitsgt_op>(BitCompareOperation::foldConstants, sgreater0);
734 ReduceNode<bitsgt_op>(BitCompareOperation::foldConstants, sgreater1);
735 ReduceNode<bitsgt_op>(BitCompareOperation::foldConstants, sgreater2);
736 ReduceNode<bitsgt_op>(BitCompareOperation::foldConstants, sgreater3);
737 ReduceNode<bitsgt_op>(BitCompareOperation::foldConstants, sgreater4);
738 graph.PruneNodes();
739
740 view(&graph.GetRootRegion(), stdout);
741
742 // Assert
743 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsgt_op(32));
744 expect_static_false(ex1.origin());
745 expect_static_true(ex2.origin());
746 expect_static_false(ex3.origin());
747 expect_static_false(ex4.origin());
748}
749
750TEST(bitstring, comparison_test_bitsgreatereq)
751{
752 using namespace jlm::rvsdg;
753
754 // Arrange
755 Graph graph;
756 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
757 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
758 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
759 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
760 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0x7fffffffL });
761 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (-0x7fffffffL - 1) });
762
763 auto & sgreatereq0 = CreateOpNode<bitsge_op>({ s0, s1 }, 32);
764 auto & sgreatereq1 = CreateOpNode<bitsge_op>({ c0, c1 }, 32);
765 auto & sgreatereq2 = CreateOpNode<bitsge_op>({ c1, c0 }, 32);
766 auto & sgreatereq3 = CreateOpNode<bitsge_op>({ c0, c0 }, 32);
767 auto & sgreatereq4 = CreateOpNode<bitsge_op>({ c2, s0 }, 32);
768 auto & sgreatereq5 = CreateOpNode<bitsge_op>({ s1, c3 }, 32);
769
770 auto & ex0 = GraphExport::Create(*sgreatereq0.output(0), "dummy");
771 auto & ex1 = GraphExport::Create(*sgreatereq1.output(0), "dummy");
772 auto & ex2 = GraphExport::Create(*sgreatereq2.output(0), "dummy");
773 auto & ex3 = GraphExport::Create(*sgreatereq3.output(0), "dummy");
774 auto & ex4 = GraphExport::Create(*sgreatereq4.output(0), "dummy");
775 auto & ex5 = GraphExport::Create(*sgreatereq5.output(0), "dummy");
776
777 view(&graph.GetRootRegion(), stdout);
778
779 // Act
780 ReduceNode<bitsge_op>(BitCompareOperation::foldConstants, sgreatereq0);
781 ReduceNode<bitsge_op>(BitCompareOperation::foldConstants, sgreatereq1);
782 ReduceNode<bitsge_op>(BitCompareOperation::foldConstants, sgreatereq2);
783 ReduceNode<bitsge_op>(BitCompareOperation::foldConstants, sgreatereq3);
784 ReduceNode<bitsge_op>(BitCompareOperation::foldConstants, sgreatereq4);
785 ReduceNode<bitsge_op>(BitCompareOperation::foldConstants, sgreatereq5);
786 graph.PruneNodes();
787
788 view(&graph.GetRootRegion(), stdout);
789
790 // Arrange
791 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsge_op(32));
792 expect_static_false(ex1.origin());
793 expect_static_true(ex2.origin());
794 expect_static_true(ex3.origin());
795 expect_static_true(ex4.origin());
796 expect_static_true(ex5.origin());
797}
798
799TEST(bitstring, comparison_test_bitsless)
800{
801 using namespace jlm::rvsdg;
802
803 // Arrange
804 Graph graph;
805 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
806 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
807
808 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
809 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
810 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0x7fffffffL });
811 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (-0x7fffffffL - 1) });
812
813 auto & sless0 = CreateOpNode<bitslt_op>({ s0, s1 }, 32);
814 auto & sless1 = CreateOpNode<bitslt_op>({ c0, c1 }, 32);
815 auto & sless2 = CreateOpNode<bitslt_op>({ c1, c0 }, 32);
816 auto & sless3 = CreateOpNode<bitslt_op>({ c2, s0 }, 32);
817 auto & sless4 = CreateOpNode<bitslt_op>({ s1, c3 }, 32);
818
819 auto & ex0 = GraphExport::Create(*sless0.output(0), "dummy");
820 auto & ex1 = GraphExport::Create(*sless1.output(0), "dummy");
821 auto & ex2 = GraphExport::Create(*sless2.output(0), "dummy");
822 auto & ex3 = GraphExport::Create(*sless3.output(0), "dummy");
823 auto & ex4 = GraphExport::Create(*sless4.output(0), "dummy");
824
825 view(&graph.GetRootRegion(), stdout);
826
827 // Act
828 ReduceNode<bitslt_op>(BitCompareOperation::foldConstants, sless0);
829 ReduceNode<bitslt_op>(BitCompareOperation::foldConstants, sless1);
830 ReduceNode<bitslt_op>(BitCompareOperation::foldConstants, sless2);
831 ReduceNode<bitslt_op>(BitCompareOperation::foldConstants, sless3);
832 ReduceNode<bitslt_op>(BitCompareOperation::foldConstants, sless4);
833 graph.PruneNodes();
834
835 view(&graph.GetRootRegion(), stdout);
836
837 // Arrange
838 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitslt_op(32));
839 expect_static_true(ex1.origin());
840 expect_static_false(ex2.origin());
841 expect_static_false(ex3.origin());
842 expect_static_false(ex4.origin());
843}
844
845TEST(bitstring, comparison_test_bitslesseq)
846{
847 using namespace jlm::rvsdg;
848
849 // Arrange
850 Graph graph;
851 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
852 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
853
854 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
855 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
856 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0x7fffffffL });
857 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (-0x7fffffffL - 1) });
858
859 auto & slesseq0 = CreateOpNode<bitsle_op>({ s0, s1 }, 32);
860 auto & slesseq1 = CreateOpNode<bitsle_op>({ c0, c1 }, 32);
861 auto & slesseq2 = CreateOpNode<bitsle_op>({ c0, c0 }, 32);
862 auto & slesseq3 = CreateOpNode<bitsle_op>({ c1, c0 }, 32);
863 auto & slesseq4 = CreateOpNode<bitsle_op>({ s0, c2 }, 32);
864 auto & slesseq5 = CreateOpNode<bitsle_op>({ c3, s1 }, 32);
865
866 auto & ex0 = GraphExport::Create(*slesseq0.output(0), "dummy");
867 auto & ex1 = GraphExport::Create(*slesseq1.output(0), "dummy");
868 auto & ex2 = GraphExport::Create(*slesseq2.output(0), "dummy");
869 auto & ex3 = GraphExport::Create(*slesseq3.output(0), "dummy");
870 auto & ex4 = GraphExport::Create(*slesseq4.output(0), "dummy");
871 auto & ex5 = GraphExport::Create(*slesseq5.output(0), "dummy");
872
873 view(&graph.GetRootRegion(), stdout);
874
875 // Act
876 ReduceNode<bitsle_op>(BitCompareOperation::foldConstants, slesseq0);
877 ReduceNode<bitsle_op>(BitCompareOperation::foldConstants, slesseq1);
878 ReduceNode<bitsle_op>(BitCompareOperation::foldConstants, slesseq2);
879 ReduceNode<bitsle_op>(BitCompareOperation::foldConstants, slesseq3);
880 ReduceNode<bitsle_op>(BitCompareOperation::foldConstants, slesseq4);
881 ReduceNode<bitsle_op>(BitCompareOperation::foldConstants, slesseq5);
882 graph.PruneNodes();
883
884 view(&graph.GetRootRegion(), stdout);
885
886 // Assert
887 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitsle_op(32));
888 expect_static_true(ex1.origin());
889 expect_static_true(ex2.origin());
890 expect_static_false(ex3.origin());
891 expect_static_true(ex4.origin());
892 expect_static_true(ex5.origin());
893}
894
895TEST(bitstring, comparison_test_bitugreater)
896{
897 using namespace jlm::rvsdg;
898
899 Graph graph;
900 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
901 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
902
903 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
904 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
905 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (0xffffffffUL) });
906 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0 });
907
908 auto & ugreater0 = CreateOpNode<bitugt_op>({ s0, s1 }, 32);
909 auto & ugreater1 = CreateOpNode<bitugt_op>({ c0, c1 }, 32);
910 auto & ugreater2 = CreateOpNode<bitugt_op>({ c1, c0 }, 32);
911 auto & ugreater3 = CreateOpNode<bitugt_op>({ s0, c2 }, 32);
912 auto & ugreater4 = CreateOpNode<bitugt_op>({ c3, s1 }, 32);
913
914 auto & ex0 = GraphExport::Create(*ugreater0.output(0), "dummy");
915 auto & ex1 = GraphExport::Create(*ugreater1.output(0), "dummy");
916 auto & ex2 = GraphExport::Create(*ugreater2.output(0), "dummy");
917 auto & ex3 = GraphExport::Create(*ugreater3.output(0), "dummy");
918 auto & ex4 = GraphExport::Create(*ugreater4.output(0), "dummy");
919
920 view(&graph.GetRootRegion(), stdout);
921
922 // Assert
923 ReduceNode<bitugt_op>(BitCompareOperation::foldConstants, ugreater0);
924 ReduceNode<bitugt_op>(BitCompareOperation::foldConstants, ugreater1);
925 ReduceNode<bitugt_op>(BitCompareOperation::foldConstants, ugreater2);
926 ReduceNode<bitugt_op>(BitCompareOperation::foldConstants, ugreater3);
927 ReduceNode<bitugt_op>(BitCompareOperation::foldConstants, ugreater4);
928 graph.PruneNodes();
929
930 view(&graph.GetRootRegion(), stdout);
931
932 // Assert
933 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitugt_op(32));
934 expect_static_false(ex1.origin());
935 expect_static_true(ex2.origin());
936 expect_static_false(ex3.origin());
937 expect_static_false(ex4.origin());
938}
939
940TEST(bitstring, comparison_test_bitugreatereq)
941{
942 using namespace jlm::rvsdg;
943
944 Graph graph;
945 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
946 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
947
948 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
949 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
950 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (0xffffffffUL) });
951 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0 });
952
953 auto & ugreatereq0 = CreateOpNode<bituge_op>({ s0, s1 }, 32);
954 auto & ugreatereq1 = CreateOpNode<bituge_op>({ c0, c1 }, 32);
955 auto & ugreatereq2 = CreateOpNode<bituge_op>({ c1, c0 }, 32);
956 auto & ugreatereq3 = CreateOpNode<bituge_op>({ c0, c0 }, 32);
957 auto & ugreatereq4 = CreateOpNode<bituge_op>({ c2, s0 }, 32);
958 auto & ugreatereq5 = CreateOpNode<bituge_op>({ s1, c3 }, 32);
959
960 auto & ex0 = GraphExport::Create(*ugreatereq0.output(0), "dummy");
961 auto & ex1 = GraphExport::Create(*ugreatereq1.output(0), "dummy");
962 auto & ex2 = GraphExport::Create(*ugreatereq2.output(0), "dummy");
963 auto & ex3 = GraphExport::Create(*ugreatereq3.output(0), "dummy");
964 auto & ex4 = GraphExport::Create(*ugreatereq4.output(0), "dummy");
965 auto & ex5 = GraphExport::Create(*ugreatereq5.output(0), "dummy");
966
967 view(&graph.GetRootRegion(), stdout);
968
969 // Act
970 ReduceNode<bituge_op>(BitCompareOperation::foldConstants, ugreatereq0);
971 ReduceNode<bituge_op>(BitCompareOperation::foldConstants, ugreatereq1);
972 ReduceNode<bituge_op>(BitCompareOperation::foldConstants, ugreatereq2);
973 ReduceNode<bituge_op>(BitCompareOperation::foldConstants, ugreatereq3);
974 ReduceNode<bituge_op>(BitCompareOperation::foldConstants, ugreatereq4);
975 ReduceNode<bituge_op>(BitCompareOperation::foldConstants, ugreatereq5);
976 graph.PruneNodes();
977
978 view(&graph.GetRootRegion(), stdout);
979
980 // Assert
981 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bituge_op(32));
982 expect_static_false(ex1.origin());
983 expect_static_true(ex2.origin());
984 expect_static_true(ex3.origin());
985 expect_static_true(ex4.origin());
986 expect_static_true(ex5.origin());
987}
988
989TEST(bitstring, bitstring_comparison_test_bituless)
990{
991 using namespace jlm::rvsdg;
992
993 // Arrange
994 Graph graph;
995 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
996 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
997
998 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
999 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
1000 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (0xffffffffUL) });
1001 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0 });
1002
1003 auto & uless0 = CreateOpNode<bitult_op>({ s0, s1 }, 32);
1004 auto & uless1 = CreateOpNode<bitult_op>({ c0, c1 }, 32);
1005 auto & uless2 = CreateOpNode<bitult_op>({ c1, c0 }, 32);
1006 auto & uless3 = CreateOpNode<bitult_op>({ c2, s0 }, 32);
1007 auto & uless4 = CreateOpNode<bitult_op>({ s1, c3 }, 32);
1008
1009 auto & ex0 = GraphExport::Create(*uless0.output(0), "dummy");
1010 auto & ex1 = GraphExport::Create(*uless1.output(0), "dummy");
1011 auto & ex2 = GraphExport::Create(*uless2.output(0), "dummy");
1012 auto & ex3 = GraphExport::Create(*uless3.output(0), "dummy");
1013 auto & ex4 = GraphExport::Create(*uless4.output(0), "dummy");
1014
1015 view(&graph.GetRootRegion(), stdout);
1016
1017 // Act
1018 ReduceNode<bitult_op>(BitCompareOperation::foldConstants, uless0);
1019 ReduceNode<bitult_op>(BitCompareOperation::foldConstants, uless1);
1020 ReduceNode<bitult_op>(BitCompareOperation::foldConstants, uless2);
1021 ReduceNode<bitult_op>(BitCompareOperation::foldConstants, uless3);
1022 ReduceNode<bitult_op>(BitCompareOperation::foldConstants, uless4);
1023 graph.PruneNodes();
1024
1025 view(&graph.GetRootRegion(), stdout);
1026
1027 // Assert
1028 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitult_op(32));
1029 expect_static_true(ex1.origin());
1030 expect_static_false(ex2.origin());
1031 expect_static_false(ex3.origin());
1032 expect_static_false(ex4.origin());
1033}
1034
1035TEST(bitstring, bitstring_comparison_test_bitulesseq)
1036{
1037 using namespace jlm::rvsdg;
1038
1039 // Arrange
1040 Graph graph;
1041 auto s0 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s0");
1042 auto s1 = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "s1");
1043
1044 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
1045 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 5 });
1046 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, (0xffffffffUL) });
1047 auto c3 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 0 });
1048
1049 auto & ulesseq0 = CreateOpNode<bitule_op>({ s0, s1 }, 32);
1050 auto & ulesseq1 = CreateOpNode<bitule_op>({ c0, c1 }, 32);
1051 auto & ulesseq2 = CreateOpNode<bitule_op>({ c0, c0 }, 32);
1052 auto & ulesseq3 = CreateOpNode<bitule_op>({ c1, c0 }, 32);
1053 auto & ulesseq4 = CreateOpNode<bitule_op>({ s0, c2 }, 32);
1054 auto & ulesseq5 = CreateOpNode<bitule_op>({ c3, s1 }, 32);
1055
1056 auto & ex0 = GraphExport::Create(*ulesseq0.output(0), "dummy");
1057 auto & ex1 = GraphExport::Create(*ulesseq1.output(0), "dummy");
1058 auto & ex2 = GraphExport::Create(*ulesseq2.output(0), "dummy");
1059 auto & ex3 = GraphExport::Create(*ulesseq3.output(0), "dummy");
1060 auto & ex4 = GraphExport::Create(*ulesseq4.output(0), "dummy");
1061 auto & ex5 = GraphExport::Create(*ulesseq5.output(0), "dummy");
1062
1063 view(&graph.GetRootRegion(), stdout);
1064
1065 // Act
1066 ReduceNode<bitule_op>(BitCompareOperation::foldConstants, ulesseq0);
1067 ReduceNode<bitule_op>(BitCompareOperation::foldConstants, ulesseq1);
1068 ReduceNode<bitule_op>(BitCompareOperation::foldConstants, ulesseq2);
1069 ReduceNode<bitule_op>(BitCompareOperation::foldConstants, ulesseq3);
1070 ReduceNode<bitule_op>(BitCompareOperation::foldConstants, ulesseq4);
1071 ReduceNode<bitule_op>(BitCompareOperation::foldConstants, ulesseq5);
1072 graph.PruneNodes();
1073
1074 view(&graph.GetRootRegion(), stdout);
1075
1076 // Assert
1077 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(), bitule_op(32));
1078 expect_static_true(ex1.origin());
1079 expect_static_true(ex2.origin());
1080 expect_static_false(ex3.origin());
1081 expect_static_true(ex4.origin());
1082 expect_static_true(ex5.origin());
1083}
1084
1085#define ZERO_64 \
1086 "00000000" \
1087 "00000000" \
1088 "00000000" \
1089 "00000000" \
1090 "00000000" \
1091 "00000000" \
1092 "00000000" \
1093 "00000000"
1094#define ONE_64 \
1095 "10000000" \
1096 "00000000" \
1097 "00000000" \
1098 "00000000" \
1099 "00000000" \
1100 "00000000" \
1101 "00000000" \
1102 "00000000"
1103#define MONE_64 \
1104 "11111111" \
1105 "11111111" \
1106 "11111111" \
1107 "11111111" \
1108 "11111111" \
1109 "11111111" \
1110 "11111111" \
1111 "11111111"
1112
1113TEST(bitstring, bitstring_test_constant)
1114{
1115 using namespace jlm::rvsdg;
1116
1117 // Arrange
1118 Graph graph;
1119
1120 auto NormalizeCne =
1121 [&](const SimpleOperation & operation, const std::vector<jlm::rvsdg::Output *> & operands)
1122 {
1123 return NormalizeSimpleOperationCommonNodeElimination(
1124 graph.GetRootRegion(),
1125 operation,
1126 operands);
1127 };
1128
1129 auto & b1 = CreateOpNode<BitConstantOperation>(graph.GetRootRegion(), "00110011");
1130 auto & b2 =
1131 *TryGetOwnerNode<Node>(BitConstantOperation::create(graph.GetRootRegion(), { 8, 204 }));
1132 auto & b3 =
1133 *TryGetOwnerNode<Node>(BitConstantOperation::create(graph.GetRootRegion(), { 8, 204 }));
1134 auto & b4 = CreateOpNode<BitConstantOperation>(graph.GetRootRegion(), "001100110");
1135
1136 auto & ex1 = GraphExport::Create(*b1.output(0), "b1");
1137 auto & ex2 = GraphExport::Create(*b2.output(0), "b2");
1138 auto & ex3 = GraphExport::Create(*b3.output(0), "b3");
1139 auto & ex4 = GraphExport::Create(*b4.output(0), "b4");
1140
1141 view(graph, stdout);
1142
1143 // Act & Assert
1144 EXPECT_EQ(b1.GetOperation(), BitConstantOperation({ 8, 204 }));
1145 EXPECT_EQ(b1.GetOperation(), BitConstantOperation({ 8, -52 }));
1146
1147 ReduceNode<BitConstantOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex1.origin()));
1148 ReduceNode<BitConstantOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex2.origin()));
1149 ReduceNode<BitConstantOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex3.origin()));
1150 ReduceNode<BitConstantOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex4.origin()));
1151
1152 EXPECT_EQ(ex1.origin(), ex2.origin());
1153 EXPECT_EQ(ex1.origin(), ex3.origin());
1154
1155 const auto node1 = TryGetOwnerNode<SimpleNode>(*ex1.origin());
1156 EXPECT_EQ(node1->GetOperation(), BitConstantOperation({ 8, 204 }));
1157 EXPECT_EQ(node1->GetOperation(), BitConstantOperation({ 8, -52 }));
1158
1159 const auto node4 = TryGetOwnerNode<SimpleNode>(*ex4.origin());
1160 EXPECT_EQ(node4->GetOperation(), BitConstantOperation({ 9, 204 }));
1161 EXPECT_EQ(node4->GetOperation(), BitConstantOperation({ 9, 204 }));
1162
1163 const auto & plus_one_128 =
1164 CreateOpNode<BitConstantOperation>(graph.GetRootRegion(), ONE_64 ZERO_64);
1165 EXPECT_EQ(plus_one_128.GetOperation(), BitConstantOperation({ 128, 1 }));
1166 EXPECT_EQ(plus_one_128.GetOperation(), BitConstantOperation({ 128, 1 }));
1167
1168 const auto & minus_one_128 =
1169 CreateOpNode<BitConstantOperation>(graph.GetRootRegion(), MONE_64 MONE_64);
1170 EXPECT_EQ(minus_one_128.GetOperation(), BitConstantOperation({ 128, -1 }));
1171
1172 view(&graph.GetRootRegion(), stdout);
1173}
1174
1175TEST(bitstring, bitstring_test_normalize)
1176{
1177 using namespace jlm::rvsdg;
1178
1179 // Arrange
1180 Graph graph;
1181
1182 BitType bits32(32);
1183 auto imp = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(32), "imp");
1184
1185 auto c0 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 3 });
1186 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), { 32, 4 });
1187
1188 auto & sum0 = CreateOpNode<bitadd_op>({ imp, c0 }, 32);
1189 auto & sum1 = CreateOpNode<bitadd_op>({ sum0.output(0), c1 }, 32);
1190
1191 auto & ex = GraphExport::Create(*sum1.output(0), "dummy");
1192
1193 view(&graph.GetRootRegion(), stdout);
1194
1195 // Act
1196 ReduceNode<bitadd_op>(FlattenAssociativeBinaryOperation, sum1);
1197 auto & flattenedBinaryNode = *TryGetOwnerNode<SimpleNode>(*ex.origin());
1198 ReduceNode<FlattenedBinaryOperation>(NormalizeFlattenedBinaryOperation, flattenedBinaryNode);
1199 graph.PruneNodes();
1200
1201 view(&graph.GetRootRegion(), stdout);
1202
1203 // Assert
1204 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1205 EXPECT_EQ(node->GetOperation(), bitadd_op(32));
1206 EXPECT_EQ(node->ninputs(), 2u);
1207 auto op1 = node->input(0)->origin();
1208 auto op2 = node->input(1)->origin();
1209 if (!is<NodeOutput>(op1))
1210 {
1211 auto tmp = op1;
1212 op1 = op2;
1213 op2 = tmp;
1214 }
1215 /* FIXME: the graph traversers are currently broken, that is why it won't normalize */
1216 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*op1)->GetOperation(), BitConstantOperation({ 32, 3 + 4 }));
1217 EXPECT_EQ(op2, imp);
1218
1219 view(&graph.GetRootRegion(), stdout);
1220}
1221
1222static void
1223assert_constant(jlm::rvsdg::Output * bitstr, size_t nbits, const char bits[])
1224{
1226 auto op = dynamic_cast<const jlm::rvsdg::BitConstantOperation &>(node->GetOperation());
1227 EXPECT_EQ(op.value(), jlm::rvsdg::BitValueRepresentation(std::string(bits, nbits).c_str()));
1228}
1229
1230TEST(bitstring, test_reduction)
1231{
1232 using namespace jlm::rvsdg;
1233
1234 // Arrange
1235 Graph graph;
1236 auto bit4Type = BitType::Create(4);
1237 std::vector types({ bit4Type, bit4Type });
1238
1239 auto a = &BitConstantOperation::create(graph.GetRootRegion(), BitValueRepresentation("1100"));
1240 auto b = &BitConstantOperation::create(graph.GetRootRegion(), BitValueRepresentation("1010"));
1241
1242 auto & bitAndNode = CreateOpNode<bitand_op>({ a, b }, 4);
1243 auto & bitOrNode = CreateOpNode<bitor_op>({ a, b }, 4);
1244 auto & bitXorNode = CreateOpNode<bitxor_op>({ a, b }, 4);
1245 auto & bitAddNode = CreateOpNode<bitadd_op>({ a, b }, 4);
1246 auto & bitMulNode = CreateOpNode<bitmul_op>({ a, b }, 4);
1247 auto & bitConcatNode = CreateOpNode<BitConcatOperation>({ a, b }, types);
1248 auto & bitNegNode1 = CreateOpNode<bitneg_op>({ a }, 4);
1249 auto & bitNegNode2 = CreateOpNode<bitneg_op>({ b }, 4);
1250
1251 auto & exBitAnd = GraphExport::Create(*bitAndNode.output(0), "bitAnd");
1252 auto & exBitOr = GraphExport::Create(*bitOrNode.output(0), "bitOr");
1253 auto & exBitXor = GraphExport::Create(*bitXorNode.output(0), "bitXor");
1254 auto & exBitAdd = GraphExport::Create(*bitAddNode.output(0), "bitAdd");
1255 auto & exBitMul = GraphExport::Create(*bitMulNode.output(0), "bitMul");
1256 auto & exBitConcat = GraphExport::Create(*bitConcatNode.output(0), "bitConcat");
1257 auto & exBitNeg1 = GraphExport::Create(*bitNegNode1.output(0), "bitNeg1");
1258 auto & exBitNeg2 = GraphExport::Create(*bitNegNode2.output(0), "bitNeg2");
1259
1260 view(&graph.GetRootRegion(), stdout);
1261
1262 // Act
1263 ReduceNode<bitand_op>(BitBinaryOperation::foldConstants, bitAndNode);
1264 ReduceNode<bitor_op>(BitBinaryOperation::foldConstants, bitOrNode);
1265 ReduceNode<bitxor_op>(BitBinaryOperation::foldConstants, bitXorNode);
1266 ReduceNode<bitadd_op>(BitBinaryOperation::foldConstants, bitAddNode);
1267 ReduceNode<bitmul_op>(BitBinaryOperation::foldConstants, bitMulNode);
1268 ReduceNode<BitConcatOperation>(NormalizeBinaryOperation, bitConcatNode);
1269 ReduceNode<bitneg_op>(BitUnaryOperation::foldConstant, bitNegNode1);
1270 ReduceNode<bitneg_op>(BitUnaryOperation::foldConstant, bitNegNode2);
1271
1272 view(&graph.GetRootRegion(), stdout);
1273
1274 // Assert
1275 assert_constant(exBitAnd.origin(), 4, "1000");
1276 assert_constant(exBitOr.origin(), 4, "1110");
1277 assert_constant(exBitXor.origin(), 4, "0110");
1278 assert_constant(exBitAdd.origin(), 4, "0001");
1279 assert_constant(exBitMul.origin(), 4, "1111");
1280 assert_constant(exBitConcat.origin(), 8, "11001010");
1281 assert_constant(exBitNeg1.origin(), 4, "1011");
1282 assert_constant(exBitNeg2.origin(), 4, "1101");
1283}
1284
1285TEST(bitstring, SliceOfConcatReduction)
1286{
1287 using namespace jlm::rvsdg;
1288
1289 // Arrange
1290 Graph graph;
1291 auto bit16Type = BitType::Create(16);
1292 auto bit32Type = BitType::Create(32);
1293 std::vector types({ bit16Type, bit16Type });
1294
1295 auto x = &jlm::rvsdg::GraphImport::Create(graph, bit16Type, "x");
1296 auto y = &jlm::rvsdg::GraphImport::Create(graph, bit16Type, "y");
1297
1298 auto & concatNode = CreateOpNode<BitConcatOperation>({ x, y }, types);
1299 auto & sliceNode = CreateOpNode<BitSliceOperation>({ concatNode.output(0) }, bit32Type, 8, 24);
1300
1301 auto & ex = GraphExport::Create(*sliceNode.output(0), "bitAnd");
1302
1303 view(&graph.GetRootRegion(), stdout);
1304
1305 // Act
1306 ReduceNode<BitSliceOperation>(BitSliceOperation::distributeSlice, sliceNode);
1307 graph.PruneNodes();
1308
1309 view(&graph.GetRootRegion(), stdout);
1310
1311 // Assert
1312 const auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1313 const auto o0_node = TryGetOwnerNode<SimpleNode>(*node->input(0)->origin());
1314 const auto o1_node = TryGetOwnerNode<SimpleNode>(*node->input(1)->origin());
1315 EXPECT_TRUE(is<BitConcatOperation>(node->GetOperation()));
1316 EXPECT_EQ(node->ninputs(), 2u);
1317 EXPECT_TRUE(is<BitSliceOperation>(o0_node->GetOperation()));
1318 EXPECT_TRUE(is<BitSliceOperation>(o1_node->GetOperation()));
1319
1320 auto attrs = dynamic_cast<const BitSliceOperation *>(&o0_node->GetOperation());
1321 EXPECT_EQ(attrs->low(), 8u);
1322 EXPECT_EQ(attrs->high(), 16u);
1323 attrs = dynamic_cast<const BitSliceOperation *>(&o1_node->GetOperation());
1324 EXPECT_EQ(attrs->low(), 0u);
1325 EXPECT_EQ(attrs->high(), 8u);
1326
1327 EXPECT_EQ(o0_node->input(0)->origin(), x);
1328 EXPECT_EQ(o1_node->input(0)->origin(), y);
1329}
1330
1331TEST(bitstring, ConcatOfSliceReduction)
1332{
1333 using namespace jlm::rvsdg;
1334
1335 // Arrange
1336 Graph graph;
1337 auto bit8Type = BitType::Create(8);
1338 auto bit16Type = BitType::Create(16);
1339 std::vector types({ bit8Type, bit8Type });
1340
1341 auto x = &jlm::rvsdg::GraphImport::Create(graph, bit16Type, "x");
1342
1343 auto slice1 = bitslice(x, 0, 8);
1344 auto slice2 = bitslice(x, 8, 16);
1345 auto & concatNode = CreateOpNode<BitConcatOperation>({ slice1, slice2 }, types);
1346
1347 auto & ex = GraphExport::Create(*concatNode.output(0), "bitAnd");
1348
1349 view(&graph.GetRootRegion(), stdout);
1350
1351 // Act
1352 ReduceNode<BitConcatOperation>(NormalizeBinaryOperation, concatNode);
1353 graph.PruneNodes();
1354
1355 view(&graph.GetRootRegion(), stdout);
1356
1357 // Assert
1358 const auto sliceNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1359 EXPECT_EQ(sliceNode->GetOperation(), BitSliceOperation(bit16Type, 0, 16));
1360 EXPECT_EQ(sliceNode->input(0)->origin(), x);
1361}
1362
1363TEST(bitstring, SliceOfConstant)
1364{
1365 using namespace jlm::rvsdg;
1366
1367 // Arrange
1368 Graph graph;
1369 auto bit8Type = BitType::Create(8);
1370
1371 const auto constant =
1372 &BitConstantOperation::create(graph.GetRootRegion(), BitValueRepresentation("00110111"));
1373 auto & sliceNode = CreateOpNode<BitSliceOperation>({ constant }, bit8Type, 2, 6);
1374 auto & ex = GraphExport::Create(*sliceNode.output(0), "dummy");
1375
1376 view(graph, stdout);
1377
1378 // Act
1379 ReduceNode<BitSliceOperation>(BitSliceOperation::foldConstant, sliceNode);
1380 graph.PruneNodes();
1381
1382 view(graph, stdout);
1383
1384 // Assert
1385 const auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1386 auto & operation = dynamic_cast<const BitConstantOperation &>(node->GetOperation());
1387 EXPECT_EQ(operation.value(), BitValueRepresentation("1101"));
1388}
1389
1390TEST(bitstring, SliceOfSlice)
1391{
1392 using namespace jlm::rvsdg;
1393
1394 // Arrange
1395 Graph graph;
1396 auto bit4Type = BitType::Create(4);
1397
1398 auto x = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "x");
1399
1400 auto slice1 = bitslice(x, 2, 6);
1401 auto & sliceNode2 = CreateOpNode<BitSliceOperation>({ slice1 }, bit4Type, 1, 3);
1402
1403 auto & ex = GraphExport::Create(*sliceNode2.output(0), "dummy");
1404 view(graph, stdout);
1405
1406 // Act
1407 ReduceNode<BitSliceOperation>(BitSliceOperation::narrowSlice, sliceNode2);
1408 graph.PruneNodes();
1409
1410 view(graph, stdout);
1411
1412 // Assert
1413 const auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1414 const auto operation = dynamic_cast<const BitSliceOperation *>(&node->GetOperation());
1415 EXPECT_EQ(operation->low(), 3u);
1416 EXPECT_EQ(operation->high(), 5u);
1417}
1418
1419TEST(bitstring, SliceOfFullNode)
1420{
1421 using namespace jlm::rvsdg;
1422
1423 // Arrange
1424 Graph graph;
1425 auto bit8Type = BitType::Create(8);
1426
1427 const auto x = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "x");
1428
1429 auto & sliceNode = CreateOpNode<BitSliceOperation>({ x }, bit8Type, 0, 8);
1430
1431 auto & ex = GraphExport::Create(*sliceNode.output(0), "dummy");
1432 view(graph, stdout);
1433
1434 // Act
1435 ReduceNode<BitSliceOperation>(BitSliceOperation::normalizeIdempotent, sliceNode);
1436 graph.PruneNodes();
1437
1438 view(graph, stdout);
1439
1440 // Assert
1441 EXPECT_EQ(ex.origin(), x);
1442}
1443
1444TEST(bitstring, SliceOfConcat)
1445{
1446 using namespace jlm::rvsdg;
1447
1448 // Arrange
1449 Graph graph;
1450 auto bit16Type = BitType::Create(16);
1451
1452 auto x = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "x");
1453 auto y = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "y");
1454
1455 auto concatResult = bitconcat({ x, y });
1456 auto & sliceNode = CreateOpNode<BitSliceOperation>({ concatResult }, bit16Type, 0, 8);
1457
1458 auto & ex = GraphExport::Create(*sliceNode.output(0), "dummy");
1459 view(graph, stdout);
1460
1461 // Act
1462 ReduceNode<BitSliceOperation>(BitSliceOperation::distributeSlice, sliceNode);
1463 auto concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1464 ReduceNode<BitSliceOperation>(
1465 BitSliceOperation::normalizeIdempotent,
1466 *TryGetOwnerNode<SimpleNode>(*concatNode->input(0)->origin()));
1467 concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1468 ReduceNode<BitConcatOperation>(NormalizeBinaryOperation, *concatNode);
1469 graph.PruneNodes();
1470
1471 view(graph, stdout);
1472
1473 // Assert
1474 const auto bitType = std::dynamic_pointer_cast<const BitType>(ex.origin()->Type());
1475 ASSERT_TRUE(bitType);
1476 EXPECT_EQ(bitType->nbits(), 8u);
1477 EXPECT_EQ(ex.origin(), x);
1478}
1479
1480TEST(bitstring, ConcatFlattening)
1481{
1482 using namespace jlm::rvsdg;
1483
1484 // Arrange
1485 Graph graph;
1486 auto x = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "x");
1487 auto y = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "y");
1488 auto z = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "z");
1489
1490 auto concatResult1 = bitconcat({ x, y });
1491 auto concatResult2 = bitconcat({ concatResult1, z });
1492
1493 auto & ex = GraphExport::Create(*concatResult2, "dummy");
1494 view(graph, stdout);
1495
1496 // Act
1497 const auto concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1498 ReduceNode<BitConcatOperation>(FlattenBitConcatOperation, *concatNode);
1499
1500 view(graph, stdout);
1501
1502 // Assert
1503 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1504 EXPECT_TRUE(is<BitConcatOperation>(node->GetOperation()));
1505 EXPECT_EQ(node->ninputs(), 3u);
1506 EXPECT_EQ(node->input(0)->origin(), x);
1507 EXPECT_EQ(node->input(1)->origin(), y);
1508 EXPECT_EQ(node->input(2)->origin(), z);
1509}
1510
1511TEST(bitstring, ConcatWithSingleOperand)
1512{
1513 using namespace jlm::rvsdg;
1514
1515 // Arrange
1516 Graph graph;
1517 auto bit8Type = BitType::Create(8);
1518 std::vector bit8Types({ bit8Type });
1519
1520 auto x = &jlm::rvsdg::GraphImport::Create(graph, bit8Type, "x");
1521
1522 auto & concatNode = CreateOpNode<BitConcatOperation>({ x }, bit8Types);
1523
1524 auto & ex = GraphExport::Create(*concatNode.output(0), "dummy");
1525 view(graph, stdout);
1526
1527 // Act
1528 ReduceNode<BitConcatOperation>(NormalizeBinaryOperation, concatNode);
1529 graph.PruneNodes();
1530
1531 view(graph, stdout);
1532
1533 // Assert
1534 EXPECT_EQ(ex.origin(), x);
1535}
1536
1537TEST(bitstring, ConcatOfSlices)
1538{
1539 using namespace jlm::rvsdg;
1540
1541 // Assert
1542 Graph graph;
1543 auto bit4Type = BitType::Create(4);
1544 std::vector bit4Types({ bit4Type, bit4Type });
1545
1546 const auto x = &jlm::rvsdg::GraphImport::Create(graph, BitType::Create(8), "x");
1547
1548 auto sliceResult1 = bitslice(x, 0, 4);
1549 auto sliceResult2 = bitslice(x, 4, 8);
1550 auto & concatNode = CreateOpNode<BitConcatOperation>({ sliceResult1, sliceResult2 }, bit4Types);
1551
1552 auto & ex = GraphExport::Create(*concatNode.output(0), "dummy");
1553 view(graph, stdout);
1554
1555 // Act
1556 ReduceNode<BitConcatOperation>(NormalizeBinaryOperation, concatNode);
1557 ReduceNode<BitSliceOperation>(
1558 BitSliceOperation::normalizeIdempotent,
1559 *TryGetOwnerNode<SimpleNode>(*ex.origin()));
1560 graph.PruneNodes();
1561
1562 view(graph, stdout);
1563
1564 // Assert
1565 EXPECT_EQ(ex.origin(), x);
1566}
1567
1568TEST(bitstring, ConcatOfConstants)
1569{
1570 using namespace jlm::rvsdg;
1571
1572 // Arrange
1573 Graph graph;
1574 auto c1 = &BitConstantOperation::create(graph.GetRootRegion(), "00110111");
1575 auto c2 = &BitConstantOperation::create(graph.GetRootRegion(), "11001000");
1576
1577 auto concatResult = bitconcat({ c1, c2 });
1578
1579 auto & ex = GraphExport::Create(*concatResult, "dummy");
1580 view(graph, stdout);
1581
1582 // Act
1583 ReduceNode<BitConcatOperation>(
1584 NormalizeBinaryOperation,
1585 *TryGetOwnerNode<SimpleNode>(*ex.origin()));
1586
1587 // Assert
1588 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1589 auto operation = dynamic_cast<const BitConstantOperation &>(node->GetOperation());
1590 EXPECT_EQ(operation.value(), BitValueRepresentation("0011011111001000"));
1591}
1592
1593TEST(bitstring, ConcatCne)
1594{
1595 using namespace jlm::rvsdg;
1596
1597 // Arrange & Act
1598 Graph graph;
1599 auto NormalizeCne =
1600 [&](const SimpleOperation & operation, const std::vector<jlm::rvsdg::Output *> & operands)
1601 {
1602 return NormalizeSimpleOperationCommonNodeElimination(
1603 graph.GetRootRegion(),
1604 operation,
1605 operands);
1606 };
1607
1608 auto bitType8 = BitType::Create(8);
1609 std::vector bitTypes({ bitType8, bitType8 });
1610
1611 auto x = &jlm::rvsdg::GraphImport::Create(graph, bitType8, "x");
1612 auto y = &jlm::rvsdg::GraphImport::Create(graph, bitType8, "y");
1613
1614 auto & concatNode1 = CreateOpNode<BitConcatOperation>({ x, y }, bitTypes);
1615 auto & concatNode2 = CreateOpNode<BitConcatOperation>({ x, y }, bitTypes);
1616
1617 auto & ex1 = GraphExport::Create(*concatNode1.output(0), "dummy");
1618 auto & ex2 = GraphExport::Create(*concatNode2.output(0), "dummy");
1619
1620 view(graph, stdout);
1621
1622 // Act
1623 ReduceNode<BitConcatOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex1.origin()));
1624 ReduceNode<BitConcatOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex2.origin()));
1625 graph.PruneNodes();
1626
1627 view(graph, stdout);
1628
1629 // Assert
1630 EXPECT_EQ(ex1.origin(), ex2.origin());
1631}
1632
1633TEST(bitstring, SliceCne)
1634{
1635 using namespace jlm::rvsdg;
1636
1637 // Arrange
1638 Graph graph;
1639 auto NormalizeCne =
1640 [&](const SimpleOperation & operation, const std::vector<jlm::rvsdg::Output *> & operands)
1641 {
1642 return NormalizeSimpleOperationCommonNodeElimination(
1643 graph.GetRootRegion(),
1644 operation,
1645 operands);
1646 };
1647
1648 auto bitType8 = BitType::Create(8);
1649
1650 auto x = &jlm::rvsdg::GraphImport::Create(graph, bitType8, "x");
1651
1652 auto & sliceNode1 = CreateOpNode<BitSliceOperation>({ x }, bitType8, 2, 6);
1653 auto & sliceNode2 = CreateOpNode<BitSliceOperation>({ x }, bitType8, 2, 6);
1654
1655 auto & ex1 = GraphExport::Create(*sliceNode1.output(0), "dummy");
1656 auto & ex2 = GraphExport::Create(*sliceNode2.output(0), "dummy");
1657
1658 view(graph, stdout);
1659
1660 // Act
1661 ReduceNode<BitSliceOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex1.origin()));
1662 ReduceNode<BitSliceOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex2.origin()));
1663 graph.PruneNodes();
1664 view(graph, stdout);
1665
1666 // Assert
1667 EXPECT_EQ(ex1.origin(), ex2.origin());
1668}
1669
1670static const char * bs[] = { "00000000", "11111111", "10000000", "01111111", "00001111",
1671 "XXXX0011", "XD001100", "XXXXDDDD", "10XDDX01", "0DDDDDD1" };
1672
1673static std::string bitstring_not[] = { "11111111", "00000000", "01111111", "10000000", "11110000",
1674 "XXXX1100", "XD110011", "XXXXDDDD", "01XDDX10", "1DDDDDD0" };
1675
1676static std::string bitstring_xor[10][10] = { { "00000000",
1677 "11111111",
1678 "10000000",
1679 "01111111",
1680 "00001111",
1681 "XXXX0011",
1682 "XD001100",
1683 "XXXXDDDD",
1684 "10XDDX01",
1685 "0DDDDDD1" },
1686 { "11111111",
1687 "00000000",
1688 "01111111",
1689 "10000000",
1690 "11110000",
1691 "XXXX1100",
1692 "XD110011",
1693 "XXXXDDDD",
1694 "01XDDX10",
1695 "1DDDDDD0" },
1696 { "10000000",
1697 "01111111",
1698 "00000000",
1699 "11111111",
1700 "10001111",
1701 "XXXX0011",
1702 "XD001100",
1703 "XXXXDDDD",
1704 "00XDDX01",
1705 "1DDDDDD1" },
1706 { "01111111",
1707 "10000000",
1708 "11111111",
1709 "00000000",
1710 "01110000",
1711 "XXXX1100",
1712 "XD110011",
1713 "XXXXDDDD",
1714 "11XDDX10",
1715 "0DDDDDD0" },
1716 { "00001111",
1717 "11110000",
1718 "10001111",
1719 "01110000",
1720 "00000000",
1721 "XXXX1100",
1722 "XD000011",
1723 "XXXXDDDD",
1724 "10XDDX10",
1725 "0DDDDDD0" },
1726 { "XXXX0011",
1727 "XXXX1100",
1728 "XXXX0011",
1729 "XXXX1100",
1730 "XXXX1100",
1731 "XXXX0000",
1732 "XXXX1111",
1733 "XXXXDDDD",
1734 "XXXXDX10",
1735 "XXXXDDD0" },
1736 { "XD001100",
1737 "XD110011",
1738 "XD001100",
1739 "XD110011",
1740 "XD000011",
1741 "XXXX1111",
1742 "XD000000",
1743 "XXXXDDDD",
1744 "XDXDDX01",
1745 "XDDDDDD1" },
1746 { "XXXXDDDD",
1747 "XXXXDDDD",
1748 "XXXXDDDD",
1749 "XXXXDDDD",
1750 "XXXXDDDD",
1751 "XXXXDDDD",
1752 "XXXXDDDD",
1753 "XXXXDDDD",
1754 "XXXXDXDD",
1755 "XXXXDDDD" },
1756 { "10XDDX01",
1757 "01XDDX10",
1758 "00XDDX01",
1759 "11XDDX10",
1760 "10XDDX10",
1761 "XXXXDX10",
1762 "XDXDDX01",
1763 "XXXXDXDD",
1764 "00XDDX00",
1765 "1DXDDXD0" },
1766 { "0DDDDDD1",
1767 "1DDDDDD0",
1768 "1DDDDDD1",
1769 "0DDDDDD0",
1770 "0DDDDDD0",
1771 "XXXXDDD0",
1772 "XDDDDDD1",
1773 "XXXXDDDD",
1774 "1DXDDXD0",
1775 "0DDDDDD0" } };
1776
1777static std::string bitstring_or[10][10] = { { "00000000",
1778 "11111111",
1779 "10000000",
1780 "01111111",
1781 "00001111",
1782 "XXXX0011",
1783 "XD001100",
1784 "XXXXDDDD",
1785 "10XDDX01",
1786 "0DDDDDD1" },
1787 { "11111111",
1788 "11111111",
1789 "11111111",
1790 "11111111",
1791 "11111111",
1792 "11111111",
1793 "11111111",
1794 "11111111",
1795 "11111111",
1796 "11111111" },
1797 { "10000000",
1798 "11111111",
1799 "10000000",
1800 "11111111",
1801 "10001111",
1802 "1XXX0011",
1803 "1D001100",
1804 "1XXXDDDD",
1805 "10XDDX01",
1806 "1DDDDDD1" },
1807 { "01111111",
1808 "11111111",
1809 "11111111",
1810 "01111111",
1811 "01111111",
1812 "X1111111",
1813 "X1111111",
1814 "X1111111",
1815 "11111111",
1816 "01111111" },
1817 { "00001111",
1818 "11111111",
1819 "10001111",
1820 "01111111",
1821 "00001111",
1822 "XXXX1111",
1823 "XD001111",
1824 "XXXX1111",
1825 "10XD1111",
1826 "0DDD1111" },
1827 { "XXXX0011",
1828 "11111111",
1829 "1XXX0011",
1830 "X1111111",
1831 "XXXX1111",
1832 "XXXX0011",
1833 "XXXX1111",
1834 "XXXXDD11",
1835 "1XXXDX11",
1836 "XXXXDD11" },
1837 { "XD001100",
1838 "11111111",
1839 "1D001100",
1840 "X1111111",
1841 "XD001111",
1842 "XXXX1111",
1843 "XD001100",
1844 "XXXX11DD",
1845 "1DXD1101",
1846 "XDDD11D1" },
1847 { "XXXXDDDD",
1848 "11111111",
1849 "1XXXDDDD",
1850 "X1111111",
1851 "XXXX1111",
1852 "XXXXDD11",
1853 "XXXX11DD",
1854 "XXXXDDDD",
1855 "1XXXDXD1",
1856 "XXXXDDD1" },
1857 { "10XDDX01",
1858 "11111111",
1859 "10XDDX01",
1860 "11111111",
1861 "10XD1111",
1862 "1XXXDX11",
1863 "1DXD1101",
1864 "1XXXDXD1",
1865 "10XDDX01",
1866 "1DXDDXD1" },
1867 { "0DDDDDD1",
1868 "11111111",
1869 "1DDDDDD1",
1870 "01111111",
1871 "0DDD1111",
1872 "XXXXDD11",
1873 "XDDD11D1",
1874 "XXXXDDD1",
1875 "1DXDDXD1",
1876 "0DDDDDD1" } };
1877
1878static std::string bitstring_and[10][10] = { { "00000000",
1879 "00000000",
1880 "00000000",
1881 "00000000",
1882 "00000000",
1883 "00000000",
1884 "00000000",
1885 "00000000",
1886 "00000000",
1887 "00000000" },
1888 { "00000000",
1889 "11111111",
1890 "10000000",
1891 "01111111",
1892 "00001111",
1893 "XXXX0011",
1894 "XD001100",
1895 "XXXXDDDD",
1896 "10XDDX01",
1897 "0DDDDDD1" },
1898 { "00000000",
1899 "10000000",
1900 "10000000",
1901 "00000000",
1902 "00000000",
1903 "X0000000",
1904 "X0000000",
1905 "X0000000",
1906 "10000000",
1907 "00000000" },
1908 { "00000000",
1909 "01111111",
1910 "00000000",
1911 "01111111",
1912 "00001111",
1913 "0XXX0011",
1914 "0D001100",
1915 "0XXXDDDD",
1916 "00XDDX01",
1917 "0DDDDDD1" },
1918 { "00000000",
1919 "00001111",
1920 "00000000",
1921 "00001111",
1922 "00001111",
1923 "00000011",
1924 "00001100",
1925 "0000DDDD",
1926 "0000DX01",
1927 "0000DDD1" },
1928 { "00000000",
1929 "XXXX0011",
1930 "X0000000",
1931 "0XXX0011",
1932 "00000011",
1933 "XXXX0011",
1934 "XX000000",
1935 "XXXX00DD",
1936 "X0XX0001",
1937 "0XXX00D1" },
1938 { "00000000",
1939 "XD001100",
1940 "X0000000",
1941 "0D001100",
1942 "00001100",
1943 "XX000000",
1944 "XD001100",
1945 "XX00DD00",
1946 "X000DX00",
1947 "0D00DD00" },
1948 { "00000000",
1949 "XXXXDDDD",
1950 "X0000000",
1951 "0XXXDDDD",
1952 "0000DDDD",
1953 "XXXX00DD",
1954 "XX00DD00",
1955 "XXXXDDDD",
1956 "X0XXDX0D",
1957 "0XXXDDDD" },
1958 { "00000000",
1959 "10XDDX01",
1960 "10000000",
1961 "00XDDX01",
1962 "0000DX01",
1963 "X0XX0001",
1964 "X000DX00",
1965 "X0XXDX0D",
1966 "10XDDX01",
1967 "00XDDX01" },
1968 { "00000000",
1969 "0DDDDDD1",
1970 "00000000",
1971 "0DDDDDD1",
1972 "0000DDD1",
1973 "0XXX00D1",
1974 "0D00DD00",
1975 "0XXXDDDD",
1976 "00XDDX01",
1977 "0DDDDDD1" } };
1978
1979static char equal[10][10] = { { '1', '0', '0', '0', '0', '0', '0', 'X', '0', '0' },
1980 { '0', '1', '0', '0', '0', '0', '0', 'X', '0', '0' },
1981 { '0', '0', '1', '0', '0', '0', '0', 'X', '0', '0' },
1982 { '0', '0', '0', '1', '0', '0', '0', 'X', '0', 'D' },
1983 { '0', '0', '0', '0', '1', '0', '0', 'X', '0', 'D' },
1984 { '0', '0', '0', '0', '0', 'X', '0', 'X', '0', 'X' },
1985 { '0', '0', '0', '0', '0', '0', 'X', 'X', '0', '0' },
1986 { 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
1987 { '0', '0', '0', '0', '0', '0', '0', 'X', 'X', '0' },
1988 { '0', '0', '0', 'D', 'D', 'X', '0', 'X', '0', 'D' } };
1989
1990static char notequal[10][10] = { { '0', '1', '1', '1', '1', '1', '1', 'X', '1', '1' },
1991 { '1', '0', '1', '1', '1', '1', '1', 'X', '1', '1' },
1992 { '1', '1', '0', '1', '1', '1', '1', 'X', '1', '1' },
1993 { '1', '1', '1', '0', '1', '1', '1', 'X', '1', 'D' },
1994 { '1', '1', '1', '1', '0', '1', '1', 'X', '1', 'D' },
1995 { '1', '1', '1', '1', '1', 'X', '1', 'X', '1', 'X' },
1996 { '1', '1', '1', '1', '1', '1', 'X', 'X', '1', '1' },
1997 { 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
1998 { '1', '1', '1', '1', '1', '1', '1', 'X', 'X', '1' },
1999 { '1', '1', '1', 'D', 'D', 'X', '1', 'X', '1', 'D' } };
2000
2001static char sgreatereq[10][10] = { { '1', '1', '0', '1', '1', '1', '0', 'X', '1', '1' },
2002 { '0', '1', '0', '1', '1', '1', '0', 'D', '1', '1' },
2003 { '1', '1', '1', '1', '1', '1', '0', 'X', '1', '1' },
2004 { '0', '0', '0', '1', '1', '1', '0', 'X', '1', '1' },
2005 { '0', '0', '0', '0', '1', '1', '0', 'X', '1', 'D' },
2006 { '0', '0', '0', '0', '0', 'X', '0', 'X', '1', 'X' },
2007 { '1', '1', '1', '1', '1', '1', 'X', 'X', '1', '1' },
2008 { 'D', 'X', 'X', 'X', 'D', 'X', 'X', 'X', 'X', 'X' },
2009 { '0', '0', '0', '0', '0', '0', '0', 'X', 'X', 'X' },
2010 { '0', '0', '0', 'D', 'D', 'X', '0', 'X', 'X', 'D' } };
2011
2012static char sgreater[10][10] = { { '0', '1', '0', '1', '1', '1', '0', 'D', '1', '1' },
2013 { '0', '0', '0', '1', '1', '1', '0', 'X', '1', '1' },
2014 { '1', '1', '0', '1', '1', '1', '0', 'X', '1', '1' },
2015 { '0', '0', '0', '0', '1', '1', '0', 'X', '1', 'D' },
2016 { '0', '0', '0', '0', '0', '1', '0', 'D', '1', 'D' },
2017 { '0', '0', '0', '0', '0', 'X', '0', 'X', '1', 'X' },
2018 { '1', '1', '1', '1', '1', '1', 'X', 'X', '1', '1' },
2019 { 'X', 'D', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
2020 { '0', '0', '0', '0', '0', '0', '0', 'X', 'X', 'X' },
2021 { '0', '0', '0', '0', 'D', 'X', '0', 'X', 'X', 'D' } };
2022
2023static char slesseq[10][10] = { { '1', '0', '1', '0', '0', '0', '1', 'D', '0', '0' },
2024 { '1', '1', '1', '0', '0', '0', '1', 'X', '0', '0' },
2025 { '0', '0', '1', '0', '0', '0', '1', 'X', '0', '0' },
2026 { '1', '1', '1', '1', '0', '0', '1', 'X', '0', 'D' },
2027 { '1', '1', '1', '1', '1', '0', '1', 'D', '0', 'D' },
2028 { '1', '1', '1', '1', '1', 'X', '1', 'X', '0', 'X' },
2029 { '0', '0', '0', '0', '0', '0', 'X', 'X', '0', '0' },
2030 { 'X', 'D', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
2031 { '1', '1', '1', '1', '1', '1', '1', 'X', 'X', 'X' },
2032 { '1', '1', '1', '1', 'D', 'X', '1', 'X', 'X', 'D' } };
2033
2034static char sless[10][10] = { { '0', '0', '1', '0', '0', '0', '1', 'X', '0', '0' },
2035 { '1', '0', '1', '0', '0', '0', '1', 'D', '0', '0' },
2036 { '0', '0', '0', '0', '0', '0', '1', 'X', '0', '0' },
2037 { '1', '1', '1', '0', '0', '0', '1', 'X', '0', '0' },
2038 { '1', '1', '1', '1', '0', '0', '1', 'X', '0', 'D' },
2039 { '1', '1', '1', '1', '1', 'X', '1', 'X', '0', 'X' },
2040 { '0', '0', '0', '0', '0', '0', 'X', 'X', '0', '0' },
2041 { 'D', 'X', 'X', 'X', 'D', 'X', 'X', 'X', 'X', 'X' },
2042 { '1', '1', '1', '1', '1', '1', '1', 'X', 'X', 'X' },
2043 { '1', '1', '1', 'D', 'D', 'X', '1', 'X', 'X', 'D' } };
2044
2045static char ugreatereq[10][10] = { { '1', '0', '0', '0', '0', '0', '0', 'X', '0', '0' },
2046 { '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' },
2047 { '1', '0', '1', '0', '0', '0', '0', 'X', '0', '0' },
2048 { '1', '0', '1', '1', '1', '1', '1', 'X', '1', '1' },
2049 { '1', '0', '1', '0', '1', '1', '1', 'X', '1', 'D' },
2050 { '1', '0', '1', '0', '0', 'X', '1', 'X', '1', 'X' },
2051 { '1', '0', '1', '0', '0', '0', 'X', 'X', '0', '0' },
2052 { '1', 'X', 'X', 'X', 'D', 'X', 'X', 'X', 'X', 'X' },
2053 { '1', '0', '1', '0', '0', '0', '1', 'X', 'X', 'X' },
2054 { '1', '0', '1', 'D', 'D', 'X', '1', 'X', 'X', 'D' } };
2055
2056static char ugreater[10][10] = { { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' },
2057 { '1', '0', '1', '1', '1', '1', '1', 'X', '1', '1' },
2058 { '1', '0', '0', '0', '0', '0', '0', 'X', '0', '0' },
2059 { '1', '0', '1', '0', '1', '1', '1', 'X', '1', 'D' },
2060 { '1', '0', '1', '0', '0', '1', '1', 'D', '1', 'D' },
2061 { '1', '0', '1', '0', '0', 'X', '1', 'X', '1', 'X' },
2062 { '1', '0', '1', '0', '0', '0', 'X', 'X', '0', '0' },
2063 { 'X', '0', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
2064 { '1', '0', '1', '0', '0', '0', '1', 'X', 'X', 'X' },
2065 { '1', '0', '1', '0', 'D', 'X', '1', 'X', 'X', 'D' } };
2066
2067static char ulesseq[10][10] = { { '1', '1', '1', '1', '1', '1', '1', '1', '1', '1' },
2068 { '0', '1', '0', '0', '0', '0', '0', 'X', '0', '0' },
2069 { '0', '1', '1', '1', '1', '1', '1', 'X', '1', '1' },
2070 { '0', '1', '0', '1', '0', '0', '0', 'X', '0', 'D' },
2071 { '0', '1', '0', '1', '1', '0', '0', 'D', '0', 'D' },
2072 { '0', '1', '0', '1', '1', 'X', '0', 'X', '0', 'X' },
2073 { '0', '1', '0', '1', '1', '1', 'X', 'X', '1', '1' },
2074 { 'X', '1', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' },
2075 { '0', '1', '0', '1', '1', '1', '0', 'X', 'X', 'X' },
2076 { '0', '1', '0', '1', 'D', 'X', '0', 'X', 'X', 'D' } };
2077
2078static char uless[10][10] = { { '0', '1', '1', '1', '1', '1', '1', 'X', '1', '1' },
2079 { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' },
2080 { '0', '1', '0', '1', '1', '1', '1', 'X', '1', '1' },
2081 { '0', '1', '0', '0', '0', '0', '0', 'X', '0', '0' },
2082 { '0', '1', '0', '1', '0', '0', '0', 'X', '0', 'D' },
2083 { '0', '1', '0', '1', '1', 'X', '0', 'X', '0', 'X' },
2084 { '0', '1', '0', '1', '1', '1', 'X', 'X', '1', '1' },
2085 { '0', 'X', 'X', 'X', 'D', 'X', 'X', 'X', 'X', 'X' },
2086 { '0', '1', '0', '1', '1', '1', '0', 'X', 'X', 'X' },
2087 { '0', '1', '0', 'D', 'D', 'X', '0', 'X', 'X', 'D' } };
2088
2089TEST(bitstring, test_value_representation)
2090{
2091 using namespace jlm::rvsdg;
2092
2093 for (size_t r = 0; r < 10; r++)
2094 {
2095 EXPECT_EQ(BitValueRepresentation(bs[r]).lnot(), bitstring_not[r]);
2096 for (size_t c = 0; c < 10; c++)
2097 {
2098 EXPECT_EQ(BitValueRepresentation(bs[r]).land(bs[c]), bitstring_and[r][c]);
2099 EXPECT_EQ(BitValueRepresentation(bs[r]).lor(bs[c]), bitstring_or[r][c]);
2100 EXPECT_EQ(BitValueRepresentation(bs[r]).lxor(bs[c]), bitstring_xor[r][c]);
2101
2102 EXPECT_EQ(BitValueRepresentation(bs[r]).ult(bs[c]), uless[r][c]);
2103 EXPECT_EQ(BitValueRepresentation(bs[r]).slt(bs[c]), sless[r][c]);
2104
2105 EXPECT_EQ(BitValueRepresentation(bs[r]).ule(bs[c]), ulesseq[r][c]);
2106 EXPECT_EQ(BitValueRepresentation(bs[r]).sle(bs[c]), slesseq[r][c]);
2107
2108 EXPECT_EQ(BitValueRepresentation(bs[r]).eq(bs[c]), equal[r][c]);
2109 EXPECT_EQ(BitValueRepresentation(bs[r]).ne(bs[c]), notequal[r][c]);
2110
2111 EXPECT_EQ(BitValueRepresentation(bs[r]).uge(bs[c]), ugreatereq[r][c]);
2112 EXPECT_EQ(BitValueRepresentation(bs[r]).sge(bs[c]), sgreatereq[r][c]);
2113
2114 EXPECT_EQ(BitValueRepresentation(bs[r]).ugt(bs[c]), ugreater[r][c]);
2115 EXPECT_EQ(BitValueRepresentation(bs[r]).sgt(bs[c]), sgreater[r][c]);
2116 }
2117 }
2118
2119 EXPECT_EQ(BitValueRepresentation("000110").to_uint(), 24u);
2120 EXPECT_EQ(BitValueRepresentation("00011").to_int(), -8);
2121
2122 for (ssize_t r = -4; r < 5; r++)
2123 {
2124 BitValueRepresentation rbits(32, r);
2125
2126 EXPECT_EQ(rbits.neg(), -r);
2127 EXPECT_EQ(rbits.shl(0), r);
2128 EXPECT_EQ(rbits.shl(1), r << 1);
2129 EXPECT_EQ(rbits.shl(32), 0u);
2130 EXPECT_EQ(rbits.ashr(0), r);
2131 EXPECT_EQ(rbits.ashr(1), r >> 1);
2132 EXPECT_EQ(rbits.ashr(34), (r < 0 ? -1 : 0));
2133
2134 if (r >= 0)
2135 {
2136 EXPECT_EQ(rbits.shr(0), r);
2137 EXPECT_EQ(rbits.shr(1), r >> 1);
2138 EXPECT_EQ(rbits.shr(34), 0u);
2139 }
2140
2141 for (ssize_t c = -4; c < 5; c++)
2142 {
2143 BitValueRepresentation cbits(32, c);
2144
2145 EXPECT_EQ(rbits.add(cbits), r + c);
2146 EXPECT_EQ(rbits.sub(cbits), r - c);
2147 EXPECT_EQ(rbits.mul(cbits), r * c);
2148
2149 if (r >= 0 && c > 0)
2150 {
2151 EXPECT_EQ(rbits.udiv(cbits), r / c);
2152 EXPECT_EQ(rbits.umod(cbits), r % c);
2153 }
2154
2155 if (c != 0)
2156 {
2157 EXPECT_EQ(rbits.sdiv(cbits), r / c);
2158 EXPECT_EQ(rbits.smod(cbits), r % c);
2159 }
2160 }
2161 }
2162}
static char notequal[10][10]
static char sless[10][10]
#define ZERO_64
static void expect_static_false(jlm::rvsdg::Output *port)
static char ugreater[10][10]
static char ugreatereq[10][10]
static char sgreatereq[10][10]
static char ulesseq[10][10]
static std::string bitstring_xor[10][10]
static char slesseq[10][10]
#define ONE_64
static char uless[10][10]
static char sgreater[10][10]
#define MONE_64
static std::string bitstring_and[10][10]
TEST(bitstring, arithmetic_test_bitand)
static std::string bitstring_not[]
static void assert_constant(jlm::rvsdg::Output *bitstr, size_t nbits, const char bits[])
static char equal[10][10]
static std::string bitstring_or[10][10]
static const char * bs[]
static void expect_static_true(jlm::rvsdg::Output *port)
std::int64_t c1
std::int64_t c2
BitValueRepresentation shl(size_t shift) const
void udiv(const BitValueRepresentation &divisor, BitValueRepresentation &quotient, BitValueRepresentation &remainder) const
BitValueRepresentation smod(const BitValueRepresentation &other) const
void mul(const BitValueRepresentation &factor1, const BitValueRepresentation &factor2, BitValueRepresentation &product) const
BitValueRepresentation sdiv(const BitValueRepresentation &other) const
BitValueRepresentation neg() const
BitValueRepresentation sub(const BitValueRepresentation &other) const
BitValueRepresentation ashr(size_t shift) const
BitValueRepresentation shr(size_t shift) const
BitValueRepresentation umod(const BitValueRepresentation &other) const
char add(char a, char b, char c) const noexcept
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition graph.cpp:36
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
void PruneNodes()
Definition graph.hpp:116
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872