Index: llvm/include/llvm/MC/MCFragment.h
===================================================================
--- llvm/include/llvm/MC/MCFragment.h
+++ llvm/include/llvm/MC/MCFragment.h
@@ -34,6 +34,7 @@
 public:
   enum FragmentType : uint8_t {
     FT_Align,
+    FT_NeverAlign,
     FT_Data,
     FT_CompactEncodedInst,
     FT_Fill,
@@ -333,6 +334,41 @@
   }
 };
 
+class MCNeverAlignFragment : public MCFragment {
+  /// Alignment - The alignment the end of the next fragment should avoid
+  unsigned Alignment;
+
+  /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+  /// of using the provided value. The exact interpretation of this flag is
+  /// target dependent.
+  bool EmitNops : 1;
+
+  /// Value - Value to use for filling padding bytes.
+  int64_t Value;
+
+  /// ValueSize - The size of the integer (in bytes) of \p Value.
+  unsigned ValueSize;
+
+public:
+  MCNeverAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
+                       MCSection *Sec = nullptr)
+      : MCFragment(FT_NeverAlign, false, Sec), Alignment(Alignment),
+        EmitNops(false), Value(Value), ValueSize(ValueSize) {}
+
+  unsigned getAlignment() const { return Alignment; }
+
+  int64_t getValue() const { return Value; }
+
+  unsigned getValueSize() const { return ValueSize; }
+
+  bool hasEmitNops() const { return EmitNops; }
+  void setEmitNops(bool Value) { EmitNops = Value; }
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_NeverAlign;
+  }
+};
+
 class MCFillFragment : public MCFragment {
   uint8_t ValueSize;
   /// Value to use for filling bytes.
Index: llvm/include/llvm/MC/MCObjectStreamer.h
===================================================================
--- llvm/include/llvm/MC/MCObjectStreamer.h
+++ llvm/include/llvm/MC/MCObjectStreamer.h
@@ -139,6 +139,8 @@
                             unsigned MaxBytesToEmit = 0) override;
   void emitCodeAlignment(unsigned ByteAlignment,
                          unsigned MaxBytesToEmit = 0) override;
+  void emitNeverAlignCodeAtEnd(unsigned ByteAlignment, int64_t Value = 0,
+                               unsigned ValueSize = 1) override;
   void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
                          SMLoc Loc) override;
   void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
Index: llvm/include/llvm/MC/MCStreamer.h
===================================================================
--- llvm/include/llvm/MC/MCStreamer.h
+++ llvm/include/llvm/MC/MCStreamer.h
@@ -837,6 +837,12 @@
   virtual void emitCodeAlignment(unsigned ByteAlignment,
                                  unsigned MaxBytesToEmit = 0);
 
+  /// If the end of the following fragment ever gets aligned to
+  /// \p ByteAlignment, emit a single nop or \t Value to break this alignment.
+  virtual void emitNeverAlignCodeAtEnd(unsigned ByteAlignment,
+                                       int64_t Value = 0,
+                                       unsigned ValueSize = 1);
+
   /// Emit some number of copies of \p Value until the byte offset \p
   /// Offset is reached.
   ///
Index: llvm/lib/MC/MCAssembler.cpp
===================================================================
--- llvm/lib/MC/MCAssembler.cpp
+++ llvm/lib/MC/MCAssembler.cpp
@@ -346,6 +346,34 @@
     return Size;
   }
 
+  case MCFragment::FT_NeverAlign: {
+    const MCNeverAlignFragment &NAF = cast<MCNeverAlignFragment>(F);
+    uint64_t Offset = Layout.getFragmentOffset(&NAF);
+    unsigned Size = 0;
+    uint64_t OffsetToAvoid = 0;
+    // Calculate offset to avoid in order to avoid aligning the end of the
+    // next fragment
+    if (const auto *NextFrag = dyn_cast<MCRelaxableFragment>(F.getNextNode())) {
+      OffsetToAvoid = NAF.getAlignment() -
+                      (NextFrag->getContents().size() % NAF.getAlignment());
+    } else if (const auto *NextFrag =
+                   dyn_cast<MCDataFragment>(F.getNextNode())) {
+      OffsetToAvoid = NAF.getAlignment() -
+                      (NextFrag->getContents().size() % NAF.getAlignment());
+    }
+    // Check if the current offset matches the alignment plus offset we want to
+    // avoid
+    if (Offset % NAF.getAlignment() == OffsetToAvoid) {
+      // Avoid this alignment by introducing one extra byte
+      Size = 1;
+      if (Size > 0 && NAF.hasEmitNops()) {
+        while (Size % getBackend().getMinimumNopSize())
+          Size += 1;
+      }
+    }
+    return Size;
+  }
+
   case MCFragment::FT_Org: {
     const MCOrgFragment &OF = cast<MCOrgFragment>(F);
     MCValue Value;
@@ -569,6 +597,44 @@
     break;
   }
 
