diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-08 03:13:22 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-08 03:13:22 +0000 |
commit | 4ec55f8ab6f172bfe38e4ca89bfd0747e166995b (patch) | |
tree | 5fd2effcf9ffde9ffec63eb4b9eca8d71efa8f4f /llvm/unittests/Transforms | |
parent | f60a0d74522ea4abd1cafcec4dd19dfeab258f8f (diff) | |
download | bcm5719-llvm-4ec55f8ab6f172bfe38e4ca89bfd0747e166995b.tar.gz bcm5719-llvm-4ec55f8ab6f172bfe38e4ca89bfd0747e166995b.zip |
Reapply "ValueMapper: Treat LocalAsMetadata more like function-local Values"
This reverts commit r265765, reapplying r265759 after changing a call from
LocalAsMetadata::get to ValueAsMetadata::get (and adding a unit test). When a
local value is mapped to a constant (like "i32 %a" => "i32 7"), the new debug
intrinsic operand may no longer be pointing at a local.
http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_build/19020/
The previous coommit message follows:
--
This is a partial re-commit -- maybe more of a re-implementation -- of
r265631 (reverted in r265637).
This makes RF_IgnoreMissingLocals behave (almost) consistently between
the Value and the Metadata hierarchy. In particular:
- MapValue returns nullptr or "metadata !{}" for missing locals in
MetadataAsValue/LocalAsMetadata bridging paris, depending on
the RF_IgnoreMissingLocals flag.
- MapValue doesn't memoize LocalAsMetadata-related results.
- MapMetadata no longer deals with LocalAsMetadata or
RF_IgnoreMissingLocals at all. (This wasn't in r265631 at all, but
I realized during testing it would make the patch simpler with no
loss of generality.)
r265631 went too far, making both functions universally ignore
RF_IgnoreMissingLocals. This broke building (e.g.) compiler-rt.
Reassociate (and possibly other passes) don't currently maintain
dominates-use invariants for metadata operands, resulting in IR like
this:
define void @foo(i32 %arg) {
call void @llvm.some.intrinsic(metadata i32 %x)
%x = add i32 1, i32 %arg
}
If the inliner chooses to inline @foo into another function, then
RemapInstruction will call `MapValue(metadata i32 %x)` and assert that
the return is not nullptr.
I've filed PR27273 to add a Verifier check and fix the underlying
problem in the optimization passes.
As a workaround, return `!{}` instead of nullptr for unmapped
LocalAsMetadata when RF_IgnoreMissingLocals is unset. Otherwise, match
the behaviour of r265631.
Original commit message:
ValueMapper: Make LocalAsMetadata match function-local Values
Start treating LocalAsMetadata similarly to function-local members of
the Value hierarchy in MapValue and MapMetadata.
- Don't memoize them.
- Return nullptr if they are missing.
This also cleans up ConstantAsMetadata to stop listening to the
RF_IgnoreMissingLocals flag.
llvm-svn: 265768
Diffstat (limited to 'llvm/unittests/Transforms')
-rw-r--r-- | llvm/unittests/Transforms/Utils/ValueMapperTest.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp index 222f2a2e863..ecaea460594 100644 --- a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp +++ b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -139,4 +140,121 @@ TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) { EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags)); } +TEST(ValueMapperTest, MapMetadataConstantAsMetadata) { + LLVMContext C; + FunctionType *FTy = + FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); + std::unique_ptr<Function> F( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); + + auto *CAM = ConstantAsMetadata::get(F.get()); + { + ValueToValueMapTy VM; + EXPECT_EQ(CAM, MapMetadata(CAM, VM)); + EXPECT_TRUE(VM.MD().count(CAM)); + VM.MD().erase(CAM); + EXPECT_EQ(CAM, MapMetadata(CAM, VM, RF_IgnoreMissingLocals)); + EXPECT_TRUE(VM.MD().count(CAM)); + + auto *N = MDTuple::get(C, None); + VM.MD()[CAM].reset(N); + EXPECT_EQ(N, MapMetadata(CAM, VM)); + EXPECT_EQ(N, MapMetadata(CAM, VM, RF_IgnoreMissingLocals)); + } + + std::unique_ptr<Function> F2( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F2")); + ValueToValueMapTy VM; + VM[F.get()] = F2.get(); + auto *F2MD = MapMetadata(CAM, VM); + EXPECT_TRUE(VM.MD().count(CAM)); + EXPECT_TRUE(F2MD); + EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue()); +} + +#ifdef GTEST_HAS_DEATH_TEST +#ifndef NDEBUG +TEST(ValueMapperTest, MapMetadataLocalAsMetadata) { + LLVMContext C; + FunctionType *FTy = + FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); + std::unique_ptr<Function> F( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); + Argument &A = *F->arg_begin(); + + // MapMetadata doesn't support LocalAsMetadata. The only valid container for + // LocalAsMetadata is a MetadataAsValue instance, so use it directly. + auto *LAM = LocalAsMetadata::get(&A); + ValueToValueMapTy VM; + EXPECT_DEATH(MapMetadata(LAM, VM), "Unexpected local metadata"); + EXPECT_DEATH(MapMetadata(LAM, VM, RF_IgnoreMissingLocals), + "Unexpected local metadata"); +} +#endif +#endif + +TEST(ValueMapperTest, MapValueLocalAsMetadata) { + LLVMContext C; + FunctionType *FTy = + FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); + std::unique_ptr<Function> F( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); + Argument &A = *F->arg_begin(); + + auto *LAM = LocalAsMetadata::get(&A); + auto *MAV = MetadataAsValue::get(C, LAM); + + // The principled answer to a LocalAsMetadata of an unmapped SSA value would + // be to return nullptr (regardless of RF_IgnoreMissingLocals). + // + // However, algorithms that use RemapInstruction assume that each instruction + // only references SSA values from previous instructions. Arguments of + // such as "metadata i32 %x" don't currently successfully maintain that + // property. To keep RemapInstruction from crashing we need a non-null + // return here, but we also shouldn't reference the unmapped local. Use + // "metadata !{}". + auto *N0 = MDTuple::get(C, None); + auto *N0AV = MetadataAsValue::get(C, N0); + ValueToValueMapTy VM; + EXPECT_EQ(N0AV, MapValue(MAV, VM)); + EXPECT_EQ(nullptr, MapValue(MAV, VM, RF_IgnoreMissingLocals)); + EXPECT_FALSE(VM.count(MAV)); + EXPECT_FALSE(VM.count(&A)); + EXPECT_EQ(None, VM.getMappedMD(LAM)); + + VM[MAV] = MAV; + EXPECT_EQ(MAV, MapValue(MAV, VM)); + EXPECT_EQ(MAV, MapValue(MAV, VM, RF_IgnoreMissingLocals)); + EXPECT_TRUE(VM.count(MAV)); + EXPECT_FALSE(VM.count(&A)); + + VM[MAV] = &A; + EXPECT_EQ(&A, MapValue(MAV, VM)); + EXPECT_EQ(&A, MapValue(MAV, VM, RF_IgnoreMissingLocals)); + EXPECT_TRUE(VM.count(MAV)); + EXPECT_FALSE(VM.count(&A)); +} + +TEST(ValueMapperTest, MapValueLocalAsMetadataToConstant) { + LLVMContext Context; + auto *Int8 = Type::getInt8Ty(Context); + FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false); + std::unique_ptr<Function> F( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); + + // Map a local value to a constant. + Argument &A = *F->arg_begin(); + Constant &C = *ConstantInt::get(Int8, 42); + ValueToValueMapTy VM; + VM[&A] = &C; + + // Look up the metadata-as-value wrapper. Don't crash. + auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A)); + auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C)); + EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata())); + EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata())); + EXPECT_EQ(&C, MapValue(&A, VM)); + EXPECT_EQ(MDC, MapValue(MDA, VM)); +} + } // end namespace |