[MIR] Serialize MachineBasicBlock::LabelMustBeEmitted (#234850)

Preserve `MachineBasicBlock::LabelMustBeEmitted` when printing and
parsing MIR using a `label-must-be-emitted` block attribute.

Assisted-by: GPT-6
diff --git a/llvm/docs/MIRLangRef.md b/llvm/docs/MIRLangRef.md
index c4b7de1..0d80e597 100644
--- a/llvm/docs/MIRLangRef.md
+++ b/llvm/docs/MIRLangRef.md
@@ -310,8 +310,8 @@
 #### Miscellaneous Attributes
 
 The attributes `IsAddressTaken`, `IsLandingPad`,
-`IsInlineAsmBrIndirectTarget` and `Alignment` can be specified in parentheses
-after the block's definition:
+`IsInlineAsmBrIndirectTarget`, `LabelMustBeEmitted` and `Alignment` can be
+specified in parentheses after the block's definition:
 
 ```text
 bb.0.entry (address-taken):
@@ -322,6 +322,8 @@
   <instructions>
 bb.4 (inlineasm-br-indirect-target):
   <instructions>
+bb.5 (label-must-be-emitted):
+  <instructions>
 ```
 
 <!-- TODO: Describe the way the reference to an unnamed LLVM IR block can be
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 125ed24..ed8b0f7 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -301,6 +301,7 @@
       .Case("ir-block-address-taken", MIToken::kw_ir_block_address_taken)
       .Case("machine-block-address-taken",
             MIToken::kw_machine_block_address_taken)
+      .Case("label-must-be-emitted", MIToken::kw_label_must_be_emitted)
       .Case("call-frame-size", MIToken::kw_call_frame_size)
       .Case("max-bytes-for-alignment", MIToken::kw_max_bytes_for_alignment)
       .Case("noconvergent", MIToken::kw_noconvergent)
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 6c27eff..555cc94 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -153,6 +153,7 @@
     kw_unknown_address,
     kw_ir_block_address_taken,
     kw_machine_block_address_taken,
+    kw_label_must_be_emitted,
     kw_call_frame_size,
     kw_max_bytes_for_alignment,
     kw_noconvergent,
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 8206bcf..337f899 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -739,6 +739,7 @@
   auto Name = Token.stringValue();
   lex();
   bool MachineBlockAddressTaken = false;
+  bool LabelMustBeEmitted = false;
   BasicBlock *AddressTakenIRBlock = nullptr;
   bool IsLandingPad = false;
   bool IsInlineAsmBrIndirectTarget = false;
@@ -760,6 +761,10 @@
         MachineBlockAddressTaken = true;
         lex();
         break;
+      case MIToken::kw_label_must_be_emitted:
+        LabelMustBeEmitted = true;
+        lex();
+        break;
       case MIToken::kw_ir_block_address_taken:
         if (parseIRBlockAddressTaken(AddressTakenIRBlock))
           return true;
@@ -846,6 +851,8 @@
   MBB->setMaxBytesForAlignment(MaxBytesForAlignment);
   if (MachineBlockAddressTaken)
     MBB->setMachineBlockAddressTaken();
+  if (LabelMustBeEmitted)
+    MBB->setLabelMustBeEmitted();
   if (AddressTakenIRBlock)
     MBB->setAddressTakenIRBlock(AddressTakenIRBlock);
   MBB->setIsEHPad(IsLandingPad);
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 9ea9b22..45d3285 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -535,6 +535,11 @@
       os << "machine-block-address-taken";
       hasAttributes = true;
     }
