Index: include/llvm/MC/MCAsmInfo.h =================================================================== --- include/llvm/MC/MCAsmInfo.h +++ include/llvm/MC/MCAsmInfo.h @@ -280,6 +280,10 @@ /// to false. bool HasNoDeadStrip; + /// True if this target supports the MachO .alt_entry directive. Defaults to + /// false. + bool HasAltEntry; + /// Used to declare a global as being a weak symbol. Defaults to ".weak". const char *WeakDirective; @@ -498,6 +502,7 @@ bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasIdentDirective() const { return HasIdentDirective; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } + bool hasAltEntry() const { return HasAltEntry; } const char *getWeakDirective() const { return WeakDirective; } const char *getWeakRefDirective() const { return WeakRefDirective; } bool hasWeakDefDirective() const { return HasWeakDefDirective; } Index: include/llvm/MC/MCDirectives.h =================================================================== --- include/llvm/MC/MCDirectives.h +++ include/llvm/MC/MCDirectives.h @@ -35,6 +35,7 @@ MCSA_Local, ///< .local (ELF) MCSA_NoDeadStrip, ///< .no_dead_strip (MachO) MCSA_SymbolResolver, ///< .symbol_resolver (MachO) + MCSA_AltEntry, ///< .alt_entry (MachO) MCSA_PrivateExtern, ///< .private_extern (MachO) MCSA_Protected, ///< .protected (ELF) MCSA_Reference, ///< .reference (MachO) Index: include/llvm/MC/MCSymbolMachO.h =================================================================== --- include/llvm/MC/MCSymbolMachO.h +++ include/llvm/MC/MCSymbolMachO.h @@ -33,6 +33,7 @@ SF_WeakReference = 0x0040, SF_WeakDefinition = 0x0080, SF_SymbolResolver = 0x0100, + SF_AltEntry = 0x0200, // Common alignment SF_CommonAlignmentMask = 0xF0FF, @@ -88,6 +89,10 @@ modifyFlags(SF_SymbolResolver, SF_SymbolResolver); } + void setAltEntry() const { + modifyFlags(SF_AltEntry, SF_AltEntry); + } + void setDesc(unsigned Value) const { assert(Value == (Value & SF_DescFlagsMask) && "Invalid .desc value!"); Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1165,8 +1165,13 @@ EmitVisibility(Name, Alias.getVisibility()); + const MCExpr *Expr = lowerConstant(Alias.getAliasee()); + + if (MAI->hasAltEntry() && isa(Expr)) + OutStreamer->EmitSymbolAttribute(Name, MCSA_AltEntry); + // Emit the directives as assignments aka .set: - OutStreamer->EmitAssignment(Name, lowerConstant(Alias.getAliasee())); + OutStreamer->EmitAssignment(Name, Expr); // If the aliasee does not correspond to a symbol in the output, i.e. the // alias is not of an object or the aliased object is private, then set the Index: lib/MC/MCAsmInfo.cpp =================================================================== --- lib/MC/MCAsmInfo.cpp +++ lib/MC/MCAsmInfo.cpp @@ -75,6 +75,7 @@ HasSingleParameterDotFile = true; HasIdentDirective = false; HasNoDeadStrip = false; + HasAltEntry = false; WeakDirective = "\t.weak\t"; WeakRefDirective = nullptr; HasWeakDefDirective = false; Index: lib/MC/MCAsmInfoDarwin.cpp =================================================================== --- lib/MC/MCAsmInfoDarwin.cpp +++ lib/MC/MCAsmInfoDarwin.cpp @@ -88,6 +88,7 @@ HasDotTypeDotSizeDirective = false; HasNoDeadStrip = true; + HasAltEntry = true; DwarfUsesRelocationsAcrossSections = false; Index: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -472,6 +472,7 @@ OS << "\t.no_dead_strip\t"; break; case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; + case MCSA_AltEntry: OS << "\t.alt_entry\t"; break; case MCSA_PrivateExtern: OS << "\t.private_extern\t"; break; Index: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -283,6 +283,9 @@ case MCSA_Internal: Symbol->setVisibility(ELF::STV_INTERNAL); break; + + case MCSA_AltEntry: + llvm_unreachable("ELF doesn't support this attribute"); } return true; Index: lib/MC/MCMachOStreamer.cpp =================================================================== --- lib/MC/MCMachOStreamer.cpp +++ lib/MC/MCMachOStreamer.cpp @@ -346,6 +346,10 @@ Symbol->setSymbolResolver(); break; + case MCSA_AltEntry: + Symbol->setAltEntry(); + break; + case MCSA_PrivateExtern: Symbol->setExternal(true); Symbol->setPrivateExtern(true); Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -349,8 +349,8 @@ DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR, DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK, DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, - DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN, - DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, + DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_ALT_ENTRY, + DK_PRIVATE_EXTERN, DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE, DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB, @@ -1597,6 +1597,8 @@ return parseDirectiveSymbolAttribute(MCSA_NoDeadStrip); case DK_SYMBOL_RESOLVER: return parseDirectiveSymbolAttribute(MCSA_SymbolResolver); + case DK_ALT_ENTRY: + return parseDirectiveSymbolAttribute(MCSA_AltEntry); case DK_PRIVATE_EXTERN: return parseDirectiveSymbolAttribute(MCSA_PrivateExtern); case DK_REFERENCE: @@ -4606,6 +4608,7 @@ DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE; DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP; DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER; + DirectiveKindMap[".alt_entry"] = DK_ALT_ENTRY; DirectiveKindMap[".private_extern"] = DK_PRIVATE_EXTERN; DirectiveKindMap[".reference"] = DK_REFERENCE; DirectiveKindMap[".weak_definition"] = DK_WEAK_DEFINITION; Index: test/CodeGen/X86/alias-gep.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/alias-gep.ll @@ -0,0 +1,22 @@ +; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck --check-prefix=MACHO %s +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck --check-prefix=ELF %s + +;MACHO: .globl _offsetSym0 +;MACHO-NOT: .alt_entry +;MACHO: _offsetSym0 = _s +;MACHO: .globl _offsetSym1 +;MACHO: .alt_entry _offsetSym1 +;MACHO: _offsetSym1 = _s+8 + +;ELF: .globl offsetSym0 +;ELF-NOT: .alt_entry +;ELF: offsetSym0 = s +;ELF: .globl offsetSym1 +;ELF-NOT: .alt_entry +;ELF: offsetSym1 = s+8 + +%struct.S1 = type { i32, i32, i32 } + +@s = global %struct.S1 { i32 31, i32 32, i32 33 }, align 4 +@offsetSym0 = alias i32, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s, i64 0, i32 0) +@offsetSym1 = alias i32, i32* getelementptr inbounds (%struct.S1, %struct.S1* @s, i64 0, i32 2)