Index: lib/Target/AMDGPU/SIDefines.h =================================================================== --- lib/Target/AMDGPU/SIDefines.h +++ lib/Target/AMDGPU/SIDefines.h @@ -45,7 +45,8 @@ Gather4 = 1 << 26, DisableWQM = 1 << 27, SOPK_ZEXT = 1 << 28, - SCALAR_STORE = 1 << 29 + SCALAR_STORE = 1 << 29, + FIXED_SIZE = 1 << 30 }; } Index: lib/Target/AMDGPU/SIInstrFormats.td =================================================================== --- lib/Target/AMDGPU/SIInstrFormats.td +++ lib/Target/AMDGPU/SIInstrFormats.td @@ -65,6 +65,10 @@ // SMEM instructions like the cache flush ones. field bits<1> ScalarStore = 0; + // Whether the operands can be ignored when computing the + // instruction size. + field bits<1> FixedSize = 0; + // These need to be kept in sync with the enum in SIInstrFlags. let TSFlags{0} = VM_CNT; let TSFlags{1} = EXP_CNT; @@ -100,6 +104,7 @@ let TSFlags{27} = DisableWQM; let TSFlags{28} = SOPKZext; let TSFlags{29} = ScalarStore; + let TSFlags{30} = FixedSize; let SchedRW = [Write32Bit]; Index: lib/Target/AMDGPU/SIInstrInfo.h =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.h +++ lib/Target/AMDGPU/SIInstrInfo.h @@ -438,6 +438,14 @@ return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE; } + static bool isFixedSize(const MachineInstr &MI) { + return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE; + } + + bool isFixedSize(uint16_t Opcode) const { + return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE; + } + bool isVGPRCopy(const MachineInstr &MI) const { assert(MI.isCopy()); unsigned Dest = MI.getOperand(0).getReg(); Index: lib/Target/AMDGPU/SIInstrInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIInstrInfo.cpp +++ lib/Target/AMDGPU/SIInstrInfo.cpp @@ -3501,12 +3501,20 @@ // If we have a definitive size, we can use it. Otherwise we need to inspect // the operands to know the size. - if (DescSize != 0) + // + // FIXME: Instructions that have a base 32-bit encoding report their size as + // 4, even though they are really 8 bytes if they have a literal operand. + if (DescSize != 0 && DescSize != 4) return DescSize; // 4-byte instructions may have a 32-bit literal encoded after them. Check // operands that coud ever be literals. if (isVALU(MI) || isSALU(MI)) { + if (isFixedSize(MI)) { + assert(DescSize == 4); + return DescSize; + } + int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0); if (Src0Idx == -1) return 4; // No operands. @@ -3524,6 +3532,9 @@ return 4; } + if (DescSize == 4) + return 4; + switch (Opc) { case AMDGPU::SI_MASK_BRANCH: case TargetOpcode::IMPLICIT_DEF: Index: lib/Target/AMDGPU/SOPInstructions.td =================================================================== --- lib/Target/AMDGPU/SOPInstructions.td +++ lib/Target/AMDGPU/SOPInstructions.td @@ -704,6 +704,7 @@ let Defs = [M0]; // No scc def let Uses = [M0]; // Other bits of m0 unmodified. let hasSideEffects = 1; // Sets mode.gpr_idx_en + let FixedSize = 1; } }