Jlm
Loading...
Searching...
No Matches
IntegerOperationsTests.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2026 Nico Reißmann <nico.reissmann@gmail.com>
3 * See COPYING for terms of redistribution.
4 */
5
6#include <gtest/gtest.h>
7
11#include <jlm/rvsdg/view.hpp>
12
13namespace jlm::llvm
14{
15
16namespace
17{
18struct FoldConstantsTestInput
19{
20 std::int64_t c1;
21 std::uint64_t numBitsC1;
22
23 std::int64_t c2;
24 std::uint64_t numBitsC2;
25
26 std::int64_t expected;
27 std::int64_t numBitsExpected;
28};
29}
30
31template<typename Operation>
32static void
33TestFoldConstants(const FoldConstantsTestInput & input)
34{
35 using namespace jlm::rvsdg;
36
37 // Arrange
38 Graph graph;
39
41 graph.GetRootRegion(),
42 BitValueRepresentation(input.numBitsC1, input.c1));
44 graph.GetRootRegion(),
45 BitValueRepresentation(input.numBitsC2, input.c2));
46
47 auto & node1 = Operation::createNode(32, *c1.output(0), *c2.output(0));
48
49 auto & x1 = GraphExport::Create(*node1.output(0), "x1");
50
51 view(graph, stdout);
52
53 // Act
54 ReduceNode<Operation>(Operation::foldConstants, dynamic_cast<SimpleNode &>(node1));
55
56 graph.PruneNodes();
57
58 view(graph, stdout);
59
60 // Assert
61 {
62 auto [_, op] = TryGetSimpleNodeAndOptionalOp<IntegerConstantOperation>(*x1.origin());
63 EXPECT_TRUE(op);
64 EXPECT_EQ(op->Representation().to_int(), input.expected);
65 EXPECT_EQ(op->Representation().nbits(), static_cast<size_t>(input.numBitsExpected));
66 }
67}
68
69TEST(IntegerEqOperationTest, foldConstants)
70{
71 TestFoldConstants<IntegerEqOperation>({ 4, 32, 4, 32, -1, 1 });
72 TestFoldConstants<IntegerEqOperation>({ 4, 32, -4, 32, 0, 1 });
73}
74
75TEST(IntegerNeOperationTest, foldConstants)
76{
77 TestFoldConstants<IntegerNeOperation>({ 4, 32, 4, 32, 0, 1 });
78 TestFoldConstants<IntegerNeOperation>({ 4, 32, -4, 32, -1, 1 });
79}
80
81TEST(IntegerSgeOperationTest, foldConstants)
82{
83 TestFoldConstants<IntegerSgeOperation>({ 4, 32, 4, 32, -1, 1 });
84 TestFoldConstants<IntegerSgeOperation>({ 4, 32, -4, 32, -1, 1 });
85}
86
87TEST(IntegerSgtOperationTest, foldConstants)
88{
89 TestFoldConstants<IntegerSgtOperation>({ 4, 32, 4, 32, 0, 1 });
90 TestFoldConstants<IntegerSgtOperation>({ 4, 32, -4, 32, -1, 1 });
91}
92
93TEST(IntegerSleOperationTest, foldConstants)
94{
95 TestFoldConstants<IntegerSleOperation>({ 4, 32, 4, 32, -1, 1 });
96 TestFoldConstants<IntegerSleOperation>({ 4, 32, -4, 32, 0, 1 });
97}
98
99TEST(IntegerSltOperationTest, foldConstants)
100{
101 TestFoldConstants<IntegerSltOperation>({ 4, 32, 4, 32, 0, 1 });
102 TestFoldConstants<IntegerSltOperation>({ 4, 32, -4, 32, 0, 1 });
103}
104
105TEST(IntegerUgeOperationTest, foldConstants)
106{
107 TestFoldConstants<IntegerUgeOperation>({ 4, 32, 4, 32, -1, 1 });
108 TestFoldConstants<IntegerUgeOperation>({ 4, 32, -4, 32, 0, 1 });
109}
110
111TEST(IntegerUgtOperationTest, foldConstants)
112{
113 TestFoldConstants<IntegerUgtOperation>({ 4, 32, 4, 32, 0, 1 });
114 TestFoldConstants<IntegerUgtOperation>({ 4, 32, -4, 32, 0, 1 });
115}
116
117TEST(IntegerUleOperationTest, foldConstants)
118{
119 TestFoldConstants<IntegerUleOperation>({ 4, 32, 4, 32, -1, 1 });
120 TestFoldConstants<IntegerUleOperation>({ 4, 32, -4, 32, -1, 1 });
121}
122
123TEST(IntegerUltOperationTest, foldConstants)
124{
125 TestFoldConstants<IntegerUltOperation>({ 4, 32, 4, 32, 0, 1 });
126 TestFoldConstants<IntegerUltOperation>({ 4, 32, -4, 32, -1, 1 });
127}
128
129TEST(IntegerOrOperationTest, foldConstants)
130{
131 TestFoldConstants<IntegerOrOperation>({ 4, 32, 4, 32, 4, 32 });
132 TestFoldConstants<IntegerOrOperation>({ 0, 32, -1, 32, -1, 32 });
133 TestFoldConstants<IntegerOrOperation>({ 1, 32, 2, 32, 3, 32 });
134}
135
136TEST(IntegerAndOperationTest, foldConstants)
137{
138 TestFoldConstants<IntegerAndOperation>({ 4, 32, 4, 32, 4, 32 });
139 TestFoldConstants<IntegerAndOperation>({ 0, 32, -1, 32, 0, 32 });
140}
141
142TEST(IntegerXorOperationTest, foldConstants)
143{
144 TestFoldConstants<IntegerXorOperation>({ 4, 32, 4, 32, 0, 32 });
145 TestFoldConstants<IntegerXorOperation>({ 0, 32, -1, 32, -1, 32 });
146}
147
148TEST(IntegerAddOperationTest, foldConstants)
149{
150 TestFoldConstants<IntegerAddOperation>({ 12, 32, 7, 32, 19, 32 });
151 TestFoldConstants<IntegerAddOperation>({ -1, 32, 2, 32, 1, 32 });
152}
153
154TEST(IntegerSubOperationTest, foldConstants)
155{
156 TestFoldConstants<IntegerSubOperation>({ 12, 32, 7, 32, 5, 32 });
157 TestFoldConstants<IntegerSubOperation>({ 0, 32, 1, 32, -1, 32 });
158}
159
160TEST(IntegerMulOperationTest, foldConstants)
161{
162 TestFoldConstants<IntegerMulOperation>({ 6, 32, 7, 32, 42, 32 });
163 TestFoldConstants<IntegerMulOperation>({ -6, 32, 7, 32, -42, 32 });
164}
165
166TEST(IntegerSDivOperationTest, foldConstants)
167{
168 TestFoldConstants<IntegerSDivOperation>({ -13, 32, 3, 32, -4, 32 });
169 TestFoldConstants<IntegerSDivOperation>({ 13, 32, -3, 32, -4, 32 });
170}
171
172TEST(IntegerUDivOperationTest, foldConstants)
173{
174 TestFoldConstants<IntegerUDivOperation>({ 13, 32, 3, 32, 4, 32 });
175 TestFoldConstants<IntegerUDivOperation>({ -1, 32, 2, 32, 2147483647, 32 });
176}
177
178TEST(IntegerSRemOperationTest, foldConstants)
179{
180 TestFoldConstants<IntegerSRemOperation>({ -13, 32, 3, 32, -1, 32 });
181 TestFoldConstants<IntegerSRemOperation>({ 13, 32, -3, 32, 1, 32 });
182}
183
184TEST(IntegerURemOperationTest, foldConstants)
185{
186 TestFoldConstants<IntegerURemOperation>({ 13, 32, 3, 32, 1, 32 });
187 TestFoldConstants<IntegerURemOperation>({ -1, 32, 10, 32, 5, 32 });
188}
189
190TEST(IntegerAShrOperationTest, foldConstants)
191{
192 TestFoldConstants<IntegerAShrOperation>({ -0x10, 32, 2, 32, -0x4, 32 });
193 TestFoldConstants<IntegerAShrOperation>({ 0x10, 32, 2, 32, 0x4, 32 });
194}
195
196TEST(IntegerShlOperationTest, foldConstants)
197{
198 TestFoldConstants<IntegerShlOperation>({ 0x3, 32, 2, 32, 0xc, 32 });
199 TestFoldConstants<IntegerShlOperation>({ 0x400, 32, 2, 32, 0x1000, 32 });
200}
201
202TEST(IntegerLShrOperationTest, foldConstants)
203{
204 TestFoldConstants<IntegerLShrOperation>({ -0x1, 32, 2, 32, 0x3fffffff, 32 });
205 TestFoldConstants<IntegerLShrOperation>({ 0x10, 32, 2, 32, 0x4, 32 });
206}
207
208TEST(IntegerSubOperationTests, normalizeAdditiveInverse)
209{
210 using namespace jlm::rvsdg;
211
212 // Arrange
213 auto i32Type = BitType::Create(32);
214
215 Graph graph;
216
217 auto & i0 = GraphImport::Create(graph, i32Type, "i0");
218
219 auto structuralNode = TestStructuralNode::create(&graph.GetRootRegion(), 1);
220 auto inputVar = structuralNode->addInputWithArguments(i0);
221
222 auto & subNode =
223 IntegerSubOperation::createNode(32, *inputVar.argument[0], *inputVar.argument[0]);
224
225 auto outputVar = structuralNode->addOutputWithResults({ subNode.output(0) });
226
227 GraphExport::Create(*outputVar.output, "x0");
228
229 // Act
230 ReduceNode<IntegerSubOperation>(
232 dynamic_cast<SimpleNode &>(subNode));
233
234 graph.PruneNodes();
235
236 view(graph, stdout);
237
238 // Assert
239 {
240 auto [_, op] =
241 TryGetSimpleNodeAndOptionalOp<IntegerConstantOperation>(*outputVar.result[0]->origin());
242 EXPECT_TRUE(op);
243 EXPECT_EQ(op->Representation().to_int(), 0u);
244 EXPECT_EQ(op->Representation().nbits(), 32u);
245 }
246}
247
248}
std::uint64_t numBitsC2
std::uint64_t numBitsC1
std::int64_t numBitsExpected
std::int64_t c1
std::int64_t c2
std::int64_t expected
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
static rvsdg::Node & createNode(const size_t numBits, rvsdg::Output &operand1, rvsdg::Output &operand2)
static std::optional< std::vector< rvsdg::Output * > > normalizeAdditiveInverse(const IntegerSubOperation &operation, const std::vector< rvsdg::Output * > &operands)
Region & GetRootRegion() const noexcept
Definition graph.hpp:99
void PruneNodes()
Definition graph.hpp:116
Global memory state passed between functions.
TEST(ControlOperationsTests, foldConstants)
static void TestFoldConstants(const FoldConstantsTestInput &input)