Mercurial > hg > CbC > CbC_llvm
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 } |