[llvm] c532713 - [Hexagon] Fix for producer operands search w/z-reg
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 28 09:20:43 PST 2021
Author: Brian Cain
Date: 2021-12-28T09:19:59-08:00
New Revision: c5327137df04ba4754547483d140aec8f8a954a9
URL: https://github.com/llvm/llvm-project/commit/c5327137df04ba4754547483d140aec8f8a954a9
DIFF: https://github.com/llvm/llvm-project/commit/c5327137df04ba4754547483d140aec8f8a954a9.diff
LOG: [Hexagon] Fix for producer operands search w/z-reg
Z-register does not show up in defs, so checks searching
for the def operand must look for a different def index
than they would normally.
Added:
llvm/test/DebugInfo/Hexagon/zreg-post-inc.s
Modified:
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
index b9233618e5fd9..ca8adcb773a9f 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
@@ -16,6 +16,7 @@
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCShuffler.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
+
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
@@ -425,81 +426,109 @@ bool HexagonMCChecker::checkPredicates() {
// Check legal use of new values.
bool HexagonMCChecker::checkNewValues() {
- for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
- if (!HexagonMCInstrInfo::isNewValue(MCII, I))
+ for (auto const &ConsumerInst :
+ HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
+ if (!HexagonMCInstrInfo::isNewValue(MCII, ConsumerInst))
continue;
- auto Consumer = HexagonMCInstrInfo::predicateInfo(MCII, I);
- bool Branch = HexagonMCInstrInfo::getDesc(MCII, I).isBranch();
- MCOperand const &Op = HexagonMCInstrInfo::getNewValueOperand(MCII, I);
+
+ const HexagonMCInstrInfo::PredicateInfo ConsumerPredInfo =
+ HexagonMCInstrInfo::predicateInfo(MCII, ConsumerInst);
+
+ bool Branch = HexagonMCInstrInfo::getDesc(MCII, ConsumerInst).isBranch();
+ MCOperand const &Op =
+ HexagonMCInstrInfo::getNewValueOperand(MCII, ConsumerInst);
assert(Op.isReg());
- auto Producer = registerProducer(Op.getReg(), Consumer);
- if (std::get<0>(Producer) == nullptr) {
- reportError(I.getLoc(), "New value register consumer has no producer");
+
+ auto Producer = registerProducer(Op.getReg(), ConsumerPredInfo);
+ const MCInst *const ProducerInst = std::get<0>(Producer);
+ const HexagonMCInstrInfo::PredicateInfo ProducerPredInfo =
+ std::get<2>(Producer);
+
+ if (ProducerInst == nullptr) {
+ reportError(ConsumerInst.getLoc(),
+ "New value register consumer has no producer");
return false;
}
if (!RelaxNVChecks) {
// Checks that statically prove correct new value consumption
- if (std::get<2>(Producer).isPredicated() &&
- (!Consumer.isPredicated() ||
- llvm::HexagonMCInstrInfo::getType(MCII, I) == HexagonII::TypeNCJ)) {
+ if (ProducerPredInfo.isPredicated() &&
+ (!ConsumerPredInfo.isPredicated() ||
+ llvm::HexagonMCInstrInfo::getType(MCII, ConsumerInst) ==
+ HexagonII::TypeNCJ)) {
reportNote(
- std::get<0>(Producer)->getLoc(),
+ ProducerInst->getLoc(),
"Register producer is predicated and consumer is unconditional");
- reportError(I.getLoc(),
+ reportError(ConsumerInst.getLoc(),
"Instruction does not have a valid new register producer");
return false;
}
- if (std::get<2>(Producer).Register != Hexagon::NoRegister &&
- std::get<2>(Producer).Register != Consumer.Register) {
- reportNote(std::get<0>(Producer)->getLoc(),
+ if (ProducerPredInfo.Register != Hexagon::NoRegister &&
+ ProducerPredInfo.Register != ConsumerPredInfo.Register) {
+ reportNote(ProducerInst->getLoc(),
"Register producer does not use the same predicate "
"register as the consumer");
- reportError(I.getLoc(),
+ reportError(ConsumerInst.getLoc(),
"Instruction does not have a valid new register producer");
return false;
}
}
- if (std::get<2>(Producer).Register == Consumer.Register &&
- Consumer.PredicatedTrue != std::get<2>(Producer).PredicatedTrue) {
+ if (ProducerPredInfo.Register == ConsumerPredInfo.Register &&
+ ConsumerPredInfo.PredicatedTrue != ProducerPredInfo.PredicatedTrue) {
reportNote(
- std::get<0>(Producer)->getLoc(),
+ ProducerInst->getLoc(),
"Register producer has the opposite predicate sense as consumer");
- reportError(I.getLoc(),
+ reportError(ConsumerInst.getLoc(),
"Instruction does not have a valid new register producer");
return false;
}
- MCInstrDesc const &Desc =
- HexagonMCInstrInfo::getDesc(MCII, *std::get<0>(Producer));
- if (Desc.OpInfo[std::get<1>(Producer)].RegClass ==
+
+ MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, *ProducerInst);
+ const unsigned ProducerOpIndex = std::get<1>(Producer);
+
+ if (Desc.OpInfo[ProducerOpIndex].RegClass ==
Hexagon::DoubleRegsRegClassID) {
- reportNote(std::get<0>(Producer)->getLoc(),
+ reportNote(ProducerInst->getLoc(),
"Double registers cannot be new-value producers");
- reportError(I.getLoc(),
+ reportError(ConsumerInst.getLoc(),
"Instruction does not have a valid new register producer");
return false;
}
- if ((Desc.mayLoad() && std::get<1>(Producer) == 1) ||
- (Desc.mayStore() && std::get<1>(Producer) == 0)) {
- unsigned Mode =
- HexagonMCInstrInfo::getAddrMode(MCII, *std::get<0>(Producer));
+
+ // The ProducerOpIsMemIndex logic checks for the index of the producer
+ // register operand. Z-reg load instructions have an implicit operand
+ // that's not encoded, so the producer won't appear as the 1-th def, it
+ // will be at the 0-th.
+ const unsigned ProducerOpSearchIndex =
+ (HexagonMCInstrInfo::getType(MCII, *ProducerInst) ==
+ HexagonII::TypeCVI_ZW)
+ ? 0
+ : 1;
+
+ const bool ProducerOpIsMemIndex =
+ ((Desc.mayLoad() && ProducerOpIndex == ProducerOpSearchIndex) ||
+ (Desc.mayStore() && ProducerOpIndex == 0));
+
+ if (ProducerOpIsMemIndex) {
+ unsigned Mode = HexagonMCInstrInfo::getAddrMode(MCII, *ProducerInst);
+
StringRef ModeError;
if (Mode == HexagonII::AbsoluteSet)
ModeError = "Absolute-set";
if (Mode == HexagonII::PostInc)
ModeError = "Auto-increment";
if (!ModeError.empty()) {
- reportNote(std::get<0>(Producer)->getLoc(),
+ reportNote(ProducerInst->getLoc(),
ModeError + " registers cannot be a new-value "
"producer");
- reportError(I.getLoc(),
+ reportError(ConsumerInst.getLoc(),
"Instruction does not have a valid new register producer");
return false;
}
}
- if (Branch && HexagonMCInstrInfo::isFloat(MCII, *std::get<0>(Producer))) {
- reportNote(std::get<0>(Producer)->getLoc(),
+ if (Branch && HexagonMCInstrInfo::isFloat(MCII, *ProducerInst)) {
+ reportNote(ProducerInst->getLoc(),
"FPU instructions cannot be new-value producers for jumps");
- reportError(I.getLoc(),
+ reportError(ConsumerInst.getLoc(),
"Instruction does not have a valid new register producer");
return false;
}
@@ -542,9 +571,11 @@ HexagonMCChecker::registerProducer(
unsigned Register, HexagonMCInstrInfo::PredicateInfo ConsumerPredicate) {
std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
WrongSense;
+
for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCB)) {
MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, I);
auto ProducerPredicate = HexagonMCInstrInfo::predicateInfo(MCII, I);
+
for (unsigned J = 0, N = Desc.getNumDefs(); J < N; ++J)
for (auto K = MCRegAliasIterator(I.getOperand(J).getReg(), &RI, true);
K.isValid(); ++K)
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
index 160d452ab9177..4d3a0f0c4cbd9 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
@@ -81,6 +81,10 @@ class HexagonMCChecker {
void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue);
bool registerUsed(unsigned Register);
+
+ /// \return a tuple of: pointer to the producer instruction or nullptr if
+ /// none was found, the operand index, and the PredicateInfo for the
+ /// producer.
std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
registerProducer(unsigned Register,
HexagonMCInstrInfo::PredicateInfo Predicated);
diff --git a/llvm/test/DebugInfo/Hexagon/zreg-post-inc.s b/llvm/test/DebugInfo/Hexagon/zreg-post-inc.s
new file mode 100644
index 0000000000000..346bec1b0fddb
--- /dev/null
+++ b/llvm/test/DebugInfo/Hexagon/zreg-post-inc.s
@@ -0,0 +1,8 @@
+# RUN: not llvm-mc -arch=hexagon -filetype=obj -mhvx -mcpu=hexagonv66 %s 2> %t; FileCheck --implicit-check-not=error %s <%t
+
+{
+ if (p0) memb(r14+#8)=r4.new
+ if (p0) z=vmem(r4++#0)
+}
+
+# CHECK: error: Instruction does not have a valid new register producer
More information about the llvm-commits
mailing list