1 //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/Utils/ValueMapper.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/DebugInfoMetadata.h"
12 #include "llvm/IR/Function.h"
13 #include "llvm/IR/GlobalVariable.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Metadata.h"
16 #include "gtest/gtest.h"
22 TEST(ValueMapperTest
, mapMDNode
) {
24 auto *U
= MDTuple::get(Context
, std::nullopt
);
26 // The node should be unchanged.
28 EXPECT_EQ(U
, ValueMapper(VM
).mapMDNode(*U
));
31 TEST(ValueMapperTest
, mapMDNodeCycle
) {
36 Metadata
*Ops
[] = {nullptr};
37 auto T
= MDTuple::getTemporary(Context
, Ops
);
39 U0
= MDTuple::get(Context
, Ops
);
40 T
->replaceOperandWith(0, U0
);
41 U1
= MDNode::replaceWithUniqued(std::move(T
));
45 EXPECT_TRUE(U0
->isResolved());
46 EXPECT_TRUE(U0
->isUniqued());
47 EXPECT_TRUE(U1
->isResolved());
48 EXPECT_TRUE(U1
->isUniqued());
49 EXPECT_EQ(U1
, U0
->getOperand(0));
50 EXPECT_EQ(U0
, U1
->getOperand(0));
52 // Cycles shouldn't be duplicated.
55 EXPECT_EQ(U0
, ValueMapper(VM
).mapMDNode(*U0
));
56 EXPECT_EQ(U1
, ValueMapper(VM
).mapMDNode(*U1
));
59 // Check the other order.
62 EXPECT_EQ(U1
, ValueMapper(VM
).mapMDNode(*U1
));
63 EXPECT_EQ(U0
, ValueMapper(VM
).mapMDNode(*U0
));
67 TEST(ValueMapperTest
, mapMDNodeDuplicatedCycle
) {
69 auto *PtrTy
= PointerType::get(Context
, 0);
70 std::unique_ptr
<GlobalVariable
> G0
= std::make_unique
<GlobalVariable
>(
71 PtrTy
, false, GlobalValue::ExternalLinkage
, nullptr, "G0");
72 std::unique_ptr
<GlobalVariable
> G1
= std::make_unique
<GlobalVariable
>(
73 PtrTy
, false, GlobalValue::ExternalLinkage
, nullptr, "G1");
75 // Create a cycle that references G0.
76 MDNode
*N0
; // !0 = !{!1}
77 MDNode
*N1
; // !1 = !{!0, i8* @G0}
79 auto T0
= MDTuple::getTemporary(Context
, nullptr);
80 Metadata
*Ops1
[] = {T0
.get(), ConstantAsMetadata::get(G0
.get())};
81 N1
= MDTuple::get(Context
, Ops1
);
82 T0
->replaceOperandWith(0, N1
);
83 N0
= MDNode::replaceWithUniqued(std::move(T0
));
87 ASSERT_FALSE(N0
->isResolved());
88 ASSERT_FALSE(N1
->isResolved());
90 ASSERT_TRUE(N0
->isResolved());
91 ASSERT_TRUE(N1
->isResolved());
93 // Seed the value map to map G0 to G1 and map the nodes. The output should
94 // have new nodes that reference G1 (instead of G0).
96 VM
[G0
.get()] = G1
.get();
97 MDNode
*MappedN0
= ValueMapper(VM
).mapMDNode(*N0
);
98 MDNode
*MappedN1
= ValueMapper(VM
).mapMDNode(*N1
);
99 EXPECT_NE(N0
, MappedN0
);
100 EXPECT_NE(N1
, MappedN1
);
101 EXPECT_EQ(ConstantAsMetadata::get(G1
.get()), MappedN1
->getOperand(1));
103 // Check that the output nodes are resolved.
104 EXPECT_TRUE(MappedN0
->isResolved());
105 EXPECT_TRUE(MappedN1
->isResolved());
108 TEST(ValueMapperTest
, mapMDNodeUnresolved
) {
110 TempMDTuple T
= MDTuple::getTemporary(Context
, std::nullopt
);
112 ValueToValueMapTy VM
;
113 EXPECT_EQ(T
.get(), ValueMapper(VM
, RF_NoModuleLevelChanges
).mapMDNode(*T
));
116 TEST(ValueMapperTest
, mapMDNodeDistinct
) {
118 auto *D
= MDTuple::getDistinct(Context
, std::nullopt
);
121 // The node should be cloned.
122 ValueToValueMapTy VM
;
123 EXPECT_NE(D
, ValueMapper(VM
).mapMDNode(*D
));
126 // The node should be moved.
127 ValueToValueMapTy VM
;
128 EXPECT_EQ(D
, ValueMapper(VM
, RF_ReuseAndMutateDistinctMDs
).mapMDNode(*D
));
132 TEST(ValueMapperTest
, mapMDNodeDistinctOperands
) {
134 Metadata
*Old
= MDTuple::getDistinct(Context
, std::nullopt
);
135 auto *D
= MDTuple::getDistinct(Context
, Old
);
136 ASSERT_EQ(Old
, D
->getOperand(0));
138 Metadata
*New
= MDTuple::getDistinct(Context
, std::nullopt
);
139 ValueToValueMapTy VM
;
140 VM
.MD()[Old
].reset(New
);
142 // Make sure operands are updated.
143 EXPECT_EQ(D
, ValueMapper(VM
, RF_ReuseAndMutateDistinctMDs
).mapMDNode(*D
));
144 EXPECT_EQ(New
, D
->getOperand(0));
147 TEST(ValueMapperTest
, mapMDNodeSeeded
) {
149 auto *D
= MDTuple::getDistinct(Context
, std::nullopt
);
151 // The node should be moved.
152 ValueToValueMapTy VM
;
153 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(D
));
155 VM
.MD().insert(std::make_pair(D
, TrackingMDRef(D
)));
156 EXPECT_EQ(D
, *VM
.getMappedMD(D
));
157 EXPECT_EQ(D
, ValueMapper(VM
).mapMDNode(*D
));
160 TEST(ValueMapperTest
, mapMDNodeSeededWithNull
) {
162 auto *D
= MDTuple::getDistinct(Context
, std::nullopt
);
164 // The node should be moved.
165 ValueToValueMapTy VM
;
166 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(D
));
168 VM
.MD().insert(std::make_pair(D
, TrackingMDRef()));
169 EXPECT_EQ(nullptr, *VM
.getMappedMD(D
));
170 EXPECT_EQ(nullptr, ValueMapper(VM
).mapMDNode(*D
));
173 TEST(ValueMapperTest
, mapMetadataNullMapGlobalWithIgnoreMissingLocals
) {
176 FunctionType::get(Type::getVoidTy(C
), Type::getInt8Ty(C
), false);
177 std::unique_ptr
<Function
> F(
178 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
180 ValueToValueMapTy VM
;
181 RemapFlags Flags
= RF_IgnoreMissingLocals
| RF_NullMapMissingGlobalValues
;
182 EXPECT_EQ(nullptr, ValueMapper(VM
, Flags
).mapValue(*F
));
185 TEST(ValueMapperTest
, mapMetadataMDString
) {
187 auto *S1
= MDString::get(C
, "S1");
188 ValueToValueMapTy VM
;
190 // Make sure S1 maps to itself, but isn't memoized.
191 EXPECT_EQ(S1
, ValueMapper(VM
).mapMetadata(*S1
));
192 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(S1
));
194 // We still expect VM.MD() to be respected.
195 auto *S2
= MDString::get(C
, "S2");
196 VM
.MD()[S1
].reset(S2
);
197 EXPECT_EQ(S2
, ValueMapper(VM
).mapMetadata(*S1
));
200 TEST(ValueMapperTest
, mapMetadataGetMappedMD
) {
202 auto *N0
= MDTuple::get(C
, std::nullopt
);
203 auto *N1
= MDTuple::get(C
, N0
);
205 // Make sure hasMD and getMappedMD work correctly.
206 ValueToValueMapTy VM
;
207 EXPECT_FALSE(VM
.hasMD());
208 EXPECT_EQ(N0
, ValueMapper(VM
).mapMetadata(*N0
));
209 EXPECT_EQ(N1
, ValueMapper(VM
).mapMetadata(*N1
));
210 EXPECT_TRUE(VM
.hasMD());
211 ASSERT_NE(std::nullopt
, VM
.getMappedMD(N0
));
212 ASSERT_NE(std::nullopt
, VM
.getMappedMD(N1
));
213 EXPECT_EQ(N0
, *VM
.getMappedMD(N0
));
214 EXPECT_EQ(N1
, *VM
.getMappedMD(N1
));
217 TEST(ValueMapperTest
, mapMetadataNoModuleLevelChanges
) {
219 auto *N0
= MDTuple::get(C
, std::nullopt
);
220 auto *N1
= MDTuple::get(C
, N0
);
222 // Nothing should be memoized when RF_NoModuleLevelChanges.
223 ValueToValueMapTy VM
;
224 EXPECT_FALSE(VM
.hasMD());
225 EXPECT_EQ(N0
, ValueMapper(VM
, RF_NoModuleLevelChanges
).mapMetadata(*N0
));
226 EXPECT_EQ(N1
, ValueMapper(VM
, RF_NoModuleLevelChanges
).mapMetadata(*N1
));
227 EXPECT_FALSE(VM
.hasMD());
228 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(N0
));
229 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(N1
));
232 TEST(ValueMapperTest
, mapMetadataConstantAsMetadata
) {
235 FunctionType::get(Type::getVoidTy(C
), Type::getInt8Ty(C
), false);
236 std::unique_ptr
<Function
> F(
237 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
239 auto *CAM
= ConstantAsMetadata::get(F
.get());
241 // ConstantAsMetadata shouldn't be memoized.
242 ValueToValueMapTy VM
;
243 EXPECT_EQ(CAM
, ValueMapper(VM
).mapMetadata(*CAM
));
244 EXPECT_FALSE(VM
.MD().count(CAM
));
245 EXPECT_EQ(CAM
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapMetadata(*CAM
));
246 EXPECT_FALSE(VM
.MD().count(CAM
));
248 // But it should respect a mapping that gets seeded.
249 auto *N
= MDTuple::get(C
, std::nullopt
);
250 VM
.MD()[CAM
].reset(N
);
251 EXPECT_EQ(N
, ValueMapper(VM
).mapMetadata(*CAM
));
252 EXPECT_EQ(N
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapMetadata(*CAM
));
255 std::unique_ptr
<Function
> F2(
256 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F2"));
257 ValueToValueMapTy VM
;
258 VM
[F
.get()] = F2
.get();
259 auto *F2MD
= ValueMapper(VM
).mapMetadata(*CAM
);
260 EXPECT_FALSE(VM
.MD().count(CAM
));
262 EXPECT_EQ(F2
.get(), cast
<ConstantAsMetadata
>(F2MD
)->getValue());
265 #ifdef GTEST_HAS_DEATH_TEST
267 TEST(ValueMapperTest
, mapMetadataLocalAsMetadata
) {
270 FunctionType::get(Type::getVoidTy(C
), Type::getInt8Ty(C
), false);
271 std::unique_ptr
<Function
> F(
272 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
273 Argument
&A
= *F
->arg_begin();
275 // mapMetadata doesn't support LocalAsMetadata. The only valid container for
276 // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
277 auto *LAM
= LocalAsMetadata::get(&A
);
278 ValueToValueMapTy VM
;
279 EXPECT_DEATH(ValueMapper(VM
).mapMetadata(*LAM
), "Unexpected local metadata");
280 EXPECT_DEATH(ValueMapper(VM
, RF_IgnoreMissingLocals
).mapMetadata(*LAM
),
281 "Unexpected local metadata");
286 TEST(ValueMapperTest
, mapValueLocalAsMetadata
) {
289 FunctionType::get(Type::getVoidTy(C
), Type::getInt8Ty(C
), false);
290 std::unique_ptr
<Function
> F(
291 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
292 Argument
&A
= *F
->arg_begin();
294 auto *LAM
= LocalAsMetadata::get(&A
);
295 auto *MAV
= MetadataAsValue::get(C
, LAM
);
297 // The principled answer to a LocalAsMetadata of an unmapped SSA value would
298 // be to return nullptr (regardless of RF_IgnoreMissingLocals).
300 // However, algorithms that use RemapInstruction assume that each instruction
301 // only references SSA values from previous instructions. Arguments of
302 // such as "metadata i32 %x" don't currently successfully maintain that
303 // property. To keep RemapInstruction from crashing we need a non-null
304 // return here, but we also shouldn't reference the unmapped local. Use
306 auto *N0
= MDTuple::get(C
, std::nullopt
);
307 auto *N0AV
= MetadataAsValue::get(C
, N0
);
308 ValueToValueMapTy VM
;
309 EXPECT_EQ(N0AV
, ValueMapper(VM
).mapValue(*MAV
));
310 EXPECT_EQ(nullptr, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapValue(*MAV
));
311 EXPECT_FALSE(VM
.count(MAV
));
312 EXPECT_FALSE(VM
.count(&A
));
313 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(LAM
));
316 EXPECT_EQ(MAV
, ValueMapper(VM
).mapValue(*MAV
));
317 EXPECT_EQ(MAV
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapValue(*MAV
));
318 EXPECT_TRUE(VM
.count(MAV
));
319 EXPECT_FALSE(VM
.count(&A
));
322 EXPECT_EQ(&A
, ValueMapper(VM
).mapValue(*MAV
));
323 EXPECT_EQ(&A
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapValue(*MAV
));
324 EXPECT_TRUE(VM
.count(MAV
));
325 EXPECT_FALSE(VM
.count(&A
));
328 TEST(ValueMapperTest
, mapValueLocalInArgList
) {
331 FunctionType::get(Type::getVoidTy(C
), Type::getInt8Ty(C
), false);
332 std::unique_ptr
<Function
> F(
333 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
334 Argument
&A
= *F
->arg_begin();
336 auto *LAM
= LocalAsMetadata::get(&A
);
337 std::vector
<ValueAsMetadata
*> Elts
;
339 auto *ArgList
= DIArgList::get(C
, Elts
);
340 auto *MAV
= MetadataAsValue::get(C
, ArgList
);
342 // The principled answer to a LocalAsMetadata of an unmapped SSA value would
343 // be to return nullptr (regardless of RF_IgnoreMissingLocals).
345 // However, algorithms that use RemapInstruction assume that each instruction
346 // only references SSA values from previous instructions. Arguments of
347 // such as "metadata i32 %x" don't currently successfully maintain that
348 // property. To keep RemapInstruction from crashing we need a non-null
349 // return here, but we also shouldn't reference the unmapped local. Use
350 // undef for uses in a DIArgList.
351 auto *N0
= UndefValue::get(Type::getInt8Ty(C
));
352 auto *N0AM
= ValueAsMetadata::get(N0
);
353 std::vector
<ValueAsMetadata
*> N0Elts
;
354 N0Elts
.push_back(N0AM
);
355 auto *N0ArgList
= DIArgList::get(C
, N0Elts
);
356 auto *N0AV
= MetadataAsValue::get(C
, N0ArgList
);
357 ValueToValueMapTy VM
;
358 EXPECT_EQ(N0AV
, ValueMapper(VM
).mapValue(*MAV
));
359 EXPECT_EQ(MAV
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapValue(*MAV
));
360 EXPECT_FALSE(VM
.count(MAV
));
361 EXPECT_FALSE(VM
.count(&A
));
362 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(LAM
));
363 EXPECT_EQ(std::nullopt
, VM
.getMappedMD(ArgList
));
366 EXPECT_EQ(MAV
, ValueMapper(VM
).mapValue(*MAV
));
367 EXPECT_EQ(MAV
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapValue(*MAV
));
368 EXPECT_TRUE(VM
.count(MAV
));
369 EXPECT_FALSE(VM
.count(&A
));
372 EXPECT_EQ(&A
, ValueMapper(VM
).mapValue(*MAV
));
373 EXPECT_EQ(&A
, ValueMapper(VM
, RF_IgnoreMissingLocals
).mapValue(*MAV
));
374 EXPECT_TRUE(VM
.count(MAV
));
375 EXPECT_FALSE(VM
.count(&A
));
378 TEST(ValueMapperTest
, mapValueLocalAsMetadataToConstant
) {
380 auto *Int8
= Type::getInt8Ty(Context
);
381 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(Context
), Int8
, false);
382 std::unique_ptr
<Function
> F(
383 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
385 // Map a local value to a constant.
386 Argument
&A
= *F
->arg_begin();
387 Constant
&C
= *ConstantInt::get(Int8
, 42);
388 ValueToValueMapTy VM
;
391 // Look up the metadata-as-value wrapper. Don't crash.
392 auto *MDA
= MetadataAsValue::get(Context
, ValueAsMetadata::get(&A
));
393 auto *MDC
= MetadataAsValue::get(Context
, ValueAsMetadata::get(&C
));
394 EXPECT_TRUE(isa
<LocalAsMetadata
>(MDA
->getMetadata()));
395 EXPECT_TRUE(isa
<ConstantAsMetadata
>(MDC
->getMetadata()));
396 EXPECT_EQ(&C
, ValueMapper(VM
).mapValue(A
));
397 EXPECT_EQ(MDC
, ValueMapper(VM
).mapValue(*MDA
));
400 // Type remapper which remaps all types to same destination.
401 class TestTypeRemapper
: public ValueMapTypeRemapper
{
403 TestTypeRemapper(Type
*Ty
) : DstTy(Ty
) { }
404 Type
*remapType(Type
*srcTy
) { return DstTy
; }
409 TEST(ValueMapperTest
, mapValuePoisonWithTypeRemap
) {
411 Type
*OldTy
= Type::getInt8Ty(C
);
412 Type
*NewTy
= Type::getInt32Ty(C
);
414 TestTypeRemapper
TM(NewTy
);
415 ValueToValueMapTy VM
;
416 ValueMapper
Mapper(VM
, RF_None
, &TM
);
418 // Check that poison is still poison and has not been converted to undef.
419 auto *OldPoison
= PoisonValue::get(OldTy
);
420 auto *NewPoison
= PoisonValue::get(NewTy
);
421 EXPECT_EQ(NewPoison
, Mapper
.mapValue(*OldPoison
));
424 TEST(ValueMapperTest
, mapValueConstantTargetNoneToLayoutTypeNullValue
) {
426 auto *OldTy
= TargetExtType::get(C
, "spirv.Event");
427 Type
*NewTy
= OldTy
->getLayoutType();
429 TestTypeRemapper
TM(NewTy
);
430 ValueToValueMapTy VM
;
431 ValueMapper
Mapper(VM
, RF_None
, &TM
);
433 // Check that ConstantTargetNone is mapped to '0' constant of its layout type.
434 auto *OldConstant
= ConstantTargetNone::get(OldTy
);
435 auto *NewConstant
= Constant::getNullValue(NewTy
);
436 EXPECT_EQ(NewConstant
, Mapper
.mapValue(*OldConstant
));