25TEST(TraceTests, testTracingIOBarrier)
44 const auto int32Type = rvsdg::BitType::Create(32);
45 const auto ioStateType = IOStateType::Create();
47 const auto myInt = &rvsdg::GraphImport::Create(graph, int32Type,
"x");
48 const auto myIo = &rvsdg::GraphImport::Create(graph, ioStateType,
"io");
50 const auto ioBarrier1 = &rvsdg::CreateOpNode<IOBarrierOperation>({ myInt, myIo }, int32Type);
51 const auto ioBarrier1Output = ioBarrier1->output(0);
53 const auto ioBarrier2 =
54 &rvsdg::CreateOpNode<IOBarrierOperation>({ ioBarrier1Output, myIo }, int32Type);
55 const auto ioBarrier2Output = ioBarrier2->output(0);
62TEST(TraceTests, testGetConstantSignedInteger)
98 const auto int64Type = rvsdg::BitType::Create(64);
99 const auto int32Type = rvsdg::BitType::Create(32);
101 const auto bits64Output = &rvsdg::BitConstantOperation::create(
105 const auto functionType = rvsdg::FunctionType::Create({}, { int32Type });
113 const auto bits64CtxVar = lambdaNode->AddContextVar(*bits64Output).inner;
114 const auto matchOutput = rvsdg::MatchOperation::Create(*bits64CtxVar, { { 0, 0 } }, 1, 2);
115 const auto & integerConstantNode =
116 IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 20);
118 auto & gammaNode = *rvsdg::GammaNode::create(matchOutput, 2);
119 const auto entryVar = gammaNode.AddEntryVar(integerConstantNode.output(0));
121 const auto exitVarOutput =
122 gammaNode.AddExitVar({ entryVar.branchArgument[0], entryVar.branchArgument[1] }).output;
123 const auto lambdaOutput = lambdaNode->finalize({ exitVarOutput });
128 EXPECT_EQ(tryGetConstantSignedInteger(*bits64Output), -37);
129 EXPECT_EQ(tryGetConstantSignedInteger(*bits64CtxVar), -37);
132 EXPECT_EQ(tryGetConstantSignedInteger(*integerConstantNode.output(0)), 20u);
133 EXPECT_EQ(tryGetConstantSignedInteger(*entryVar.branchArgument[0]), 20u);
134 EXPECT_EQ(tryGetConstantSignedInteger(*entryVar.branchArgument[1]), 20u);
135 EXPECT_EQ(tryGetConstantSignedInteger(*exitVarOutput), 20u);
138 EXPECT_EQ(tryGetConstantSignedInteger(*matchOutput), std::nullopt);
139 EXPECT_EQ(tryGetConstantSignedInteger(*lambdaOutput), std::nullopt);
142TEST(TraceTests, testGetConstantSignedIntegerExtAndTrunc)
169 const auto int64Type = rvsdg::BitType::Create(64);
170 const auto int32Type = rvsdg::BitType::Create(32);
171 const auto int8Type = rvsdg::BitType::Create(8);
173 auto & bits32Output5 = rvsdg::BitConstantOperation::create(
176 auto & sextOutput = SExtOperation::create(64, bits32Output5);
177 auto & zextOutput = ZExtOperation::create(64, bits32Output5);
179 auto & bits8OutputMinus20 = rvsdg::BitConstantOperation::create(
182 auto & sext2Output = SExtOperation::create(32, bits8OutputMinus20);
183 auto & zext2Output = ZExtOperation::create(32, bits8OutputMinus20);
185 auto & bits32Output1023 = rvsdg::BitConstantOperation::create(
188 auto & truncOutput = TruncOperation::create(8, bits32Output1023);
189 auto & sext3Output = SExtOperation::create(32, truncOutput);
190 auto & zext3Output = ZExtOperation::create(32, truncOutput);
194 EXPECT_EQ(tryGetConstantSignedInteger(bits32Output5), 5u);
195 EXPECT_EQ(tryGetConstantSignedInteger(sextOutput), 5u);
196 EXPECT_EQ(tryGetConstantSignedInteger(zextOutput), 5u);
199 EXPECT_EQ(tryGetConstantSignedInteger(bits8OutputMinus20), -20);
200 EXPECT_EQ(tryGetConstantSignedInteger(sext2Output), -20);
201 EXPECT_EQ(tryGetConstantSignedInteger(zext2Output), 236u);
204 EXPECT_EQ(tryGetConstantSignedInteger(bits32Output1023), 1023u);
205 EXPECT_EQ(tryGetConstantSignedInteger(truncOutput), -1);
206 EXPECT_EQ(tryGetConstantSignedInteger(sext3Output), -1);
207 EXPECT_EQ(tryGetConstantSignedInteger(zext3Output), 255u);
210TEST(TraceTests, testGetConstantSignedIntegerExtThroughGamma)
239 auto & bits32Output = rvsdg::BitConstantOperation::create(
242 auto & controlOutput = rvsdg::ControlConstantOperation::create(graph.
GetRootRegion(), 2, 1);
244 auto & gammaNode = *rvsdg::GammaNode::create(&controlOutput, 2);
245 auto entryVar = gammaNode.AddEntryVar(&bits32Output);
246 auto exitVarOutput = gammaNode.AddExitVar(entryVar.branchArgument).output;
248 auto & sextOutput = SExtOperation::create(32, *exitVarOutput);
249 auto & truncOutput = TruncOperation::create(16, sextOutput);
250 auto & zextOutput = ZExtOperation::create(32, truncOutput);
254 EXPECT_EQ(tryGetConstantSignedInteger(bits32Output), -20);
255 EXPECT_EQ(tryGetConstantSignedInteger(*exitVarOutput), -20);
258 EXPECT_EQ(tryGetConstantSignedInteger(sextOutput), -20);
259 EXPECT_EQ(tryGetConstantSignedInteger(truncOutput), -20);
260 EXPECT_EQ(tryGetConstantSignedInteger(zextOutput), 65516u);
263TEST(TraceTests, testTraceAllPointerOriginsTheta)
295 const auto int32Type = rvsdg::BitType::Create(32);
296 const auto pointerType = PointerType::Create();
297 const auto arrayType = ArrayType::Create(int32Type, 100);
299 auto & zero = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 0);
300 auto & one = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 1);
302 auto & allocaNode = AllocaOperation::createNode(arrayType, *one.output(0), 4);
303 auto * arrayPointer = allocaNode.output(0);
304 auto * initialPointer =
305 GetElementPtrOperation::create(arrayPointer, { zero.output(0), zero.output(0) }, arrayType);
307 auto * theta = rvsdg::ThetaNode::create(&graph.
GetRootRegion());
308 auto i = theta->AddLoopVar(zero.output(0));
309 auto p = theta->AddLoopVar(initialPointer);
311 auto & oneInLoop = IntegerConstantOperation::Create(*theta->subregion(), 32, 1);
312 auto & hundredInLoop = IntegerConstantOperation::Create(*theta->subregion(), 32, 100);
314 auto * incrementedPointer =
315 GetElementPtrOperation::create(p.pre, { oneInLoop.output(0) }, int32Type);
316 auto * incrementedI =
317 rvsdg::CreateOpNode<rvsdg::bitadd_op>({ i.pre, oneInLoop.output(0) }, 32).output(0);
318 auto * isLessThanHundred =
319 rvsdg::CreateOpNode<rvsdg::bitult_op>({ incrementedI, hundredInLoop.output(0) }, 32)
321 auto & matchNode = rvsdg::MatchOperation::CreateNode(*isLessThanHundred, { { 1, 1 } }, 0, 2);
323 i.post->divert_to(incrementedI);
324 p.post->divert_to(incrementedPointer);
325 theta->set_predicate(matchNode.output(0));
327 auto * pAfterLoop = theta->output(1);
330 const auto pInLoopTraced = TracePointerOriginPrecise(*p.pre);
332 ASSERT_TRUE(TraceAllPointerOrigins(pInLoopTraced, pInLoopTraceCollection, 16));
334 const auto pAfterLoopTraced = TracePointerOriginPrecise(*pAfterLoop);
336 ASSERT_TRUE(TraceAllPointerOrigins(pAfterLoopTraced, pAfterLoopTraceCollection, 16));
339 EXPECT_EQ(pInLoopTraceCollection.
TopOrigins.size(), 1u);
340 EXPECT_EQ(pInLoopTraceCollection.
TopOrigins.count(arrayPointer), 1u);
341 EXPECT_EQ(pInLoopTraceCollection.
TopOrigins.at(arrayPointer), std::nullopt);
343 EXPECT_EQ(pAfterLoopTraceCollection.
TopOrigins.size(), 1u);
344 EXPECT_EQ(pAfterLoopTraceCollection.
TopOrigins.count(arrayPointer), 1u);
345 EXPECT_EQ(pAfterLoopTraceCollection.
TopOrigins.at(arrayPointer), std::nullopt);