diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1134,9 +1134,11 @@
   bool HasAnyRealCode = false;
   int NumInstsInFunction = 0;
 
+  const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
   for (auto &MBB : *MF) {
     // Print a label for the basic block.
     emitBasicBlockStart(MBB);
+    DenseMap<unsigned, unsigned> OpcodeCounts;
     for (auto &MI : MBB) {
       // Print the assembly for the instruction.
       if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
@@ -1202,6 +1204,8 @@
         break;
       default:
         emitInstruction(&MI);
+        auto I = OpcodeCounts.insert({MI.getOpcode(), 0u});
+        I.first->second++;
         break;
       }
 
@@ -1245,6 +1249,14 @@
       }
     }
     emitBasicBlockEnd(MBB);
+    MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",
+                                        MBB.begin()->getDebugLoc(), &MBB);
+
+    for (auto &KV : OpcodeCounts) {
+      auto Name = (Twine("INST_") + TII->getName(KV.first)).str();
+      R << ore::NV(Name, KV.second) << " " << Name << "\n";
+    }
+    ORE->emit(R);
   }
 
   EmittedInsts += NumInstsInFunction;
diff --git a/llvm/test/CodeGen/AArch64/arm64-instruction-mix-remarks.ll b/llvm/test/CodeGen/AArch64/arm64-instruction-mix-remarks.ll
new file mode 100644
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64-instruction-mix-remarks.ll
@@ -0,0 +1,55 @@
+
+; RUN: llc -mtriple=arm64-apple-ios7.0 -pass-remarks-output=%t -pass-remarks=asm-printer %s
+; RUN: FileCheck --input-file=%t --check-prefix=YAML %s
+
+; YAML:      Name:            InstructionMix
+; YAML-NEXT: DebugLoc:        { File: arm64-summary-remarks.ll, Line: 10, Column: 10 }
+; YAML-NEXT: Function:        foo
+; YAML-NEXT: Args:
+; YAML-NEXT: - INST_Bcc:        '1'
+; YAML:      - INST_LDRWui:     '1'
+; YAML:      - INST_ADDWrs:     '1'
+; YAML:      - INST_SUBSWri:    '1'
+
+; YAML:      Name:            InstructionMix
+; YAML-NEXT: DebugLoc:        { File: arm64-summary-remarks.ll, Line: 20, Column: 20 }
+; YAML-NEXT: Function:        foo
+; YAML-NEXT: Args:
+; YAML-NEXT:   - INST_ORRWrs:     '1'
+; YAML:        - INST_RET:        '1'
+
+; YAML:      Name:            InstructionMix
+; YAML-NEXT: DebugLoc:        { File: arm64-summary-remarks.ll, Line: 30, Column: 30 }
+; YAML-NEXT: Function:        foo
+; YAML-NEXT: Args:
+; YAML-NEXT:  - INST_ORRWrs:     '1'
+; YAML:       - INST_RET:        '1'
+; YAML:       - INST_MADDWrrr:   '2'
+; YAML:       - INST_STRWui:     '1'
+define i32 @foo(i32* %ptr, i32 %x) !dbg !3 {
+entry:
+  %l = load i32, i32* %ptr, !dbg !4
+  %add = add i32 %l, %x, !dbg !4
+  %c = icmp eq i32 %add, 100, !dbg !4
+  br i1 %c, label %then, label %else, !dbg !4
+
+then:
+  ret i32 %add, !dbg !5
+
+else:
+  store i32 10, i32* %ptr, !dbg !6
+  %res = mul i32 %add, %x, !dbg !6
+  %res.2 = mul i32 %res, %x, !dbg !6
+  ret i32 %res.2, !dbg !6
+}
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1)
+!1 = !DIFile(filename: "arm64-summary-remarks.ll", directory: "")
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 5, scopeLine: 5, unit: !0)
+!4 = distinct !DILocation(line: 10, column: 10, scope: !3)
+!5 = distinct !DILocation(line: 20, column: 20, scope: !3)
+!6 = distinct !DILocation(line: 30, column: 30, scope: !3)
+