diff --git a/llvm/include/llvm/IR/GlobalIndirectSymbol.h b/llvm/include/llvm/IR/GlobalIndirectSymbol.h --- a/llvm/include/llvm/IR/GlobalIndirectSymbol.h +++ b/llvm/include/llvm/IR/GlobalIndirectSymbol.h @@ -54,9 +54,7 @@ static_cast(this)->getIndirectSymbol()); } - const GlobalObject *getBaseObject() const { - return dyn_cast(getIndirectSymbol()->stripInBoundsOffsets()); - } + const GlobalObject *getBaseObject() const; GlobalObject *getBaseObject() { return const_cast( static_cast(this)->getBaseObject()); diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -427,6 +427,42 @@ Op<0>() = Symbol; } +static const GlobalObject * +findBaseObject(const Constant *C, + DenseSet &Aliases) { + if (auto *GO = dyn_cast(C)) + return GO; + if (auto *GIS = dyn_cast(C)) + if (Aliases.insert(GIS).second) + return findBaseObject(GIS->getOperand(0), Aliases); + if (auto *CE = dyn_cast(C)) { + switch (CE->getOpcode()) { + case Instruction::Add: { + if (auto *GIS = findBaseObject(CE->getOperand(0), Aliases)) + return GIS; + return findBaseObject(CE->getOperand(1), Aliases); + } + case Instruction::Sub: { + if (findBaseObject(CE->getOperand(1), Aliases)) + return nullptr; + return findBaseObject(CE->getOperand(0), Aliases); + } + case Instruction::IntToPtr: + case Instruction::PtrToInt: + case Instruction::BitCast: + case Instruction::GetElementPtr: + return findBaseObject(CE->getOperand(0), Aliases); + default: + break; + } + } + return nullptr; +} + +const GlobalObject *GlobalIndirectSymbol::getBaseObject() const { + DenseSet Aliases; + return findBaseObject(getOperand(0), Aliases); +} //===----------------------------------------------------------------------===// // GlobalAlias Implementation diff --git a/llvm/test/Bitcode/thinlto-alias3.ll b/llvm/test/Bitcode/thinlto-alias3.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/thinlto-alias3.ll @@ -0,0 +1,11 @@ +; Test that inttoptr, add and ptrtoint don't cause problems in alias summaries. +; RUN: opt -module-summary %s -o - | llvm-dis | FileCheck %s + +; CHECK: ^1 = gv: (name: "a", {{.*}} aliasee: ^2 +; CHECK: ^2 = gv: (name: "b", + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@a = alias i32, i32* inttoptr (i64 add (i64 ptrtoint (i32* @b to i64), i64 1297036692682702848) to i32*) +@b = global i32 1 diff --git a/llvm/test/Linker/comdat8.ll b/llvm/test/Linker/comdat8.ll --- a/llvm/test/Linker/comdat8.ll +++ b/llvm/test/Linker/comdat8.ll @@ -2,7 +2,7 @@ $c1 = comdat largest -@some_name = private unnamed_addr constant i32 42, comdat($c1) -@c1 = alias i8, inttoptr (i32 ptrtoint (i32* @some_name to i32) to i8*) +@some_name = unnamed_addr constant i32 42, comdat($c1) +@c1 = alias i8, inttoptr (i32 1 to i8*) ; CHECK: COMDAT key involves incomputable alias size.