[llvm] r305915 - [AMDGPU][MC] Corrected V_*QSAD* instructions to check that dest register is different than any of the src

Dmitry Preobrazhensky via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 21 07:41:34 PDT 2017


Author: dpreobra
Date: Wed Jun 21 09:41:34 2017
New Revision: 305915

URL: http://llvm.org/viewvc/llvm-project?rev=305915&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
    llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
    llvm/trunk/test/MC/AMDGPU/regression/bug28168.s
    llvm/trunk/test/MC/AMDGPU/vop3-errs.s
    llvm/trunk/test/MC/AMDGPU/vop3.s

Modified: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp?rev=305915&r1=305914&r2=305915&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp Wed Jun 21 09:41:34 2017
@@ -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(co
          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::validateOperandLim
   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::MatchAndEmitInstru
   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());

Modified: llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp?rev=305915&r1=305914&r2=305915&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp Wed Jun 21 09:41:34 2017
@@ -538,6 +538,27 @@ bool isSGPR(unsigned Reg, const MCRegist
     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) {

Modified: llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h?rev=305915&r1=305914&r2=305915&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h (original)
+++ llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h Wed Jun 21 09:41:34 2017
@@ -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);

Modified: llvm/trunk/test/MC/AMDGPU/regression/bug28168.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/regression/bug28168.s?rev=305915&r1=305914&r2=305915&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/regression/bug28168.s (original)
+++ llvm/trunk/test/MC/AMDGPU/regression/bug28168.s Wed Jun 21 09:41:34 2017
@@ -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]

Modified: llvm/trunk/test/MC/AMDGPU/vop3-errs.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/vop3-errs.s?rev=305915&r1=305914&r2=305915&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/vop3-errs.s (original)
+++ llvm/trunk/test/MC/AMDGPU/vop3-errs.s Wed Jun 21 09:41:34 2017
@@ -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

Modified: llvm/trunk/test/MC/AMDGPU/vop3.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AMDGPU/vop3.s?rev=305915&r1=305914&r2=305915&view=diff
==============================================================================
--- llvm/trunk/test/MC/AMDGPU/vop3.s (original)
+++ llvm/trunk/test/MC/AMDGPU/vop3.s Wed Jun 21 09:41:34 2017
@@ -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




More information about the llvm-commits mailing list