Jlm
StdLibIntrinsicOperationsTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 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/TestType.hpp>
12 
13 TEST(StdLibIntrinsicOperationsTests, memcpyOperationEqualityTest)
14 {
15  using namespace jlm::llvm;
16  using namespace jlm::rvsdg;
17 
18  // Arrange
19  auto valueType = jlm::rvsdg::TestType::createValueType();
20  auto bit32Type = jlm::rvsdg::BitType::Create(32);
21  auto bit64Type = jlm::rvsdg::BitType::Create(64);
22 
23  MemCpyNonVolatileOperation operation1(bit32Type, 1);
24  MemCpyNonVolatileOperation operation2(bit64Type, 4);
25  TestOperation operation3({ valueType }, { valueType });
26 
27  // Act & Assert
28  EXPECT_EQ(operation1, operation1);
29  EXPECT_NE(operation1, operation2); // length type differs
30  EXPECT_NE(operation1, operation3); // number of memory states differs
31 }
32 
33 TEST(StdLibIntrinsicOperationsTests, memcpyAccessorsTest)
34 {
35  using namespace jlm::llvm;
36 
37  // Arrange
38  auto pointerType = PointerType::Create();
39  auto bit32Type = jlm::rvsdg::BitType::Create(32);
40  auto memStateType = jlm::llvm::MemoryStateType::Create();
41 
42  jlm::rvsdg::Graph graph;
43  auto & address1 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
44  auto & address2 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
45  auto & memState = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState");
46  auto & constant100 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 100);
47 
48  auto & memCpy = jlm::rvsdg::CreateOpNode<MemCpyNonVolatileOperation>(
49  { &address1, &address2, constant100.output(0), &memState },
50  bit32Type,
51  1);
52 
53  // Act & Assert
54  EXPECT_EQ(MemCpyOperation::destinationInput(memCpy).origin(), &address1);
55  EXPECT_EQ(MemCpyOperation::sourceInput(memCpy).origin(), &address2);
56  EXPECT_EQ(MemCpyOperation::countInput(memCpy).origin(), constant100.output(0));
57 }
58 
59 TEST(StdLibIntrinsicOperationsTests, memcpyMapMemoryStateInputToOutput)
60 {
61  using namespace jlm::llvm;
62 
63  // Arrange
64  auto pointerType = PointerType::Create();
65  auto bit32Type = jlm::rvsdg::BitType::Create(32);
66  auto ioStateType = IOStateType::Create();
67  auto memStateType = MemoryStateType::Create();
68 
69  jlm::rvsdg::Graph graph;
70  auto & address1 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
71  auto & address2 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
72  auto & ioState = jlm::rvsdg::GraphImport::Create(graph, ioStateType, "ioState");
73  auto & memState1 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState1");
74  auto & memState2 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState2");
75 
76  auto & constant100 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 100);
77 
78  auto & memCpyNonVolatile = MemCpyNonVolatileOperation::createNode(
79  address1,
80  address2,
81  *constant100.output(0),
82  { &memState1, &memState2 });
83 
84  auto & memCpyVolatile = MemCpyVolatileOperation::CreateNode(
85  address1,
86  address2,
87  *constant100.output(0),
88  ioState,
89  { &memState1, &memState2 });
90 
91  // Act & Assert
92  EXPECT_EQ(
93  &MemCpyOperation::mapMemoryStateInputToOutput(*memCpyNonVolatile.input(3)),
94  memCpyNonVolatile.output(0));
95  EXPECT_EQ(
96  &MemCpyOperation::mapMemoryStateInputToOutput(*memCpyNonVolatile.input(4)),
97  memCpyNonVolatile.output(1));
98 
99  EXPECT_EQ(
100  &MemCpyOperation::mapMemoryStateInputToOutput(*memCpyVolatile.input(4)),
101  memCpyVolatile.output(1));
102  EXPECT_EQ(
103  &MemCpyOperation::mapMemoryStateInputToOutput(*memCpyVolatile.input(5)),
104  memCpyVolatile.output(2));
105 }
106 
107 TEST(StdLibIntrinsicOperationsTests, memcpyMapMemoryStateOutputToInput)
108 {
109  using namespace jlm::llvm;
110 
111  // Arrange
112  auto pointerType = PointerType::Create();
113  auto bit32Type = jlm::rvsdg::BitType::Create(32);
114  auto ioStateType = IOStateType::Create();
115  auto memStateType = MemoryStateType::Create();
116 
117  jlm::rvsdg::Graph graph;
118  auto & address1 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
119  auto & address2 = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address2");
120  auto & ioState = jlm::rvsdg::GraphImport::Create(graph, ioStateType, "ioState");
121  auto & memState1 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState1");
122  auto & memState2 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState2");
123 
124  auto & constant100 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 100);
125 
126  auto & memCpyNonVolatile = MemCpyNonVolatileOperation::createNode(
127  address1,
128  address2,
129  *constant100.output(0),
130  { &memState1, &memState2 });
131 
132  auto & memCpyVolatile = MemCpyVolatileOperation::CreateNode(
133  address1,
134  address2,
135  *constant100.output(0),
136  ioState,
137  { &memState1, &memState2 });
138 
139  // Act & Assert
140  EXPECT_EQ(
141  MemCpyOperation::mapMemoryStateOutputToInput(*memCpyNonVolatile.output(0)).origin(),
142  &memState1);
143  EXPECT_EQ(
144  MemCpyOperation::mapMemoryStateOutputToInput(*memCpyNonVolatile.output(1)).origin(),
145  &memState2);
146 
147  EXPECT_EQ(
148  MemCpyOperation::mapMemoryStateOutputToInput(*memCpyVolatile.output(1)).origin(),
149  &memState1);
150  EXPECT_EQ(
151  MemCpyOperation::mapMemoryStateOutputToInput(*memCpyVolatile.output(2)).origin(),
152  &memState2);
153 }
154 
155 TEST(StdLibIntrinsicOperationsTests, memsetOperationEquality)
156 {
157  using namespace jlm::llvm;
158  using namespace jlm::rvsdg;
159 
160  // Arrange
161  auto valueType = TestType::createValueType();
162  auto bit32Type = BitType::Create(32);
163  auto bit64Type = BitType::Create(64);
164 
165  MemSetNonVolatileOperation operation1(bit32Type, 1);
166  MemSetNonVolatileOperation operation2(bit64Type, 4);
167  TestOperation operation3({ valueType }, { valueType });
168 
169  // Act & Assert
170  EXPECT_EQ(operation1, operation1);
171  EXPECT_NE(operation1, operation2); // length type differs
172  EXPECT_NE(operation1, operation3); // number of memory states differs
173 }
174 
175 TEST(StdLibIntrinsicOperationsTests, memsetAccessorsTest)
176 {
177  using namespace jlm::llvm;
178 
179  // Arrange
180  auto pointerType = PointerType::Create();
181  auto bit8Type = jlm::rvsdg::BitType::Create(8);
182  auto bit32Type = jlm::rvsdg::BitType::Create(32);
183  auto memStateType = MemoryStateType::Create();
184 
185  jlm::rvsdg::Graph graph;
186  auto & address = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
187  auto & value = jlm::rvsdg::GraphImport::Create(graph, bit8Type, "value");
188  auto & memState = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState");
189  auto & constant100 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 100);
190 
191  auto & memsetNode = jlm::rvsdg::CreateOpNode<MemSetNonVolatileOperation>(
192  { &address, &value, constant100.output(0), &memState },
193  bit32Type,
194  1);
195 
196  // Act & Assert
197  EXPECT_EQ(MemSetOperation::destinationInput(memsetNode).origin(), &address);
198  EXPECT_EQ(MemSetOperation::valueInput(memsetNode).origin(), &value);
199  EXPECT_EQ(MemSetOperation::lengthInput(memsetNode).origin(), constant100.output(0));
200 }
201 
202 TEST(StdLibIntrinsicOperationsTests, memsetMapMemoryStateInputToOutput)
203 {
204  using namespace jlm::llvm;
205 
206  // Arrange
207  auto pointerType = PointerType::Create();
208  auto bit8Type = jlm::rvsdg::BitType::Create(8);
209  auto bit32Type = jlm::rvsdg::BitType::Create(32);
210  auto memStateType = MemoryStateType::Create();
211 
212  jlm::rvsdg::Graph graph;
213  auto & address = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
214  auto & value = jlm::rvsdg::GraphImport::Create(graph, bit8Type, "value");
215  auto & memState1 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState1");
216  auto & memState2 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState2");
217 
218  auto & constant100 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 100);
219 
220  auto & memsetNode = MemSetNonVolatileOperation::createNode(
221  address,
222  value,
223  *constant100.output(0),
224  { &memState1, &memState2 });
225 
226  // Act & Assert
227  EXPECT_EQ(
228  &MemSetOperation::mapMemoryStateInputToOutput(*memsetNode.input(3)),
229  memsetNode.output(0));
230  EXPECT_EQ(
231  &MemSetOperation::mapMemoryStateInputToOutput(*memsetNode.input(4)),
232  memsetNode.output(1));
233 }
234 
235 TEST(StdLibIntrinsicOperationsTests, memsetMapMemoryStateOutputToInput)
236 {
237  using namespace jlm::llvm;
238 
239  // Arrange
240  auto pointerType = PointerType::Create();
241  auto bit8Type = jlm::rvsdg::BitType::Create(8);
242  auto bit32Type = jlm::rvsdg::BitType::Create(32);
243  auto memStateType = MemoryStateType::Create();
244 
245  jlm::rvsdg::Graph graph;
246  auto & address = jlm::rvsdg::GraphImport::Create(graph, pointerType, "address1");
247  auto & value = jlm::rvsdg::GraphImport::Create(graph, bit8Type, "value");
248  auto & memState1 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState1");
249  auto & memState2 = jlm::rvsdg::GraphImport::Create(graph, memStateType, "memState2");
250 
251  auto & constant100 = IntegerConstantOperation::Create(graph.GetRootRegion(), 32, 100);
252 
253  auto & memsetNode = MemSetNonVolatileOperation::createNode(
254  address,
255  value,
256  *constant100.output(0),
257  { &memState1, &memState2 });
258 
259  // Act & Assert
260  EXPECT_EQ(
261  MemSetOperation::mapMemoryStateOutputToInput(*memsetNode.output(0)).origin(),
262  &memState1);
263  EXPECT_EQ(
264  MemSetOperation::mapMemoryStateOutputToInput(*memsetNode.output(1)).origin(),
265  &memState2);
266 }
TEST(StdLibIntrinsicOperationsTests, memcpyOperationEqualityTest)
static std::shared_ptr< const IOStateType > Create()
Definition: types.cpp:343
static rvsdg::Node & Create(rvsdg::Region &region, IntegerValueRepresentation representation)
static rvsdg::SimpleNode & createNode(rvsdg::Output &destination, rvsdg::Output &source, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & countInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & sourceInput(const rvsdg::Node &node) noexcept
static rvsdg::Output & mapMemoryStateInputToOutput(const rvsdg::Input &input)
static rvsdg::SimpleNode & CreateNode(rvsdg::Output &destination, rvsdg::Output &source, rvsdg::Output &length, rvsdg::Output &ioState, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::SimpleNode & createNode(rvsdg::Output &destination, rvsdg::Output &value, rvsdg::Output &length, const std::vector< rvsdg::Output * > &memoryStates)
static rvsdg::Input & mapMemoryStateOutputToInput(const rvsdg::Output &output)
static rvsdg::Input & destinationInput(const rvsdg::Node &node) noexcept
static rvsdg::Input & lengthInput(const rvsdg::Node &node) noexcept
static rvsdg::Output & mapMemoryStateInputToOutput(const rvsdg::Input &input)
static rvsdg::Input & valueInput(const rvsdg::Node &node) noexcept
static std::shared_ptr< const MemoryStateType > Create()
Definition: types.cpp:379
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
static std::shared_ptr< const BitType > Create(std::size_t nbits)
Creates bit type of specified width.
Definition: type.cpp:45
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Output * origin() const noexcept
Definition: node.hpp:58
static std::shared_ptr< const TestType > createValueType()
Definition: TestType.cpp:67
Global memory state passed between functions.