25TEST(TraceTests, testTracingMemoryHoistBarrier)
33 const auto ptrType = PointerType::Create();
34 const auto ioStateType = IOStateType::Create();
36 const auto myPtr = &rvsdg::GraphImport::Create(graph, ptrType,
"x");
37 const auto myIo = &rvsdg::GraphImport::Create(graph, ioStateType,
"io");
39 const auto & hoistBarrier1 = MemoryHoistBarrierOperation::createNode(*myPtr, *myIo, 0);
40 const auto hoistBarrier1Output = hoistBarrier1.output(0);
42 const auto & hoistBarrier2 =
43 MemoryHoistBarrierOperation::createNode(*hoistBarrier1Output, *myIo, 0);
44 const auto hoistBarrier2Output = hoistBarrier2.output(0);
48 EXPECT_EQ(&tracer.
trace(*hoistBarrier1Output), myPtr);
49 EXPECT_EQ(&tracer.
trace(*hoistBarrier2Output), myPtr);
52 EXPECT_EQ(&tracer.
trace(*hoistBarrier1Output), hoistBarrier1Output);
53 EXPECT_EQ(&tracer.
trace(*hoistBarrier2Output), hoistBarrier2Output);
56TEST(TraceTests, testGetConstantSignedInteger)
92 const auto int64Type = rvsdg::BitType::Create(64);
93 const auto int32Type = rvsdg::BitType::Create(32);
95 const auto bits64Output = &rvsdg::BitConstantOperation::create(
99 const auto functionType = rvsdg::FunctionType::Create({}, { int32Type });
107 const auto bits64CtxVar = lambdaNode->AddContextVar(*bits64Output).inner;
108 const auto matchOutput = rvsdg::MatchOperation::Create(*bits64CtxVar, { { 0, 0 } }, 1, 2);
109 const auto & integerConstantNode =
110 IntegerConstantOperation::Create(*lambdaNode->subregion(), 32, 20);
112 auto & gammaNode = *rvsdg::GammaNode::create(matchOutput, 2);
113 const auto entryVar = gammaNode.AddEntryVar(integerConstantNode.output(0));
115 const auto exitVarOutput =
116 gammaNode.AddExitVar({ entryVar.branchArgument[0], entryVar.branchArgument[1] }).output;
117 const auto lambdaOutput = lambdaNode->finalize({ exitVarOutput });
122 EXPECT_EQ(tryGetConstantSignedInteger(*bits64Output), -37);
123 EXPECT_EQ(tryGetConstantSignedInteger(*bits64CtxVar), -37);
126 EXPECT_EQ(tryGetConstantSignedInteger(*integerConstantNode.output(0)), 20u);
127 EXPECT_EQ(tryGetConstantSignedInteger(*entryVar.branchArgument[0]), 20u);
128 EXPECT_EQ(tryGetConstantSignedInteger(*entryVar.branchArgument[1]), 20u);
129 EXPECT_EQ(tryGetConstantSignedInteger(*exitVarOutput), 20u);
132 EXPECT_EQ(tryGetConstantSignedInteger(*matchOutput), std::nullopt);
133 EXPECT_EQ(tryGetConstantSignedInteger(*lambdaOutput), std::nullopt);
136TEST(TraceTests, testGetConstantSignedIntegerExtAndTrunc)
163 const auto int64Type = rvsdg::BitType::Create(64);
164 const auto int32Type = rvsdg::BitType::Create(32);
165 const auto int8Type = rvsdg::BitType::Create(8);
167 auto & bits32Output5 = rvsdg::BitConstantOperation::create(
170 auto & sextOutput = SExtOperation::create(64, bits32Output5);
171 auto & zextOutput = ZExtOperation::create(64, bits32Output5);
173 auto & bits8OutputMinus20 = rvsdg::BitConstantOperation::create(
176 auto & sext2Output = SExtOperation::create(32, bits8OutputMinus20);
177 auto & zext2Output = ZExtOperation::create(32, bits8OutputMinus20);
179 auto & bits32Output1023 = rvsdg::BitConstantOperation::create(
182 auto & truncOutput = TruncOperation::create(8, bits32Output1023);
183 auto & sext3Output = SExtOperation::create(32, truncOutput);
184 auto & zext3Output = ZExtOperation::create(32, truncOutput);
188 EXPECT_EQ(tryGetConstantSignedInteger(bits32Output5), 5u);
189 EXPECT_EQ(tryGetConstantSignedInteger(sextOutput), 5u);
190 EXPECT_EQ(tryGetConstantSignedInteger(zextOutput), 5u);
193 EXPECT_EQ(tryGetConstantSignedInteger(bits8OutputMinus20), -20);
194 EXPECT_EQ(tryGetConstantSignedInteger(sext2Output), -20);
195 EXPECT_EQ(tryGetConstantSignedInteger(zext2Output), 236u);
198 EXPECT_EQ(tryGetConstantSignedInteger(bits32Output1023), 1023u);
199 EXPECT_EQ(tryGetConstantSignedInteger(truncOutput), -1);
200 EXPECT_EQ(tryGetConstantSignedInteger(sext3Output), -1);
201 EXPECT_EQ(tryGetConstantSignedInteger(zext3Output), 255u);
204TEST(TraceTests, testGetConstantSignedIntegerExtThroughGamma)
233 auto & bits32Output = rvsdg::BitConstantOperation::create(
236 auto & controlOutput = rvsdg::ControlConstantOperation::create(graph.
GetRootRegion(), 2, 1);
238 auto & gammaNode = *rvsdg::GammaNode::create(&controlOutput, 2);
239 auto entryVar = gammaNode.AddEntryVar(&bits32Output);
240 auto exitVarOutput = gammaNode.AddExitVar(entryVar.branchArgument).output;
242 auto & sextOutput = SExtOperation::create(32, *exitVarOutput);
243 auto & truncOutput = TruncOperation::create(16, sextOutput);
244 auto & zextOutput = ZExtOperation::create(32, truncOutput);
248 EXPECT_EQ(tryGetConstantSignedInteger(bits32Output), -20);
249 EXPECT_EQ(tryGetConstantSignedInteger(*exitVarOutput), -20);
252 EXPECT_EQ(tryGetConstantSignedInteger(sextOutput), -20);
253 EXPECT_EQ(tryGetConstantSignedInteger(truncOutput), -20);
254 EXPECT_EQ(tryGetConstantSignedInteger(zextOutput), 65516u);
257TEST(TraceTests, testGetConstantSignedIntegerOnThetaOutput)
281 auto & zero = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 0);
283 auto * theta = rvsdg::ThetaNode::create(&graph.
GetRootRegion());
284 auto loopVar = theta->AddLoopVar(zero.output(0));
286 auto & c = IntegerConstantOperation::Create(*theta->subregion(), 32, 42);
287 loopVar.post->divert_to(c.output(0));
288 theta->set_predicate(&rvsdg::ControlConstantOperation::create(*theta->subregion(), 2, 1));
291 EXPECT_EQ(tryGetConstantSignedInteger(*loopVar.output), 42);
294TEST(TraceTests, testTraceAllPointerOriginsTheta)
326 const auto int32Type = rvsdg::BitType::Create(32);
327 const auto pointerType = PointerType::Create();
328 const auto arrayType = ArrayType::Create(int32Type, 100);
330 auto & zero = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 0);
331 auto & one = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 1);
333 auto & allocaNode = AllocaOperation::createNode(arrayType, *one.output(0), 4);
334 auto * arrayPointer = allocaNode.output(0);
335 auto * initialPointer =
336 GetElementPtrOperation::create(arrayPointer, { zero.output(0), zero.output(0) }, arrayType);
338 auto * theta = rvsdg::ThetaNode::create(&graph.
GetRootRegion());
339 auto i = theta->AddLoopVar(zero.output(0));
340 auto p = theta->AddLoopVar(initialPointer);
342 auto & oneInLoop = IntegerConstantOperation::Create(*theta->subregion(), 32, 1);
343 auto & hundredInLoop = IntegerConstantOperation::Create(*theta->subregion(), 32, 100);
345 auto * incrementedPointer =
346 GetElementPtrOperation::create(p.pre, { oneInLoop.output(0) }, int32Type);
347 auto * incrementedI =
348 rvsdg::CreateOpNode<rvsdg::bitadd_op>({ i.pre, oneInLoop.output(0) }, 32).output(0);
349 auto * isLessThanHundred =
350 rvsdg::CreateOpNode<rvsdg::bitult_op>({ incrementedI, hundredInLoop.output(0) }, 32)
352 auto & matchNode = rvsdg::MatchOperation::CreateNode(*isLessThanHundred, { { 1, 1 } }, 0, 2);
354 i.post->divert_to(incrementedI);
355 p.post->divert_to(incrementedPointer);
356 theta->set_predicate(matchNode.output(0));
358 auto * pAfterLoop = theta->output(1);
361 const auto pInLoopTraced = TracePointerOriginPrecise(*p.pre);
363 ASSERT_TRUE(TraceAllPointerOrigins(pInLoopTraced, pInLoopTraceCollection, 16));
365 const auto pAfterLoopTraced = TracePointerOriginPrecise(*pAfterLoop);
367 ASSERT_TRUE(TraceAllPointerOrigins(pAfterLoopTraced, pAfterLoopTraceCollection, 16));
370 EXPECT_EQ(pInLoopTraceCollection.
TopOrigins.size(), 1u);
371 EXPECT_EQ(pInLoopTraceCollection.
TopOrigins.count(arrayPointer), 1u);
372 EXPECT_EQ(pInLoopTraceCollection.
TopOrigins.at(arrayPointer), std::nullopt);
374 EXPECT_EQ(pAfterLoopTraceCollection.
TopOrigins.size(), 1u);
375 EXPECT_EQ(pAfterLoopTraceCollection.
TopOrigins.count(arrayPointer), 1u);
376 EXPECT_EQ(pAfterLoopTraceCollection.
TopOrigins.at(arrayPointer), std::nullopt);