[llvm] r240869 - [MC] Align fragments when -mc-relax-all flag is used

Petr Hosek phosek at chromium.org
Fri Jun 26 18:49:53 PDT 2015


Author: phosek
Date: Fri Jun 26 20:49:53 2015
New Revision: 240869

URL: http://llvm.org/viewvc/llvm-project?rev=240869&view=rev
Log:
[MC] Align fragments when -mc-relax-all flag is used

Summary:
Ensure that fragments are bundle aligned when instruction bundling
is enabled and the -mc-relax-all flag is set. This is implicitly
assumed by the bundle padding implementation but this assumption
does not hold when custom alignment is being used.

The change was tested by running PNaCl toolchain trybots with
-mc-relax-all flag set.

Fixes https://code.google.com/p/nativeclient/issues/detail?id=4063

Test Plan: Regression test attached

Reviewers: mseaborn

Subscribers: jfb, llvm-commits

Differential Revision: http://reviews.llvm.org/D10044

Added:
    llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle-group.s
    llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle.s
Modified:
    llvm/trunk/lib/MC/MCAssembler.cpp

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=240869&r1=240868&r2=240869&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Jun 26 20:49:53 2015
@@ -254,7 +254,7 @@ uint64_t llvm::computeBundlePadding(cons
     else { // EndOfFragment > BundleSize
       return 2 * BundleSize - EndOfFragment;
     }
-  } else if (EndOfFragment > BundleSize)
+  } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)
     return BundleSize - OffsetInBundle;
   else
     return 0;
@@ -581,16 +581,22 @@ void MCAsmLayout::layoutFragment(MCFragm
   // size won't include the padding.
   //
   // When the -mc-relax-all flag is used, we optimize bundling by writting the
-  // bundle padding directly into fragments when the instructions are emitted
-  // inside the streamer.
+  // padding directly into fragments when the instructions are emitted inside
+  // the streamer. When the fragment is larger than the bundle size, we need to
+  // ensure that it's bundle aligned. This means that if we end up with
+  // multiple fragments, we must emit bundle padding between fragments.
   //
-  if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() &&
-      F->hasInstructions()) {
+  // ".align N" is an example of a directive that introduces multiple
+  // fragments. We could add a special case to handle ".align N" by emitting
+  // within-fragment padding (which would produce less padding when N is less
+  // than the bundle size), but for now we don't.
+  //
+  if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
     assert(isa<MCEncodedFragment>(F) &&
            "Only MCEncodedFragment implementations have instructions");
     uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
 
-    if (FSize > Assembler.getBundleAlignSize())
+    if (!Assembler.getRelaxAll() && FSize > Assembler.getBundleAlignSize())
       report_fatal_error("Fragment can't be larger than a bundle size");
 
     uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,

Added: llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle-group.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle-group.s?rev=240869&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle-group.s (added)
+++ llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle-group.s Fri Jun 26 20:49:53 2015
@@ -0,0 +1,23 @@
+# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - \
+# RUN:   | llvm-objdump -disassemble -no-show-raw-insn - \
+# RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-OPT %s
+# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -mc-relax-all %s -o - \
+# RUN:   | llvm-objdump -disassemble -no-show-raw-insn - \
+# RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-RELAX %s
+
+        .text
+foo:
+        .bundle_align_mode 5
+        push    %ebp # 1 byte
+        .align  16
+        .bundle_lock align_to_end
+# CHECK:            1:  nopw %cs:(%eax,%eax)
+# CHECK:            10: nopw %cs:(%eax,%eax)
+# CHECK-RELAX:      1f: nop
+# CHECK-RELAX:      20: nopw %cs:(%eax,%eax)
+# CHECK-RELAX:      2f: nopw %cs:(%eax,%eax)
+# CHECK-OPT:        1b: calll -4
+# CHECK-RELAX:      3b: calll -4
+        calll   bar # 5 bytes
+        .bundle_unlock
+        ret         # 1 byte

Added: llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle.s?rev=240869&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle.s (added)
+++ llvm/trunk/test/MC/X86/AlignedBundling/misaligned-bundle.s Fri Jun 26 20:49:53 2015
@@ -0,0 +1,31 @@
+# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - \
+# RUN:   | llvm-objdump -disassemble -no-show-raw-insn - \
+# RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-OPT %s
+# RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -mc-relax-all %s -o - \
+# RUN:   | llvm-objdump -disassemble -no-show-raw-insn - \
+# RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-RELAX %s
+
+        .text
+foo:
+        .bundle_align_mode 5
+        push    %ebp          # 1 byte
+        .align  16
+# CHECK:            1:  nopw %cs:(%eax,%eax)
+# CHECK-RELAX:      10: nopw %cs:(%eax,%eax)
+# CHECK-RELAX:      1f: nop
+# CHECK-OPT:        10: movl $1, (%esp)
+# CHECK-RELAX:      20: movl $1, (%esp)
+        movl $0x1, (%esp)     # 7 bytes
+        movl $0x1, (%esp)     # 7 bytes
+# CHECK-OPT:        1e: nop
+        movl $0x2, 0x1(%esp)  # 8 bytes
+        movl $0x2, 0x1(%esp)  # 8 bytes
+# CHECK-RELAX:      3e: nop
+# CHECK-RELAX:      40: movl $2, 1(%esp)
+        movl $0x2, 0x1(%esp)  # 8 bytes
+        movl $0x2, (%esp)     # 7 bytes
+# CHECK-OPT:        3f: nop
+# CHECK-OPT:        40: movl $3, (%esp)
+        movl $0x3, (%esp)     # 7 bytes
+        movl $0x3, (%esp)     # 7 bytes
+        ret





More information about the llvm-commits mailing list