From c15f8d2a082173006f183b41d28eb228978f1d07 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 2 May 2017 17:56:11 +0000 Subject: [PATCH] [Hexagon] Extract function that checks endloops with other branches Change location number to point to conflicting branch instruction. Patch by Colin LeMahieu. llvm-svn: 301946 --- .../Hexagon/MCTargetDesc/HexagonMCChecker.cpp | 73 +++++++++++----------- .../Target/Hexagon/MCTargetDesc/HexagonMCChecker.h | 2 +- .../test/MC/Hexagon/PacketRules/endloop_branches.s | 12 ++++ llvm/test/MC/Hexagon/endloop.s | 19 ------ 4 files changed, 51 insertions(+), 55 deletions(-) create mode 100644 llvm/test/MC/Hexagon/PacketRules/endloop_branches.s delete mode 100644 llvm/test/MC/Hexagon/endloop.s diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp index f8b2a52..6ce0277 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp @@ -246,6 +246,7 @@ bool HexagonMCChecker::check(bool FullCheck) { bool chkNV = checkNewValues(); bool chkR = checkRegisters(); bool chkRRO = checkRegistersReadOnly(); + bool chkELB = checkEndloopBranches(); checkRegisterCurDefs(); bool chkS = checkSolo(); bool chkSh = true; @@ -254,11 +255,30 @@ bool HexagonMCChecker::check(bool FullCheck) { bool chkSl = true; if (FullCheck) chkSl = checkSlots(); - bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkS && chkSh && chkSl; + bool chk = chkB && chkP && chkNV && chkR && chkRRO && chkELB && chkS && + chkSh && chkSl; return chk; } +bool HexagonMCChecker::checkEndloopBranches() { + for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) { + MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I); + if (Desc.isBranch() || Desc.isCall()) { + auto Inner = HexagonMCInstrInfo::isInnerLoop(MCB); + if (Inner || HexagonMCInstrInfo::isOuterLoop(MCB)) { + reportError(I.getLoc(), + llvm::Twine("packet marked with `:endloop") + + (Inner ? "0" : "1") + "' " + + "cannot contain instructions that modify register " + + "`" + llvm::Twine(RI.getName(Hexagon::PC)) + "'"); + return false; + } + } + } + return true; +} + bool HexagonMCChecker::checkSlots() { unsigned slotsUsed = 0; for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) { @@ -304,16 +324,6 @@ bool HexagonMCChecker::checkBranches() { } } - if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too? - if (HexagonMCInstrInfo::isInnerLoop(MCB) || - HexagonMCInstrInfo::isOuterLoop(MCB)) { - // Error out if there's any branch in a loop-end packet. - Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1'); - reportError("packet marked with `:endloop" + N + "' " + - "cannot contain instructions that modify register " + "`" + - llvm::Twine(RI.getName(Hexagon::PC)) + "'"); - return false; - } if (Branches > 1) if (!hasConditional || Conditional > Unconditional) { // Error out if more than one unconditional branch or @@ -391,29 +401,23 @@ bool HexagonMCChecker::checkRegistersReadOnly() { return true; } -bool HexagonMCChecker::registerUsed(MCInst const &Inst, unsigned Register) { - unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs(); - for (unsigned j = Defs, n = Inst.getNumOperands(); j < n; ++j) { - MCOperand const &Operand = Inst.getOperand(j); - if (Operand.isReg() && Operand.getReg() == Register) - return true; - } - return false; -} - bool HexagonMCChecker::registerUsed(unsigned Register) { - for (auto const &I: HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) - if (registerUsed(I, Register)) - return true; + for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) + for (unsigned j = HexagonMCInstrInfo::getDesc(MCII, I).getNumDefs(), + n = I.getNumOperands(); + j < n; ++j) { + MCOperand const &Operand = I.getOperand(j); + if (Operand.isReg() && Operand.getReg() == Register) + return true; + } return false; } void HexagonMCChecker::checkRegisterCurDefs() { - for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { - MCInst const &Inst = *I.getInst(); - if (HexagonMCInstrInfo::isCVINew(MCII, Inst) && - HexagonMCInstrInfo::getDesc(MCII, Inst).mayLoad()) { - unsigned Register = Inst.getOperand(0).getReg(); + for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) { + if (HexagonMCInstrInfo::isCVINew(MCII, I) && + HexagonMCInstrInfo::getDesc(MCII, I).mayLoad()) { + unsigned Register = I.getOperand(0).getReg(); if (!registerUsed(Register)) reportWarning("Register `" + llvm::Twine(RI.getName(Register)) + "' used with `.cur' " @@ -512,12 +516,11 @@ bool HexagonMCChecker::checkRegisters() { // Check for legal use of solo insns. bool HexagonMCChecker::checkSolo() { if (HexagonMCInstrInfo::bundleSize(MCB) > 1) - for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { - if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) { - SMLoc Loc = I.getInst()->getLoc(); - reportError(Loc, "Instruction is marked `isSolo' and " - "cannot have other instructions in " - "the same packet"); + for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) { + if (llvm::HexagonMCInstrInfo::isSolo(MCII, I)) { + reportError(I.getLoc(), "Instruction is marked `isSolo' and " + "cannot have other instructions in " + "the same packet"); return false; } } diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h index c67a217..2937c7a 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h @@ -107,13 +107,13 @@ class HexagonMCChecker { void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue); bool registerUsed(unsigned Register); - bool registerUsed(MCInst const &Inst, unsigned Register); // Checks performed. bool checkBranches(); bool checkPredicates(); bool checkNewValues(); bool checkRegisters(); bool checkRegistersReadOnly(); + bool checkEndloopBranches(); void checkRegisterCurDefs(); bool checkSolo(); bool checkShuffle(); diff --git a/llvm/test/MC/Hexagon/PacketRules/endloop_branches.s b/llvm/test/MC/Hexagon/PacketRules/endloop_branches.s new file mode 100644 index 0000000..fbaa246 --- /dev/null +++ b/llvm/test/MC/Hexagon/PacketRules/endloop_branches.s @@ -0,0 +1,12 @@ +# RUN: not llvm-mc -triple=hexagon -filetype=asm %s 2>&1 | FileCheck %s + +# Check that a branch in an end-loop packet is caught. + +{ jump unknown +}:endloop0 +# CHECK: 5:3: error: packet marked with `:endloop0' cannot contain instructions that modify register + +{ jump unknown +}:endloop1 + +# CHECK: 9:3: error: packet marked with `:endloop1' cannot contain instructions that modify register diff --git a/llvm/test/MC/Hexagon/endloop.s b/llvm/test/MC/Hexagon/endloop.s deleted file mode 100644 index d537eb0..0000000 --- a/llvm/test/MC/Hexagon/endloop.s +++ /dev/null @@ -1,19 +0,0 @@ -# RUN: not llvm-mc -triple=hexagon -filetype=asm %s 2>&1 | FileCheck %s - -# Check that a branch in an end-loop packet is caught. - -1: -{ - r0 = #1 - p0 = cmp.eq (r1, r2) - if (p0) jump 1b -}:endloop0 - -2: -{ - r0 = #1 - p0 = cmp.eq (r1, r2) - if (p0) jump 2b -}:endloop1 - -# CHECK: rror: packet marked with `:endloop{{.}}' cannot contain instructions that modify register -- 2.7.4