summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Transforms
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-08 03:13:22 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-08 03:13:22 +0000
commit4ec55f8ab6f172bfe38e4ca89bfd0747e166995b (patch)
tree5fd2effcf9ffde9ffec63eb4b9eca8d71efa8f4f /llvm/unittests/Transforms
parentf60a0d74522ea4abd1cafcec4dd19dfeab258f8f (diff)
downloadbcm5719-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.cpp118
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
OpenPOWER on IntegriCloud