diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 4e8f359481b81..67b80c2825fd2 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -776,7 +776,7 @@ const Value *Value::stripAndAccumulateConstantOffsets( Operator::getOpcode(V) == Instruction::AddrSpaceCast) { V = cast(V)->getOperand(0); } else if (auto *GA = dyn_cast(V)) { - if (!GA->isInterposable()) + if (!GA->isInterposable() && GA->getAliasee()) V = GA->getAliasee(); } else if (const auto *Call = dyn_cast(V)) { if (const Value *RV = Call->getReturnedArgOperand()) diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp index 21d45960dce7c..8aa1783bceaaa 100644 --- a/llvm/unittests/IR/InstructionsTest.cpp +++ b/llvm/unittests/IR/InstructionsTest.cpp @@ -10,6 +10,7 @@ #include "llvm-c/Core.h" #include "llvm/ADT/CombinationGenerator.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Analysis/TargetFolder.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" #include "llvm/AsmParser/Parser.h" @@ -874,6 +875,36 @@ TEST(InstructionsTest, GEPIndices) { delete GEPI; } +TEST(InstructionsTest, PtrToIntGEPFolding) { + LLVMContext Context; + llvm::Module *M = new llvm::Module("PtrToIntGEPFolding", Context); + llvm::IRBuilder Builder( + Context, llvm::TargetFolder(M->getDataLayout())); + + auto *Int64Ty = Builder.getInt64Ty(); + auto *ArrTy = llvm::ArrayType::get(Int64Ty, 1); + auto *StructTy = llvm::StructType::create(Context, {ArrTy}, "anon_struct"); + + // Create alias @m2 to @0 + llvm::GlobalAlias *AliasM2 = llvm::GlobalAlias::create( + StructTy, + 0, // address space + llvm::GlobalValue::InternalLinkage, "m2", (llvm::Constant *)nullptr, M); + + // Build getelementptr for ptrtoint + std::vector GEPIdxs = { + llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 0), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 0), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(Context), 1)}; + llvm::Value *GEP = Builder.CreateGEP(StructTy, AliasM2, GEPIdxs, "", + llvm::GEPNoWrapFlags::inBounds()); + // Make sure stripAndAccumulateConstantOffsets can properly handle + // GEPs with nullptr global aliasees. + llvm::Value *PtrToInt = Builder.CreatePtrToInt(GEP, Int64Ty); + EXPECT_TRUE(PtrToInt); + delete M; +} + TEST(InstructionsTest, ZeroIndexGEP) { LLVMContext Context; DataLayout DL;