[llvm] r366494 - IR: Teach Constant::needsRelocation() that relative pointers don't need to be relocated.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 18 13:56:21 PDT 2019


Author: pcc
Date: Thu Jul 18 13:56:21 2019
New Revision: 366494

URL: http://llvm.org/viewvc/llvm-project?rev=366494&view=rev
Log:
IR: Teach Constant::needsRelocation() that relative pointers don't need to be relocated.

This causes sections with relative pointers to be marked as read only,
which means that they won't end up sharing pages with writable data.

Differential Revision: https://reviews.llvm.org/D64948

Added:
    llvm/trunk/test/CodeGen/X86/relptr-rodata.ll
Modified:
    llvm/trunk/lib/IR/Constants.cpp

Modified: llvm/trunk/lib/IR/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=366494&r1=366493&r2=366494&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Constants.cpp (original)
+++ llvm/trunk/lib/IR/Constants.cpp Thu Jul 18 13:56:21 2019
@@ -502,22 +502,34 @@ bool Constant::needsRelocation() const {
   if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
     return BA->getFunction()->needsRelocation();
 
-  // While raw uses of blockaddress need to be relocated, differences between
-  // two of them don't when they are for labels in the same function.  This is a
-  // common idiom when creating a table for the indirect goto extension, so we
-  // handle it efficiently here.
-  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this))
+  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
     if (CE->getOpcode() == Instruction::Sub) {
       ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
       ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
       if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
-          RHS->getOpcode() == Instruction::PtrToInt &&
-          isa<BlockAddress>(LHS->getOperand(0)) &&
-          isa<BlockAddress>(RHS->getOperand(0)) &&
-          cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
-              cast<BlockAddress>(RHS->getOperand(0))->getFunction())
-        return false;
+          RHS->getOpcode() == Instruction::PtrToInt) {
+        Constant *LHSOp0 = LHS->getOperand(0);
+        Constant *RHSOp0 = RHS->getOperand(0);
+
+        // While raw uses of blockaddress need to be relocated, differences
+        // between two of them don't when they are for labels in the same
+        // function.  This is a common idiom when creating a table for the
+        // indirect goto extension, so we handle it efficiently here.
+        if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(LHSOp0) &&
+            cast<BlockAddress>(LHSOp0)->getFunction() ==
+                cast<BlockAddress>(RHSOp0)->getFunction())
+          return false;
+
+        // Relative pointers do not need to be dynamically relocated.
+        if (auto *LHSGV = dyn_cast<GlobalValue>(
+                LHSOp0->stripPointerCastsNoFollowAliases()))
+          if (auto *RHSGV = dyn_cast<GlobalValue>(
+                  RHSOp0->stripPointerCastsNoFollowAliases()))
+            if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
+              return false;
+      }
     }
+  }
 
   bool Result = false;
   for (unsigned i = 0, e = getNumOperands(); i != e; ++i)

Added: llvm/trunk/test/CodeGen/X86/relptr-rodata.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/relptr-rodata.ll?rev=366494&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/relptr-rodata.ll (added)
+++ llvm/trunk/test/CodeGen/X86/relptr-rodata.ll Thu Jul 18 13:56:21 2019
@@ -0,0 +1,21 @@
+; RUN: llc -relocation-model=pic -data-sections -o - %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+ at hidden = external hidden global i8
+ at default = external global i8
+
+; CHECK: .section .rodata.rodata
+; CHECK: rodata:
+; CHECK: .long hidden-rodata
+ at rodata = hidden constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @rodata to i64)) to i32)
+
+; CHECK: .section .data.rel.ro.relro1
+; CHECK: relro1:
+; CHECK: .long default-relro1
+ at relro1 = hidden constant i32 trunc (i64 sub (i64 ptrtoint (i8* @default to i64), i64 ptrtoint (i32* @relro1 to i64)) to i32)
+
+; CHECK: .section .data.rel.ro.relro2
+; CHECK: relro2:
+; CHECK: .long hidden-relro2
+ at relro2 = constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @relro2 to i64)) to i32)




More information about the llvm-commits mailing list