ValueMapperTest.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Transforms/Utils/ValueMapper.h"
  9. #include "llvm/IR/Constants.h"
  10. #include "llvm/IR/Function.h"
  11. #include "llvm/IR/GlobalVariable.h"
  12. #include "llvm/IR/LLVMContext.h"
  13. #include "llvm/IR/Metadata.h"
  14. #include "gtest/gtest.h"
  15. using namespace llvm;
  16. namespace {
  17. TEST(ValueMapperTest, mapMDNode) {
  18. LLVMContext Context;
  19. auto *U = MDTuple::get(Context, None);
  20. // The node should be unchanged.
  21. ValueToValueMapTy VM;
  22. EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U));
  23. }
  24. TEST(ValueMapperTest, mapMDNodeCycle) {
  25. LLVMContext Context;
  26. MDNode *U0;
  27. MDNode *U1;
  28. {
  29. Metadata *Ops[] = {nullptr};
  30. auto T = MDTuple::getTemporary(Context, Ops);
  31. Ops[0] = T.get();
  32. U0 = MDTuple::get(Context, Ops);
  33. T->replaceOperandWith(0, U0);
  34. U1 = MDNode::replaceWithUniqued(std::move(T));
  35. U0->resolveCycles();
  36. }
  37. EXPECT_TRUE(U0->isResolved());
  38. EXPECT_TRUE(U0->isUniqued());
  39. EXPECT_TRUE(U1->isResolved());
  40. EXPECT_TRUE(U1->isUniqued());
  41. EXPECT_EQ(U1, U0->getOperand(0));
  42. EXPECT_EQ(U0, U1->getOperand(0));
  43. // Cycles shouldn't be duplicated.
  44. {
  45. ValueToValueMapTy VM;
  46. EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
  47. EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
  48. }
  49. // Check the other order.
  50. {
  51. ValueToValueMapTy VM;
  52. EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
  53. EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
  54. }
  55. }
  56. TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) {
  57. LLVMContext Context;
  58. auto *PtrTy = Type::getInt8Ty(Context)->getPointerTo();
  59. std::unique_ptr<GlobalVariable> G0 = std::make_unique<GlobalVariable>(
  60. PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G0");
  61. std::unique_ptr<GlobalVariable> G1 = std::make_unique<GlobalVariable>(
  62. PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G1");
  63. // Create a cycle that references G0.
  64. MDNode *N0; // !0 = !{!1}
  65. MDNode *N1; // !1 = !{!0, i8* @G0}
  66. {
  67. auto T0 = MDTuple::getTemporary(Context, nullptr);
  68. Metadata *Ops1[] = {T0.get(), ConstantAsMetadata::get(G0.get())};
  69. N1 = MDTuple::get(Context, Ops1);
  70. T0->replaceOperandWith(0, N1);
  71. N0 = MDNode::replaceWithUniqued(std::move(T0));
  72. }
  73. // Resolve N0 and N1.
  74. ASSERT_FALSE(N0->isResolved());
  75. ASSERT_FALSE(N1->isResolved());
  76. N0->resolveCycles();
  77. ASSERT_TRUE(N0->isResolved());
  78. ASSERT_TRUE(N1->isResolved());
  79. // Seed the value map to map G0 to G1 and map the nodes. The output should
  80. // have new nodes that reference G1 (instead of G0).
  81. ValueToValueMapTy VM;
  82. VM[G0.get()] = G1.get();
  83. MDNode *MappedN0 = ValueMapper(VM).mapMDNode(*N0);
  84. MDNode *MappedN1 = ValueMapper(VM).mapMDNode(*N1);
  85. EXPECT_NE(N0, MappedN0);
  86. EXPECT_NE(N1, MappedN1);
  87. EXPECT_EQ(ConstantAsMetadata::get(G1.get()), MappedN1->getOperand(1));
  88. // Check that the output nodes are resolved.
  89. EXPECT_TRUE(MappedN0->isResolved());
  90. EXPECT_TRUE(MappedN1->isResolved());
  91. }
  92. TEST(ValueMapperTest, mapMDNodeUnresolved) {
  93. LLVMContext Context;
  94. TempMDTuple T = MDTuple::getTemporary(Context, None);
  95. ValueToValueMapTy VM;
  96. EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T));
  97. }
  98. TEST(ValueMapperTest, mapMDNodeDistinct) {
  99. LLVMContext Context;
  100. auto *D = MDTuple::getDistinct(Context, None);
  101. {
  102. // The node should be cloned.
  103. ValueToValueMapTy VM;
  104. EXPECT_NE(D, ValueMapper(VM).mapMDNode(*D));
  105. }
  106. {
  107. // The node should be moved.
  108. ValueToValueMapTy VM;
  109. EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
  110. }
  111. }
  112. TEST(ValueMapperTest, mapMDNodeDistinctOperands) {
  113. LLVMContext Context;
  114. Metadata *Old = MDTuple::getDistinct(Context, None);
  115. auto *D = MDTuple::getDistinct(Context, Old);
  116. ASSERT_EQ(Old, D->getOperand(0));
  117. Metadata *New = MDTuple::getDistinct(Context, None);
  118. ValueToValueMapTy VM;
  119. VM.MD()[Old].reset(New);
  120. // Make sure operands are updated.
  121. EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
  122. EXPECT_EQ(New, D->getOperand(0));
  123. }
  124. TEST(ValueMapperTest, mapMDNodeSeeded) {
  125. LLVMContext Context;
  126. auto *D = MDTuple::getDistinct(Context, None);
  127. // The node should be moved.
  128. ValueToValueMapTy VM;
  129. EXPECT_EQ(None, VM.getMappedMD(D));
  130. VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
  131. EXPECT_EQ(D, *VM.getMappedMD(D));
  132. EXPECT_EQ(D, ValueMapper(VM).mapMDNode(*D));
  133. }
  134. TEST(ValueMapperTest, mapMDNodeSeededWithNull) {
  135. LLVMContext Context;
  136. auto *D = MDTuple::getDistinct(Context, None);
  137. // The node should be moved.
  138. ValueToValueMapTy VM;
  139. EXPECT_EQ(None, VM.getMappedMD(D));
  140. VM.MD().insert(std::make_pair(D, TrackingMDRef()));
  141. EXPECT_EQ(nullptr, *VM.getMappedMD(D));
  142. EXPECT_EQ(nullptr, ValueMapper(VM).mapMDNode(*D));
  143. }
  144. TEST(ValueMapperTest, mapMetadataNullMapGlobalWithIgnoreMissingLocals) {
  145. LLVMContext C;
  146. FunctionType *FTy =
  147. FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
  148. std::unique_ptr<Function> F(
  149. Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
  150. ValueToValueMapTy VM;
  151. RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
  152. EXPECT_EQ(nullptr, ValueMapper(VM, Flags).mapValue(*F));
  153. }
  154. TEST(ValueMapperTest, mapMetadataMDString) {
  155. LLVMContext C;
  156. auto *S1 = MDString::get(C, "S1");
  157. ValueToValueMapTy VM;
  158. // Make sure S1 maps to itself, but isn't memoized.
  159. EXPECT_EQ(S1, ValueMapper(VM).mapMetadata(*S1));
  160. EXPECT_EQ(None, VM.getMappedMD(S1));
  161. // We still expect VM.MD() to be respected.
  162. auto *S2 = MDString::get(C, "S2");
  163. VM.MD()[S1].reset(S2);
  164. EXPECT_EQ(S2, ValueMapper(VM).mapMetadata(*S1));
  165. }
  166. TEST(ValueMapperTest, mapMetadataGetMappedMD) {
  167. LLVMContext C;
  168. auto *N0 = MDTuple::get(C, None);
  169. auto *N1 = MDTuple::get(C, N0);
  170. // Make sure hasMD and getMappedMD work correctly.
  171. ValueToValueMapTy VM;
  172. EXPECT_FALSE(VM.hasMD());
  173. EXPECT_EQ(N0, ValueMapper(VM).mapMetadata(*N0));
  174. EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1));
  175. EXPECT_TRUE(VM.hasMD());
  176. ASSERT_NE(None, VM.getMappedMD(N0));
  177. ASSERT_NE(None, VM.getMappedMD(N1));
  178. EXPECT_EQ(N0, *VM.getMappedMD(N0));
  179. EXPECT_EQ(N1, *VM.getMappedMD(N1));
  180. }
  181. TEST(ValueMapperTest, mapMetadataNoModuleLevelChanges) {
  182. LLVMContext C;
  183. auto *N0 = MDTuple::get(C, None);
  184. auto *N1 = MDTuple::get(C, N0);
  185. // Nothing should be memoized when RF_NoModuleLevelChanges.
  186. ValueToValueMapTy VM;
  187. EXPECT_FALSE(VM.hasMD());
  188. EXPECT_EQ(N0, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0));
  189. EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1));
  190. EXPECT_FALSE(VM.hasMD());
  191. EXPECT_EQ(None, VM.getMappedMD(N0));
  192. EXPECT_EQ(None, VM.getMappedMD(N1));
  193. }
  194. TEST(ValueMapperTest, mapMetadataConstantAsMetadata) {
  195. LLVMContext C;
  196. FunctionType *FTy =
  197. FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
  198. std::unique_ptr<Function> F(
  199. Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
  200. auto *CAM = ConstantAsMetadata::get(F.get());
  201. {
  202. // ConstantAsMetadata shouldn't be memoized.
  203. ValueToValueMapTy VM;
  204. EXPECT_EQ(CAM, ValueMapper(VM).mapMetadata(*CAM));
  205. EXPECT_FALSE(VM.MD().count(CAM));
  206. EXPECT_EQ(CAM, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
  207. EXPECT_FALSE(VM.MD().count(CAM));
  208. // But it should respect a mapping that gets seeded.
  209. auto *N = MDTuple::get(C, None);
  210. VM.MD()[CAM].reset(N);
  211. EXPECT_EQ(N, ValueMapper(VM).mapMetadata(*CAM));
  212. EXPECT_EQ(N, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
  213. }
  214. std::unique_ptr<Function> F2(
  215. Function::Create(FTy, GlobalValue::ExternalLinkage, "F2"));
  216. ValueToValueMapTy VM;
  217. VM[F.get()] = F2.get();
  218. auto *F2MD = ValueMapper(VM).mapMetadata(*CAM);
  219. EXPECT_FALSE(VM.MD().count(CAM));
  220. EXPECT_TRUE(F2MD);
  221. EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue());
  222. }
  223. #ifdef GTEST_HAS_DEATH_TEST
  224. #ifndef NDEBUG
  225. TEST(ValueMapperTest, mapMetadataLocalAsMetadata) {
  226. LLVMContext C;
  227. FunctionType *FTy =
  228. FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
  229. std::unique_ptr<Function> F(
  230. Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
  231. Argument &A = *F->arg_begin();
  232. // mapMetadata doesn't support LocalAsMetadata. The only valid container for
  233. // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
  234. auto *LAM = LocalAsMetadata::get(&A);
  235. ValueToValueMapTy VM;
  236. EXPECT_DEATH(ValueMapper(VM).mapMetadata(*LAM), "Unexpected local metadata");
  237. EXPECT_DEATH(ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*LAM),
  238. "Unexpected local metadata");
  239. }
  240. #endif
  241. #endif
  242. TEST(ValueMapperTest, mapValueLocalAsMetadata) {
  243. LLVMContext C;
  244. FunctionType *FTy =
  245. FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
  246. std::unique_ptr<Function> F(
  247. Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
  248. Argument &A = *F->arg_begin();
  249. auto *LAM = LocalAsMetadata::get(&A);
  250. auto *MAV = MetadataAsValue::get(C, LAM);
  251. // The principled answer to a LocalAsMetadata of an unmapped SSA value would
  252. // be to return nullptr (regardless of RF_IgnoreMissingLocals).
  253. //
  254. // However, algorithms that use RemapInstruction assume that each instruction
  255. // only references SSA values from previous instructions. Arguments of
  256. // such as "metadata i32 %x" don't currently successfully maintain that
  257. // property. To keep RemapInstruction from crashing we need a non-null
  258. // return here, but we also shouldn't reference the unmapped local. Use
  259. // "metadata !{}".
  260. auto *N0 = MDTuple::get(C, None);
  261. auto *N0AV = MetadataAsValue::get(C, N0);
  262. ValueToValueMapTy VM;
  263. EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV));
  264. EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
  265. EXPECT_FALSE(VM.count(MAV));
  266. EXPECT_FALSE(VM.count(&A));
  267. EXPECT_EQ(None, VM.getMappedMD(LAM));
  268. VM[MAV] = MAV;
  269. EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV));
  270. EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
  271. EXPECT_TRUE(VM.count(MAV));
  272. EXPECT_FALSE(VM.count(&A));
  273. VM[MAV] = &A;
  274. EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV));
  275. EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
  276. EXPECT_TRUE(VM.count(MAV));
  277. EXPECT_FALSE(VM.count(&A));
  278. }
  279. TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) {
  280. LLVMContext Context;
  281. auto *Int8 = Type::getInt8Ty(Context);
  282. FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false);
  283. std::unique_ptr<Function> F(
  284. Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
  285. // Map a local value to a constant.
  286. Argument &A = *F->arg_begin();
  287. Constant &C = *ConstantInt::get(Int8, 42);
  288. ValueToValueMapTy VM;
  289. VM[&A] = &C;
  290. // Look up the metadata-as-value wrapper. Don't crash.
  291. auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A));
  292. auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C));
  293. EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata()));
  294. EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata()));
  295. EXPECT_EQ(&C, ValueMapper(VM).mapValue(A));
  296. EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA));
  297. }
  298. } // end namespace