From 6b82f4e52628372b41a7426d4c14b81cbbbc3700 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 24 Jul 2019 22:23:05 +0000 Subject: [PATCH] IR: Teach GlobalIndirectSymbol::getBaseObject() to handle more kinds of expressions. For aliases, any expression that lowers at the MC level to global_object or global_object+constant is valid at the object file level. getBaseObject() should return a result if the aliasee ends up being of that form even if the IR used to produce it is somewhat unconventional. Note that this is different from what stripInBoundsOffsets() and that family of functions is doing. Those functions are concerned about semantic properties of IR, whereas here we only care about the lowering result. Therefore reimplement getBaseObject() in a way that matches the lowering result. This fixes a crash when producing a summary for aliases such as that in the included test case. Differential Revision: https://reviews.llvm.org/D65115 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366952 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/GlobalIndirectSymbol.h | 4 +-- lib/IR/Globals.cpp | 37 ++++++++++++++++++++++++++ test/Bitcode/thinlto-alias3.ll | 11 ++++++++ test/Linker/comdat8.ll | 4 +-- 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 test/Bitcode/thinlto-alias3.ll diff --git a/include/llvm/IR/GlobalIndirectSymbol.h b/include/llvm/IR/GlobalIndirectSymbol.h index 8bc3f90b94a..678c038d88e 100644 --- a/include/llvm/IR/GlobalIndirectSymbol.h +++ b/include/llvm/IR/GlobalIndirectSymbol.h @@ -54,9 +54,7 @@ public: 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/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index e2bfc0420bc..8e87b969a1b 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -427,6 +427,43 @@ GlobalIndirectSymbol::GlobalIndirectSymbol(Type *Ty, ValueTy VTy, Op<0>() = Symbol; } +static const GlobalObject * +findBaseObject(const Constant *C, DenseSet &Aliases) { + if (auto *GO = dyn_cast(C)) + return GO; + if (auto *GA = dyn_cast(C)) + if (Aliases.insert(GA).second) + return findBaseObject(GA->getOperand(0), Aliases); + if (auto *CE = dyn_cast(C)) { + switch (CE->getOpcode()) { + case Instruction::Add: { + auto *LHS = findBaseObject(CE->getOperand(0), Aliases); + auto *RHS = findBaseObject(CE->getOperand(1), Aliases); + if (LHS && RHS) + return nullptr; + return LHS ? LHS : RHS; + } + 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/test/Bitcode/thinlto-alias3.ll b/test/Bitcode/thinlto-alias3.ll new file mode 100644 index 00000000000..274b4a6dc54 --- /dev/null +++ b/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/test/Linker/comdat8.ll b/test/Linker/comdat8.ll index 490f8053c55..f7aa3117de1 100644 --- a/test/Linker/comdat8.ll +++ b/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. -- 2.40.0