+    if (hasLabelMustBeEmitted()) {
+      os << (hasAttributes ? ", " : " (");
+      os << "label-must-be-emitted";
+      hasAttributes = true;
+    }
     if (isIRBlockAddressTaken()) {
       os << (hasAttributes ? ", " : " (");
       os << "ir-block-address-taken ";
diff --git a/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll b/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll
index 8b67406..6fdf45a 100644
--- a/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll
+++ b/llvm/test/CodeGen/AArch64/callbr-asm-obj-file.ll
@@ -1,6 +1,12 @@
 ; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -filetype=obj -o - \
 ; RUN:  | llvm-objdump --no-print-imm-hex --triple=aarch64-unknown-linux-gnu --show-all-symbols -d - \
 ; RUN:  | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -stop-after=finalize-isel -o %t.mir
+; RUN: llc %t.mir -start-after=finalize-isel -filetype=obj -o - \
+; RUN:  | llvm-objdump --no-print-imm-hex --triple=aarch64-unknown-linux-gnu --show-all-symbols -d - \
+; RUN:  | FileCheck %s
+
+; The inline asm targets must keep their labels when round-tripped through MIR.
 
 %struct.c = type { ptr }
 
diff --git a/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll
index fd04580..31f73e4 100644
--- a/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll
+++ b/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll
@@ -22,7 +22,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY %5
   ; CHECK-NEXT:   B %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.entry.indirect_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.entry.indirect_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.5(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %5
@@ -35,7 +35,7 @@
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr32all = COPY %7
   ; CHECK-NEXT:   B %bb.4
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.3.direct.indirect_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.3.direct.indirect_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.5(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr32all = COPY %7
@@ -87,7 +87,7 @@
   ; CHECK-NEXT:   $w0 = COPY [[MOVi32imm]]
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.y (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.y (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY $wzr
   ; CHECK-NEXT:   $w0 = COPY [[COPY]]
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -116,7 +116,7 @@
   ; CHECK-NEXT:   $w0 = COPY [[MOVi32imm]]
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.y (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.y (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   $w0 = COPY %1
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
 entry:
@@ -147,7 +147,7 @@
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY $wzr
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr32all = COPY [[COPY1]]
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.y (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.y (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   [[PHI:%[0-9]+]]:gpr32all = PHI [[COPY]], %bb.0, [[COPY2]], %bb.1
   ; CHECK-NEXT:   $w0 = COPY [[PHI]]
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -174,7 +174,7 @@
   ; CHECK-NEXT: bb.1.x:
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.v (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.v (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42
   ; CHECK-NEXT:   $w0 = COPY [[MOVi32imm]]
   ; CHECK-NEXT:   RET_ReallyLR implicit $w0
@@ -198,7 +198,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY %3
   ; CHECK-NEXT:   B %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.entry.y_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.entry.y_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.3(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %3
@@ -248,7 +248,7 @@
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %5
   ; CHECK-NEXT:   B %bb.3
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.w.v_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.w.v_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.4(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr32all = COPY %5
@@ -301,7 +301,7 @@
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr32all = COPY %6
   ; CHECK-NEXT:   B %bb.3
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.w.v_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.w.v_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.4(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr32all = COPY %6
@@ -349,7 +349,7 @@
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   B %bb.3
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.y (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.y (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.3(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %3
@@ -383,7 +383,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY %3
   ; CHECK-NEXT:   B %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.y (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.y (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %3
@@ -414,7 +414,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY %3
   ; CHECK-NEXT:   B %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.entry.out_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.entry.out_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.3(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %3
@@ -460,7 +460,7 @@
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr32all = COPY %4
   ; CHECK-NEXT:   B %bb.3
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.loop.loop_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.loop.loop_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.1(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr32all = COPY %4
@@ -495,7 +495,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY %3
   ; CHECK-NEXT:   B %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.entry.same_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.entry.same_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %3
@@ -526,7 +526,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr32all = COPY %3
   ; CHECK-NEXT:   B %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.entry.same_crit_edge (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.entry.same_crit_edge (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr32all = COPY %3
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-basic-block-label-must-be-emitted.mir b/llvm/test/CodeGen/MIR/Generic/machine-basic-block-label-must-be-emitted.mir
new file mode 100644
index 0000000..a34a2b3
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/Generic/machine-basic-block-label-must-be-emitted.mir
@@ -0,0 +1,25 @@
+# RUN: llc -run-pass=none -o - %s | FileCheck %s
+# RUN: llc -run-pass=none -o - %s | llc -x mir -run-pass=none -o - | FileCheck %s
+
+# Test label-must-be-emitted independently of the address-taken and inline asm
+# target attributes, and in combination with other attributes and IR references.
+
+--- |
+  define void @test() {
+    ret void
+  }
+...
+---
+name: test
+body: |
+  ; CHECK: bb.0:
+  bb.0:
+  ; CHECK: bb.1 (label-must-be-emitted):
+  bb.1 (label-must-be-emitted):
+  ; CHECK: bb.2 (label-must-be-emitted, align 8):
+  bb.2 (align 8, label-must-be-emitted):
+  ; CHECK: bb.3 (machine-block-address-taken, label-must-be-emitted, inlineasm-br-indirect-target):
+  bb.3 (label-must-be-emitted, inlineasm-br-indirect-target, machine-block-address-taken):
+  ; CHECK: bb.4 (%ir-block.0, label-must-be-emitted):
+  bb.4 (label-must-be-emitted, %ir-block.0):
+...
diff --git a/llvm/test/CodeGen/PowerPC/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/PowerPC/callbr-asm-outputs-indirect-isel.ll
index 336b5a0..e35b09f 100644
--- a/llvm/test/CodeGen/PowerPC/callbr-asm-outputs-indirect-isel.ll
+++ b/llvm/test/CodeGen/PowerPC/callbr-asm-outputs-indirect-isel.ll
@@ -22,7 +22,7 @@
   ; CHECK-NEXT: bb.2.Efault:
   ; CHECK-NEXT:   BLR8 implicit $lr8, implicit $rm
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.3.Efault.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.3.Efault.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   STB %1, 0, $zero8 :: (store (s8) into `ptr null`)
diff --git a/llvm/test/CodeGen/X86/callbr-asm-obj-file.ll b/llvm/test/CodeGen/X86/callbr-asm-obj-file.ll
index 43089d4..975e654 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-obj-file.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-obj-file.ll
@@ -1,6 +1,13 @@
 ; RUN: llc < %s -mtriple=x86_64-linux-gnu -filetype=obj -o - \
 ; RUN:  | llvm-objdump --no-print-imm-hex --triple=x86_64-linux-gnu -d - \
 ; RUN:  | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -stop-after=finalize-isel -o %t.mir
+; RUN: llc %t.mir -start-after=finalize-isel -filetype=obj -o - \
+; RUN:  | llvm-objdump --no-print-imm-hex --triple=x86_64-linux-gnu -d - \
+; RUN:  | FileCheck %s
+
+; The inline asm target must keep its label when round-tripped through MIR,
+; including when branch folding merges it with the fallthrough block.
 
 ; CHECK: 0000000000000000 <test1>:
 ; CHECK-NEXT:   0: 74 00 je 0x2 <test1+0x2>
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
index 125661a..24737ba 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel-m32.ll
@@ -22,7 +22,7 @@
   ; CHECK-NEXT:   $al = COPY [[SETCCr]]
   ; CHECK-NEXT:   RET 0, $al
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.efaultu64.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.efaultu64.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
   ; CHECK-NEXT:   $al = COPY [[SETCCr1]]
   ; CHECK-NEXT:   RET 0, $al
@@ -62,7 +62,7 @@
   ; CHECK-NEXT:   $eax = COPY [[COPY2]]
   ; CHECK-NEXT:   RET 0, $eax
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.efaultu64.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.efaultu64.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   $eax = COPY %3
   ; CHECK-NEXT:   RET 0, $eax
 entry:
@@ -99,7 +99,7 @@
   ; CHECK-NEXT:   $edx = COPY [[COPY2]]
   ; CHECK-NEXT:   RET 0, $eax, $edx
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   liveins: $eax, $edx
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gr32 = COPY $eax
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
index 8bed51d..707eedf 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll
@@ -19,7 +19,7 @@
   ; CHECK-NEXT:   $eax = COPY [[MOV32ri]]
   ; CHECK-NEXT:   RET 0, $eax
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.z.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.z.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   $eax = COPY %1
   ; CHECK-NEXT:   RET 0, $eax
   %direct = callbr i32 asm "", "=r,!i"()
@@ -43,7 +43,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr32 = COPY %4
   ; CHECK-NEXT:   JMP_1 %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.z.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.z.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY %4
@@ -77,7 +77,7 @@
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY %5
   ; CHECK-NEXT:   JMP_1 %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.z.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.z.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gr32 = COPY %5
@@ -112,7 +112,7 @@
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY [[COPY]]
   ; CHECK-NEXT:   JMP_1 %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.z.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.z.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT:   liveins: $ebx
   ; CHECK-NEXT: {{  $}}
@@ -150,7 +150,7 @@
   ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gr32 = COPY [[COPY]]
   ; CHECK-NEXT:   JMP_1 %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.z.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.z.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT:   liveins: $ebx, $edx
   ; CHECK-NEXT: {{  $}}
@@ -187,7 +187,7 @@
   ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gr32 = COPY [[COPY]]
   ; CHECK-NEXT:   JMP_1 %bb.1
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.cleanup (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.cleanup (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   liveins: $ebx
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gr32 = COPY $ebx
@@ -227,7 +227,7 @@
   ; CHECK-NEXT:   $rax = COPY [[PHI]]
   ; CHECK-NEXT:   RET 0, $rax
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.3.foo.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.3.foo.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT:   liveins: $rdx
   ; CHECK-NEXT: {{  $}}
@@ -235,7 +235,7 @@
   ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gr64 = COPY [[COPY4]]
   ; CHECK-NEXT:   JMP_1 %bb.2
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.4.foo.split2 (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.4.foo.split2 (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.2(0x80000000)
   ; CHECK-NEXT:   liveins: $rbx
   ; CHECK-NEXT: {{  $}}
@@ -286,7 +286,7 @@
   ; CHECK-NEXT:   $eax = COPY [[COPY2]]
   ; CHECK-NEXT:   RET 0, $eax
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.3.retry.split (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.3.retry.split (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.1(0x80000000)
   ; CHECK-NEXT:   liveins: $edx
   ; CHECK-NEXT: {{  $}}
@@ -321,7 +321,7 @@
   ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gr32 = COPY %1
   ; CHECK-NEXT:   JMP_1 %bb.1
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.1.cleanup (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.1.cleanup (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   $eax = COPY %1
   ; CHECK-NEXT:   RET 0, $eax
 entry:
@@ -348,7 +348,7 @@
   ; CHECK-NEXT:   $rax = COPY [[SUBREG_TO_REG]]
   ; CHECK-NEXT:   RET 0, $rax
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.2.c (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.2.c (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
   ; CHECK-NEXT:   [[MOVZX32rr8_1:%[0-9]+]]:gr32 = MOVZX32rr8 [[SETCCr1]]
   ; CHECK-NEXT:   [[SUBREG_TO_REG1:%[0-9]+]]:gr64 = SUBREG_TO_REG [[MOVZX32rr8_1]], %subreg.sub_32bit
diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll
index 1504516..6547b04 100644
--- a/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll
+++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-pred-succ.ll
@@ -17,12 +17,12 @@
 
 ; Check the second INLINEASM_BR target block is preceded by the block with the
 ; second INLINEASM_BR.
-; CHECK: bb.2 (%ir-block.7, inlineasm-br-indirect-target):
+; CHECK: bb.2 (%ir-block.7, label-must-be-emitted, inlineasm-br-indirect-target):
 ; CHECK-NEXT: predecessors: %bb.1
 
 ; Check the first INLINEASM_BR target block is predecessed by the block with
 ; the first INLINEASM_BR.
-; CHECK: bb.4 (%ir-block.12, inlineasm-br-indirect-target):
+; CHECK: bb.4 (%ir-block.12, label-must-be-emitted, inlineasm-br-indirect-target):
 ; CHECK-NEXT: predecessors: %bb.0
 
 @.str = private unnamed_addr constant [26 x i8] c"inline asm#1 returned %d\0A\00", align 1
diff --git a/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll b/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll
index 366b819..a705961 100644
--- a/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll
+++ b/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll
@@ -39,7 +39,7 @@
   ; CHECK-NEXT:   INLINEASM_BR &"#$0 $1 $2", sideeffect mayload attdialect, imm, 42, imm, 0, imm, %bb.4, clobber, implicit-def dead early-clobber $df, clobber, implicit-def dead early-clobber $fpsw, clobber, implicit-def dead early-clobber $eflags
   ; CHECK-NEXT:   JMP_1 %bb.5
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.4.bb17.i.i.i (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.4.bb17.i.i.i (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.5(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT: bb.5.kmem_cache_has_cpu_partial.exit:
@@ -118,7 +118,7 @@
   ; CHECK-NEXT:   LIFETIME_END %stack.0.skip.i.i
   ; CHECK-NEXT:   JMP_1 %bb.1
   ; CHECK-NEXT: {{  $}}
-  ; CHECK-NEXT: bb.5.if.end.i (inlineasm-br-indirect-target):
+  ; CHECK-NEXT: bb.5.if.end.i (label-must-be-emitted, inlineasm-br-indirect-target):
   ; CHECK-NEXT:   successors: %bb.1(0x80000000)
   ; CHECK-NEXT: {{  $}}
   ; CHECK-NEXT:   LIFETIME_END %stack.0.skip.i.i
diff --git a/llvm/test/tools/llvm-reduce/mir/preserve-block-info.mir b/llvm/test/tools/llvm-reduce/mir/preserve-block-info.mir
index 1b96a9d..95504e1 100644
--- a/llvm/test/tools/llvm-reduce/mir/preserve-block-info.mir
+++ b/llvm/test/tools/llvm-reduce/mir/preserve-block-info.mir
@@ -20,6 +20,7 @@
 # RESULT: bb.9:
 # RESULT: bb.10.exitblock:
 # RESULT: bb.11 (machine-block-address-taken):
+# RESULT: bb.12 (label-must-be-emitted):
 
 --- |
   define void @func(i32 %size)  {
@@ -72,4 +73,6 @@
     S_ENDPGM 0, implicit %0
 
   bb.11 (machine-block-address-taken):
+
+  bb.12 (label-must-be-emitted):
 ...
diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index 4d8a570..eee4688 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -274,7 +274,6 @@
     if (SrcMBB.isMachineBlockAddressTaken())
       DstMBB->setMachineBlockAddressTaken();
 
-    // FIXME: This is not serialized
     if (SrcMBB.hasLabelMustBeEmitted())
       DstMBB->setLabelMustBeEmitted();