forked from OSchip/llvm-project
[AMDGPU][MC] Corrected V_*QSAD* instructions to check that dest register is different than any of the src
See Bug 33279: https://bugs.llvm.org//show_bug.cgi?id=33279 Reviewers: artem.tamazov, vpykhtin Differential Revision: https://reviews.llvm.org/D34003 llvm-svn: 305915
This commit is contained in:
parent
cec6a500a8
commit
dc4ac823ec
|
@ -995,7 +995,9 @@ private:
|
|||
void errorExpTgt();
|
||||
OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
|
||||
|
||||
bool validateOperandLimitations(const MCInst &Inst);
|
||||
bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc);
|
||||
bool validateConstantBusLimitations(const MCInst &Inst);
|
||||
bool validateEarlyClobberLimitations(const MCInst &Inst);
|
||||
bool usesConstantBus(const MCInst &Inst, unsigned OpIdx);
|
||||
bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
|
||||
unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const;
|
||||
|
@ -2095,7 +2097,7 @@ bool AMDGPUAsmParser::usesConstantBus(const MCInst &Inst, unsigned OpIdx) {
|
|||
isSGPR(mc2PseudoReg(MO.getReg()), getContext().getRegisterInfo());
|
||||
}
|
||||
|
||||
bool AMDGPUAsmParser::validateOperandLimitations(const MCInst &Inst) {
|
||||
bool AMDGPUAsmParser::validateConstantBusLimitations(const MCInst &Inst) {
|
||||
const unsigned Opcode = Inst.getOpcode();
|
||||
const MCInstrDesc &Desc = MII.get(Opcode);
|
||||
unsigned ConstantBusUseCount = 0;
|
||||
|
@ -2149,6 +2151,60 @@ bool AMDGPUAsmParser::validateOperandLimitations(const MCInst &Inst) {
|
|||
return ConstantBusUseCount <= 1;
|
||||
}
|
||||
|
||||
bool AMDGPUAsmParser::validateEarlyClobberLimitations(const MCInst &Inst) {
|
||||
|
||||
const unsigned Opcode = Inst.getOpcode();
|
||||
const MCInstrDesc &Desc = MII.get(Opcode);
|
||||
|
||||
const int DstIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vdst);
|
||||
if (DstIdx == -1 ||
|
||||
Desc.getOperandConstraint(DstIdx, MCOI::EARLY_CLOBBER) == -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const MCRegisterInfo *TRI = getContext().getRegisterInfo();
|
||||
|
||||
const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
|
||||
const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
|
||||
const int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
|
||||
|
||||
assert(DstIdx != -1);
|
||||
const MCOperand &Dst = Inst.getOperand(DstIdx);
|
||||
assert(Dst.isReg());
|
||||
const unsigned DstReg = mc2PseudoReg(Dst.getReg());
|
||||
|
||||
const int SrcIndices[] = { Src0Idx, Src1Idx, Src2Idx };
|
||||
|
||||
for (int SrcIdx : SrcIndices) {
|
||||
if (SrcIdx == -1) break;
|
||||
const MCOperand &Src = Inst.getOperand(SrcIdx);
|
||||
if (Src.isReg()) {
|
||||
const unsigned SrcReg = mc2PseudoReg(Src.getReg());
|
||||
if (isRegIntersect(DstReg, SrcReg, TRI)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
|
||||
const SMLoc &IDLoc) {
|
||||
if (!validateConstantBusLimitations(Inst)) {
|
||||
Error(IDLoc,
|
||||
"invalid operand (violates constant bus restrictions)");
|
||||
return false;
|
||||
}
|
||||
if (!validateEarlyClobberLimitations(Inst)) {
|
||||
Error(IDLoc,
|
||||
"destination must be different than all sources");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
OperandVector &Operands,
|
||||
MCStreamer &Out,
|
||||
|
@ -2181,9 +2237,8 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
switch (Result) {
|
||||
default: break;
|
||||
case Match_Success:
|
||||
if (!validateOperandLimitations(Inst)) {
|
||||
return Error(IDLoc,
|
||||
"invalid operand (violates constant bus restrictions)");
|
||||
if (!validateInstruction(Inst, IDLoc)) {
|
||||
return true;
|
||||
}
|
||||
Inst.setLoc(IDLoc);
|
||||
Out.EmitInstruction(Inst, getSTI());
|
||||
|
|
|
@ -538,6 +538,27 @@ bool isSGPR(unsigned Reg, const MCRegisterInfo* TRI) {
|
|||
Reg == AMDGPU::SCC;
|
||||
}
|
||||
|
||||
bool isRegIntersect(unsigned Reg0, unsigned Reg1, const MCRegisterInfo* TRI) {
|
||||
|
||||
if (Reg0 == Reg1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned SubReg0 = TRI->getSubReg(Reg0, 1);
|
||||
if (SubReg0 == 0) {
|
||||
return TRI->getSubRegIndex(Reg1, Reg0) > 0;
|
||||
}
|
||||
|
||||
for (unsigned Idx = 2; SubReg0 > 0; ++Idx) {
|
||||
if (isRegIntersect(Reg1, SubReg0, TRI)) {
|
||||
return true;
|
||||
}
|
||||
SubReg0 = TRI->getSubReg(Reg0, Idx);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI) {
|
||||
|
||||
switch(Reg) {
|
||||
|
|
|
@ -271,6 +271,9 @@ bool isGFX9(const MCSubtargetInfo &STI);
|
|||
/// \brief Is Reg - scalar register
|
||||
bool isSGPR(unsigned Reg, const MCRegisterInfo* TRI);
|
||||
|
||||
/// \brief Is there any intersection between registers
|
||||
bool isRegIntersect(unsigned Reg0, unsigned Reg1, const MCRegisterInfo* TRI);
|
||||
|
||||
/// If \p Reg is a pseudo reg, return the correct hardware register given
|
||||
/// \p STI otherwise return \p Reg.
|
||||
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// RUN: llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=SICI --check-prefix=CI
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=CIVI --check-prefix=VI
|
||||
|
||||
v_mqsad_pk_u16_u8 v[0:1], s[0:1], 1, v[254:255]
|
||||
// CI: [0x00,0x00,0xe6,0xd2,0x00,0x02,0xf9,0x07]
|
||||
// VI: [0x00,0x00,0xe6,0xd1,0x00,0x02,0xf9,0x07]
|
||||
v_mqsad_pk_u16_u8 v[2:3], s[0:1], 1, v[254:255]
|
||||
// CI: [0x02,0x00,0xe6,0xd2,0x00,0x02,0xf9,0x07]
|
||||
// VI: [0x02,0x00,0xe6,0xd1,0x00,0x02,0xf9,0x07]
|
||||
|
||||
v_qsad_pk_u16_u8 v[0:1], v[0:1], 1, s[0:1]
|
||||
// CI: [0x00,0x00,0xe4,0xd2,0x00,0x03,0x01,0x00]
|
||||
// VI: [0x00,0x00,0xe5,0xd1,0x00,0x03,0x01,0x00]
|
||||
v_qsad_pk_u16_u8 v[2:3], v[0:1], 1, s[0:1]
|
||||
// CI: [0x02,0x00,0xe4,0xd2,0x00,0x03,0x01,0x00]
|
||||
// VI: [0x02,0x00,0xe5,0xd1,0x00,0x03,0x01,0x00]
|
||||
|
|
|
@ -9,3 +9,27 @@ v_div_scale_f32 v24, vcc, v22, 1.1, v22
|
|||
|
||||
v_mqsad_u32_u8 v[0:3], s[2:3], v4, v[0:3]
|
||||
// CHECK: error: instruction not supported on this GPU
|
||||
|
||||
v_mqsad_pk_u16_u8 v[0:1], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[1:2], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[2:3], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[3:4], v[0:1], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[4:5], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[5:6], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[8:9], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
||||
v_mqsad_pk_u16_u8 v[9:10], v[1:2], v9, v[4:5]
|
||||
// CHECK: error: destination must be different than all sources
|
||||
|
|
|
@ -385,9 +385,9 @@ v_mad_f32 v9, 0.5, v5, -v8
|
|||
// SICI: v_mad_f32 v9, 0.5, v5, -v8 ; encoding: [0x09,0x00,0x82,0xd2,0xf0,0x0a,0x22,0x84]
|
||||
// VI: v_mad_f32 v9, 0.5, v5, -v8 ; encoding: [0x09,0x00,0xc1,0xd1,0xf0,0x0a,0x22,0x84]
|
||||
|
||||
v_mqsad_u32_u8 v[0:3], s[2:3], v4, v[0:3]
|
||||
// CI: v_mqsad_u32_u8 v[0:3], s[2:3], v4, v[0:3] ; encoding: [0x00,0x00,0xea,0xd2,0x02,0x08,0x02,0x04]
|
||||
// VI: v_mqsad_u32_u8 v[0:3], s[2:3], v4, v[0:3] ; encoding: [0x00,0x00,0xe7,0xd1,0x02,0x08,0x02,0x04]
|
||||
v_mqsad_u32_u8 v[5:8], s[2:3], v4, v[0:3]
|
||||
// CI: v_mqsad_u32_u8 v[5:8], s[2:3], v4, v[0:3] ; encoding: [0x05,0x00,0xea,0xd2,0x02,0x08,0x02,0x04]
|
||||
// VI: v_mqsad_u32_u8 v[5:8], s[2:3], v4, v[0:3] ; encoding: [0x05,0x00,0xe7,0xd1,0x02,0x08,0x02,0x04]
|
||||
// NOSI: error: instruction not supported on this GPU
|
||||
|
||||
v_mad_u64_u32 v[5:6], s[12:13], s1, 0, 0
|
||||
|
|
Loading…
Reference in New Issue