Jlm
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 
13 TEST(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>(NormalizeBinaryOperation, and0);
35  ReduceNode<bitand_op>(NormalizeBinaryOperation, 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 
47 TEST(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>(NormalizeBinaryOperation, ashr0);
77  ReduceNode<bitashr_op>(NormalizeBinaryOperation, ashr1);
78  ReduceNode<bitashr_op>(NormalizeBinaryOperation, ashr2);
79  ReduceNode<bitashr_op>(NormalizeBinaryOperation, ashr3);
80  ReduceNode<bitashr_op>(NormalizeBinaryOperation, 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 
101 TEST(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 
126 TEST(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>(NormalizeUnaryOperation, neg0);
147  ReduceNode<bitneg_op>(NormalizeUnaryOperation, neg1);
148  ReduceNode<bitneg_op>(NormalizeUnaryOperation, 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 
163 TEST(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>(NormalizeUnaryOperation, not0);
184  ReduceNode<bitnot_op>(NormalizeUnaryOperation, not1);
185  ReduceNode<bitnot_op>(NormalizeUnaryOperation, 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 
200 TEST(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>(NormalizeBinaryOperation, or0);
222  ReduceNode<bitor_op>(NormalizeBinaryOperation, 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 
234 TEST(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>(NormalizeBinaryOperation, product0);
256  ReduceNode<bitmul_op>(NormalizeBinaryOperation, 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 
268 TEST(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 
293 TEST(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>(NormalizeBinaryOperation, shl0);
318  ReduceNode<bitshl_op>(NormalizeBinaryOperation, shl1);
319  ReduceNode<bitshl_op>(NormalizeBinaryOperation, 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 
334 TEST(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>(NormalizeBinaryOperation, shr0);
359  ReduceNode<bitshr_op>(NormalizeBinaryOperation, shr1);
360  ReduceNode<bitshr_op>(NormalizeBinaryOperation, 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 
375 TEST(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>(NormalizeBinaryOperation, smod0);
397  ReduceNode<bitsmod_op>(NormalizeBinaryOperation, 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 
409 TEST(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>(NormalizeBinaryOperation, squot0);
431  ReduceNode<bitsdiv_op>(NormalizeBinaryOperation, 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 
443 TEST(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>(NormalizeBinaryOperation, sum0);
465  ReduceNode<bitadd_op>(NormalizeBinaryOperation, 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 
477 TEST(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 
502 TEST(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>(NormalizeBinaryOperation, umod0);
524  ReduceNode<bitumod_op>(NormalizeBinaryOperation, 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 
536 TEST(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>(NormalizeBinaryOperation, uquot0);
558  ReduceNode<bitudiv_op>(NormalizeBinaryOperation, 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 
570 TEST(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>(NormalizeBinaryOperation, xor0);
592  ReduceNode<bitxor_op>(NormalizeBinaryOperation, 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 
604 static inline void
606 {
607  auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*port);
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 
614 static inline void
616 {
617  auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*port);
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 
624 TEST(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 });
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>(NormalizeBinaryOperation, equal0);
650  ReduceNode<biteq_op>(NormalizeBinaryOperation, equal1);
651  ReduceNode<biteq_op>(NormalizeBinaryOperation, equal2);
652  ReduceNode<biteq_op>(NormalizeBinaryOperation, 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 
664 TEST(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 });
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>(NormalizeBinaryOperation, nequal0);
690  ReduceNode<bitne_op>(NormalizeBinaryOperation, nequal1);
691  ReduceNode<bitne_op>(NormalizeBinaryOperation, nequal2);
692  ReduceNode<bitne_op>(NormalizeBinaryOperation, 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 
704 TEST(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>(NormalizeBinaryOperation, sgreater0);
734  ReduceNode<bitsgt_op>(NormalizeBinaryOperation, sgreater1);
735  ReduceNode<bitsgt_op>(NormalizeBinaryOperation, sgreater2);
736  ReduceNode<bitsgt_op>(NormalizeBinaryOperation, sgreater3);
737  ReduceNode<bitsgt_op>(NormalizeBinaryOperation, 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 
750 TEST(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>(NormalizeBinaryOperation, sgreatereq0);
781  ReduceNode<bitsge_op>(NormalizeBinaryOperation, sgreatereq1);
782  ReduceNode<bitsge_op>(NormalizeBinaryOperation, sgreatereq2);
783  ReduceNode<bitsge_op>(NormalizeBinaryOperation, sgreatereq3);
784  ReduceNode<bitsge_op>(NormalizeBinaryOperation, sgreatereq4);
785  ReduceNode<bitsge_op>(NormalizeBinaryOperation, 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 
799 TEST(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>(NormalizeBinaryOperation, sless0);
829  ReduceNode<bitslt_op>(NormalizeBinaryOperation, sless1);
830  ReduceNode<bitslt_op>(NormalizeBinaryOperation, sless2);
831  ReduceNode<bitslt_op>(NormalizeBinaryOperation, sless3);
832  ReduceNode<bitslt_op>(NormalizeBinaryOperation, 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 
845 TEST(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>(NormalizeBinaryOperation, slesseq0);
877  ReduceNode<bitsle_op>(NormalizeBinaryOperation, slesseq1);
878  ReduceNode<bitsle_op>(NormalizeBinaryOperation, slesseq2);
879  ReduceNode<bitsle_op>(NormalizeBinaryOperation, slesseq3);
880  ReduceNode<bitsle_op>(NormalizeBinaryOperation, slesseq4);
881  ReduceNode<bitsle_op>(NormalizeBinaryOperation, 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 
895 TEST(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>(NormalizeBinaryOperation, ugreater0);
924  ReduceNode<bitugt_op>(NormalizeBinaryOperation, ugreater1);
925  ReduceNode<bitugt_op>(NormalizeBinaryOperation, ugreater2);
926  ReduceNode<bitugt_op>(NormalizeBinaryOperation, ugreater3);
927  ReduceNode<bitugt_op>(NormalizeBinaryOperation, 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 
940 TEST(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>(NormalizeBinaryOperation, ugreatereq0);
971  ReduceNode<bituge_op>(NormalizeBinaryOperation, ugreatereq1);
972  ReduceNode<bituge_op>(NormalizeBinaryOperation, ugreatereq2);
973  ReduceNode<bituge_op>(NormalizeBinaryOperation, ugreatereq3);
974  ReduceNode<bituge_op>(NormalizeBinaryOperation, ugreatereq4);
975  ReduceNode<bituge_op>(NormalizeBinaryOperation, 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 
989 TEST(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>(NormalizeBinaryOperation, uless0);
1019  ReduceNode<bitult_op>(NormalizeBinaryOperation, uless1);
1020  ReduceNode<bitult_op>(NormalizeBinaryOperation, uless2);
1021  ReduceNode<bitult_op>(NormalizeBinaryOperation, uless3);
1022  ReduceNode<bitult_op>(NormalizeBinaryOperation, 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 
1035 TEST(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>(NormalizeBinaryOperation, ulesseq0);
1067  ReduceNode<bitule_op>(NormalizeBinaryOperation, ulesseq1);
1068  ReduceNode<bitule_op>(NormalizeBinaryOperation, ulesseq2);
1069  ReduceNode<bitule_op>(NormalizeBinaryOperation, ulesseq3);
1070  ReduceNode<bitule_op>(NormalizeBinaryOperation, ulesseq4);
1071  ReduceNode<bitule_op>(NormalizeBinaryOperation, 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 
1113 TEST(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  {
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 
1175 TEST(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 
1222 static void
1223 assert_constant(jlm::rvsdg::Output * bitstr, size_t nbits, const char bits[])
1224 {
1225  auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*bitstr);
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 
1230 TEST(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 
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>(NormalizeBinaryOperation, bitAndNode);
1264  ReduceNode<bitor_op>(NormalizeBinaryOperation, bitOrNode);
1265  ReduceNode<bitxor_op>(NormalizeBinaryOperation, bitXorNode);
1266  ReduceNode<bitadd_op>(NormalizeBinaryOperation, bitAddNode);
1267  ReduceNode<bitmul_op>(NormalizeBinaryOperation, bitMulNode);
1268  ReduceNode<BitConcatOperation>(NormalizeBinaryOperation, bitConcatNode);
1269  ReduceNode<bitneg_op>(NormalizeUnaryOperation, bitNegNode1);
1270  ReduceNode<bitneg_op>(NormalizeUnaryOperation, 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 
1285 TEST(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>(NormalizeUnaryOperation, 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 
1331 TEST(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 
1363 TEST(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 =
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>(NormalizeUnaryOperation, 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 
1390 TEST(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>(NormalizeUnaryOperation, 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 
1419 TEST(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>(NormalizeUnaryOperation, sliceNode);
1436  graph.PruneNodes();
1437 
1438  view(graph, stdout);
1439 
1440  // Assert
1441  EXPECT_EQ(ex.origin(), x);
1442 }
1443 
1444 TEST(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>(NormalizeUnaryOperation, sliceNode);
1463  auto concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1464  ReduceNode<BitSliceOperation>(
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 
1480 TEST(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 
1511 TEST(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 
1537 TEST(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>(
1559  *TryGetOwnerNode<SimpleNode>(*ex.origin()));
1560  graph.PruneNodes();
1561 
1562  view(graph, stdout);
1563 
1564  // Assert
1565  EXPECT_EQ(ex.origin(), x);
1566 }
1567 
1568 TEST(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>(
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 
1593 TEST(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  {
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 
1633 TEST(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  {
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 
1670 static const char * bs[] = { "00000000", "11111111", "10000000", "01111111", "00001111",
1671  "XXXX0011", "XD001100", "XXXXDDDD", "10XDDX01", "0DDDDDD1" };
1672 
1673 static std::string bitstring_not[] = { "11111111", "00000000", "01111111", "10000000", "11110000",
1674  "XXXX1100", "XD110011", "XXXXDDDD", "01XDDX10", "1DDDDDD0" };
1675 
1676 static 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 
1777 static 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 
1878 static 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 
1979 static 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 
1990 static 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 
2001 static 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 
2012 static 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 
2023 static 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 
2034 static 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 
2045 static 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 
2056 static 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 
2067 static 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 
2078 static 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 
2089 TEST(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(1), r << 1);
2128  EXPECT_EQ(rbits.shl(32), 0);
2129  EXPECT_EQ(rbits.ashr(1), r >> 1);
2130  EXPECT_EQ(rbits.ashr(34), (r < 0 ? -1 : 0));
2131 
2132  if (r >= 0)
2133  {
2134  EXPECT_EQ(rbits.shr(1), r >> 1);
2135  EXPECT_EQ(rbits.shr(34), 0);
2136  }
2137 
2138  for (ssize_t c = -4; c < 5; c++)
2139  {
2140  BitValueRepresentation cbits(32, c);
2141 
2142  EXPECT_EQ(rbits.add(cbits), r + c);
2143  EXPECT_EQ(rbits.sub(cbits), r - c);
2144  EXPECT_EQ(rbits.mul(cbits), r * c);
2145 
2146  if (r >= 0 && c > 0)
2147  {
2148  EXPECT_EQ(rbits.udiv(cbits), r / c);
2149  EXPECT_EQ(rbits.umod(cbits), r % c);
2150  }
2151 
2152  if (c != 0)
2153  {
2154  EXPECT_EQ(rbits.sdiv(cbits), r / c);
2155  EXPECT_EQ(rbits.smod(cbits), r % c);
2156  }
2157  }
2158  }
2159 }
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)
static Output & createUndefined(Region &region, const size_t numBits)
Definition: constant.hpp:50
static Output & create(Region &region, BitValueRepresentation value)
Definition: constant.hpp:44
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
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 GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
void PruneNodes()
Definition: graph.hpp:116
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
std::optional< std::vector< rvsdg::Output * > > NormalizeBinaryOperation(const BinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Applies the reductions implemented in the binary operations reduction functions.
Definition: binary.cpp:112
std::optional< std::vector< rvsdg::Output * > > FlattenBitConcatOperation(const BitConcatOperation &, const std::vector< rvsdg::Output * > &operands)
Definition: concat.cpp:154
std::optional< std::vector< rvsdg::Output * > > NormalizeSimpleOperationCommonNodeElimination(Region &region, const SimpleOperation &operation, const std::vector< rvsdg::Output * > &operands)
Performs common node elimination for a given operation and operands in a region.
Definition: simple-node.cpp:85
jlm::rvsdg::Output * bitconcat(const std::vector< jlm::rvsdg::Output * > &operands)
Definition: concat.cpp:16
std::string view(const rvsdg::Region *region)
Definition: view.cpp:142
std::optional< std::vector< rvsdg::Output * > > NormalizeUnaryOperation(const UnaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Applies the reductions implemented in the unary operations reduction functions.
Definition: unary.cpp:17
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
Definition: node.hpp:1049
std::optional< std::vector< rvsdg::Output * > > NormalizeFlattenedBinaryOperation(const FlattenedBinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Applies the reductions of the binary operation represented by the flattened binary operation.
Definition: binary.cpp:253
std::optional< std::vector< rvsdg::Output * > > FlattenAssociativeBinaryOperation(const BinaryOperation &operation, const std::vector< rvsdg::Output * > &operands)
Flattens a cascade of the same binary operations into a single flattened binary operation.
Definition: binary.cpp:64
jlm::rvsdg::Output * bitslice(jlm::rvsdg::Output *argument, size_t low, size_t high)
Create bitslice.
Definition: slice.cpp:106