Index: llvm/include/llvm/CodeGen/TargetInstrInfo.h =================================================================== --- llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -1306,6 +1306,9 @@ /// Returns true if the instruction is already predicated. virtual bool isPredicated(const MachineInstr &MI) const { return false; } + /// Returns the name for the specified condition code + virtual const char *getPredicateByName(int CC) const {return nullptr; }; + /// Returns true if the instruction is a /// terminator instruction that has not been predicated. virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const; Index: llvm/lib/CodeGen/MIRParser/MILexer.cpp =================================================================== --- llvm/lib/CodeGen/MIRParser/MILexer.cpp +++ llvm/lib/CodeGen/MIRParser/MILexer.cpp @@ -104,6 +104,19 @@ return C; } +/// Machine operands can have comments, enclosed between '[' and ']'. +/// This eats up all tokens, including the brackets. +static Cursor skipMachineOperandComment(Cursor C) { + if (C.peek() != '[') + return C; + + while (C.peek() != ']') + C.advance(); + + C.advance(); + return C; +} + /// Return true if the given character satisfies the following regular /// expression: [-a-zA-Z$._0-9] static bool isIdentifierChar(char C) { @@ -691,6 +704,8 @@ return C.remaining(); } + C = skipMachineOperandComment(C); + if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback)) return R.remaining(); if (Cursor R = maybeLexIdentifier(C, Token)) Index: llvm/lib/CodeGen/MIRPrinter.cpp =================================================================== --- llvm/lib/CodeGen/MIRPrinter.cpp +++ llvm/lib/CodeGen/MIRPrinter.cpp @@ -822,19 +822,40 @@ Operand.Name); } +static std::string getImmOperandComment(const MachineInstr &MI, + const MachineOperand &Op, + unsigned OpIdx) { + if (MI.findFirstPredOperandIdx() != (int) OpIdx) + return ""; + + const auto *MF = MI.getMF(); + const auto &SubTarget = MF->getSubtarget(); + const auto *TRI = SubTarget.getRegisterInfo(); + assert(TRI && "Expected target register info"); + const auto *TII = SubTarget.getInstrInfo(); + + if (const char *PredName = TII->getPredicateByName(Op.getImm())) + return " [" + std::string(PredName) + "]"; + + return ""; +} + void MIPrinter::print(const MachineInstr &MI, unsigned OpIdx, const TargetRegisterInfo *TRI, bool ShouldPrintRegisterTies, LLT TypeToPrint, bool PrintDef) { + std::string MOComment = ""; const MachineOperand &Op = MI.getOperand(OpIdx); switch (Op.getType()) { - case MachineOperand::MO_Immediate: + case MachineOperand::MO_Immediate: { + MOComment = getImmOperandComment(MI, Op, OpIdx); if (MI.isOperandSubregIdx(OpIdx)) { MachineOperand::printTargetFlags(OS, Op); MachineOperand::printSubRegIdx(OS, Op.getImm(), TRI); break; } LLVM_FALLTHROUGH; + } case MachineOperand::MO_Register: case MachineOperand::MO_CImmediate: case MachineOperand::MO_FPImmediate: @@ -858,6 +879,7 @@ const TargetIntrinsicInfo *TII = MI.getMF()->getTarget().getIntrinsicInfo(); Op.print(OS, MST, TypeToPrint, OpIdx, PrintDef, /*IsStandalone=*/false, ShouldPrintRegisterTies, TiedOperandIdx, TRI, TII); + OS << MOComment; break; } case MachineOperand::MO_FrameIndex: Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.h =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -146,6 +146,8 @@ // Predication support. bool isPredicated(const MachineInstr &MI) const override; + const char *getPredicateByName(int CC) const override; + ARMCC::CondCodes getPredicate(const MachineInstr &MI) const { int PIdx = MI.findFirstPredOperandIdx(); return PIdx != -1 ? (ARMCC::CondCodes)MI.getOperand(PIdx).getImm() Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -495,6 +495,28 @@ return PIdx != -1 && MI.getOperand(PIdx).getImm() != ARMCC::AL; } +const char *ARMBaseInstrInfo::getPredicateByName(int CC) const { + switch (CC) { + case 0: return "equal"; + case 1: return "notequal"; + case 2: return "highersame"; + case 3: return "lower"; + case 4: return "minus"; + case 5: return "plus"; + case 6: return "overflow"; + case 7: return "nooverflow"; + case 8: return "higher"; + case 9: return "lowersame"; + case 10: return "greaterequal"; + case 11: return "less"; + case 12: return "greater"; + case 13: return "lessequal"; + case 14: return "always"; + default: + llvm_unreachable("unexpected condition code"); + } +} + bool ARMBaseInstrInfo::PredicateInstruction( MachineInstr &MI, ArrayRef Pred) const { unsigned Opc = MI.getOpcode(); Index: llvm/test/CodeGen/Thumb2/t2-teq-reduce.mir =================================================================== --- llvm/test/CodeGen/Thumb2/t2-teq-reduce.mir +++ llvm/test/CodeGen/Thumb2/t2-teq-reduce.mir @@ -100,38 +100,38 @@ ; CHECK: bb.0.entry: ; CHECK: successors: %bb.2(0x80000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: t2B %bb.2, 14, $noreg + ; CHECK: t2B %bb.2, 14 [always], $noreg ; CHECK: bb.1.while.body.end: ; CHECK: successors: %bb.2(0x80000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i.14) - ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr + ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 [always], $noreg :: (load 4 from %ir.next.i.14) + ; CHECK: tCMPi8 renamable $r0, 0, 14 [always], $noreg, implicit-def $cpsr ; CHECK: BUNDLE implicit-def dead $itstate, implicit killed $cpsr, implicit $r0 { ; CHECK: t2IT 0, 8, implicit-def $itstate - ; CHECK: tBX_RET 0, killed $cpsr, implicit $r0, implicit internal killed $itstate + ; CHECK: tBX_RET 0 [equal], killed $cpsr, implicit $r0, implicit internal killed $itstate ; CHECK: } ; CHECK: bb.2.while.begin: ; CHECK: successors: %bb.4(0x04000000), %bb.3(0x7c000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 14, $noreg :: (load 4 from %ir.info.i) - ; CHECK: renamable $r2 = tLDRHi killed renamable $r2, 0, 14, $noreg :: (load 2 from %ir.data16.i1) - ; CHECK: dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14, $noreg - ; CHECK: t2Bcc %bb.4, 0, killed $cpsr + ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 14 [always], $noreg :: (load 4 from %ir.info.i) + ; CHECK: renamable $r2 = tLDRHi killed renamable $r2, 0, 14 [always], $noreg :: (load 2 from %ir.data16.i1) + ; CHECK: dead renamable $r2, $cpsr = tEOR killed renamable $r2, renamable $r1, 14 [always], $noreg + ; CHECK: t2Bcc %bb.4, 0 [equal], killed $cpsr ; CHECK: bb.3.while.body.a: ; CHECK: successors: %bb.4(0x4207fef8), %bb.1(0x3df80108) ; CHECK: liveins: $r0, $r1 - ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.next.i2) - ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr + ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14 [always], $noreg :: (load 4 from %ir.next.i2) + ; CHECK: tCMPi8 renamable $r0, 0, 14 [always], $noreg, implicit-def $cpsr ; CHECK: BUNDLE implicit-def dead $itstate, implicit-def dead $r2, implicit-def $cpsr, implicit $r0, implicit killed $cpsr, implicit $r1 { ; CHECK: t2IT 1, 30, implicit-def $itstate - ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 1, $cpsr, implicit internal $itstate :: (load 4 from %ir.info.i.1) - ; CHECK: renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1, $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load 2 from %ir.data16.i.13) - ; CHECK: t2TEQrr internal killed renamable $r2, renamable $r1, 1, killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate + ; CHECK: renamable $r2 = tLDRi renamable $r0, 1, 1 [notequal], $cpsr, implicit internal $itstate :: (load 4 from %ir.info.i.1) + ; CHECK: renamable $r2 = tLDRHi internal killed renamable $r2, 0, 1 [notequal], $cpsr, implicit internal killed $r2, implicit internal $itstate :: (load 2 from %ir.data16.i.13) + ; CHECK: t2TEQrr internal killed renamable $r2, renamable $r1, 1 [notequal], killed $cpsr, implicit-def $cpsr, implicit internal killed $itstate ; CHECK: } - ; CHECK: t2Bcc %bb.1, 1, killed $cpsr + ; CHECK: t2Bcc %bb.1, 1 [notequal], killed $cpsr ; CHECK: bb.4.exit: ; CHECK: liveins: $r0 - ; CHECK: tBX_RET 14, $noreg, implicit killed $r0 + ; CHECK: tBX_RET 14 [always], $noreg, implicit killed $r0 bb.0.entry: successors: %bb.1(0x80000000) liveins: $r0, $r1 @@ -189,36 +189,36 @@ ; CHECK: bb.0.entry: ; CHECK: successors: %bb.1(0x80000000) ; CHECK: liveins: $r0, $r1 - ; CHECK: $r2 = tMOVr $r0, 14, $noreg + ; CHECK: $r2 = tMOVr $r0, 14 [always], $noreg ; CHECK: bb.1.while.begin: ; CHECK: successors: %bb.5(0x04000000), %bb.2(0x7c000000) ; CHECK: liveins: $r1, $r2 - ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14, $noreg :: (load 4 from %ir.info.i) - ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i1) - ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.5, 0, killed $cpsr + ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14 [always], $noreg :: (load 4 from %ir.info.i) + ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14 [always], $noreg :: (load 2 from %ir.data16.i1) + ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14 [always], $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.5, 0 [equal], killed $cpsr ; CHECK: bb.2.while.body.a: ; CHECK: successors: %bb.5(0x04000000), %bb.3(0x7c000000) ; CHECK: liveins: $r0, $r1, $r2 - ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i2) - ; CHECK: tCMPi8 renamable $r2, 0, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.5, 0, killed $cpsr + ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14 [always], $noreg :: (load 4 from %ir.next.i2) + ; CHECK: tCMPi8 renamable $r2, 0, 14 [always], $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.5, 0 [equal], killed $cpsr ; CHECK: bb.3.it.block: ; CHECK: successors: %bb.5(0x04000000), %bb.4(0x7c000000) ; CHECK: liveins: $r1, $r2 - ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14, $noreg :: (load 4 from %ir.info.i.1) - ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14, $noreg :: (load 2 from %ir.data16.i.13) - ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.5, 0, killed $cpsr + ; CHECK: renamable $r0 = tLDRi renamable $r2, 1, 14 [always], $noreg :: (load 4 from %ir.info.i.1) + ; CHECK: renamable $r0 = tLDRHi killed renamable $r0, 0, 14 [always], $noreg :: (load 2 from %ir.data16.i.13) + ; CHECK: t2TEQrr renamable $r0, renamable $r1, 14 [always], $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.5, 0 [equal], killed $cpsr ; CHECK: bb.4.while.body.end: ; CHECK: successors: %bb.5(0x04000000), %bb.1(0x7c000000) ; CHECK: liveins: $r0, $r1, $r2 - ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14, $noreg :: (load 4 from %ir.next.i.14) - ; CHECK: tCMPi8 renamable $r2, 0, 14, $noreg, implicit-def $cpsr - ; CHECK: t2Bcc %bb.1, 1, killed $cpsr + ; CHECK: renamable $r2 = tLDRi killed renamable $r2, 0, 14 [always], $noreg :: (load 4 from %ir.next.i.14) + ; CHECK: tCMPi8 renamable $r2, 0, 14 [always], $noreg, implicit-def $cpsr + ; CHECK: t2Bcc %bb.1, 1 [notequal], killed $cpsr ; CHECK: bb.5.exit: ; CHECK: liveins: $r0 - ; CHECK: tBX_RET 14, $noreg, implicit $r0 + ; CHECK: tBX_RET 14 [always], $noreg, implicit $r0 bb.0.entry: successors: %bb.1(0x80000000) liveins: $r0, $r1