220TEST(StoreOperationTests, TestDuplicateStateReduction)
226 auto valueType = TestType::createValueType();
227 auto pointerType = PointerType::Create();
228 auto memoryStateType = MemoryStateType::Create();
237 auto & storeNode = StoreNonVolatileOperation::CreateNode(*a, *v, { s1, s2, s1, s2, s3 }, 4);
239 auto & exS1 = GraphExport::Create(*storeNode.output(0),
"exS1");
240 auto & exS2 = GraphExport::Create(*storeNode.output(1),
"exS2");
241 auto & exS3 = GraphExport::Create(*storeNode.output(2),
"exS3");
242 auto & exS4 = GraphExport::Create(*storeNode.output(3),
"exS4");
243 auto & exS5 = GraphExport::Create(*storeNode.output(4),
"exS5");
249 StoreNonVolatileOperation::NormalizeDuplicateStates,
256 EXPECT_TRUE(success);
258 EXPECT_TRUE(is<StoreNonVolatileOperation>(node));
259 EXPECT_EQ(node->ninputs(), 5u);
260 EXPECT_EQ(node->noutputs(), 3u);
261 EXPECT_EQ(exS1.origin(), node->output(0));
262 EXPECT_EQ(exS2.origin(), node->output(1));
263 EXPECT_EQ(exS3.origin(), node->output(0));
264 EXPECT_EQ(exS4.origin(), node->output(1));
265 EXPECT_EQ(exS5.origin(), node->output(2));
318TEST(StoreOperationTests, testStoreStoreReduction)
324 const auto i32Type = BitType::Create(32);
325 const auto i64Type = BitType::Create(64);
326 const auto pointerType = PointerType::Create();
327 const auto memoryStateType = MemoryStateType::Create();
330 auto addressImport1 = &GraphImport::Create(graph, pointerType,
"address1");
331 auto addressImport2 = &GraphImport::Create(graph, pointerType,
"address2");
332 auto i32Import = &GraphImport::Create(graph, i32Type,
"i32");
333 auto i64Import1 = &GraphImport::Create(graph, i64Type,
"i64-1");
334 auto i64Import2 = &GraphImport::Create(graph, i64Type,
"i64-2");
335 auto memoryStateImport1 = &GraphImport::Create(graph, memoryStateType,
"memoryState1");
336 auto memoryStateImport2 = &GraphImport::Create(graph, memoryStateType,
"memoryState2");
338 auto & storeNode1 = StoreNonVolatileOperation::CreateNode(
341 { memoryStateImport1 },
344 StoreNonVolatileOperation::CreateNode(*addressImport1, *i64Import2, outputs(&storeNode1), 4);
346 auto & storeNode3 = StoreNonVolatileOperation::CreateNode(
349 { memoryStateImport1 },
351 auto & storeNode4 = StoreNonVolatileOperation::CreateNode(
354 { outputs(&storeNode3).front(), memoryStateImport2 },
357 auto & storeNode5 = StoreNonVolatileOperation::CreateNode(
360 { memoryStateImport1 },
363 StoreNonVolatileOperation::CreateNode(*addressImport1, *i32Import, outputs(&storeNode5), 4);
365 auto & storeNode7 = StoreNonVolatileOperation::CreateNode(
368 { memoryStateImport1 },
371 StoreNonVolatileOperation::CreateNode(*addressImport2, *i64Import2, outputs(&storeNode7), 4);
373 auto & storeNode9 = StoreNonVolatileOperation::CreateNode(
376 { memoryStateImport1 },
379 StoreNonVolatileOperation::CreateNode(*addressImport1, *i64Import2, outputs(&storeNode9), 4);
380 GraphExport::Create(*outputs(&storeNode9).front(),
"");
382 auto & storeNode11 = StoreNonVolatileOperation::CreateNode(
385 { memoryStateImport1, memoryStateImport2 },
387 auto & storeNode12 = StoreNonVolatileOperation::CreateNode(
390 { storeNode11.output(0) },
393 auto & ex1 = GraphExport::Create(*storeNode2.output(0),
"ex1");
394 auto & ex2 = GraphExport::Create(*storeNode4.output(0),
"ex2");
395 auto & ex3 = GraphExport::Create(*storeNode6.output(0),
"ex3");
396 auto & ex4 = GraphExport::Create(*storeNode8.output(0),
"ex4");
397 auto & ex5 = GraphExport::Create(*storeNode10.output(0),
"ex5");
398 auto & ex6 = GraphExport::Create(*storeNode12.output(0),
"ex6");
403 auto success1 = ReduceNode<StoreNonVolatileOperation>(
404 StoreNonVolatileOperation::normalizeStoreStore,
407 auto success2 = ReduceNode<StoreNonVolatileOperation>(
408 StoreNonVolatileOperation::normalizeStoreStore,
411 auto success3 = ReduceNode<StoreNonVolatileOperation>(
412 StoreNonVolatileOperation::normalizeStoreStore,
415 auto success4 = ReduceNode<StoreNonVolatileOperation>(
416 StoreNonVolatileOperation::normalizeStoreStore,
419 auto success5 = ReduceNode<StoreNonVolatileOperation>(
420 StoreNonVolatileOperation::normalizeStoreStore,
423 auto success6 = ReduceNode<StoreNonVolatileOperation>(
424 StoreNonVolatileOperation::normalizeStoreStore,
434 EXPECT_TRUE(success1);
435 auto [storeNode, storeOp] =
436 TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(*ex1.origin());
437 EXPECT_NE(storeOp,
nullptr);
438 EXPECT_EQ(StoreOperation::AddressInput(*storeNode).origin(), addressImport1);
439 EXPECT_EQ(StoreOperation::StoredValueInput(*storeNode).origin(), i64Import2);
440 EXPECT_EQ(storeOp->NumMemoryStates(), 1u);
442 StoreOperation::getMemoryStateInputs(*storeNode).begin()->origin(),
449 EXPECT_FALSE(success2);
450 auto [fstStoreNode, _] =
451 TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(*ex2.origin());
452 EXPECT_EQ(fstStoreNode, &storeNode4);
453 auto [sndStoreNode, sndStoreOp] = TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(
454 *StoreOperation::getMemoryStateInputs(*fstStoreNode).begin()->origin());
455 EXPECT_EQ(sndStoreNode, &storeNode3);
461 EXPECT_FALSE(success3);
462 auto [fstStoreNode, _] =
463 TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(*ex3.origin());
464 EXPECT_EQ(fstStoreNode, &storeNode6);
465 auto [sndStoreNode, sndStoreOp] = TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(
466 *StoreOperation::getMemoryStateInputs(*fstStoreNode).begin()->origin());
467 EXPECT_EQ(sndStoreNode, &storeNode5);
473 EXPECT_FALSE(success4);
474 auto [fstStoreNode, _] =
475 TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(*ex4.origin());
476 EXPECT_EQ(fstStoreNode, &storeNode8);
477 auto [sndStoreNode, sndStoreOp] = TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(
478 *StoreOperation::getMemoryStateInputs(*fstStoreNode).begin()->origin());
479 EXPECT_EQ(sndStoreNode, &storeNode7);
485 EXPECT_FALSE(success5);
486 auto [fstStoreNode, _] =
487 TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(*ex5.origin());
488 EXPECT_EQ(fstStoreNode, &storeNode10);
489 auto [sndStoreNode, sndStoreOp] = TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(
490 *StoreOperation::getMemoryStateInputs(*fstStoreNode).begin()->origin());
491 EXPECT_EQ(sndStoreNode, &storeNode9);
496 EXPECT_TRUE(success6);
497 auto [storeNode, storeOp] =
498 TryGetSimpleNodeAndOptionalOp<StoreNonVolatileOperation>(*ex6.origin());
499 EXPECT_NE(storeOp,
nullptr);
500 EXPECT_EQ(StoreOperation::AddressInput(*storeNode).origin(), addressImport1);
501 EXPECT_EQ(StoreOperation::StoredValueInput(*storeNode).origin(), i64Import2);
502 EXPECT_EQ(storeOp->NumMemoryStates(), 1u);
504 StoreOperation::getMemoryStateInputs(*storeNode).begin()->origin(),
509TEST(StoreOperationTests, normalizeIOBarrierAddress)
515 const auto pointerType = PointerType::Create();
516 const auto memoryStateType = MemoryStateType::Create();
518 const auto ioStateType = IOStateType::Create();
521 const auto addressImport = &GraphImport::Create(graph, pointerType,
"address");
522 const auto valueImport = &GraphImport::Create(graph, bit32Type,
"value");
523 const auto sizeImport = &GraphImport::Create(graph, bit32Type,
"value");
524 auto memoryStateImport = &GraphImport::Create(graph, memoryStateType,
"memState");
525 auto ioStateImport = &GraphImport::Create(graph, ioStateType,
"ioState");
527 auto allocaResults = AllocaOperation::create(bit32Type, sizeImport, 4);
529 { allocaResults[0], ioStateImport },
532 auto & storeNode1 = StoreNonVolatileOperation::CreateNode(
533 *ioBarrierNode.output(0),
535 { allocaResults[1] },
539 StoreNonVolatileOperation::CreateNode(*addressImport, *valueImport, { memoryStateImport }, 4);
541 auto & ex1 = GraphExport::Create(*storeNode1.output(0),
"store1");
542 auto & ex2 = GraphExport::Create(*storeNode2.output(0),
"store2");
548 StoreNonVolatileOperation::normalizeIOBarrierAddress,
552 StoreNonVolatileOperation::normalizeIOBarrierAddress,
559 EXPECT_TRUE(successStoreNode1);
566 EXPECT_FALSE(successStoreNode2);
572TEST(StoreOperationTests, normalizeIOBarrierAddress_Gamma)
578 const auto pointerType = PointerType::Create();
580 const auto ioStateType = IOStateType::Create();
581 const auto controlTye = ControlType::Create(2);
584 const auto valueImport = &GraphImport::Create(graph, bit32Type,
"value");
585 const auto sizeImport = &GraphImport::Create(graph, bit32Type,
"value");
586 auto ioStateImport = &GraphImport::Create(graph, ioStateType,
"ioState");
587 const auto controlImport = &GraphImport::Create(graph, controlTye,
"control");
589 auto allocaResults = AllocaOperation::create(bit32Type, sizeImport, 4);
591 auto gammaNode = GammaNode::create(controlImport, 2);
592 auto addressEntryVar = gammaNode->AddEntryVar(allocaResults[0]);
593 auto memoryStateEntryVar = gammaNode->AddEntryVar(allocaResults[1]);
594 auto ioStateEntryVar = gammaNode->AddEntryVar(ioStateImport);
595 auto valueEntryVar = gammaNode->AddEntryVar(valueImport);
598 { addressEntryVar.branchArgument[0], ioStateEntryVar.branchArgument[0] },
601 auto & storeNode = StoreNonVolatileOperation::CreateNode(
602 *ioBarrierNode.output(0),
603 *valueEntryVar.branchArgument[0],
604 { memoryStateEntryVar.branchArgument[0] },
608 gammaNode->AddExitVar({ storeNode.output(0), memoryStateEntryVar.branchArgument[1] });
610 GraphExport::Create(*exitVar.output,
"store");
616 StoreNonVolatileOperation::normalizeIOBarrierAddress,
623 EXPECT_TRUE(successStoreNode);
626 EXPECT_EQ(gammaNode->subregion(0)->numNodes(), 1u);
631 addressEntryVar.branchArgument[0]);
634TEST(StoreOperationTests, normalizeIOBarrierAddress_GEP)
640 const auto pointerType = PointerType::Create();
641 const auto memoryStateType = MemoryStateType::Create();
643 const auto ioStateType = IOStateType::Create();
644 const auto arrayType = ArrayType::Create(bit32Type, 10);
647 const auto valueImport = &GraphImport::Create(graph, bit32Type,
"value");
648 const auto sizeImport = &GraphImport::Create(graph, bit32Type,
"value");
649 auto ioStateImport = &GraphImport::Create(graph, ioStateType,
"ioState");
651 auto & zeroNode = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 0);
652 auto & twoNode = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 2);
653 auto & tenNode = IntegerConstantOperation::Create(graph.
GetRootRegion(), 32, 10);
655 auto allocaResults = AllocaOperation::create(arrayType, sizeImport, 4);
657 auto & gepNode1 = GetElementPtrOperation::createNode(
659 { zeroNode.output(0), twoNode.output(0) },
662 { gepNode1.output(0), ioStateImport },
664 auto & storeNode1 = StoreNonVolatileOperation::CreateNode(
665 *ioBarrierNode1.output(0),
667 { allocaResults[1] },
670 auto & gepNode2 = GetElementPtrOperation::createNode(
672 { zeroNode.output(0), tenNode.output(0) },
675 { gepNode2.output(0), ioStateImport },
677 auto & storeNode2 = StoreNonVolatileOperation::CreateNode(
678 *ioBarrierNode2.output(0),
680 { allocaResults[1] },
683 auto & ex1 = GraphExport::Create(*storeNode1.output(0),
"store1");
684 auto & ex2 = GraphExport::Create(*storeNode2.output(0),
"store2");
690 StoreNonVolatileOperation::normalizeIOBarrierAddress,
694 StoreNonVolatileOperation::normalizeIOBarrierAddress,
702 EXPECT_TRUE(successStoreNode1);
711 EXPECT_FALSE(successStoreNode2);
714 ioBarrierNode2.output(0));