summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCAsmLayout.h7
-rw-r--r--lib/MC/MCAssembler.cpp15
-rw-r--r--test/MC/X86/AlignedBundling/relax-at-bundle-end.s16
3 files changed, 28 insertions, 10 deletions
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index 8cb4601283..3058b7b487 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -60,9 +60,10 @@ public:
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
- /// \brief Invalidate the fragments after F because it has been resized.
- /// The fragment's size should have already been updated.
- void invalidateFragmentsAfter(MCFragment *F);
+ /// \brief Invalidate the fragments starting with F because it has been
+ /// resized. The fragment's size should have already been updated, but
+ /// its bundle padding will be recomputed.
+ void invalidateFragmentsFrom(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been laid out correctly, and the parent section has
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 498fbf77ad..fd281e67c7 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -82,14 +82,15 @@ bool MCAsmLayout::isFragmentValid(const MCFragment *F) const {
return F->getLayoutOrder() <= LastValid->getLayoutOrder();
}
-void MCAsmLayout::invalidateFragmentsAfter(MCFragment *F) {
+void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) {
// If this fragment wasn't already valid, we don't need to do anything.
if (!isFragmentValid(F))
return;
- // Otherwise, reset the last valid fragment to this fragment.
+ // Otherwise, reset the last valid fragment to the previous fragment
+ // (if this is the first fragment, it will be NULL).
const MCSectionData &SD = *F->getParent();
- LastValidFragment[&SD] = F;
+ LastValidFragment[&SD] = F->getPrevNode();
}
void MCAsmLayout::ensureValid(const MCFragment *F) const {
@@ -165,14 +166,14 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F,
uint64_t FOffset, uint64_t FSize) {
uint64_t BundleSize = Assembler.getBundleAlignSize();
- assert(BundleSize > 0 &&
+ assert(BundleSize > 0 &&
"computeBundlePadding should only be called if bundling is enabled");
uint64_t BundleMask = BundleSize - 1;
uint64_t OffsetInBundle = FOffset & BundleMask;
uint64_t EndOfFragment = OffsetInBundle + FSize;
// There are two kinds of bundling restrictions:
- //
+ //
// 1) For alignToBundleEnd(), add padding to ensure that the fragment will
// *end* on a bundle boundary.
// 2) Otherwise, check if the fragment would cross a bundle boundary. If it
@@ -939,7 +940,7 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) {
FirstRelaxedFragment = I;
}
if (FirstRelaxedFragment) {
- Layout.invalidateFragmentsAfter(FirstRelaxedFragment);
+ Layout.invalidateFragmentsFrom(FirstRelaxedFragment);
return true;
}
return false;
@@ -999,7 +1000,7 @@ void MCFragment::dump() {
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
<< " Offset:" << Offset
<< " HasInstructions:" << hasInstructions()
- << " BundlePadding:" << getBundlePadding() << ">";
+ << " BundlePadding:" << static_cast<unsigned>(getBundlePadding()) << ">";
switch (getKind()) {
case MCFragment::FT_Align: {
diff --git a/test/MC/X86/AlignedBundling/relax-at-bundle-end.s b/test/MC/X86/AlignedBundling/relax-at-bundle-end.s
new file mode 100644
index 0000000000..ab4affbbea
--- /dev/null
+++ b/test/MC/X86/AlignedBundling/relax-at-bundle-end.s
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - \
+# RUN: | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s
+
+# Test that an instruction near a bundle end gets properly padded
+# after it is relaxed.
+.text
+foo:
+ .bundle_align_mode 5
+ .rept 29
+ push %rax
+ .endr
+# CHECK: 1c: push
+# CHECK: 1d: nop
+# CHECK: 20: jne
+ jne 0x100
+