7 #include <gtest/gtest.h>
13 TEST(bitstring, arithmetic_test_bitand)
25 auto & and0 = CreateOpNode<bitand_op>({ s0, s1 }, 32);
26 auto & and1 = CreateOpNode<bitand_op>({ c0, c1 }, 32);
41 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitand_op(32));
43 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
47 TEST(bitstring, arithmetic_test_bitashr)
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);
86 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitashr_op(32));
88 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
91 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
94 TryGetOwnerNode<SimpleNode>(*ex3.origin())->GetOperation(),
97 TryGetOwnerNode<SimpleNode>(*ex4.origin())->GetOperation(),
101 TEST(bitstring, arithmetic_test_bitdifference)
110 auto & diff = CreateOpNode<bitsub_op>({ s0, s1 }, 32);
123 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsub_op(32));
126 TEST(bitstring, arithmetic_test_bitnegate)
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);
154 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitneg_op(32));
156 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
159 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
163 TEST(bitstring, arithmetic_test_bitnot)
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);
191 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitnot_op(32));
193 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
196 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
200 TEST(bitstring, arithmetic_test_bitor)
212 auto & or0 = CreateOpNode<bitor_op>({ s0, s1 }, 32);
213 auto & or1 = CreateOpNode<bitor_op>({ c0, c1 }, 32);
228 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitor_op(32));
230 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
234 TEST(bitstring, arithmetic_test_bitproduct)
246 auto & product0 = CreateOpNode<bitmul_op>({ s0, s1 }, 32);
247 auto & product1 = CreateOpNode<bitmul_op>({ c0, c1 }, 32);
262 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitmul_op(32));
264 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
268 TEST(bitstring, arithmetic_test_bitshiproduct)
277 auto & shiproduct = CreateOpNode<bitsmulh_op>({ s0, s1 }, 32);
290 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsmulh_op(32));
293 TEST(bitstring, arithmetic_test_bitshl)
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);
325 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitshl_op(32));
327 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
330 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
334 TEST(bitstring, arithmetic_test_bitshr)
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);
366 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitshr_op(32));
368 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
371 TryGetOwnerNode<SimpleNode>(*ex2.origin())->GetOperation(),
375 TEST(bitstring, arithmetic_test_bitsmod)
387 auto & smod0 = CreateOpNode<bitsmod_op>({ s0, s1 }, 32);
388 auto & smod1 = CreateOpNode<bitsmod_op>({ c0, c1 }, 32);
403 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsmod_op(32));
405 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
409 TEST(bitstring, arithmetic_test_bitsquotient)
421 auto & squot0 = CreateOpNode<bitsdiv_op>({ s0, s1 }, 32);
422 auto & squot1 = CreateOpNode<bitsdiv_op>({ c0, c1 }, 32);
437 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsdiv_op(32));
439 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
443 TEST(bitstring, arithmetic_test_bitsum)
455 auto & sum0 = CreateOpNode<bitadd_op>({ s0, s1 }, 32);
456 auto & sum1 = CreateOpNode<bitadd_op>({ c0, c1 }, 32);
471 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitadd_op(32));
473 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
477 TEST(bitstring, arithmetic_test_bituhiproduct)
486 auto & uhiproduct = CreateOpNode<bitumulh_op>({ s0, s1 }, 32);
499 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitumulh_op(32));
502 TEST(bitstring, arithmetic_test_bitumod)
514 auto & umod0 = CreateOpNode<bitumod_op>({ s0, s1 }, 32);
515 auto & umod1 = CreateOpNode<bitumod_op>({ c0, c1 }, 32);
530 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitumod_op(32));
532 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
536 TEST(bitstring, arithmetic_test_bituquotient)
548 auto & uquot0 = CreateOpNode<bitudiv_op>({ s0, s1 }, 32);
549 auto & uquot1 = CreateOpNode<bitudiv_op>({ c0, c1 }, 32);
564 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitudiv_op(32));
566 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
570 TEST(bitstring, arithmetic_test_bitxor)
582 auto & xor0 = CreateOpNode<bitxor_op>({ s0, s1 }, 32);
583 auto & xor1 = CreateOpNode<bitxor_op>({ c0, c1 }, 32);
598 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitxor_op(32));
600 TryGetOwnerNode<SimpleNode>(*ex1.origin())->GetOperation(),
607 auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*port);
610 EXPECT_EQ(op->value().nbits(), 1u);
611 EXPECT_EQ(op->value().str(),
"1");
617 auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*port);
620 EXPECT_EQ(op->value().nbits(), 1u);
621 EXPECT_EQ(op->value().str(),
"0");
624 TEST(bitstring, comparison_test_bitequal)
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);
658 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
biteq_op(32));
661 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex3.origin())->GetOperation(),
biteq_op(32));
664 TEST(bitstring, comparison_test_bitnotequal)
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);
698 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitne_op(32));
701 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex3.origin())->GetOperation(),
bitne_op(32));
704 TEST(bitstring, comparison_test_bitsgreater)
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);
743 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsgt_op(32));
750 TEST(bitstring, comparison_test_bitsgreatereq)
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);
791 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsge_op(32));
799 TEST(bitstring, comparison_test_bitsless)
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);
838 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitslt_op(32));
845 TEST(bitstring, comparison_test_bitslesseq)
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);
887 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitsle_op(32));
895 TEST(bitstring, comparison_test_bitugreater)
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);
933 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitugt_op(32));
940 TEST(bitstring, comparison_test_bitugreatereq)
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);
981 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bituge_op(32));
989 TEST(bitstring, bitstring_comparison_test_bituless)
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);
1028 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitult_op(32));
1035 TEST(bitstring, bitstring_comparison_test_bitulesseq)
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);
1077 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*ex0.origin())->GetOperation(),
bitule_op(32));
1113 TEST(bitstring, bitstring_test_constant)
1129 auto & b1 = CreateOpNode<BitConstantOperation>(graph.
GetRootRegion(),
"00110011");
1134 auto & b4 = CreateOpNode<BitConstantOperation>(graph.
GetRootRegion(),
"001100110");
1141 view(graph, stdout);
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()));
1152 EXPECT_EQ(ex1.origin(), ex2.origin());
1153 EXPECT_EQ(ex1.origin(), ex3.origin());
1155 const auto node1 = TryGetOwnerNode<SimpleNode>(*ex1.origin());
1159 const auto node4 = TryGetOwnerNode<SimpleNode>(*ex4.origin());
1163 const auto & plus_one_128 =
1168 const auto & minus_one_128 =
1175 TEST(bitstring, bitstring_test_normalize)
1188 auto & sum0 = CreateOpNode<bitadd_op>({ imp, c0 }, 32);
1189 auto & sum1 = CreateOpNode<bitadd_op>({ sum0.output(0), c1 }, 32);
1197 auto & flattenedBinaryNode = *TryGetOwnerNode<SimpleNode>(*ex.origin());
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))
1216 EXPECT_EQ(TryGetOwnerNode<SimpleNode>(*op1)->GetOperation(),
BitConstantOperation({ 32, 3 + 4 }));
1217 EXPECT_EQ(op2, imp);
1225 auto node = jlm::rvsdg::TryGetOwnerNode<jlm::rvsdg::SimpleNode>(*bitstr);
1237 std::vector types({ bit4Type, bit4Type });
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);
1285 TEST(bitstring, SliceOfConcatReduction)
1293 std::vector types({ bit16Type, bit16Type });
1298 auto & concatNode = CreateOpNode<BitConcatOperation>({ x, y }, types);
1299 auto & sliceNode = CreateOpNode<BitSliceOperation>({ concatNode.output(0) }, bit32Type, 8, 24);
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()));
1321 EXPECT_EQ(attrs->low(), 8u);
1322 EXPECT_EQ(attrs->high(), 16u);
1324 EXPECT_EQ(attrs->low(), 0u);
1325 EXPECT_EQ(attrs->high(), 8u);
1327 EXPECT_EQ(o0_node->input(0)->origin(), x);
1328 EXPECT_EQ(o1_node->input(0)->origin(), y);
1331 TEST(bitstring, ConcatOfSliceReduction)
1339 std::vector types({ bit8Type, bit8Type });
1345 auto & concatNode = CreateOpNode<BitConcatOperation>({ slice1, slice2 }, types);
1358 const auto sliceNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1360 EXPECT_EQ(sliceNode->input(0)->origin(), x);
1371 const auto constant =
1373 auto & sliceNode = CreateOpNode<BitSliceOperation>({ constant }, bit8Type, 2, 6);
1376 view(graph, stdout);
1382 view(graph, stdout);
1385 const auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1401 auto & sliceNode2 = CreateOpNode<BitSliceOperation>({ slice1 }, bit4Type, 1, 3);
1404 view(graph, stdout);
1410 view(graph, stdout);
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);
1429 auto & sliceNode = CreateOpNode<BitSliceOperation>({ x }, bit8Type, 0, 8);
1432 view(graph, stdout);
1438 view(graph, stdout);
1441 EXPECT_EQ(ex.origin(), x);
1455 auto concatResult =
bitconcat({ x, y });
1456 auto & sliceNode = CreateOpNode<BitSliceOperation>({ concatResult }, bit16Type, 0, 8);
1459 view(graph, stdout);
1463 auto concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1464 ReduceNode<BitSliceOperation>(
1466 *TryGetOwnerNode<SimpleNode>(*concatNode->input(0)->origin()));
1467 concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1471 view(graph, stdout);
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);
1490 auto concatResult1 =
bitconcat({ x, y });
1491 auto concatResult2 =
bitconcat({ concatResult1, z });
1494 view(graph, stdout);
1497 const auto concatNode = TryGetOwnerNode<SimpleNode>(*ex.origin());
1500 view(graph, stdout);
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);
1511 TEST(bitstring, ConcatWithSingleOperand)
1518 std::vector bit8Types({ bit8Type });
1522 auto & concatNode = CreateOpNode<BitConcatOperation>({ x }, bit8Types);
1525 view(graph, stdout);
1531 view(graph, stdout);
1534 EXPECT_EQ(ex.origin(), x);
1544 std::vector bit4Types({ bit4Type, bit4Type });
1548 auto sliceResult1 =
bitslice(x, 0, 4);
1549 auto sliceResult2 =
bitslice(x, 4, 8);
1550 auto & concatNode = CreateOpNode<BitConcatOperation>({ sliceResult1, sliceResult2 }, bit4Types);
1553 view(graph, stdout);
1557 ReduceNode<BitSliceOperation>(
1559 *TryGetOwnerNode<SimpleNode>(*ex.origin()));
1562 view(graph, stdout);
1565 EXPECT_EQ(ex.origin(), x);
1577 auto concatResult =
bitconcat({ c1, c2 });
1580 view(graph, stdout);
1583 ReduceNode<BitConcatOperation>(
1585 *TryGetOwnerNode<SimpleNode>(*ex.origin()));
1588 auto node = TryGetOwnerNode<SimpleNode>(*ex.origin());
1609 std::vector bitTypes({ bitType8, bitType8 });
1614 auto & concatNode1 = CreateOpNode<BitConcatOperation>({ x, y }, bitTypes);
1615 auto & concatNode2 = CreateOpNode<BitConcatOperation>({ x, y }, bitTypes);
1620 view(graph, stdout);
1623 ReduceNode<BitConcatOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex1.origin()));
1624 ReduceNode<BitConcatOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex2.origin()));
1627 view(graph, stdout);
1630 EXPECT_EQ(ex1.origin(), ex2.origin());
1652 auto & sliceNode1 = CreateOpNode<BitSliceOperation>({ x }, bitType8, 2, 6);
1653 auto & sliceNode2 = CreateOpNode<BitSliceOperation>({ x }, bitType8, 2, 6);
1658 view(graph, stdout);
1661 ReduceNode<BitSliceOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex1.origin()));
1662 ReduceNode<BitSliceOperation>(NormalizeCne, *TryGetOwnerNode<SimpleNode>(*ex2.origin()));
1664 view(graph, stdout);
1667 EXPECT_EQ(ex1.origin(), ex2.origin());
1670 static const char *
bs[] = {
"00000000",
"11111111",
"10000000",
"01111111",
"00001111",
1671 "XXXX0011",
"XD001100",
"XXXXDDDD",
"10XDDX01",
"0DDDDDD1" };
1673 static std::string
bitstring_not[] = {
"11111111",
"00000000",
"01111111",
"10000000",
"11110000",
1674 "XXXX1100",
"XD110011",
"XXXXDDDD",
"01XDDX10",
"1DDDDDD0" };
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' } };
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' } };
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' } };
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' } };
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' } };
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' } };
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' } };
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' } };
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' } };
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' } };
2089 TEST(bitstring, test_value_representation)
2093 for (
size_t r = 0; r < 10; r++)
2096 for (
size_t c = 0; c < 10; c++)
2122 for (ssize_t r = -4; r < 5; r++)
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));
2134 EXPECT_EQ(rbits.
shr(1), r >> 1);
2135 EXPECT_EQ(rbits.
shr(34), 0);
2138 for (ssize_t c = -4; c < 5; c++)
2142 EXPECT_EQ(rbits.
add(cbits), r + c);
2143 EXPECT_EQ(rbits.
sub(cbits), r - c);
2144 EXPECT_EQ(rbits.
mul(cbits), r * c);
2146 if (r >= 0 && c > 0)
2148 EXPECT_EQ(rbits.
udiv(cbits), r / c);
2149 EXPECT_EQ(rbits.
umod(cbits), r % c);
2154 EXPECT_EQ(rbits.
sdiv(cbits), r / c);
2155 EXPECT_EQ(rbits.
smod(cbits), r % c);
static char notequal[10][10]
static char sless[10][10]
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]
static char uless[10][10]
static char sgreater[10][10]
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 void expect_static_true(jlm::rvsdg::Output *port)
static Output & createUndefined(Region ®ion, const size_t numBits)
static Output & create(Region ®ion, BitValueRepresentation value)
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
BitValueRepresentation shl(size_t shift) const
void udiv(const BitValueRepresentation &divisor, BitValueRepresentation "ient, 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)
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Region & GetRootRegion() const noexcept
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.
std::optional< std::vector< rvsdg::Output * > > FlattenBitConcatOperation(const BitConcatOperation &, const std::vector< rvsdg::Output * > &operands)
std::optional< std::vector< rvsdg::Output * > > NormalizeSimpleOperationCommonNodeElimination(Region ®ion, const SimpleOperation &operation, const std::vector< rvsdg::Output * > &operands)
Performs common node elimination for a given operation and operands in a region.
jlm::rvsdg::Output * bitconcat(const std::vector< jlm::rvsdg::Output * > &operands)
std::string view(const rvsdg::Region *region)
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.
static std::vector< jlm::rvsdg::Output * > operands(const Node *node)
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.
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.
jlm::rvsdg::Output * bitslice(jlm::rvsdg::Output *argument, size_t low, size_t high)
Create bitslice.