[X86] Teach the assembly parser to warn on duplicate registers in gather instructions.

Fixes PR32238.

Differential Revision: https://reviews.llvm.org/D39077

llvm-svn: 316700
This commit is contained in:
Craig Topper 2017-10-26 21:03:54 +00:00
parent 21cc2fa3f6
commit 8a2a104129
2 changed files with 90 additions and 0 deletions

View File

@ -856,6 +856,7 @@ private:
bool parseDirectiveFPOEndProc(SMLoc L);
bool parseDirectiveFPOData(SMLoc L);
bool validateInstruction(MCInst &Inst, const OperandVector &Ops);
bool processInstruction(MCInst &Inst, const OperandVector &Ops);
/// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
@ -2627,6 +2628,72 @@ bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
return false;
}
bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) {
const MCRegisterInfo *MRI = getContext().getRegisterInfo();
switch (Inst.getOpcode()) {
case X86::VGATHERDPDYrm:
case X86::VGATHERDPDrm:
case X86::VGATHERDPSYrm:
case X86::VGATHERDPSrm:
case X86::VGATHERQPDYrm:
case X86::VGATHERQPDrm:
case X86::VGATHERQPSYrm:
case X86::VGATHERQPSrm:
case X86::VPGATHERDDYrm:
case X86::VPGATHERDDrm:
case X86::VPGATHERDQYrm:
case X86::VPGATHERDQrm:
case X86::VPGATHERQDYrm:
case X86::VPGATHERQDrm:
case X86::VPGATHERQQYrm:
case X86::VPGATHERQQrm: {
unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
unsigned Mask = MRI->getEncodingValue(Inst.getOperand(1).getReg());
unsigned Index =
MRI->getEncodingValue(Inst.getOperand(3 + X86::AddrIndexReg).getReg());
if (Dest == Mask || Dest == Index || Mask == Index)
return Warning(Ops[0]->getStartLoc(), "mask, index, and destination "
"registers should be distinct");
break;
}
case X86::VGATHERDPDZ128rm:
case X86::VGATHERDPDZ256rm:
case X86::VGATHERDPDZrm:
case X86::VGATHERDPSZ128rm:
case X86::VGATHERDPSZ256rm:
case X86::VGATHERDPSZrm:
case X86::VGATHERQPDZ128rm:
case X86::VGATHERQPDZ256rm:
case X86::VGATHERQPDZrm:
case X86::VGATHERQPSZ128rm:
case X86::VGATHERQPSZ256rm:
case X86::VGATHERQPSZrm:
case X86::VPGATHERDDZ128rm:
case X86::VPGATHERDDZ256rm:
case X86::VPGATHERDDZrm:
case X86::VPGATHERDQZ128rm:
case X86::VPGATHERDQZ256rm:
case X86::VPGATHERDQZrm:
case X86::VPGATHERQDZ128rm:
case X86::VPGATHERQDZ256rm:
case X86::VPGATHERQDZrm:
case X86::VPGATHERQQZ128rm:
case X86::VPGATHERQQZ256rm:
case X86::VPGATHERQQZrm: {
unsigned Dest = MRI->getEncodingValue(Inst.getOperand(0).getReg());
unsigned Index =
MRI->getEncodingValue(Inst.getOperand(4 + X86::AddrIndexReg).getReg());
if (Dest == Index)
return Warning(Ops[0]->getStartLoc(), "index and destination registers "
"should be distinct");
break;
}
}
return false;
}
static const char *getSubtargetFeatureName(uint64_t Val);
void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
@ -2723,6 +2790,8 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
isParsingIntelSyntax())) {
default: llvm_unreachable("Unexpected match result!");
case Match_Success:
if (validateInstruction(Inst, Operands))
return true;
// Some instructions need post-processing to, for example, tweak which
// encoding is selected. Loop on it while changes happen so the
// individual transformations can chain off each other.
@ -3012,6 +3081,8 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
// instruction will already have been filled in correctly, since the failing
// matches won't have modified it).
if (NumSuccessfulMatches == 1) {
if (validateInstruction(Inst, Operands))
return true;
// Some instructions need post-processing to, for example, tweak which
// encoding is selected. Loop on it while changes happen so the individual
// transformations can chain off each other.

19
llvm/test/MC/X86/gather.s Normal file
View File

@ -0,0 +1,19 @@
// RUN: llvm-mc -triple x86_64-unknown-unknown -mattr=avx512f -show-encoding %s > %t 2> %t.err
// RUN: FileCheck < %t %s
// RUN: FileCheck --check-prefix=CHECK-STDERR < %t.err %s
// CHECK: vgatherdps %xmm2, (%rdi,%xmm2,2), %xmm2
// CHECK-STDERR: warning: mask, index, and destination registers should be distinct
vgatherdps %xmm2, (%rdi,%xmm2,2), %xmm2
// CHECK: vpgatherdd (%r14,%zmm11,8), %zmm11 {%k1}
// CHECK-STDERR: warning: index and destination registers should be distinct
vpgatherdd (%r14, %zmm11,8), %zmm11 {%k1}
// CHECK: vpgatherqd (%r14,%zmm11,8), %ymm11 {%k1}
// CHECK-STDERR: warning: index and destination registers should be distinct
vpgatherqd (%r14, %zmm11,8), %ymm11 {%k1}
// CHECK: vpgatherdq (%r14,%ymm11,8), %zmm11 {%k1}
// CHECK-STDERR: warning: index and destination registers should be distinct
vpgatherdq (%r14, %ymm11,8), %zmm11 {%k1}