Avoid relocations in a common case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114229 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 8295dac..d0fc9ca 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -470,12 +470,22 @@
   unsigned Index = 0;
   int64_t Value = Target.getConstant();
 
+  bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
   if (!Target.isAbsolute()) {
     const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
     MCSymbolData &SD = Asm.getSymbolData(*Symbol);
     const MCSymbolData *Base = Asm.getAtom(Layout, &SD);
     MCFragment *F = SD.getFragment();
 
+    // Avoid relocations for cases like jumps and calls in the same file.
+    if (Symbol->isDefined() && !SD.isExternal() &&
+        IsPCRel &&
+        &Fragment->getParent()->getSection() == &Symbol->getSection()) {
+      uint64_t FixupAddr = Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
+      FixedValue = Layout.getSymbolAddress(&SD) + Target.getConstant() - FixupAddr;
+      return;
+    }
+
     if (Base) {
       if (F && (!Symbol->isInSection() || SD.isCommon()) && !SD.isExternal()) {
         Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
@@ -507,7 +517,6 @@
   FixedValue = Value;
 
   // determine the type of the relocation
-  bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
   unsigned Type;
   if (Is64Bit) {
     if (IsPCRel) {