[PATCH] R600/SI: Fix READLANE and WRITELANE lane select for VI

Matt Arsenault arsenm2 at gmail.com
Sat Feb 14 09:51:53 PST 2015


> On Feb 14, 2015, at 7:24 AM, Marek Olšák <maraeo at gmail.com> wrote:
> 
> From: Marek Olšák <marek.olsak at amd.com>
> 
> VOP2 declares vsrc1, but VOP3 declares src1.
> We can't use the same "ins" if the operands have different names in SI
> and VI encodings.
> 
> Since the verifier only checks src1, verification of what was vsrc1 is now
> enabled.
> 
> This fixes a hang in geometry shaders which spill M0 on VI.
> (BTW it doesn't look like M0 needs spilling and the spilling seems
> duplicated 3 times)
> ---
> lib/Target/R600/SIInstrFormats.td |  4 ++--
> lib/Target/R600/SIInstrInfo.cpp   | 20 +++++++++++++++++---
> lib/Target/R600/SIInstructions.td |  8 ++++----
> 3 files changed, 23 insertions(+), 9 deletions(-)
> 
> diff --git a/lib/Target/R600/SIInstrFormats.td b/lib/Target/R600/SIInstrFormats.td
> index 0798241..ca9b3d4 100644
> --- a/lib/Target/R600/SIInstrFormats.td
> +++ b/lib/Target/R600/SIInstrFormats.td
> @@ -300,10 +300,10 @@ class VOP2e <bits<6> op> : Enc32 {
> 
>   bits<8> VDST;
>   bits<9> SRC0;
> -  bits<8> VSRC1;
> +  bits<8> SRC1;
> 
>   let Inst{8-0} = SRC0;
> -  let Inst{16-9} = VSRC1;
> +  let Inst{16-9} = SRC1;
>   let Inst{24-17} = VDST;
>   let Inst{30-25} = op;
>   let Inst{31} = 0x0; //encoding
> diff --git a/lib/Target/R600/SIInstrInfo.cpp b/lib/Target/R600/SIInstrInfo.cpp
> index 8b65d5c..41d4770 100644
> --- a/lib/Target/R600/SIInstrInfo.cpp
> +++ b/lib/Target/R600/SIInstrInfo.cpp
> @@ -1233,9 +1233,23 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
>   // Verify SRC1 for VOP2 and VOPC
>   if (Src1Idx != -1 && (isVOP2(Opcode) || isVOPC(Opcode))) {
>     const MachineOperand &Src1 = MI->getOperand(Src1Idx);
> -    if (Src1.isImm()) {
> -      ErrInfo = "VOP[2C] src1 cannot be an immediate.";
> -      return false;
> +
> +    switch (Opcode) {
> +    // The lane select can be an SGPR, M0, or inline constant.
> +    // Only SI uses VOP2 encoding for these.
> +    case AMDGPU::V_READLANE_B32_si:
> +    case AMDGPU::V_WRITELANE_B32_si:
> +      if (isLiteralConstant(Src1, getOpSize(Opcode, Src1Idx))) {
> +        ErrInfo = "Lane select cannot be a literal constant.";
> +        return false;
> +      }
> +      break;
> +
I don’t think you need to special case these instructions. Why isn’t this already handled by OPERAND_REG_INLINE_C type operands? Do you need another that includes m0?

> +    default:
> +      if (Src1.isImm()) {
> +        ErrInfo = "VOP[2C] src1 cannot be an immediate.";
> +        return false;
> +      }
>     }
>   }
> 
> diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td
> index fbd38c9..f598e30 100644
> --- a/lib/Target/R600/SIInstructions.td
> +++ b/lib/Target/R600/SIInstructions.td
> @@ -1510,16 +1510,16 @@ defm V_READLANE_B32 : VOP2SI_3VI_m <
>   vop3 <0x001, 0x289>,
>   "v_readlane_b32",
>   (outs SReg_32:$vdst),
> -  (ins VGPR_32:$src0, SSrc_32:$vsrc1),
> -  "v_readlane_b32 $vdst, $src0, $vsrc1"
> +  (ins VGPR_32:$src0, SSrc_32:$src1),
> +  "v_readlane_b32 $vdst, $src0, $src1"
>> ;
> 
> defm V_WRITELANE_B32 : VOP2SI_3VI_m <
>   vop3 <0x002, 0x28a>,
>   "v_writelane_b32",
>   (outs VGPR_32:$vdst),
> -  (ins SReg_32:$src0, SSrc_32:$vsrc1),
> -  "v_writelane_b32 $vdst, $src0, $vsrc1"
> +  (ins SReg_32:$src0, SSrc_32:$src1),
> +  "v_writelane_b32 $vdst, $src0, $src1"
>> ;
> 
> // These instructions only exist on SI and CI
> -- 
> 2.1.0
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list