+  case MCFragment::FT_NeverAlign: {
+    const MCNeverAlignFragment &NAF = cast<MCNeverAlignFragment>(F);
+    assert(NAF.getValueSize() && "Invalid virtual align in concrete fragment!");
+
+    uint64_t Count = FragmentSize / NAF.getValueSize();
+    if (Count == 0)
+      break;
+    assert(Count * NAF.getValueSize() == FragmentSize);
+
+    if (NAF.hasEmitNops()) {
+      if (!Asm.getBackend().writeNopData(OS, Count))
+        report_fatal_error("unable to write nop sequence of " + Twine(Count) +
+                           " bytes");
+      break;
+    }
+
+    // Otherwise, write out in multiples of the value size.
+    for (uint64_t I = 0; I != Count; ++I) {
+      switch (NAF.getValueSize()) {
+      default:
+        llvm_unreachable("Invalid size!");
+      case 1:
+        OS << char(NAF.getValue());
+        break;
+      case 2:
+        support::endian::write<uint16_t>(OS, NAF.getValue(), Endian);
+        break;
+      case 4:
+        support::endian::write<uint32_t>(OS, NAF.getValue(), Endian);
+        break;
+      case 8:
+        support::endian::write<uint64_t>(OS, NAF.getValue(), Endian);
+        break;
+      }
+    }
+    break;
+  }
+
   case MCFragment::FT_Data:
     ++stats::EmittedDataFragments;
     OS << cast<MCDataFragment>(F).getContents();
@@ -757,6 +823,11 @@
                 cast<MCAlignFragment>(F).getValue() == 0) &&
                "Invalid align in virtual section!");
         break;
+      case MCFragment::FT_NeverAlign:
+        assert((cast<MCNeverAlignFragment>(F).getValueSize() == 0 ||
+                cast<MCNeverAlignFragment>(F).getValue() == 0) &&
+               "Invalid neveralign in virtual section!");
+        break;
       case MCFragment::FT_Fill:
         assert((cast<MCFillFragment>(F).getValue() == 0) &&
                "Invalid fill in virtual section!");
Index: llvm/lib/MC/MCFragment.cpp
===================================================================
--- llvm/lib/MC/MCFragment.cpp
+++ llvm/lib/MC/MCFragment.cpp
@@ -270,6 +270,9 @@
     case FT_Align:
       delete cast<MCAlignFragment>(this);
       return;
+    case FT_NeverAlign:
+      delete cast<MCNeverAlignFragment>(this);
+      return;
     case FT_Data:
       delete cast<MCDataFragment>(this);
       return;
@@ -338,6 +341,9 @@
   OS << "<";
   switch (getKind()) {
   case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
+  case MCFragment::FT_NeverAlign:
+    OS << "MCNeverAlignFragment";
+    break;
   case MCFragment::FT_Data:  OS << "MCDataFragment"; break;
   case MCFragment::FT_CompactEncodedInst:
     OS << "MCCompactEncodedInstFragment"; break;
@@ -377,6 +383,15 @@
        << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">";
     break;
   }
+  case MCFragment::FT_NeverAlign: {
+    const MCNeverAlignFragment *NAF = cast<MCNeverAlignFragment>(this);
+    if (NAF->hasEmitNops())
+      OS << " (emit nops)";
+    OS << "\n       ";
+    OS << " Alignment:" << NAF->getAlignment() << " Value:" << NAF->getValue()
+       << " ValueSize:" << NAF->getValueSize();
+    break;
+  }
   case MCFragment::FT_Data:  {
     const auto *DF = cast<MCDataFragment>(this);
     OS << "\n       ";
Index: llvm/lib/MC/MCObjectStreamer.cpp
===================================================================
--- llvm/lib/MC/MCObjectStreamer.cpp
+++ llvm/lib/MC/MCObjectStreamer.cpp
@@ -599,6 +599,13 @@
   cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
 }
 
+void MCObjectStreamer::emitNeverAlignCodeAtEnd(unsigned ByteAlignment,
+                                               int64_t Value,
+                                               unsigned ValueSize) {
+  insert(new MCNeverAlignFragment(ByteAlignment, 0, 1));
+  cast<MCNeverAlignFragment>(getCurrentFragment())->setEmitNops(true);
+}
+
 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
                                          unsigned char Value,
                                          SMLoc Loc) {
Index: llvm/lib/MC/MCStreamer.cpp
===================================================================
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -1158,6 +1158,8 @@
                                       unsigned MaxBytesToEmit) {}
 void MCStreamer::emitCodeAlignment(unsigned ByteAlignment,
                                    unsigned MaxBytesToEmit) {}
+void MCStreamer::emitNeverAlignCodeAtEnd(unsigned ByteAlignment, int64_t Value,
+                                         unsigned ValueSize) {}
 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
                                    SMLoc Loc) {}
 void MCStreamer::emitBundleAlignMode(unsigned AlignPow2) {}