Index: llvm/include/llvm/CodeGen/MachineInstr.h =================================================================== --- llvm/include/llvm/CodeGen/MachineInstr.h +++ llvm/include/llvm/CodeGen/MachineInstr.h @@ -1150,10 +1150,15 @@ // Debugging support // void print(raw_ostream &OS, bool SkipOpers = false) const; - void print(raw_ostream &OS, ModuleSlotTracker &MST, - bool SkipOpers = false) const; + void print(raw_ostream &OS, ModuleSlotTracker &MST, bool SkipOpers = false, + const TargetInstrInfo * const = nullptr) const; void dump() const; + // A dumper that prevents UNKNOWN when outputting + // an MI that is a result of combining MIs. + // Possibly useful for other situations when the TII* cannot be computed. + void dump(const TargetInstrInfo * const) const; + //===--------------------------------------------------------------------===// // Accessors used to build up machine instructions. Index: llvm/lib/CodeGen/MachineCombiner.cpp =================================================================== --- llvm/lib/CodeGen/MachineCombiner.cpp +++ llvm/lib/CodeGen/MachineCombiner.cpp @@ -134,7 +134,7 @@ // are tracked in the InstrIdxForVirtReg map depth is looked up in InstrDepth for (auto *InstrPtr : InsInstrs) { // for each Use unsigned IDepth = 0; - DEBUG(dbgs() << "NEW INSTR "; InstrPtr->dump(); dbgs() << "\n";); + DEBUG(dbgs() << "NEW INSTR "; InstrPtr->dump(TII); dbgs() << "\n";); for (const MachineOperand &MO : InstrPtr->operands()) { // Check for virtual register operand. if (!(MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))) Index: llvm/lib/CodeGen/MachineInstr.cpp =================================================================== --- llvm/lib/CodeGen/MachineInstr.cpp +++ llvm/lib/CodeGen/MachineInstr.cpp @@ -1701,7 +1701,8 @@ } void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, - bool SkipOpers) const { + bool SkipOpers, + const TargetInstrInfo * const TII_in) const { // We can be a bit tidier if we know the MachineFunction. const MachineFunction *MF = nullptr; const TargetRegisterInfo *TRI = nullptr; @@ -1742,6 +1743,9 @@ if (StartOp != 0) OS << " = "; + if (!TII) + TII = TII_in; + // Print the opcode name. if (TII) OS << TII->getName(getOpcode()); @@ -1986,6 +1990,19 @@ OS << '\n'; } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +void MachineInstr::dump(const TargetInstrInfo * const TII_in) const { + dbgs() << " "; + const Module *M = nullptr; + if (const MachineBasicBlock *MBB = getParent()) + if (const MachineFunction *MF = MBB->getParent()) + M = MF->getFunction()->getParent(); + + ModuleSlotTracker MST(M); + print(dbgs(), MST, false /* SkipOpers */, TII_in); +} +#endif + bool MachineInstr::addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound) { Index: llvm/test/CodeGen/AArch64/debug_output_upon_new-MachineInstr-from-combiner.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/debug_output_upon_new-MachineInstr-from-combiner.ll @@ -0,0 +1,36 @@ +; Check for correct debug output when +; a new MachineInstr is generated in the machine combiner. + +; Converted from a machine-reduced C++ test case. + +; The fix is actually ISA-agnostic, but this test is AArch64-specific. + +; RUN: llc -mcpu=cortex-a57 -debug-only=machine-combiner -o - %s |& FileCheck %s + +; CHECK: NEW INSTR{{.*}}MADDXrrr +; CHECK-NOT: NEW INSTR{{.*}}UNKNOWN + +target triple = "aarch64-linux-gnu" + +%class.D = type { %class.basic_string.base, [4 x i8] } +%class.basic_string.base = type <{ i64, i64, i32 }> +@a = global %class.D* zeroinitializer, align 8 +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) +define internal void @fun() section ".text.startup" { +entry: + %tmp.i.i = alloca %class.D, align 8 + %y = bitcast %class.D* %tmp.i.i to i8* + br label %loop +loop: + %conv11.i.i = phi i64 [ 0, %entry ], [ %inc.i.i, %loop ] + %i = phi i64 [ undef, %entry ], [ %inc.i.i, %loop ] + %x = load %class.D*, %class.D** getelementptr inbounds (%class.D*, %class.D** @a, i64 0), align 8 + %arrayidx.i.i.i = getelementptr inbounds %class.D, %class.D* %x, i64 %conv11.i.i + %d = bitcast %class.D* %arrayidx.i.i.i to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %y, i8* %d, i64 24, i32 8, i1 false) + %inc.i.i = add i64 %i, 1 + %cmp.i.i = icmp slt i64 %inc.i.i, 0 + br i1 %cmp.i.i, label %loop, label %exit +exit: + ret void +}