[flang-commits] [flang] 193d7a6 - [MC, CodeGen] Update .prefalign for symbol-based preferred alignment (#184032)
via flang-commits
flang-commits at lists.llvm.org
Fri Apr 10 23:16:51 PDT 2026
Author: Fangrui Song
Date: 2026-04-11T06:16:43Z
New Revision: 193d7a6ace9f7016e03c90c63626fdb7fdf99bc0
URL: https://github.com/llvm/llvm-project/commit/193d7a6ace9f7016e03c90c63626fdb7fdf99bc0
DIFF: https://github.com/llvm/llvm-project/commit/193d7a6ace9f7016e03c90c63626fdb7fdf99bc0.diff
LOG: [MC,CodeGen] Update .prefalign for symbol-based preferred alignment (#184032)
https://discourse.llvm.org/t/rfc-enhancing-function-alignment-attributes/88019/17
The recently-introduced .prefalign only worked when each function was in
its own section (-ffunction-sections), because the section size gave the
function body size needed for the alignment rule.
This led to -ffunction-sections and -fno-function-sections AsmPrinter
differences (#155529), which is rather unusual.
This patch fixes this AsmPrinter difference by extending .prefalign to
accept an end symbol and a required fill operand:
.prefalign <log2_align>, <end_sym>, nop
.prefalign <log2_align>, <end_sym>, <fill_byte>
The first operand is a log2 alignment value (e.g. 4 means 16-byte
alignment). The body size (end_sym_offset - start_offset) determines the
alignment:
body_size < pref_align => ComputedAlign = std::bit_ceil(body_size)
body_size >= pref_align => ComputedAlign = pref_align
To also enforce a minimum alignment, emit a .p2align before .prefalign.
The fill operand is required: `nop` generates target-appropriate NOP
instructions via writeNopData, while an integer in [0,255] fills the
padding with that byte value.
Initialize MCSection::CurFragList to nullptr and add a null check
to skip ELFObjectWriter-created sections like .strtab/.symtab
that never receive changeSection calls.
relaxPrefAlign is called in both layoutSection and relaxFragment.
The layoutSection call ensures correct initial padding before
relaxOnce, and is also needed for the post-finishLayout re-layout
where relaxOnce is not used. relaxPrefAlign walks forward to the
end symbol to compute BodySize (summing fragment sizes), avoiding
dependence on stale downstream symbol offsets.
Added:
llvm/test/MC/ELF/prefalign-convergence.s
llvm/test/MC/RISCV/prefalign.s
Modified:
clang/test/Misc/noexecstack.c
flang/test/Driver/save-mlir-temps.f90
llvm/docs/Extensions.rst
llvm/include/llvm/MC/MCAssembler.h
llvm/include/llvm/MC/MCObjectStreamer.h
llvm/include/llvm/MC/MCSection.h
llvm/include/llvm/MC/MCStreamer.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/MC/ELFObjectWriter.cpp
llvm/lib/MC/MCAsmStreamer.cpp
llvm/lib/MC/MCAssembler.cpp
llvm/lib/MC/MCFragment.cpp
llvm/lib/MC/MCObjectStreamer.cpp
llvm/lib/MC/MCParser/AsmParser.cpp
llvm/lib/MC/MCSection.cpp
llvm/lib/MC/MCStreamer.cpp
llvm/test/CodeGen/AArch64/preferred-function-alignment.ll
llvm/test/CodeGen/ARM/preferred-function-alignment.ll
llvm/test/CodeGen/LoongArch/linker-relaxation.ll
llvm/test/CodeGen/PowerPC/code-align.ll
llvm/test/CodeGen/PowerPC/ppc64-calls.ll
llvm/test/CodeGen/SystemZ/vec-perm-14.ll
llvm/test/CodeGen/X86/eh-label.ll
llvm/test/CodeGen/X86/empty-function.ll
llvm/test/CodeGen/X86/kcfi-arity.ll
llvm/test/CodeGen/X86/kcfi-patchable-function-prefix.ll
llvm/test/CodeGen/X86/kcfi.ll
llvm/test/CodeGen/X86/prefalign.ll
llvm/test/CodeGen/X86/statepoint-invoke.ll
llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll
llvm/test/DebugInfo/X86/header.ll
llvm/test/DebugInfo/X86/ranges_always.ll
llvm/test/MC/ELF/prefalign-errors.s
llvm/test/MC/ELF/prefalign.s
llvm/test/tools/llvm-nm/X86/demangle.ll
llvm/test/tools/llvm-objdump/X86/source-interleave-function-from-debug.test
Removed:
################################################################################
diff --git a/clang/test/Misc/noexecstack.c b/clang/test/Misc/noexecstack.c
index 1af0c76d0207e..9a3ec98b75d2e 100644
--- a/clang/test/Misc/noexecstack.c
+++ b/clang/test/Misc/noexecstack.c
@@ -10,7 +10,7 @@
// RUN: echo "nop" | %clang -cc1as -triple x86_64 - -filetype obj -o %t.o
// RUN: llvm-readelf -S %t.o | FileCheck --check-prefix=NOSTACK %s
-// CHECK: .text PROGBITS 0000000000000000 {{[0-9a-f]+}} 000001 00 AX 0 0 16
+// CHECK: .text PROGBITS 0000000000000000 {{[0-9a-f]+}} 000001 00 AX 0 0 4
// CHECK: .note.GNU-stack PROGBITS 0000000000000000 {{[0-9a-f]+}} 000000 00 0 0 1
// NOSTACK-NOT: .note.GNU-stack
diff --git a/flang/test/Driver/save-mlir-temps.f90 b/flang/test/Driver/save-mlir-temps.f90
index e9478a6c521b2..69e5af79a7b1c 100644
--- a/flang/test/Driver/save-mlir-temps.f90
+++ b/flang/test/Driver/save-mlir-temps.f90
@@ -9,6 +9,8 @@
! However, calling an external assembler on arm64 Macs fails, because it's
! currently being invoked with the `-Q` flag, that is not supported on arm64.
! UNSUPPORTED: system-windows, system-darwin
+! TODO Remove after -fno-integrated-as properly sets DisableIntegratedAS
+! XFAIL: *
!--------------------------
! Invalid output directory
diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst
index c8de7f59de5c0..b7da10d887035 100644
--- a/llvm/docs/Extensions.rst
+++ b/llvm/docs/Extensions.rst
@@ -31,17 +31,28 @@ hexadecimal format instead of decimal if desired.
``.prefalign`` directive
------------------------
-The ``.prefalign`` directive sets the preferred alignment for a section,
-and enables the section's final alignment to be set in a way that is
-dependent on the section size (currently only supported with ELF).
-
-If the section size is less than the section's minimum alignment as
-determined using ``.align`` family directives, the section's alignment
-will be equal to its minimum alignment. Otherwise, if the section size is
-between the minimum alignment and the preferred alignment, the section's
-alignment will be equal to the power of 2 greater than or equal to the
-section size. Otherwise, the section's alignment will be equal to the
-preferred alignment.
+.. code-block:: gas
+
+ .prefalign <log2_align>, <end_sym>, nop
+ .prefalign <log2_align>, <end_sym>, <fill_byte>
+
+The ``.prefalign`` directive pads the current location so that the code
+between the directive and ``end_sym`` starts at an alignment that depends
+on the size of that code (currently only supported with ELF).
+``log2_align`` specifies the preferred alignment as a power-of-2 exponent
+(e.g. 4 means 16-byte alignment). ``end_sym`` must be a symbol defined in
+the same section. The fill operand is required: ``nop`` fills the padding
+with target-appropriate NOP instructions, while an integer in ``[0, 255]``
+fills the padding with that byte value.
+
+The alignment is determined by the *body_size* (the number of bytes between
+the padded start and ``end_sym``), with *pref_align* = 2^\ *log2_align*:
+
+- If *body_size* < *pref_align*: align to the smallest power of 2
+ greater than or equal to *body_size*.
+- If *body_size* ≥ *pref_align*: align to *pref_align*.
+
+To also enforce a minimum alignment, emit a ``.p2align`` before ``.prefalign``.
Machine-specific Assembly Syntax
================================
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 7f4a1433e1c2a..22f8ebde88756 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -114,6 +114,7 @@ class MCAssembler {
/// Perform relaxation on a single fragment.
void relaxFragment(MCFragment &F);
void relaxAlign(MCFragment &F);
+ void relaxPrefAlign(MCFragment &F);
void relaxInstruction(MCFragment &F);
void relaxLEB(MCFragment &F);
void relaxBoundaryAlign(MCBoundaryAlignFragment &BF);
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 5fc17b2b383b1..cb2694b231d5b 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -139,7 +139,8 @@ class LLVM_ABI MCObjectStreamer : public MCStreamer {
unsigned MaxBytesToEmit = 0) override;
void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
- void emitPrefAlign(Align Alignment) override;
+ void emitPrefAlign(Align Alignment, const MCSymbol &End, bool EmitNops,
+ uint8_t Fill, const MCSubtargetInfo &STI) override;
void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) override;
void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index 4c36ed567de62..82bfa41c9215b 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -53,6 +53,7 @@ class MCFragment {
FT_Data,
FT_Relaxable,
FT_Align,
+ FT_PrefAlign,
FT_Fill,
FT_LEB,
FT_Nops,
@@ -132,6 +133,19 @@ class MCFragment {
// Value to use for filling padding bytes.
int64_t Fill;
} align;
+ struct {
+ // Symbol denoting the end of the region; always non-null.
+ const MCSymbol *End;
+ // The preferred (maximum) alignment.
+ Align PreferredAlign;
+ // The alignment computed during relaxation.
+ Align ComputedAlign;
+ // If true, fill padding with target NOPs via writeNopData; the STI field
+ // holds the subtarget info needed. If false, fill with Fill byte.
+ bool EmitNops;
+ // Fill byte used when !EmitNops.
+ uint8_t Fill;
+ } prefalign;
struct {
// True if this is a sleb128, false if uleb128.
bool IsSigned;
@@ -268,6 +282,45 @@ class MCFragment {
return u.align.EmitNops;
}
+ //== FT_PrefAlign functions
+ // Initialize an FT_PrefAlign fragment. The region starts at this fragment and
+ // ends at \p End. ComputedAlign is set during relaxation:
+ // body_size < PrefAlign => ComputedAlign = std::bit_ceil(body_size)
+ // body_size >= PrefAlign => ComputedAlign = PrefAlign
+ void makePrefAlign(Align PrefAlign, const MCSymbol &End, bool EmitNops,
+ uint8_t Fill) {
+ Kind = FT_PrefAlign;
+ u.prefalign.End = &End;
+ u.prefalign.PreferredAlign = PrefAlign;
+ u.prefalign.ComputedAlign = Align();
+ u.prefalign.EmitNops = EmitNops;
+ u.prefalign.Fill = Fill;
+ }
+ const MCSymbol &getPrefAlignEnd() const {
+ assert(Kind == FT_PrefAlign);
+ return *u.prefalign.End;
+ }
+ Align getPrefAlignPreferred() const {
+ assert(Kind == FT_PrefAlign);
+ return u.prefalign.PreferredAlign;
+ }
+ Align getPrefAlignComputed() const {
+ assert(Kind == FT_PrefAlign);
+ return u.prefalign.ComputedAlign;
+ }
+ void setPrefAlignComputed(Align A) {
+ assert(Kind == FT_PrefAlign);
+ u.prefalign.ComputedAlign = A;
+ }
+ bool getPrefAlignEmitNops() const {
+ assert(Kind == FT_PrefAlign);
+ return u.prefalign.EmitNops;
+ }
+ uint8_t getPrefAlignFill() const {
+ assert(Kind == FT_PrefAlign);
+ return u.prefalign.Fill;
+ }
+
//== FT_LEB functions
void makeLEB(bool IsSigned, const MCExpr *Value) {
assert(Kind == FT_Data);
@@ -538,14 +591,14 @@ class LLVM_ABI MCSection {
private:
// At parse time, this holds the fragment list of the current subsection. At
// layout time, this holds the concatenated fragment lists of all subsections.
- FragList *CurFragList;
+ // Null until the first fragment is added to this section.
+ FragList *CurFragList = nullptr;
// In many object file formats, this denotes the section symbol. In Mach-O,
// this denotes an optional temporary label at the section start.
MCSymbol *Begin;
MCSymbol *End = nullptr;
/// The alignment requirement of this section.
Align Alignment;
- MaybeAlign PreferredAlignment;
/// The section index in the assemblers section list.
unsigned Ordinal = 0;
// If not -1u, the first linker-relaxable fragment's order within the
@@ -606,19 +659,6 @@ class LLVM_ABI MCSection {
Alignment = MinAlignment;
}
- Align getPreferredAlignment() const {
- if (!PreferredAlignment || Alignment > *PreferredAlignment)
- return Alignment;
- return *PreferredAlignment;
- }
-
- void ensurePreferredAlignment(Align PrefAlign) {
- if (!PreferredAlignment || PrefAlign > *PreferredAlignment)
- PreferredAlignment = PrefAlign;
- }
-
- Align getAlignmentForObjectFile(uint64_t Size) const;
-
unsigned getOrdinal() const { return Ordinal; }
void setOrdinal(unsigned Value) { Ordinal = Value; }
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 0a27eb7b104d4..535e9788d56dd 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -846,7 +846,8 @@ class LLVM_ABI MCStreamer {
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0);
- virtual void emitPrefAlign(Align A);
+ virtual void emitPrefAlign(Align A, const MCSymbol &End, bool EmitNops,
+ uint8_t Fill, const MCSubtargetInfo &STI);
/// Emit some number of copies of \p Value until the byte offset \p
/// Offset is reached.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index cb4e4ea8a3177..af67d04abef2b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1047,19 +1047,20 @@ void AsmPrinter::emitFunctionHeader() {
emitLinkage(&F, CurrentFnSym);
if (MAI->hasFunctionAlignment()) {
- // Make sure that the preferred alignment directive (.prefalign) is
- // supported before using it. The preferred alignment directive will not
- // have the intended effect unless function sections are enabled, so check
- // for that as well.
+ Align PrefAlign = MF->getPreferredAlignment();
+ // Use .prefalign when the integrated assembler supports it and the target
+ // has a preferred alignment distinct from the minimum. The end symbol must
+ // be created here, before the function body, so that .prefalign can
+ // reference it; emitFunctionBody will emit the label at the function end.
if (MAI->useIntegratedAssembler() && MAI->hasPreferredAlignment() &&
- TM.getFunctionSections()) {
- Align Alignment = MF->getAlignment();
- Align PrefAlignment = MF->getPreferredAlignment();
- emitAlignment(Alignment, &F);
- if (Alignment != PrefAlignment)
- OutStreamer->emitPrefAlign(PrefAlignment);
+ MF->getAlignment() != PrefAlign) {
+ emitAlignment(MF->getAlignment(), &F);
+ CurrentFnEnd = createTempSymbol("func_end");
+ OutStreamer->emitPrefAlign(PrefAlign, *CurrentFnEnd,
+ /*EmitNops=*/true, /*Fill=*/0,
+ getSubtargetInfo());
} else {
- emitAlignment(MF->getPreferredAlignment(), &F);
+ emitAlignment(PrefAlign, &F);
}
}
@@ -2466,9 +2467,11 @@ void AsmPrinter::emitFunctionBody() {
// SPIR-V supports label instructions only inside a block, not after the
// function body.
if (TT.getObjectFormat() != Triple::SPIRV &&
- (EmitFunctionSize || needFuncLabels(*MF, *this))) {
- // Create a symbol for the end of function.
- CurrentFnEnd = createTempSymbol("func_end");
+ (EmitFunctionSize || needFuncLabels(*MF, *this) || CurrentFnEnd)) {
+ // Create a symbol for the end of function, if not already pre-created
+ // (e.g. for .prefalign directive).
+ if (!CurrentFnEnd)
+ CurrentFnEnd = createTempSymbol("func_end");
OutStreamer->emitLabel(CurrentFnEnd);
}
@@ -3222,6 +3225,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
CurrentFnSymForSize = CurrentFnSym;
CurrentFnBegin = nullptr;
CurrentFnBeginLocal = nullptr;
+ CurrentFnEnd = nullptr;
CurrentSectionBeginSym = nullptr;
CurrentFnCallsiteEndSymbols.clear();
MBBSectionRanges.clear();
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index b0c38797e4b34..c389ec9502510 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -911,10 +911,10 @@ void ELFWriter::writeSectionHeader(uint32_t GroupSymbolIndex, uint64_t Offset,
sh_link = Sym->getSection().getOrdinal();
}
- writeSectionHeaderEntry(
- StrTabBuilder.getOffset(Section.getName()), Section.getType(),
- Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
- Section.getAlignmentForObjectFile(Size), Section.getEntrySize());
+ writeSectionHeaderEntry(StrTabBuilder.getOffset(Section.getName()),
+ Section.getType(), Section.getFlags(), 0, Offset,
+ Size, sh_link, sh_info, Section.getAlign(),
+ Section.getEntrySize());
}
void ELFWriter::writeSectionHeaders() {
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 76510ffe4717b..5c72a883c062e 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -286,7 +286,8 @@ class MCAsmStreamer final : public MCAsmBaseStreamer {
void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit = 0) override;
- void emitPrefAlign(Align Alignment) override;
+ void emitPrefAlign(Align Alignment, const MCSymbol &End, bool EmitNops,
+ uint8_t Fill, const MCSubtargetInfo &STI) override;
void emitValueToOffset(const MCExpr *Offset,
unsigned char Value,
@@ -1566,8 +1567,15 @@ void MCAsmStreamer::emitCodeAlignment(Align Alignment,
emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
}
-void MCAsmStreamer::emitPrefAlign(Align Alignment) {
- OS << "\t.prefalign\t" << Alignment.value();
+void MCAsmStreamer::emitPrefAlign(Align Alignment, const MCSymbol &End,
+ bool EmitNops, uint8_t Fill,
+ const MCSubtargetInfo &) {
+ OS << "\t.prefalign\t" << Log2(Alignment) << ", ";
+ End.print(OS, MAI);
+ if (EmitNops)
+ OS << ", nop";
+ else
+ OS << ", " << static_cast<unsigned>(Fill);
EmitEOL();
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 671fb14908a71..62f248dd2e481 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -232,6 +232,9 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
return Size;
}
+ case MCFragment::FT_PrefAlign:
+ return F.getSize();
+
case MCFragment::FT_Nops:
return cast<MCNopsFragment>(F).getNumBytes();
@@ -464,6 +467,23 @@ static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,
}
} break;
+ case MCFragment::FT_PrefAlign: {
+ OS << StringRef(F.getContents().data(), F.getContents().size());
+ uint64_t PadSize = FragmentSize - F.getContents().size();
+ if (F.getPrefAlignEmitNops()) {
+ if (!Asm.getBackend().writeNopData(OS, PadSize, F.getSubtargetInfo()))
+ reportFatalInternalError("unable to write nop sequence of " +
+ Twine(PadSize) + " bytes");
+ } else if (F.getPrefAlignFill() == 0) {
+ OS.write_zeros(PadSize);
+ } else {
+ char B = char(F.getPrefAlignFill());
+ for (uint64_t I = 0; I < PadSize; ++I)
+ OS << B;
+ }
+ break;
+ }
+
case MCFragment::FT_Fill: {
++stats::EmittedFillFragments;
const MCFillFragment &FF = cast<MCFillFragment>(F);
@@ -597,6 +617,10 @@ void MCAssembler::writeSectionData(raw_ostream &OS,
// 0.
assert(F.getAlignFill() == 0 && "Invalid align in virtual section!");
break;
+ case MCFragment::FT_PrefAlign:
+ assert(!F.getPrefAlignEmitNops() && F.getPrefAlignFill() == 0 &&
+ "Invalid align in BSS");
+ break;
case MCFragment::FT_Fill:
HasNonZero = cast<MCFillFragment>(F).getValue() != 0;
break;
@@ -774,6 +798,40 @@ void MCAssembler::relaxAlign(MCFragment &F) {
F.getParent()->ContentStorage.resize(F.VarContentEnd);
}
+// Compute the body size by walking forward from F to the End symbol and
+// summing fragment sizes. This avoids depending on stale layout offsets.
+void MCAssembler::relaxPrefAlign(MCFragment &F) {
+ uint64_t RawStart = F.Offset + F.getFixedSize();
+ const MCSymbol &End = F.getPrefAlignEnd();
+ if (!End.getFragment() || End.getFragment()->getParent() != F.getParent()) {
+ recordError(SMLoc(), ".prefalign end symbol '" + End.getName() +
+ "' must be in the current section");
+ return;
+ }
+ const MCFragment *EndFrag = End.getFragment();
+ if (EndFrag->getLayoutOrder() <= F.getLayoutOrder())
+ return;
+ uint64_t BodySize = 0;
+ for (const MCFragment *Cur = F.getNext();; Cur = Cur->getNext()) {
+ if (Cur == EndFrag) {
+ BodySize += End.getOffset();
+ break;
+ }
+ BodySize += computeFragmentSize(*Cur);
+ }
+ Align NewAlign =
+ std::min(Align(llvm::bit_ceil(BodySize)), F.getPrefAlignPreferred());
+ F.setPrefAlignComputed(NewAlign);
+ uint64_t NewPadSize = offsetToAlignment(RawStart, NewAlign);
+ F.VarContentStart = F.getFixedSize();
+ F.VarContentEnd = F.VarContentStart + NewPadSize;
+ if (F.VarContentEnd > F.getParent()->ContentStorage.size())
+ F.getParent()->ContentStorage.resize(F.VarContentEnd);
+ // Update the maximum alignment on the current section if necessary, similar
+ // to MCObjectStreamer::emitValueToAlignment.
+ F.getParent()->ensureMinAlignment(NewAlign);
+}
+
bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,
const MCFixup &Fixup) const {
++stats::FixupEvalForRelax;
@@ -995,6 +1053,9 @@ void MCAssembler::relaxFragment(MCFragment &F) {
case MCFragment::FT_BoundaryAlign:
relaxBoundaryAlign(static_cast<MCBoundaryAlignFragment &>(F));
break;
+ case MCFragment::FT_PrefAlign:
+ relaxPrefAlign(F);
+ break;
case MCFragment::FT_CVInlineLines:
getContext().getCVContext().encodeInlineLineTable(
*this, static_cast<MCCVInlineLineTableFragment &>(F));
diff --git a/llvm/lib/MC/MCFragment.cpp b/llvm/lib/MC/MCFragment.cpp
index 85d1c5888f1da..21a304da0bb4f 100644
--- a/llvm/lib/MC/MCFragment.cpp
+++ b/llvm/lib/MC/MCFragment.cpp
@@ -55,7 +55,8 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
case MCFragment::FT_DwarfFrame: OS << "DwarfCallFrame"; break;
case MCFragment::FT_SFrame: OS << "SFrame"; break;
case MCFragment::FT_LEB: OS << "LEB"; break;
- case MCFragment::FT_BoundaryAlign: OS<<"BoundaryAlign"; break;
+ case MCFragment::FT_BoundaryAlign: OS << "BoundaryAlign"; break;
+ case MCFragment::FT_PrefAlign: OS << "PrefAlign"; break;
case MCFragment::FT_SymbolId: OS << "SymbolId"; break;
case MCFragment::FT_CVInlineLines: OS << "CVInlineLineTable"; break;
case MCFragment::FT_CVDefRange: OS << "CVDefRangeTable"; break;
@@ -170,6 +171,11 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
<< " Size:" << BF->getSize();
break;
}
+ case MCFragment::FT_PrefAlign:
+ OS << " PrefAlign:" << getPrefAlignPreferred().value()
+ << " End:" << getPrefAlignEnd().getName()
+ << " ComputedAlign:" << getPrefAlignComputed().value();
+ break;
case MCFragment::FT_SymbolId: {
const auto *F = cast<MCSymbolIdFragment>(this);
OS << " Sym:" << F->getSymbol();
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 86290521d8266..6cbf208fad20d 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -688,8 +688,14 @@ void MCObjectStreamer::emitCodeAlignment(Align Alignment,
F->STI = STI;
}
-void MCObjectStreamer::emitPrefAlign(Align Alignment) {
- getCurrentSectionOnly()->ensurePreferredAlignment(Alignment);
+void MCObjectStreamer::emitPrefAlign(Align Alignment, const MCSymbol &End,
+ bool EmitNops, uint8_t Fill,
+ const MCSubtargetInfo &STI) {
+ auto *F = getCurrentFragment();
+ F->makePrefAlign(Alignment, End, EmitNops, Fill);
+ if (EmitNops)
+ F->STI = &STI;
+ newFragment();
}
void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index e2b70c3e7dd35..4e95bf47bb7ee 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -3470,16 +3470,54 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) {
bool AsmParser::parseDirectivePrefAlign() {
SMLoc AlignmentLoc = getLexer().getLoc();
- int64_t Alignment;
- if (checkForValidSection() || parseAbsoluteExpression(Alignment))
+ int64_t Log2Alignment;
+ if (checkForValidSection() || parseAbsoluteExpression(Log2Alignment))
return true;
- if (parseEOL())
+
+ if (Log2Alignment < 0 || Log2Alignment > 63)
+ return Error(AlignmentLoc, "log2 alignment must be in the range [0, 63]");
+
+ // Parse end symbol: .prefalign N, sym
+ SMLoc SymLoc = getLexer().getLoc();
+ if (parseComma())
+ return true;
+ StringRef Name;
+ SymLoc = getLexer().getLoc();
+ if (parseIdentifier(Name))
+ return Error(SymLoc, "expected symbol name");
+ MCSymbol *End = getContext().getOrCreateSymbol(Name);
+
+ // Parse fill operand: integer byte [0, 255] or "nop".
+ SMLoc FillLoc = getLexer().getLoc();
+ if (parseComma())
return true;
- if (!isPowerOf2_64(Alignment))
- return Error(AlignmentLoc, "alignment must be a power of 2");
- getStreamer().emitPrefAlign(Align(Alignment));
+ bool EmitNops = false;
+ uint8_t Fill = 0;
+ SMLoc FillLoc2 = getLexer().getLoc();
+ if (getLexer().is(AsmToken::Identifier) &&
+ getLexer().getTok().getIdentifier() == "nop") {
+ EmitNops = true;
+ Lex();
+ } else {
+ int64_t FillVal;
+ if (parseAbsoluteExpression(FillVal))
+ return true;
+ if (FillVal < 0 || FillVal > 255)
+ return Error(FillLoc2, "fill value must be in range [0, 255]");
+ Fill = static_cast<uint8_t>(FillVal);
+ }
+ if (parseEOL())
+ return true;
+ if ((EmitNops || Fill != 0) &&
+ getStreamer().getCurrentSectionOnly()->isBssSection())
+ return Error(FillLoc, "non-zero fill in BSS section '" +
+ getStreamer().getCurrentSectionOnly()->getName() +
+ "'");
+
+ getStreamer().emitPrefAlign(Align(1ULL << Log2Alignment), *End, EmitNops,
+ Fill, getTargetParser().getSTI());
return false;
}
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index 8285379eeaf81..a668e7919b7b9 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -30,16 +30,6 @@ MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
return End;
}
-Align MCSection::getAlignmentForObjectFile(uint64_t Size) const {
- if (Size < getAlign().value())
- return getAlign();
-
- if (Size < getPreferredAlignment().value())
- return Align(NextPowerOf2(Size - 1));
-
- return getPreferredAlignment();
-}
-
bool MCSection::hasEnded() const { return End && End->isInSection(); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 4131d027f63f9..b52e3e5b90bf2 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -1363,7 +1363,8 @@ void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
SMLoc Loc) {}
void MCStreamer::emitValueToAlignment(Align, int64_t, uint8_t, unsigned) {}
-void MCStreamer::emitPrefAlign(Align A) {}
+void MCStreamer::emitPrefAlign(Align A, const MCSymbol &End, bool EmitNops,
+ uint8_t Fill, const MCSubtargetInfo &STI) {}
void MCStreamer::emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
unsigned MaxBytesToEmit) {}
void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
diff --git a/llvm/test/CodeGen/AArch64/preferred-function-alignment.ll b/llvm/test/CodeGen/AArch64/preferred-function-alignment.ll
index a6cb7123e5af4..fa14d94e856dc 100644
--- a/llvm/test/CodeGen/AArch64/preferred-function-alignment.ll
+++ b/llvm/test/CodeGen/AArch64/preferred-function-alignment.ll
@@ -29,10 +29,11 @@ define void @test() {
}
; CHECK-LABEL: test
-; ALIGN2: .p2align 2
-; ALIGN3: .p2align 3
-; ALIGN4: .p2align 4
-; ALIGN5: .p2align 5
+; CHECK: .p2align 2
+; ALIGN2-NOT: .prefalign
+; ALIGN3-NEXT: .prefalign 3
+; ALIGN4-NEXT: .prefalign 4
+; ALIGN5-NEXT: .prefalign 5
define void @test_optsize() optsize {
ret void
diff --git a/llvm/test/CodeGen/ARM/preferred-function-alignment.ll b/llvm/test/CodeGen/ARM/preferred-function-alignment.ll
index 2fc67905f6db7..4fd9ed345d9ec 100644
--- a/llvm/test/CodeGen/ARM/preferred-function-alignment.ll
+++ b/llvm/test/CodeGen/ARM/preferred-function-alignment.ll
@@ -1,15 +1,18 @@
; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m85 < %s | FileCheck --check-prefixes=CHECK,ALIGN-64,ALIGN-CS-16 %s
; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m23 < %s | FileCheck --check-prefixes=CHECK,ALIGN-16,ALIGN-CS-16 %s
-; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-a5 < %s | FileCheck --check-prefixes=CHECK,ALIGN-32,ALIGN-CS-32 %s
-; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m33 < %s | FileCheck --check-prefixes=CHECK,ALIGN-32,ALIGN-CS-16 %s
-; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m55 < %s | FileCheck --check-prefixes=CHECK,ALIGN-32,ALIGN-CS-16 %s
+; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-a5 < %s | FileCheck --check-prefixes=CHECK,ALIGN-32A,ALIGN-CS-32 %s
+; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m33 < %s | FileCheck --check-prefixes=CHECK,ALIGN-32T,ALIGN-CS-16 %s
+; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m55 < %s | FileCheck --check-prefixes=CHECK,ALIGN-32T,ALIGN-CS-16 %s
; RUN: llc -mtriple=arm-none-eabi -mcpu=cortex-m7 < %s | FileCheck --check-prefixes=CHECK,ALIGN-64,ALIGN-CS-16 %s
; CHECK-LABEL: test
; ALIGN-16: .p2align 1
-; ALIGN-32: .p2align 2
-; ALIGN-64: .p2align 3
+; ALIGN-32A: .p2align 2
+; ALIGN-32T: .p2align 1
+; ALIGN-32T-NEXT: .prefalign 2
+; ALIGN-64: .p2align 1
+; ALIGN-64-NEXT: .prefalign 3
define void @test() {
ret void
diff --git a/llvm/test/CodeGen/LoongArch/linker-relaxation.ll b/llvm/test/CodeGen/LoongArch/linker-relaxation.ll
index 6b197bc578919..873a1f9168323 100644
--- a/llvm/test/CodeGen/LoongArch/linker-relaxation.ll
+++ b/llvm/test/CodeGen/LoongArch/linker-relaxation.ll
@@ -77,7 +77,6 @@ declare dso_local void @callee3() nounwind
; RELAX-NEXT: R_LARCH_RELAX - 0x0
; CHECK-RELOC-NEXT: R_LARCH_PCALA_LO12 g_i1 0x0
; RELAX-NEXT: R_LARCH_RELAX - 0x0
-; RELAX-NEXT: R_LARCH_ALIGN - 0x1C
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee1 0x0
; RELAX-NEXT: R_LARCH_RELAX - 0x0
; CHECK-RELOC-NEXT: R_LARCH_CALL36 callee2 0x0
diff --git a/llvm/test/CodeGen/PowerPC/code-align.ll b/llvm/test/CodeGen/PowerPC/code-align.ll
index 805873816c4d9..841636d65d87e 100644
--- a/llvm/test/CodeGen/PowerPC/code-align.ll
+++ b/llvm/test/CodeGen/PowerPC/code-align.ll
@@ -20,9 +20,7 @@ entry:
ret i32 %mul
; CHECK-LABEL: .globl foo
-; GENERIC: .p2align 2
-; BASIC: .p2align 4
-; PWR: .p2align 4
+; CHECK: .p2align 2
; CHECK: @foo
}
diff --git a/llvm/test/CodeGen/PowerPC/ppc64-calls.ll b/llvm/test/CodeGen/PowerPC/ppc64-calls.ll
index 2c2743f5400d9..67ff626b4f680 100644
--- a/llvm/test/CodeGen/PowerPC/ppc64-calls.ll
+++ b/llvm/test/CodeGen/PowerPC/ppc64-calls.ll
@@ -19,7 +19,7 @@ define dso_local void @test_direct() nounwind readnone {
tail call void @foo() nounwind
; Because of tail call optimization, it can be 'b' instruction.
; CHECK: [[BR:b[l]?]] foo
-; CHECK-NOT: nop
+; CHECK-NOT: {{^[[:space:]]+}}nop
ret void
}
diff --git a/llvm/test/CodeGen/SystemZ/vec-perm-14.ll b/llvm/test/CodeGen/SystemZ/vec-perm-14.ll
index 0b392676fa3ec..3c946f72935fc 100644
--- a/llvm/test/CodeGen/SystemZ/vec-perm-14.ll
+++ b/llvm/test/CodeGen/SystemZ/vec-perm-14.ll
@@ -61,7 +61,8 @@ define <4 x i8> @fun1(<2 x i8> %arg) {
; CHECK-NEXT: .space 1
; CHECK-NEXT: .text
; CHECK-NEXT: .globl fun1
-; CHECK-NEXT: .p2align 4
+; CHECK-NEXT: .p2align 1
+; CHECK-NEXT: .prefalign 4, .Lfunc_end1, nop
; CHECK-NEXT: .type fun1, at function
; CHECK-NEXT: fun1: # @fun1
; CHECK-NEXT: .cfi_startproc
@@ -96,7 +97,8 @@ define <4 x i8> @fun2(<2 x i8> %arg) {
; CHECK-NEXT: .space 1
; CHECK-NEXT: .text
; CHECK-NEXT: .globl fun2
-; CHECK-NEXT: .p2align 4
+; CHECK-NEXT: .p2align 1
+; CHECK-NEXT: .prefalign 4, .Lfunc_end2, nop
; CHECK-NEXT: .type fun2, at function
; CHECK-NEXT:fun2: # @fun2
; CHECK-NEXT: .cfi_startproc
diff --git a/llvm/test/CodeGen/X86/eh-label.ll b/llvm/test/CodeGen/X86/eh-label.ll
index 78611000e18dd..b3954700463eb 100644
--- a/llvm/test/CodeGen/X86/eh-label.ll
+++ b/llvm/test/CodeGen/X86/eh-label.ll
@@ -7,7 +7,7 @@ define void @f() personality ptr @g {
bb0:
call void asm ".Lfunc_end0:", ""()
; CHECK: #APP
-; CHECK-NEXT: .Lfunc_end0:
+; CHECK-NEXT: .Lfunc_end0{{.*}}:
; CHECK-NEXT: #NO_APP
invoke void @g() to label %bb2 unwind label %bb1
diff --git a/llvm/test/CodeGen/X86/empty-function.ll b/llvm/test/CodeGen/X86/empty-function.ll
index 7d908311ec8dc..bf05c8e359130 100644
--- a/llvm/test/CodeGen/X86/empty-function.ll
+++ b/llvm/test/CodeGen/X86/empty-function.ll
@@ -16,7 +16,7 @@ entry:
; CHECK-LABEL: f:
; WIN32: nop
; WIN64: nop
-; LINUX-NOT: nop
+; LINUX-NOT: {{^[[:space:]]+}}nop
; LINUX-NOT: ud2
}
diff --git a/llvm/test/CodeGen/X86/kcfi-arity.ll b/llvm/test/CodeGen/X86/kcfi-arity.ll
index 5a19bcd7835ea..ef859ef65fb63 100644
--- a/llvm/test/CodeGen/X86/kcfi-arity.ll
+++ b/llvm/test/CodeGen/X86/kcfi-arity.ll
@@ -3,7 +3,8 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs -stop-after=finalize-isel < %s | FileCheck %s --check-prefixes=MIR,ISEL
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs -stop-after=kcfi < %s | FileCheck %s --check-prefixes=MIR,KCFI
-; ASM: .p2align 4
+; ASM: .p2align 2
+; ASM: .prefalign 4
; ASM: .type __cfi_f1, at function
; ASM-LABEL: __cfi_f1:
; ASM-NEXT: nop
diff --git a/llvm/test/CodeGen/X86/kcfi-patchable-function-prefix.ll b/llvm/test/CodeGen/X86/kcfi-patchable-function-prefix.ll
index 1b7bd7835e890..63018b75c908f 100644
--- a/llvm/test/CodeGen/X86/kcfi-patchable-function-prefix.ll
+++ b/llvm/test/CodeGen/X86/kcfi-patchable-function-prefix.ll
@@ -1,6 +1,6 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s
-; CHECK: .p2align 4
+; CHECK: .prefalign 4, .Lfunc_end0, nop
; CHECK-LABEL: __cfi_f1:
; CHECK-COUNT-11: nop
; CHECK-NEXT: movl $12345678, %eax
@@ -12,10 +12,11 @@ define void @f1(ptr noundef %x) !kcfi_type !1 {
call void %x() [ "kcfi"(i32 12345678) ]
ret void
}
+; CHECK: .Lfunc_end0:
-; CHECK: .p2align 4
+; CHECK: .prefalign 4
; CHECK-NOT: __cfi_f2:
-; CHECK-NOT: nop
+; CHECK-NOT: {{^[[:space:]]+}}nop
; CHECK-LABEL: f2:
define void @f2(ptr noundef %x) {
; CHECK: addl -4(%r{{..}}), %r10d
@@ -23,9 +24,9 @@ define void @f2(ptr noundef %x) {
ret void
}
-; CHECK: .p2align 4
+; CHECK: .prefalign 4
; CHECK-LABEL: __cfi_f3:
-; CHECK-NOT: nop
+; CHECK-NOT: {{^[[:space:]]+}}nop
; CHECK-NEXT: movl $12345678, %eax
; CHECK-COUNT-11: nop
; CHECK-LABEL: f3:
@@ -35,9 +36,9 @@ define void @f3(ptr noundef %x) #0 !kcfi_type !1 {
ret void
}
-; CHECK: .p2align 4
+; CHECK: .prefalign 4
; CHECK-NOT: __cfi_f4:
-; CHECK-COUNT-16: nop
+; CHECK-COUNT-16: {{^[[:space:]]+}}nop
; CHECK-LABEL: f4:
define void @f4(ptr noundef %x) #0 {
; CHECK: addl -15(%r{{..}}), %r10d
diff --git a/llvm/test/CodeGen/X86/kcfi.ll b/llvm/test/CodeGen/X86/kcfi.ll
index fd93b8e3d4188..4a01f65e92721 100644
--- a/llvm/test/CodeGen/X86/kcfi.ll
+++ b/llvm/test/CodeGen/X86/kcfi.ll
@@ -2,7 +2,8 @@
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs -stop-after=finalize-isel < %s | FileCheck %s --check-prefixes=MIR,ISEL
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs -stop-after=kcfi < %s | FileCheck %s --check-prefixes=MIR,KCFI
-; ASM: .p2align 4
+; ASM: .p2align 2
+; ASM: .prefalign 4
; ASM: .type __cfi_f1, at function
; ASM-LABEL: __cfi_f1:
; ASM-NEXT: nop
diff --git a/llvm/test/CodeGen/X86/prefalign.ll b/llvm/test/CodeGen/X86/prefalign.ll
index 062cf740eabeb..c5d5a9223c2ba 100644
--- a/llvm/test/CodeGen/X86/prefalign.ll
+++ b/llvm/test/CodeGen/X86/prefalign.ll
@@ -1,12 +1,11 @@
-; RUN: llc < %s | FileCheck --check-prefixes=CHECK,NOFS %s
-; RUN: llc -function-sections < %s | FileCheck --check-prefixes=CHECK,FS %s
+; RUN: llc < %s | FileCheck %s
+; RUN: llc -function-sections < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK: .globl f1
-; NOFS-NEXT: .p2align 4
-; FS-NEXT: .prefalign 16
+; CHECK-NEXT: .prefalign 4
define void @f1() {
ret void
}
@@ -19,9 +18,8 @@ define void @f2() prefalign(1) {
}
; CHECK: .globl f3
-; NOFS-NEXT: .p2align 2
-; FS-NEXT: .p2align 1
-; FS-NEXT: .prefalign 4
+; CHECK-NEXT: .p2align 1
+; CHECK-NEXT: .prefalign 2
define void @f3() align 2 prefalign(4) {
ret void
}
diff --git a/llvm/test/CodeGen/X86/statepoint-invoke.ll b/llvm/test/CodeGen/X86/statepoint-invoke.ll
index 34dbc21a8a8cb..add4041a28c73 100644
--- a/llvm/test/CodeGen/X86/statepoint-invoke.ll
+++ b/llvm/test/CodeGen/X86/statepoint-invoke.ll
@@ -56,7 +56,7 @@ exceptional_return:
; CHECK: .uleb128 .Ltmp{{[0-9]+}}-.Ltmp{{[0-9]+}}
; CHECK: .uleb128 .Ltmp{{[0-9]+}}-.Lfunc_begin{{[0-9]+}}
; CHECK: .byte 0
-; CHECK: .p2align 4
+; CHECK: .prefalign 4
define ptr addrspace(1) @test_result(ptr addrspace(1) %obj,
; CHECK-LABEL: test_result:
@@ -99,7 +99,7 @@ exceptional_return:
; CHECK: .uleb128 .Ltmp{{[0-9]+}}-.Ltmp{{[0-9]+}}
; CHECK: .uleb128 .Ltmp{{[0-9]+}}-.Lfunc_begin{{[0-9]+}}
; CHECK: .byte 0
-; CHECK: .p2align 4
+; CHECK: .prefalign 4
define ptr addrspace(1) @test_same_val(i1 %cond, ptr addrspace(1) %val1, ptr addrspace(1) %val2, ptr addrspace(1) %val3)
; CHECK-LABEL: test_same_val:
diff --git a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
index b97b436ffc573..f2acb802b5295 100644
--- a/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
+++ b/llvm/test/DebugInfo/KeyInstructions/X86/dwarf-basic.ll
@@ -21,16 +21,16 @@
; OBJ: 0000000000000000 <_Z1fi>:
; OBJ-NEXT: 0: leal 0x1(%rdi), %eax
; OBJ-NEXT: 3: retq
-; OBJ: 0000000000000010 <_Z1gi>:
-; OBJ-NEXT: 10: leal 0x1(%rdi), %eax
-; OBJ-NEXT: 13: retq
+; OBJ: 0000000000000004 <_Z1gi>:
+; OBJ-NEXT: 4: leal 0x1(%rdi), %eax
+; OBJ-NEXT: 7: retq
; DBG: Address Line Column File ISA Discriminator OpIndex Flags
; DBG-NEXT: ------------------ ------ ------ ------ --- ------------- ------- -------------
; DBG-NEXT: 0x0000000000000000 2 0 0 0 0 0 is_stmt prologue_end
; DBG-NEXT: 0x0000000000000003 3 0 0 0 0 0 is_stmt
-; DBG-NEXT: 0x0000000000000010 2 0 0 0 0 0 is_stmt prologue_end
-; DBG-NEXT: 0x0000000000000013 6 0 0 0 0 0 is_stmt
+; DBG-NEXT: 0x0000000000000004 2 0 0 0 0 0 is_stmt prologue_end
+; DBG-NEXT: 0x0000000000000007 6 0 0 0 0 0 is_stmt
target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll b/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll
index 073ab562df57b..458d7e79c67cb 100644
--- a/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll
+++ b/llvm/test/DebugInfo/LoongArch/relax_dwo_ranges.ll
@@ -46,9 +46,9 @@
; DWARF5: Addrs: [
; DWARF5-NEXT: 0x0000000000000000
; DWARF5-NEXT: 0x0000000000000040
-; DWARF5-NEXT: 0x000000000000005c
-; DWARF5-NEXT: 0x000000000000009c
-; DWARF5-NEXT: 0x00000000000000e0
+; DWARF5-NEXT: 0x0000000000000040
+; DWARF5-NEXT: 0x0000000000000080
+; DWARF5-NEXT: 0x00000000000000c4
; DWARF5-NEXT: ]
; HDR-NOT: .rela.{{.*}}.dwo
@@ -57,9 +57,9 @@
; entries respectively
; DWARF5: .debug_rnglists.dwo contents:
; DWARF5: ranges:
-; DWARF5-NEXT: 0x00000014: [DW_RLE_startx_length]: 0x0000000000000002, 0x0000000000000024 => [0x000000000000005c, 0x0000000000000080)
+; DWARF5-NEXT: 0x00000014: [DW_RLE_startx_length]: 0x0000000000000002, 0x0000000000000024 => [0x0000000000000040, 0x0000000000000064)
; DWARF5-NEXT: 0x00000017: [DW_RLE_end_of_list ]
-; DWARF5-NEXT: 0x00000018: [DW_RLE_startx_endx ]: 0x0000000000000003, 0x0000000000000004 => [0x000000000000009c, 0x00000000000000e0)
+; DWARF5-NEXT: 0x00000018: [DW_RLE_startx_endx ]: 0x0000000000000003, 0x0000000000000004 => [0x0000000000000080, 0x00000000000000c4)
; DWARF5-NEXT: 0x0000001b: [DW_RLE_end_of_list ]
; DWARF5-EMPTY:
@@ -72,13 +72,13 @@
; DWARF4: DW_AT_name {{.*}} "square")
; DWARF4: DW_TAG_subprogram
-; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index] (indexed (00000002) address = 0x000000000000005c ".text")
+; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index] (indexed (00000002) address = 0x0000000000000040 ".text")
; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x00000024)
; DWARF4: DW_AT_name {{.*}} "boo")
; DWARF4: DW_TAG_subprogram
-; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index] (indexed (00000003) address = 0x000000000000009c ".text")
-; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_GNU_addr_index] (indexed (00000004) address = 0x00000000000000e0 ".text")
+; DWARF4-NEXT: DW_AT_low_pc [DW_FORM_GNU_addr_index] (indexed (00000003) address = 0x0000000000000080 ".text")
+; DWARF4-NEXT: DW_AT_high_pc [DW_FORM_GNU_addr_index] (indexed (00000004) address = 0x00000000000000c4 ".text")
; DWARF4: DW_AT_name {{.*}} "main")
; HDR-NOT: .rela.{{.*}}.dwo
@@ -88,9 +88,9 @@
; DWARF4: Addrs: [
; DWARF4-NEXT: 0x0000000000000000
; DWARF4-NEXT: 0x0000000000000040
-; DWARF4-NEXT: 0x000000000000005c
-; DWARF4-NEXT: 0x000000000000009c
-; DWARF4-NEXT: 0x00000000000000e0
+; DWARF4-NEXT: 0x0000000000000040
+; DWARF4-NEXT: 0x0000000000000080
+; DWARF4-NEXT: 0x00000000000000c4
; DWARF4-NEXT: ]
; HDR-NOT: .rela.{{.*}}.dwo
diff --git a/llvm/test/DebugInfo/X86/header.ll b/llvm/test/DebugInfo/X86/header.ll
index 0c730252701c5..70efb946a2f0c 100644
--- a/llvm/test/DebugInfo/X86/header.ll
+++ b/llvm/test/DebugInfo/X86/header.ll
@@ -5,7 +5,7 @@
; CHECK: .file "<stdin>"
; CHECK-NEXT: .text
; CHECK-NEXT: .globl f
-; CHECK-NEXT: .p2align 4
+; CHECK-NEXT: .prefalign 4, .Lfunc_end0, nop
; CHECK-NEXT: .type f, at function
; CHECK-NEXT: f: # @f
diff --git a/llvm/test/DebugInfo/X86/ranges_always.ll b/llvm/test/DebugInfo/X86/ranges_always.ll
index 76f846e51d2fb..7c07b464f3af4 100644
--- a/llvm/test/DebugInfo/X86/ranges_always.ll
+++ b/llvm/test/DebugInfo/X86/ranges_always.ll
@@ -102,9 +102,9 @@
; CHECK: NULL
; CHECK: DW_TAG_subprogram
; EXPR: DW_AT_low_pc
-; EXPR-SAME: [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0x30, DW_OP_plus)
+; EXPR-SAME: [DW_FORM_exprloc] (DW_OP_addrx 0x0, DW_OP_const4u 0x1e, DW_OP_plus)
; FORM: DW_AT_low_pc
-; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x30 address = 0x0000000000000030 ".text")
+; FORM-SAME: [DW_FORM_LLVM_addrx_offset] (indexed (00000000) + 0x1e address = 0x000000000000001e ".text")
; EXPRORFORM: DW_AT_high_pc
; EXPRORFORM-SAME: (0x00000001)
; RNG: DW_AT_ranges
diff --git a/llvm/test/MC/ELF/prefalign-convergence.s b/llvm/test/MC/ELF/prefalign-convergence.s
new file mode 100644
index 0000000000000..263764d4b8f29
--- /dev/null
+++ b/llvm/test/MC/ELF/prefalign-convergence.s
@@ -0,0 +1,47 @@
+# REQUIRES: asserts
+## Test that sections with many .prefalign fragments converge quickly.
+## PrefAlign fragments see fresh offsets and converge in 1 iteration.
+
+# RUN: llvm-mc -filetype=obj -triple x86_64 --stats %s -o %t 2>&1 | FileCheck %s --check-prefix=STATS
+# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
+
+# STATS: 2 assembler - Number of assembler layout and relaxation steps
+
+# CHECK: 8: int3
+# CHECK-NEXT: 9: int3
+# CHECK-NEXT: a: int3
+# CHECK-NEXT: b: int3
+# CHECK-NEXT: c: int3
+# CHECK-NEXT: d: nopl
+# CHECK-NEXT: 10: int3
+# CHECK: 15: nopl
+# CHECK-NEXT: 18: int3
+# CHECK: 1d: nopl
+# CHECK-NEXT: 20: int3
+# CHECK: 25: nopl
+# CHECK-NEXT: 28: int3
+# CHECK: 2d: nopl
+# CHECK-NEXT: 30: int3
+# CHECK: 35: nopl
+# CHECK-NEXT: 38: int3
+# CHECK: 3d: nopl
+# CHECK-NEXT: 40: int3
+# CHECK: 45: nopl
+# CHECK-NEXT: 48: int3
+# CHECK: 4d: nopl
+# CHECK-NEXT: 50: int3
+# CHECK-NEXT: 51: int3
+# CHECK-NEXT: 52: int3
+# CHECK-NEXT: 53: int3
+# CHECK-NEXT: 54: int3
+
+.section .text,"ax", at progbits
+.byte 0
+
+.rept 10
+.prefalign 4, .Lend\+, nop
+.rept 5
+int3
+.endr
+.Lend\+:
+.endr
diff --git a/llvm/test/MC/ELF/prefalign-errors.s b/llvm/test/MC/ELF/prefalign-errors.s
index 802a78fde7c44..4325e507577e7 100644
--- a/llvm/test/MC/ELF/prefalign-errors.s
+++ b/llvm/test/MC/ELF/prefalign-errors.s
@@ -1,5 +1,50 @@
-// RUN: not llvm-mc -filetype=asm -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s
+# RUN: rm -fr %t && split-file %s %t && cd %t
+# RUN: not llvm-mc -triple=x86_64 a.s 2>&1 | FileCheck a.s
+# RUN: not llvm-mc -triple=x86_64 -filetype=obj b.s 2>&1 | FileCheck b.s
+# RUN: not llvm-mc -triple=x86_64 -filetype=obj c.s 2>&1 | FileCheck c.s
+#--- a.s
.section .text.f1,"ax", at progbits
-// CHECK: {{.*}}.s:[[# @LINE+1]]:12: error: alignment must be a power of 2
-.prefalign 3
+# CHECK: [[#@LINE+1]]:12: error: log2 alignment must be in the range [0, 63]
+.prefalign 64
+
+# CHECK: [[#@LINE+1]]:13: error: expected comma
+.prefalign 4
+
+# CHECK: [[#@LINE+1]]:14: error: expected symbol name
+.prefalign 4,
+
+# CHECK: [[#@LINE+1]]:22: error: expected comma
+.prefalign 4,.text.f1
+
+# CHECK: [[#@LINE+1]]:23: error: expected absolute expression
+.prefalign 4,.text.f1,trap
+
+# CHECK: [[#@LINE+1]]:23: error: fill value must be in range [0, 255]
+.prefalign 4,.text.f1,256
+
+# CHECK: [[#@LINE+1]]:23: error: fill value must be in range [0, 255]
+.prefalign 4,.text.f1,-1
+
+## Non-zero fill in a BSS section.
+.bss
+# CHECK: [[#@LINE+1]]:19: error: non-zero fill in BSS section '.bss'
+.prefalign 4,.Lend,1
+# CHECK: [[#@LINE+1]]:19: error: non-zero fill in BSS section '.bss'
+.prefalign 4,.Lend,nop
+.space 1
+.Lend:
+
+#--- b.s
+## End symbol is undefined.
+.section .text.f1,"ax", at progbits
+# CHECK: <unknown>:0: error: .prefalign end symbol 'undef' must be in the current section
+.prefalign 4,undef,0
+
+#--- c.s
+## End symbol is defined in a
diff erent section.
+.section .text.f1,"ax", at progbits
+.prefalign 4,.Lend,0
+# CHECK: <unknown>:0: error: .prefalign end symbol '.Lend' must be in the current section
+.section .text.f2,"ax", at progbits
+.Lend:
diff --git a/llvm/test/MC/ELF/prefalign.s b/llvm/test/MC/ELF/prefalign.s
index 803bb5d730340..032cd114d3cc3 100644
--- a/llvm/test/MC/ELF/prefalign.s
+++ b/llvm/test/MC/ELF/prefalign.s
@@ -1,104 +1,138 @@
-// RUN: llvm-mc -triple x86_64 %s -o - | FileCheck --check-prefix=ASM %s
-// RUN: llvm-mc -filetype=obj -triple x86_64 %s -o - | llvm-readelf -SW - | FileCheck --check-prefix=OBJ %s
+# RUN: llvm-mc -triple x86_64 %s -o - | FileCheck --check-prefix=ASM %s
+# RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t
+# RUN: llvm-readelf -SW %t | FileCheck --check-prefix=OBJ %s
+# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=DIS %s
+# RUN: llvm-objdump -s -j .text.f1 -j .text.f2 -j .text.f6 %t | FileCheck --check-prefix=HEX %s
-// Minimum alignment >= preferred alignment, no effect on sh_addralign.
-// ASM: .section .text.f1lt
-// ASM: .p2align 2
-// ASM: .prefalign 2
-// OBJ: .text.f1lt PROGBITS 0000000000000000 000040 000003 00 AX 0 0 4
-.section .text.f1lt,"ax", at progbits
+## MinAlign >= PrefAlign: the three-way rule is bounded by MinAlign regardless
+## of body size, so sh_addralign stays at MinAlign.
+# ASM: .section .text.f1
+# ASM: .p2align 2
+# ASM: .prefalign 1, .Lf1_end, 0
+# OBJ: .text.f1 PROGBITS 0000000000000000 {{[0-9a-f]+}} 000003 00 AX 0 0 4
+# HEX: Contents of section .text.f1:
+# HEX-NEXT: 0000 f8f8f8 ...
+.section .text.f1,"ax", at progbits
.p2align 2
-.prefalign 2
+.prefalign 1, .Lf1_end, 0
.rept 3
-nop
+clc
.endr
+.Lf1_end:
-// ASM: .section .text.f1eq
-// ASM: .p2align 2
-// ASM: .prefalign 2
-// OBJ: .text.f1eq PROGBITS 0000000000000000 000044 000004 00 AX 0 0 4
-.section .text.f1eq,"ax", at progbits
+## Multiple .prefalign on the same end symbol: effective PrefAlign is the maximum.
+# ASM: .section .text.f2
+# ASM: .prefalign 3, .Lf2_end, 0
+# ASM: .prefalign 4, .Lf2_end, 0
+# ASM: .prefalign 3, .Lf2_end, 0
+# OBJ: .text.f2 PROGBITS 0000000000000000 {{[0-9a-f]+}} 000009 00 AX 0 0 16
+# HEX-NEXT: Contents of section .text.f2:
+# HEX-NEXT: 0000 f8f8f8f8 f8f8f8f8 f8 .........
+.section .text.f2,"ax", at progbits
.p2align 2
-.prefalign 2
-.rept 4
-nop
-.endr
-
-// ASM: .section .text.f1gt
-// ASM: .p2align 2
-// ASM: .prefalign 2
-// OBJ: .text.f1gt PROGBITS 0000000000000000 000048 000005 00 AX 0 0 4
-.section .text.f1gt,"ax", at progbits
-.p2align 2
-.prefalign 2
-.rept 5
-nop
+.prefalign 3, .Lf2_end, 0
+.prefalign 4, .Lf2_end, 1-1
+.prefalign 3, .Lf2_end, 0
+.rept 9
+clc
.endr
+.Lf2_end:
-// Minimum alignment < preferred alignment, sh_addralign influenced by section size.
-// Use maximum of all .prefalign directives.
-// ASM: .section .text.f2lt
-// ASM: .p2align 2
-// ASM: .prefalign 8
-// ASM: .prefalign 16
-// ASM: .prefalign 8
-// OBJ: .text.f2lt PROGBITS 0000000000000000 000050 000003 00 AX 0 0 4
-.section .text.f2lt,"ax", at progbits
+## Multiple functions in a section, each with its own .prefalign.
+## nop fill; f3b's 5-byte padding is a NOP.
+## f3b: ComputedAlign=8, padding=5
+## f3c: ComputedAlign=16, padding=0
+# ASM: .prefalign 4, .Lf3a_end, nop
+# ASM: .prefalign 4, .Lf3b_end, nop
+# ASM: .prefalign 4, .Lf3c_end, 204
+# OBJ: .text.f3 PROGBITS 0000000000000000 {{[0-9a-f]+}} 000020 00 AX 0 0 16
+# DIS: Disassembly of section .text.f3:
+# DIS: 0: clc
+# DIS-NEXT: 1: clc
+# DIS-NEXT: 2: clc
+# DIS-NEXT: 3: nopl
+# DIS-NEXT: 8: stc
+# DIS: f: stc
+# DIS-NEXT: 10: clc
+# DIS: 1f: clc
+# DIS-EMPTY:
+.section .text.f3,"ax", at progbits
.p2align 2
-.prefalign 8
-.prefalign 16
-.prefalign 8
+.prefalign 4, .Lf3a_end, nop
.rept 3
-nop
+clc
.endr
-
-// ASM: .section .text.f2between1
-// OBJ: .text.f2between1 PROGBITS 0000000000000000 000054 000008 00 AX 0 0 8
-.section .text.f2between1,"ax", at progbits
-.p2align 2
-.prefalign 8
-.prefalign 16
-.prefalign 8
+.Lf3a_end:
+.prefalign 4, .Lf3b_end, nop
.rept 8
-nop
+stc
.endr
-
-// OBJ: .text.f2between2 PROGBITS 0000000000000000 00005c 000009 00 AX 0 0 16
-.section .text.f2between2,"ax", at progbits
-.p2align 2
-.prefalign 8
-.prefalign 16
-.prefalign 8
-.rept 9
-nop
+.Lf3b_end:
+.prefalign 4, .Lf3c_end, 0xcc
+.rept 16
+clc
.endr
+.Lf3c_end:
+## No-op prefalign
+.prefalign 4, .Lf3d_end, 0xcc
+.Lf3d_end:
+.prefalign 4, .Lf3a_end, 0xcb+1
-// OBJ: .text.f2between3 PROGBITS 0000000000000000 000068 000010 00 AX 0 0 16
-.section .text.f2between3,"ax", at progbits
+## Two functions in one section where the second function's padding depends on
+## the first function's size.
+# OBJ: .text.f4 PROGBITS 0000000000000000 {{[0-9a-f]+}} 00001e 00 AX 0 0 16
+# DIS: Disassembly of section .text.f4:
+# DIS: 0: pushq
+# DIS: 7: retq
+# DIS-NEXT: 8: nopl
+# DIS-NEXT: 10: movl
+# DIS: 1d: retq
+# DIS-EMPTY:
+.section .text.f4,"ax", at progbits
.p2align 2
-.prefalign 8
-.prefalign 16
-.prefalign 8
-.rept 16
-nop
+.prefalign 4, .Lf4a_end, nop
+pushq %rbp
+movq %rsp, %rbp
+xorl %eax, %eax
+popq %rbp
+retq
+.Lf4a_end:
+.prefalign 4, .Lf4b_end, nop
+movl $0, 0
+xorl %eax, %eax
+retq
+.Lf4b_end:
+
+## sh_addralign stays at 32, not downgraded by .prefalign.
+# OBJ: .text.f5 PROGBITS 0000000000000000 {{[0-9a-f]+}} 000003 00 AX 0 0 32
+.section .text.f5,"ax", at progbits
+.p2align 5
+.prefalign 4, .Lf5_end, 0
+.rept 3
+clc
.endr
+.Lf5_end:
-// OBJ: .text.f2gt1 PROGBITS 0000000000000000 000078 000011 00 AX 0 0 16
-.section .text.f2gt1,"ax", at progbits
-.p2align 2
-.prefalign 8
-.prefalign 16
-.prefalign 8
-.rept 17
-nop
+## body_size > PrefAlign: ComputedAlign is clamped to PrefAlign.
+## body=20, pref=8 => ComputedAlign=8, padding=7 zero bytes.
+# OBJ: .text.f6 PROGBITS 0000000000000000 {{[0-9a-f]+}} 00001c 00 AX 0 0 8
+# HEX-NEXT: Contents of section .text.f6:
+# HEX-NEXT: 0000 01030303 03030303 f8f8f8f8 f8f8f8f8 ................
+# HEX-NEXT: 0010 f8f8f8f8 f8f8f8f8 f8f8f8f8 ............
+.section .text.f6,"ax", at progbits
+.byte 1
+.prefalign 3, .Lf6_end, 3
+.rept 20
+clc
.endr
+.Lf6_end:
-// OBJ: .text.f2gt2 PROGBITS 0000000000000000 00008c 000021 00 AX 0 0 16
-.section .text.f2gt2,"ax", at progbits
+## .prefalign in a BSS section with zero fill.
+# ASM: .bss
+# ASM: .prefalign 4, .Lbss_end, 0
+# OBJ: .bss NOBITS 0000000000000000 {{[0-9a-f]+}} 000004 00 WA 0 0 4
+.bss
.p2align 2
-.prefalign 8
-.prefalign 16
-.prefalign 8
-.rept 33
-nop
-.endr
+.prefalign 4, .Lbss_end, 0
+.space 4
+.Lbss_end:
diff --git a/llvm/test/MC/RISCV/prefalign.s b/llvm/test/MC/RISCV/prefalign.s
new file mode 100644
index 0000000000000..488234ee04ba0
--- /dev/null
+++ b/llvm/test/MC/RISCV/prefalign.s
@@ -0,0 +1,34 @@
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+relax %s -o %t
+# RUN: llvm-readelf -SW %t | FileCheck --check-prefix=OBJ %s
+# RUN: llvm-objdump -d -M no-aliases --no-show-raw-insn %t | FileCheck --check-prefix=DIS %s
+# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOC %s
+
+## Two functions in one section with nop fill.
+## f1: body = 12 bytes < 16, ComputedAlign=16, but section start is 16-aligned
+## so pad = 0
+## f2: body = 32 bytes >= 16, ComputedAlign=16, pad = 4 (one nop at 0xc)
+# OBJ: .text.f1 PROGBITS {{[0-9a-f]+}} {{[0-9a-f]+}} 000030 00 AX 0 0 16
+# DIS: 0: addi a0, zero, 0x1
+# DIS-NEXT: 4: addi a0, zero, 0x2
+# DIS-NEXT: 8: add a0, a0, a1
+## Padding nop for f2
+# DIS-NEXT: c: addi zero, zero, 0x0
+## f2 starts at 0x10, aligned to 16
+# DIS-NEXT: 10: add a0, a0, a1
+.section .text.f1,"ax", at progbits
+.p2align 2
+.prefalign 4, .Lf1_end, nop
+addi a0, zero, 1
+addi a0, zero, 2
+add a0, a0, a1
+.Lf1_end:
+.prefalign 4, .Lf2_end, nop
+.rept 8
+add a0, a0, a1
+.endr
+.Lf2_end:
+
+## .prefalign does not emit R_RISCV_ALIGN relocations. The padding is fully
+## resolved at assembly time, so no linker adjustment is needed.
+# RELOC: Relocations [
+# RELOC-NEXT: ]
diff --git a/llvm/test/tools/llvm-nm/X86/demangle.ll b/llvm/test/tools/llvm-nm/X86/demangle.ll
index cab2e09cc1d49..b0e3d75993a9f 100644
--- a/llvm/test/tools/llvm-nm/X86/demangle.ll
+++ b/llvm/test/tools/llvm-nm/X86/demangle.ll
@@ -6,7 +6,7 @@
; RUN: llc -filetype=obj -mtriple=x86_64-apple-darwin9 -o %t.macho %s
; RUN: llvm-nm %t.macho | FileCheck --check-prefix="MACHO-MANGLED" %s
-; RUN: llvm-nm -C %t.macho | FileCheck --check-prefix="DEMANGLED" %s
+; RUN: llvm-nm -C %t.macho | FileCheck --check-prefix="MACHO-DEMANGLED" %s
; RUN: llc -filetype=obj -mtriple=x86_64-pc-win32 -o %t.coff %s
; RUN: llvm-nm %t.coff | FileCheck --check-prefix="COFF-MANGLED" %s
@@ -33,8 +33,8 @@ entry:
ret i32 1
}
-; MANGLED: 0000000000000020 T _RNvC1a3baz
-; MANGLED: 0000000000000010 T _Z3barf
+; MANGLED: 0000000000000010 T _RNvC1a3baz
+; MANGLED: 0000000000000008 T _Z3barf
; MANGLED: 0000000000000000 T _Z3fooi
; MACHO-MANGLED: 0000000000000020 T __RNvC1a3baz
@@ -45,10 +45,14 @@ entry:
; COFF-MANGLED: 00000010 T _Z3barf
; COFF-MANGLED: 00000000 T _Z3fooi
-; DEMANGLED: 0000000000000020 T a::baz
-; DEMANGLED: 0000000000000010 T bar(float)
+; DEMANGLED: 0000000000000010 T a::baz
+; DEMANGLED: 0000000000000008 T bar(float)
; DEMANGLED: 0000000000000000 T foo(int)
+; MACHO-DEMANGLED: 0000000000000020 T a::baz
+; MACHO-DEMANGLED: 0000000000000010 T bar(float)
+; MACHO-DEMANGLED: 0000000000000000 T foo(int)
+
; COFF-DEMANGLED: 00000020 T a::baz
; COFF-DEMANGLED: 00000010 T bar(float)
; COFF-DEMANGLED: 00000000 T foo(int)
diff --git a/llvm/test/tools/llvm-objdump/X86/source-interleave-function-from-debug.test b/llvm/test/tools/llvm-objdump/X86/source-interleave-function-from-debug.test
index edf87c02c692e..96ae656100531 100644
--- a/llvm/test/tools/llvm-objdump/X86/source-interleave-function-from-debug.test
+++ b/llvm/test/tools/llvm-objdump/X86/source-interleave-function-from-debug.test
@@ -13,23 +13,23 @@
; CHECK-NEXT: 0: b8 05 00 00 00 movl $5, %eax
; CHECK-NEXT: 5: c3 retq
-; CHECK-NO-DEMANGLE: 0000000000000010 <_ZN3xyz3barEv>:
+; CHECK-NO-DEMANGLE: 0000000000000008 <_ZN3xyz3barEv>:
; CHECK-NO-DEMANGLE-NEXT: ; _ZN3xyz3barEv():
-; CHECK-DEMANGLE: 0000000000000010 <xyz::bar()>:
+; CHECK-DEMANGLE: 0000000000000008 <xyz::bar()>:
; CHECK-DEMANGLE-NEXT: ; xyz::bar():
; CHECK-NEXT: ; /tmp{{/|\\}}src.cc:3
-; CHECK-NEXT: 10: b8 0a 00 00 00 movl $10, %eax
-; CHECK-NEXT: 15: c3 retq
+; CHECK-NEXT: 8: b8 0a 00 00 00 movl $10, %eax
+; CHECK-NEXT: d: c3 retq
-; CHECK-NO-DEMANGLE: 0000000000000020 <_ZN3xyz3bazEv>:
+; CHECK-NO-DEMANGLE: 0000000000000010 <_ZN3xyz3bazEv>:
; CHECK-NO-DEMANGLE-NEXT: ; _ZN3xyz3bazEv():
-; CHECK-DEMANGLE: 0000000000000020 <xyz::baz()>:
+; CHECK-DEMANGLE: 0000000000000010 <xyz::baz()>:
; CHECK-DEMANGLE-NEXT: ; xyz::baz():
; CHECK-NEXT: ; /tmp{{/|\\}}src.cc:3
-; CHECK-NEXT: 20: b8 14 00 00 00 movl $20, %eax
-; CHECK-NEXT: 25: c3 retq
+; CHECK-NEXT: 10: b8 14 00 00 00 movl $20, %eax
+; CHECK-NEXT: 15: c3 retq
;; When symbol information is missing, we can get function names from debug
;; info. The IR is intentionally doctored to have
diff erent names in debug info
@@ -45,13 +45,13 @@
; STRIPPED: ; xyz::bar():
; STRIPPED-NEXT: ; /tmp{{/|\\}}src.cc:3
-; STRIPPED-NEXT: 10: b8 0a 00 00 00 movl $10, %eax
-; STRIPPED-NEXT: 15: c3 retq
+; STRIPPED-NEXT: 8: b8 0a 00 00 00 movl $10, %eax
+; STRIPPED-NEXT: d: c3 retq
; STRIPPED: ; xyz::baz():
; STRIPPED-NEXT: ; /tmp{{/|\\}}src.cc:3
-; STRIPPED-NEXT: 20: b8 14 00 00 00 movl $20, %eax
-; STRIPPED-NEXT: 25: c3 retq
+; STRIPPED-NEXT: 10: b8 14 00 00 00 movl $20, %eax
+; STRIPPED-NEXT: 15: c3 retq
;; IR adapted from:
;; $ cat /tmp/src.cc
More information about the flang-commits
mailing list