comparison llvm/unittests/Analysis/MemorySSATest.cpp @ 236:c4bab56944e8 llvm-original

LLVM 16
author kono
date Wed, 09 Nov 2022 17:45:10 +0900
parents 79ff65ed7e25
children 1f2b6ac9f198
comparison
equal deleted inserted replaced
232:70dce7da266c 236:c4bab56944e8
1001 EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2), 1001 EXPECT_EQ(MSSA.getWalker()->getClobberingMemoryAccess(DefX2),
1002 MSSA.getLiveOnEntryDef()) 1002 MSSA.getLiveOnEntryDef())
1003 << "(DefX1 = " << DefX1 << ")"; 1003 << "(DefX1 = " << DefX1 << ")";
1004 } 1004 }
1005 1005
1006 // Test Must alias for optimized uses
1007 TEST_F(MemorySSATest, TestLoadMustAlias) {
1008 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
1009 GlobalValue::ExternalLinkage, "F", &M);
1010 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1011 Type *Int8 = Type::getInt8Ty(C);
1012 Value *AllocaA = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "A");
1013 Value *AllocaB = B.CreateAlloca(Int8, ConstantInt::get(Int8, 1), "B");
1014
1015 B.CreateStore(ConstantInt::get(Int8, 1), AllocaB);
1016 // Check load from LOE
1017 LoadInst *LA1 = B.CreateLoad(Int8, AllocaA, "");
1018 // Check load alias cached for second load
1019 LoadInst *LA2 = B.CreateLoad(Int8, AllocaA, "");
1020
1021 B.CreateStore(ConstantInt::get(Int8, 1), AllocaA);
1022 // Check load from store/def
1023 LoadInst *LA3 = B.CreateLoad(Int8, AllocaA, "");
1024 // Check load alias cached for second load
1025 LoadInst *LA4 = B.CreateLoad(Int8, AllocaA, "");
1026
1027 setupAnalyses();
1028 MemorySSA &MSSA = *Analyses->MSSA;
1029
1030 unsigned I = 0;
1031 for (LoadInst *V : {LA1, LA2}) {
1032 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1033 EXPECT_EQ(MemUse->getOptimizedAccessType(), None)
1034 << "Load " << I << " doesn't have the correct alias information";
1035 // EXPECT_EQ expands such that if we increment I above, it won't get
1036 // incremented except when we try to print the error message.
1037 ++I;
1038 }
1039 for (LoadInst *V : {LA3, LA4}) {
1040 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1041 EXPECT_EQ(MemUse->getOptimizedAccessType().getValue(),
1042 AliasResult::MustAlias)
1043 << "Load " << I << " doesn't have the correct alias information";
1044 // EXPECT_EQ expands such that if we increment I above, it won't get
1045 // incremented except when we try to print the error message.
1046 ++I;
1047 }
1048 }
1049
1050 // Test Must alias for optimized defs. 1006 // Test Must alias for optimized defs.
1051 TEST_F(MemorySSATest, TestStoreMustAlias) { 1007 TEST_F(MemorySSATest, TestStoreMustAlias) {
1052 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false), 1008 F = Function::Create(FunctionType::get(B.getVoidTy(), {}, false),
1053 GlobalValue::ExternalLinkage, "F", &M); 1009 GlobalValue::ExternalLinkage, "F", &M);
1054 B.SetInsertPoint(BasicBlock::Create(C, "", F)); 1010 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1069 unsigned I = 0; 1025 unsigned I = 0;
1070 for (StoreInst *V : {SA1, SB1, SA2, SB2, SA3, SB3}) { 1026 for (StoreInst *V : {SA1, SB1, SA2, SB2, SA3, SB3}) {
1071 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V)); 1027 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
1072 EXPECT_EQ(MemDef->isOptimized(), false) 1028 EXPECT_EQ(MemDef->isOptimized(), false)
1073 << "Store " << I << " is optimized from the start?"; 1029 << "Store " << I << " is optimized from the start?";
1074 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1075 << "Store " << I
1076 << " has correct alias information before being optimized?";
1077 if (V == SA1) 1030 if (V == SA1)
1078 Walker->getClobberingMemoryAccess(V); 1031 Walker->getClobberingMemoryAccess(V);
1079 else { 1032 else {
1080 MemoryAccess *Def = MemDef->getDefiningAccess(); 1033 MemoryAccess *Def = MemDef->getDefiningAccess();
1081 MemoryAccess *Clob = Walker->getClobberingMemoryAccess(V); 1034 MemoryAccess *Clob = Walker->getClobberingMemoryAccess(V);
1082 EXPECT_NE(Def, Clob) << "Store " << I 1035 EXPECT_NE(Def, Clob) << "Store " << I
1083 << " has Defining Access equal to Clobbering Access"; 1036 << " has Defining Access equal to Clobbering Access";
1084 } 1037 }
1085 EXPECT_EQ(MemDef->isOptimized(), true) 1038 EXPECT_EQ(MemDef->isOptimized(), true)
1086 << "Store " << I << " was not optimized"; 1039 << "Store " << I << " was not optimized";
1087 if (I == 0 || I == 1)
1088 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1089 << "Store " << I << " doesn't have the correct alias information";
1090 else
1091 EXPECT_EQ(MemDef->getOptimizedAccessType().getValue(),
1092 AliasResult::MustAlias)
1093 << "Store " << I << " doesn't have the correct alias information";
1094 // EXPECT_EQ expands such that if we increment I above, it won't get
1095 // incremented except when we try to print the error message.
1096 ++I;
1097 }
1098 }
1099
1100 // Test May alias for optimized uses.
1101 TEST_F(MemorySSATest, TestLoadMayAlias) {
1102 F = Function::Create(FunctionType::get(B.getVoidTy(),
1103 {B.getInt8PtrTy(), B.getInt8PtrTy()},
1104 false),
1105 GlobalValue::ExternalLinkage, "F", &M);
1106 B.SetInsertPoint(BasicBlock::Create(C, "", F));
1107 Type *Int8 = Type::getInt8Ty(C);
1108 auto *ArgIt = F->arg_begin();
1109 Argument *PointerA = &*ArgIt;
1110 Argument *PointerB = &*(++ArgIt);
1111 B.CreateStore(ConstantInt::get(Int8, 1), PointerB);
1112 LoadInst *LA1 = B.CreateLoad(Int8, PointerA, "");
1113 B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
1114 LoadInst *LB1 = B.CreateLoad(Int8, PointerB, "");
1115 B.CreateStore(ConstantInt::get(Int8, 0), PointerA);
1116 LoadInst *LA2 = B.CreateLoad(Int8, PointerA, "");
1117 B.CreateStore(ConstantInt::get(Int8, 0), PointerB);
1118 LoadInst *LB2 = B.CreateLoad(Int8, PointerB, "");
1119
1120 setupAnalyses();
1121 MemorySSA &MSSA = *Analyses->MSSA;
1122
1123 unsigned I = 0;
1124 for (LoadInst *V : {LA1, LB1}) {
1125 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1126 EXPECT_EQ(MemUse->getOptimizedAccessType().getValue(),
1127 AliasResult::MayAlias)
1128 << "Load " << I << " doesn't have the correct alias information";
1129 // EXPECT_EQ expands such that if we increment I above, it won't get
1130 // incremented except when we try to print the error message.
1131 ++I;
1132 }
1133 for (LoadInst *V : {LA2, LB2}) {
1134 MemoryUse *MemUse = dyn_cast_or_null<MemoryUse>(MSSA.getMemoryAccess(V));
1135 EXPECT_EQ(MemUse->getOptimizedAccessType().getValue(),
1136 AliasResult::MustAlias)
1137 << "Load " << I << " doesn't have the correct alias information";
1138 // EXPECT_EQ expands such that if we increment I above, it won't get 1040 // EXPECT_EQ expands such that if we increment I above, it won't get
1139 // incremented except when we try to print the error message. 1041 // incremented except when we try to print the error message.
1140 ++I; 1042 ++I;
1141 } 1043 }
1142 } 1044 }
1176 unsigned I = 0; 1078 unsigned I = 0;
1177 for (StoreInst *V : Sts) { 1079 for (StoreInst *V : Sts) {
1178 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V)); 1080 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
1179 EXPECT_EQ(MemDef->isOptimized(), false) 1081 EXPECT_EQ(MemDef->isOptimized(), false)
1180 << "Store " << I << " is optimized from the start?"; 1082 << "Store " << I << " is optimized from the start?";
1181 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1182 << "Store " << I
1183 << " has correct alias information before being optimized?";
1184 ++I; 1083 ++I;
1185 } 1084 }
1186 1085
1187 for (StoreInst *V : Sts) 1086 for (StoreInst *V : Sts)
1188 Walker->getClobberingMemoryAccess(V); 1087 Walker->getClobberingMemoryAccess(V);
1190 I = 0; 1089 I = 0;
1191 for (StoreInst *V : Sts) { 1090 for (StoreInst *V : Sts) {
1192 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V)); 1091 MemoryDef *MemDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess(V));
1193 EXPECT_EQ(MemDef->isOptimized(), true) 1092 EXPECT_EQ(MemDef->isOptimized(), true)
1194 << "Store " << I << " was not optimized"; 1093 << "Store " << I << " was not optimized";
1195 if (I == 1 || I == 3 || I == 4)
1196 EXPECT_EQ(MemDef->getOptimizedAccessType().getValue(),
1197 AliasResult::MayAlias)
1198 << "Store " << I << " doesn't have the correct alias information";
1199 else if (I == 0 || I == 2)
1200 EXPECT_EQ(MemDef->getOptimizedAccessType(), None)
1201 << "Store " << I << " doesn't have the correct alias information";
1202 else
1203 EXPECT_EQ(MemDef->getOptimizedAccessType().getValue(),
1204 AliasResult::MustAlias)
1205 << "Store " << I << " doesn't have the correct alias information";
1206 // EXPECT_EQ expands such that if we increment I above, it won't get 1094 // EXPECT_EQ expands such that if we increment I above, it won't get
1207 // incremented except when we try to print the error message. 1095 // incremented except when we try to print the error message.
1208 ++I; 1096 ++I;
1209 } 1097 }
1210 } 1098 }
1724 EXPECT_TRUE(ItB->second.Size.hasValue()); 1612 EXPECT_TRUE(ItB->second.Size.hasValue());
1725 EXPECT_TRUE(ItB->second.Size.getValue() == 8); 1613 EXPECT_TRUE(ItB->second.Size.getValue() == 8);
1726 } 1614 }
1727 } 1615 }
1728 } 1616 }
1617
1618 TEST_F(MemorySSATest, TestInvariantGroup) {
1619 SMDiagnostic E;
1620 auto M = parseAssemblyString("declare void @f(i8*)\n"
1621 "define i8 @test(i8* %p) {\n"
1622 "entry:\n"
1623 " store i8 42, i8* %p, !invariant.group !0\n"
1624 " call void @f(i8* %p)\n"
1625 " %v = load i8, i8* %p, !invariant.group !0\n"
1626 " ret i8 %v\n"
1627 "}\n"
1628 "!0 = !{}",
1629 E, C);
1630 ASSERT_TRUE(M);
1631 F = M->getFunction("test");
1632 ASSERT_TRUE(F);
1633 setupAnalyses();
1634 MemorySSA &MSSA = *Analyses->MSSA;
1635 MemorySSAWalker *Walker = Analyses->Walker;
1636
1637 auto &BB = F->getEntryBlock();
1638 auto &SI = cast<StoreInst>(*BB.begin());
1639 auto &Call = cast<CallBase>(*std::next(BB.begin()));
1640 auto &LI = cast<LoadInst>(*std::next(std::next(BB.begin())));
1641
1642 {
1643 MemoryAccess *SAccess = MSSA.getMemoryAccess(&SI);
1644 MemoryAccess *LAccess = MSSA.getMemoryAccess(&LI);
1645 MemoryAccess *SClobber = Walker->getClobberingMemoryAccess(SAccess);
1646 EXPECT_TRUE(MSSA.isLiveOnEntryDef(SClobber));
1647 MemoryAccess *LClobber = Walker->getClobberingMemoryAccess(LAccess);
1648 EXPECT_EQ(SAccess, LClobber);
1649 }
1650
1651 // remove store and verify that the memory accesses still make sense
1652 MemorySSAUpdater Updater(&MSSA);
1653 Updater.removeMemoryAccess(&SI);
1654 SI.eraseFromParent();
1655
1656 {
1657 MemoryAccess *CallAccess = MSSA.getMemoryAccess(&Call);
1658 MemoryAccess *LAccess = MSSA.getMemoryAccess(&LI);
1659 MemoryAccess *LClobber = Walker->getClobberingMemoryAccess(LAccess);
1660 EXPECT_EQ(CallAccess, LClobber);
1661 }
1662 }
1663
1664 static BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
1665 for (BasicBlock &BB : F)
1666 if (BB.getName() == Name)
1667 return &BB;
1668 llvm_unreachable("Expected to find basic block!");
1669 }
1670
1671 static Instruction *getInstructionByName(Function &F, StringRef Name) {
1672 for (BasicBlock &BB : F)
1673 for (Instruction &I : BB)
1674 if (I.getName() == Name)
1675 return &I;
1676 llvm_unreachable("Expected to find instruction!");
1677 }
1678
1679 TEST_F(MemorySSATest, TestVisitedBlocks) {
1680 SMDiagnostic E;
1681 auto M = parseAssemblyString(
1682 "define void @test(i64* noalias %P, i64 %N) {\n"
1683 "preheader.n:\n"
1684 " br label %header.n\n"
1685 "header.n:\n"
1686 " %n = phi i64 [ 0, %preheader.n ], [ %inc.n, %latch.n ]\n"
1687 " %guard.cond.i = icmp slt i64 0, %N\n"
1688 " br i1 %guard.cond.i, label %header.i.check, label %other.i\n"
1689 "header.i.check:\n"
1690 " br label %preheader.i\n"
1691 "preheader.i:\n"
1692 " br label %header.i\n"
1693 "header.i:\n"
1694 " %i = phi i64 [ 0, %preheader.i ], [ %inc.i, %header.i ]\n"
1695 " %v1 = load i64, i64* %P, align 8\n"
1696 " %v2 = load i64, i64* %P, align 8\n"
1697 " %inc.i = add nsw i64 %i, 1\n"
1698 " %cmp.i = icmp slt i64 %inc.i, %N\n"
1699 " br i1 %cmp.i, label %header.i, label %exit.i\n"
1700 "exit.i:\n"
1701 " br label %commonexit\n"
1702 "other.i:\n"
1703 " br label %commonexit\n"
1704 "commonexit:\n"
1705 " br label %latch.n\n"
1706 "latch.n:\n"
1707 " %inc.n = add nsw i64 %n, 1\n"
1708 " %cmp.n = icmp slt i64 %inc.n, %N\n"
1709 " br i1 %cmp.n, label %header.n, label %exit.n\n"
1710 "exit.n:\n"
1711 " ret void\n"
1712 "}\n",
1713 E, C);
1714 ASSERT_TRUE(M);
1715 F = M->getFunction("test");
1716 ASSERT_TRUE(F);
1717 setupAnalyses();
1718 MemorySSA &MSSA = *Analyses->MSSA;
1719 MemorySSAUpdater Updater(&MSSA);
1720
1721 {
1722 // Move %v1 before the terminator of %header.i.check
1723 BasicBlock *BB = getBasicBlockByName(*F, "header.i.check");
1724 Instruction *LI = getInstructionByName(*F, "v1");
1725 LI->moveBefore(BB->getTerminator());
1726 if (MemoryUseOrDef *MUD = MSSA.getMemoryAccess(LI))
1727 Updater.moveToPlace(MUD, BB, MemorySSA::BeforeTerminator);
1728
1729 // Change the termiantor of %header.i.check to `br label true, label
1730 // %preheader.i, label %other.i`
1731 BB->getTerminator()->eraseFromParent();
1732 ConstantInt *BoolTrue = ConstantInt::getTrue(F->getContext());
1733 BranchInst::Create(getBasicBlockByName(*F, "preheader.i"),
1734 getBasicBlockByName(*F, "other.i"), BoolTrue, BB);
1735 SmallVector<DominatorTree::UpdateType, 4> DTUpdates;
1736 DTUpdates.push_back(DominatorTree::UpdateType(
1737 DominatorTree::Insert, BB, getBasicBlockByName(*F, "other.i")));
1738 Updater.applyUpdates(DTUpdates, Analyses->DT, true);
1739 }
1740
1741 // After the first moveToPlace(), %other.i is in VisitedBlocks, even after
1742 // there is a new edge to %other.i, which makes the second moveToPlace()
1743 // traverse incorrectly.
1744 {
1745 // Move %v2 before the terminator of %preheader.i
1746 BasicBlock *BB = getBasicBlockByName(*F, "preheader.i");
1747 Instruction *LI = getInstructionByName(*F, "v2");
1748 LI->moveBefore(BB->getTerminator());
1749 // Check that there is no assertion of "Incomplete phi during partial
1750 // rename"
1751 if (MemoryUseOrDef *MUD = MSSA.getMemoryAccess(LI))
1752 Updater.moveToPlace(MUD, BB, MemorySSA::BeforeTerminator);
1753 }
1754 }
1755
1756 TEST_F(MemorySSATest, TestNoDbgInsts) {
1757 SMDiagnostic E;
1758 auto M = parseAssemblyString(R"(
1759 define void @test() presplitcoroutine {
1760 entry:
1761 %i = alloca i32
1762 call void @llvm.dbg.declare(metadata ptr %i, metadata !6, metadata !DIExpression()), !dbg !10
1763 call void @llvm.dbg.value(metadata ptr %i, metadata !6, metadata !DIExpression()), !dbg !10
1764 ret void
1765 }
1766
1767 declare void @llvm.dbg.declare(metadata, metadata, metadata) nocallback nofree nosync nounwind readnone speculatable willreturn
1768 declare void @llvm.dbg.value(metadata, metadata, metadata) nocallback nofree nosync nounwind readnone speculatable willreturn
1769
1770 !llvm.dbg.cu = !{!0}
1771
1772 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 15.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
1773 !1 = !DIFile(filename: "repro.cpp", directory: ".")
1774 !2 = !{}
1775 !3 = !{i32 7, !"Dwarf Version", i32 4}
1776 !4 = !{i32 2, !"Debug Info Version", i32 3}
1777 !5 = !{!"clang version 15.0.0"}
1778 !6 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 24, type: !10)
1779 !7 = distinct !DILexicalBlock(scope: !8, file: !1, line: 23, column: 12)
1780 !8 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 23, type: !9, scopeLine: 23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
1781 !9 = !DISubroutineType(types: !2)
1782 !10 = !DILocation(line: 24, column: 7, scope: !7)
1783 )",
1784 E, C);
1785 ASSERT_TRUE(M);
1786 F = M->getFunction("test");
1787 ASSERT_TRUE(F);
1788 setupAnalyses();
1789 MemorySSA &MSSA = *Analyses->MSSA;
1790 MemorySSAUpdater Updater(&MSSA);
1791
1792 BasicBlock &Entry = F->front();
1793 auto I = Entry.begin();
1794 Instruction *DbgDeclare = cast<Instruction>(I++);
1795 Instruction *DbgValue = cast<Instruction>(I++);
1796 ASSERT_EQ(MSSA.getMemoryAccess(DbgDeclare), nullptr);
1797 ASSERT_EQ(MSSA.getMemoryAccess(DbgValue), nullptr);
1798 }