]> granicus.if.org Git - llvm/commitdiff
IR: Teach GlobalIndirectSymbol::getBaseObject() to handle more kinds of expressions.
authorPeter Collingbourne <peter@pcc.me.uk>
Wed, 24 Jul 2019 22:23:05 +0000 (22:23 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Wed, 24 Jul 2019 22:23:05 +0000 (22:23 +0000)
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
lib/IR/Globals.cpp
test/Bitcode/thinlto-alias3.ll [new file with mode: 0644]
test/Linker/comdat8.ll

index 8bc3f90b94aaf23e389161bdcf41c405b2837c43..678c038d88ecabfbd9898bf00f8707823b77dff4 100644 (file)
@@ -54,9 +54,7 @@ public:
           static_cast<const GlobalIndirectSymbol *>(this)->getIndirectSymbol());
   }
 
-  const GlobalObject *getBaseObject() const {
-    return dyn_cast<GlobalObject>(getIndirectSymbol()->stripInBoundsOffsets());
-  }
+  const GlobalObject *getBaseObject() const;
   GlobalObject *getBaseObject() {
     return const_cast<GlobalObject *>(
               static_cast<const GlobalIndirectSymbol *>(this)->getBaseObject());
index e2bfc0420bc53657b0b939978ae3e8b2b015c505..8e87b969a1b9073e877e7b60fe2eb09f63804a30 100644 (file)
@@ -427,6 +427,43 @@ GlobalIndirectSymbol::GlobalIndirectSymbol(Type *Ty, ValueTy VTy,
     Op<0>() = Symbol;
 }
 
+static const GlobalObject *
+findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) {
+  if (auto *GO = dyn_cast<GlobalObject>(C))
+    return GO;
+  if (auto *GA = dyn_cast<GlobalAlias>(C))
+    if (Aliases.insert(GA).second)
+      return findBaseObject(GA->getOperand(0), Aliases);
+  if (auto *CE = dyn_cast<ConstantExpr>(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<const GlobalAlias *> 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 (file)
index 0000000..274b4a6
--- /dev/null
@@ -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
index 490f8053c5500bd27b74f4e32e203782e5322961..f7aa3117de1ee489bc95212e5994fe9f01e21a54 100644 (file)
@@ -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.