From 2ebcd57e6adf2dc951eb7ad5f42952961f1a60c9 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 30 Sep 2013 21:23:03 +0000 Subject: Fix getOrInsertGlobal dropping the address space. Currently it will insert an illegal bitcast. Arguably, the address space argument should be added for the creation case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191702 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/Module.cpp | 6 ++++-- unittests/IR/ValueTest.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index ba4ee7f6a6..f200da8923 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -260,8 +260,10 @@ Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { // If the variable exists but has the wrong type, return a bitcast to the // right type. - if (GV->getType() != PointerType::getUnqual(Ty)) - return ConstantExpr::getBitCast(GV, PointerType::getUnqual(Ty)); + Type *GVTy = GV->getType(); + PointerType *PTy = PointerType::get(Ty, GVTy->getPointerAddressSpace()); + if (GV->getType() != PTy) + return ConstantExpr::getBitCast(GV, PTy); // Otherwise, we just found the existing function or a prototype. return GV; diff --git a/unittests/IR/ValueTest.cpp b/unittests/IR/ValueTest.cpp index 52efb1a220..ebe23e8694 100644 --- a/unittests/IR/ValueTest.cpp +++ b/unittests/IR/ValueTest.cpp @@ -43,4 +43,44 @@ TEST(ValueTest, UsedInBasicBlock) { EXPECT_TRUE(F->arg_begin()->isUsedInBasicBlock(F->begin())); } +TEST(GlobalTest, CreateAddressSpace) { + LLVMContext &Ctx = getGlobalContext(); + OwningPtr M(new Module("TestModule", Ctx)); + Type *Int8Ty = Type::getInt8Ty(Ctx); + Type *Int32Ty = Type::getInt32Ty(Ctx); + + GlobalVariable *Dummy0 + = new GlobalVariable(*M, + Int32Ty, + true, + GlobalValue::ExternalLinkage, + Constant::getAllOnesValue(Int32Ty), + "dummy", + 0, + GlobalVariable::NotThreadLocal, + 1); + + // Make sure the address space isn't dropped when returning this. + Constant *Dummy1 = M->getOrInsertGlobal("dummy", Int32Ty); + EXPECT_EQ(Dummy0, Dummy1); + EXPECT_EQ(1u, Dummy1->getType()->getPointerAddressSpace()); + + + // This one requires a bitcast, but the address space must also stay the same. + GlobalVariable *DummyCast0 + = new GlobalVariable(*M, + Int32Ty, + true, + GlobalValue::ExternalLinkage, + Constant::getAllOnesValue(Int32Ty), + "dummy_cast", + 0, + GlobalVariable::NotThreadLocal, + 1); + + // Make sure the address space isn't dropped when returning this. + Constant *DummyCast1 = M->getOrInsertGlobal("dummy_cast", Int8Ty); + EXPECT_EQ(1u, DummyCast1->getType()->getPointerAddressSpace()); + EXPECT_NE(DummyCast0, DummyCast1) << *DummyCast1; +} } // end anonymous namespace -- cgit v1.2.3