[x86] Teach the instruction lowering to add comments describing constant
pool data being loaded into a vector register.
The comments take the form of:
# ymm0 = [a,b,c,d,...]
# xmm1 = <x,y,z...>
The []s are used for generic sequential data and the <>s are used for
specifically ConstantVector loads. Undef elements are printed as the
letter 'u', integers in decimal, and floating point values as floating
point values. Suggestions on improving the formatting or other aspects
of the display are very welcome.
My primary use case for this is to be able to FileCheck test masks
passed to vector shuffle instructions in-register. It isn't fantastic
for that (no decoding special zeroing semantics or other tricks), but it
at least puts the mask onto an instruction line that could reasonably be
checked. I've updated many of the new vector shuffle lowering tests to
leverage this in their test cases so that we're actually checking the
shuffle masks remain as expected.
Before implementing this, I tried a *bunch* of different approaches.
I looked into teaching the MCInstLower code to scan up the basic block
and find a definition of a register used in a shuffle instruction and
then decode that, but this seems incredibly brittle and complex.
I talked to Hal a lot about the "right" way to do this: attach the raw
shuffle mask to the instruction itself in some form of unencoded
operands, and then use that to emit the comments. I still think that's
the optimal solution here, but it proved to be beyond what I'm up for
here. In particular, it seems likely best done by completing the
plumbing of metadata through these layers and attaching the shuffle mask
in metadata which could have fully automatic dropping when encoding an
actual instruction.
llvm-svn: 218377
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index f01e86cf..004d2ac 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -864,25 +864,23 @@
return --MBBI;
}
-static const Constant *getShuffleMaskConstant(const MachineInstr &MI,
- const MachineOperand &DstOp,
- const MachineOperand &SrcOp,
- const MachineOperand &MaskOp) {
- if (!MaskOp.isCPI())
+static const Constant *getConstantFromPool(const MachineInstr &MI,
+ const MachineOperand &Op) {
+ if (!Op.isCPI())
return nullptr;
ArrayRef<MachineConstantPoolEntry> Constants =
MI.getParent()->getParent()->getConstantPool()->getConstants();
- const MachineConstantPoolEntry &MaskConstantEntry =
- Constants[MaskOp.getIndex()];
+ const MachineConstantPoolEntry &ConstantEntry =
+ Constants[Op.getIndex()];
// Bail if this is a machine constant pool entry, we won't be able to dig out
// anything useful.
- if (MaskConstantEntry.isMachineConstantPoolEntry())
+ if (ConstantEntry.isMachineConstantPoolEntry())
return nullptr;
- auto *C = dyn_cast<Constant>(MaskConstantEntry.Val.ConstVal);
- assert((!C || MaskConstantEntry.getType() == C->getType()) &&
+ auto *C = dyn_cast<Constant>(ConstantEntry.Val.ConstVal);
+ assert((!C || ConstantEntry.getType() == C->getType()) &&
"Expected a constant of the same type!");
return C;
}
@@ -1109,7 +1107,7 @@
const MachineOperand &SrcOp = MI->getOperand(1);
const MachineOperand &MaskOp = MI->getOperand(5);
- if (auto *C = getShuffleMaskConstant(*MI, DstOp, SrcOp, MaskOp)) {
+ if (auto *C = getConstantFromPool(*MI, MaskOp)) {
SmallVector<int, 16> Mask;
DecodePSHUFBMask(C, Mask);
if (!Mask.empty())
@@ -1129,7 +1127,7 @@
const MachineOperand &SrcOp = MI->getOperand(1);
const MachineOperand &MaskOp = MI->getOperand(5);
- if (auto *C = getShuffleMaskConstant(*MI, DstOp, SrcOp, MaskOp)) {
+ if (auto *C = getConstantFromPool(*MI, MaskOp)) {
SmallVector<int, 16> Mask;
DecodeVPERMILPMask(C, Mask);
if (!Mask.empty())
@@ -1137,6 +1135,74 @@
}
break;
}
+
+ // For loads from a constant pool to a vector register, print the constant
+ // loaded.
+ case X86::MOVAPDrm:
+ case X86::VMOVAPDrm:
+ case X86::VMOVAPDYrm:
+ case X86::MOVUPDrm:
+ case X86::VMOVUPDrm:
+ case X86::VMOVUPDYrm:
+ case X86::MOVAPSrm:
+ case X86::VMOVAPSrm:
+ case X86::VMOVAPSYrm:
+ case X86::MOVUPSrm:
+ case X86::VMOVUPSrm:
+ case X86::VMOVUPSYrm:
+ case X86::MOVDQArm:
+ case X86::VMOVDQArm:
+ case X86::VMOVDQAYrm:
+ case X86::MOVDQUrm:
+ case X86::VMOVDQUrm:
+ case X86::VMOVDQUYrm:
+ if (!OutStreamer.isVerboseAsm())
+ break;
+ if (MI->getNumOperands() > 4)
+ if (auto *C = getConstantFromPool(*MI, MI->getOperand(4))) {
+ std::string Comment;
+ raw_string_ostream CS(Comment);
+ const MachineOperand &DstOp = MI->getOperand(0);
+ CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = ";
+ if (auto *CDS = dyn_cast<ConstantDataSequential>(C)) {
+ CS << "[";
+ for (int i = 0, NumElements = CDS->getNumElements(); i < NumElements; ++i) {
+ if (i != 0)
+ CS << ",";
+ if (CDS->getElementType()->isIntegerTy())
+ CS << CDS->getElementAsInteger(i);
+ else if (CDS->getElementType()->isFloatTy())
+ CS << CDS->getElementAsFloat(i);
+ else if (CDS->getElementType()->isDoubleTy())
+ CS << CDS->getElementAsDouble(i);
+ else
+ CS << "?";
+ }
+ CS << "]";
+ OutStreamer.AddComment(CS.str());
+ } else if (auto *CV = dyn_cast<ConstantVector>(C)) {
+ CS << "<";
+ for (int i = 0, NumOperands = CV->getNumOperands(); i < NumOperands; ++i) {
+ if (i != 0)
+ CS << ",";
+ Constant *COp = CV->getOperand(i);
+ if (isa<UndefValue>(COp)) {
+ CS << "u";
+ } else if (auto *CI = dyn_cast<ConstantInt>(COp)) {
+ CS << CI->getZExtValue();
+ } else if (auto *CF = dyn_cast<ConstantFP>(COp)) {
+ SmallString<32> Str;
+ CF->getValueAPF().toString(Str);
+ CS << Str;
+ } else {
+ CS << "?";
+ }
+ }
+ CS << ">";
+ OutStreamer.AddComment(CS.str());
+ }
+ }
+ break;
}
MCInst TmpInst;