[llvm] r223614 - R600/SI: Set 20-bit immediate byte offset for SMRD on VI

Matt Arsenault arsenm2 at gmail.com
Sun Dec 7 09:35:06 PST 2014


> On Dec 7, 2014, at 12:17 PM, Marek Olsak <marek.olsak at amd.com> wrote:
> 
> Author: mareko
> Date: Sun Dec  7 11:17:38 2014
> New Revision: 223614
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=223614&view=rev
> Log:
> R600/SI: Set 20-bit immediate byte offset for SMRD on VI
> 
> Modified:
>    llvm/trunk/lib/Target/R600/SIISelLowering.cpp
>    llvm/trunk/lib/Target/R600/SIInstrInfo.cpp
>    llvm/trunk/lib/Target/R600/SIInstrInfo.h
>    llvm/trunk/lib/Target/R600/SIInstrInfo.td
>    llvm/trunk/lib/Target/R600/SIInstructions.td
>    llvm/trunk/lib/Target/R600/VIInstructions.td
> 
> Modified: llvm/trunk/lib/Target/R600/SIISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIISelLowering.cpp?rev=223614&r1=223613&r2=223614&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/SIISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/R600/SIISelLowering.cpp Sun Dec  7 11:17:38 2014
> @@ -2156,7 +2156,12 @@ MachineSDNode *SITargetLowering::AdjustR
>     SmallVector<SDValue, 8> Ops;
>     Ops.push_back(SDValue(RSrc, 0));
>     Ops.push_back(N->getOperand(0));
> -    Ops.push_back(DAG.getConstant(Offset->getSExtValue() << 2, MVT::i32));
> +
> +    // The immediate offset is in dwords on SI and in bytes on VI.
> +    if (Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS)
> +      Ops.push_back(DAG.getConstant(Offset->getSExtValue(), MVT::i32));
> +    else
> +      Ops.push_back(DAG.getConstant(Offset->getSExtValue() << 2, MVT::i32));

These should be using getTargetConstant


> 
>     // Copy remaining operands so we keep any chain and glue nodes that follow
>     // the normal operands.
> 
> Modified: llvm/trunk/lib/Target/R600/SIInstrInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstrInfo.cpp?rev=223614&r1=223613&r2=223614&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/SIInstrInfo.cpp (original)
> +++ llvm/trunk/lib/Target/R600/SIInstrInfo.cpp Sun Dec  7 11:17:38 2014
> @@ -971,15 +971,19 @@ bool SIInstrInfo::isImmOperandLegal(cons
>   return RI.regClassCanUseInlineConstant(OpInfo.RegClass);
> }
> 
> -bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) {
> +bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) const {
>   switch (AS) {
>   case AMDGPUAS::GLOBAL_ADDRESS: {
>     // MUBUF instructions a 12-bit offset in bytes.
>     return isUInt<12>(OffsetSize);
>   }
>   case AMDGPUAS::CONSTANT_ADDRESS: {
> -    // SMRD instructions have an 8-bit offset in dwords.
> -    return (OffsetSize % 4 == 0) && isUInt<8>(OffsetSize / 4);
> +    // SMRD instructions have an 8-bit offset in dwords on SI and
> +    // a 20-bit offset in bytes on VI.
> +    if (RI.ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS)
> +      return isUInt<20>(OffsetSize);
> +    else
> +      return (OffsetSize % 4 == 0) && isUInt<8>(OffsetSize / 4);
>   }
>   case AMDGPUAS::LOCAL_ADDRESS:
>   case AMDGPUAS::REGION_ADDRESS: {
> @@ -1701,27 +1705,30 @@ void SIInstrInfo::splitSMRD(MachineInstr
>       getNamedOperand(*MI, AMDGPU::OpName::offset);
>   const MachineOperand *SBase = getNamedOperand(*MI, AMDGPU::OpName::sbase);
> 
> +  // The SMRD has an 8-bit offset in dwords on SI and a 20-bit offset in bytes
> +  // on VI.
>   if (OffOp) {
> +    bool isVI = RI.ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS;
> +    unsigned OffScale = isVI ? 1 : 4;
>     // Handle the _IMM variant
> -    unsigned LoOffset = OffOp->getImm();
> -    unsigned HiOffset = LoOffset + (HalfSize / 4);
> +    unsigned LoOffset = OffOp->getImm() * OffScale;
> +    unsigned HiOffset = LoOffset + HalfSize;
>     Lo = BuildMI(*MBB, MI, DL, get(HalfImmOp), RegLo)
>                   .addOperand(*SBase)
> -                  .addImm(LoOffset);
> +                  .addImm(LoOffset / OffScale);
> 
> -    if (!isUInt<8>(HiOffset)) {
> +    if (!isUInt<20>(HiOffset) || (!isVI && !isUInt<8>(HiOffset / OffScale))) {
>       unsigned OffsetSGPR =
>           MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
>       BuildMI(*MBB, MI, DL, get(AMDGPU::S_MOV_B32), OffsetSGPR)
> -              .addImm(HiOffset << 2);  // The immediate offset is in dwords,
> -                                       // but offset in register is in bytes.
> +              .addImm(HiOffset); // The offset in register is in bytes.
>       Hi = BuildMI(*MBB, MI, DL, get(HalfSGPROp), RegHi)
>                     .addOperand(*SBase)
>                     .addReg(OffsetSGPR);
>     } else {
>       Hi = BuildMI(*MBB, MI, DL, get(HalfImmOp), RegHi)
>                      .addOperand(*SBase)
> -                     .addImm(HiOffset);
> +                     .addImm(HiOffset / OffScale);
>     }
>   } else {
>     // Handle the _SGPR variant
> @@ -1786,10 +1793,13 @@ void SIInstrInfo::moveSMRDToVALU(Machine
>         ImmOffset = 0;
>       } else {
>         assert(MI->getOperand(2).isImm());
> -        // SMRD instructions take a dword offsets and MUBUF instructions
> -        // take a byte offset.
> -        ImmOffset = MI->getOperand(2).getImm() << 2;
> +        // SMRD instructions take a dword offsets on SI and byte offset on VI
> +        // and MUBUF instructions always take a byte offset.
> +        ImmOffset = MI->getOperand(2).getImm();
> +        if (RI.ST.getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS)
> +          ImmOffset <<= 2;
>         RegOffset = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
> +
>         if (isUInt<12>(ImmOffset)) {
>           BuildMI(*MBB, MI, MI->getDebugLoc(), get(AMDGPU::S_MOV_B32),
>                   RegOffset)
> 
> Modified: llvm/trunk/lib/Target/R600/SIInstrInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstrInfo.h?rev=223614&r1=223613&r2=223614&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/SIInstrInfo.h (original)
> +++ llvm/trunk/lib/Target/R600/SIInstrInfo.h Sun Dec  7 11:17:38 2014
> @@ -209,7 +209,7 @@ public:
> 
>   /// \brief Return true if the given offset Size in bytes can be folded into
>   /// the immediate offsets of a memory instruction for the given address space.
> -  static bool canFoldOffset(unsigned OffsetSize, unsigned AS) LLVM_READNONE;
> +  bool canFoldOffset(unsigned OffsetSize, unsigned AS) const;
> 
>   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
>   /// This function will return false if you pass it a 32-bit instruction.
> 
> Modified: llvm/trunk/lib/Target/R600/SIInstrInfo.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstrInfo.td?rev=223614&r1=223613&r2=223614&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/SIInstrInfo.td (original)
> +++ llvm/trunk/lib/Target/R600/SIInstrInfo.td Sun Dec  7 11:17:38 2014
> @@ -171,6 +171,10 @@ def IMM16bit : PatLeaf <(imm),
>   [{return isUInt<16>(N->getZExtValue());}]
>> ;
> 
> +def IMM20bit : PatLeaf <(imm),
> +  [{return isUInt<20>(N->getZExtValue());}]
> +>;
> +
> def IMM32bit : PatLeaf <(imm),
>   [{return isUInt<32>(N->getZExtValue());}]
>> ;
> 
> Modified: llvm/trunk/lib/Target/R600/SIInstructions.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstructions.td?rev=223614&r1=223613&r2=223614&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/SIInstructions.td (original)
> +++ llvm/trunk/lib/Target/R600/SIInstructions.td Sun Dec  7 11:17:38 2014
> @@ -34,6 +34,9 @@ def isSICI : Predicate<
>> ;
> def isCI : Predicate<"Subtarget.getGeneration() "
>                       ">= AMDGPUSubtarget::SEA_ISLANDS">;
> +def isVI : Predicate <
> +  "Subtarget.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS"
> +>;
> 
> def HasFlatAddressSpace : Predicate<"Subtarget.hasFlatAddressSpace()">;
> 
> @@ -1974,7 +1977,7 @@ def : Pat <
> 
> multiclass SMRD_Pattern <SMRD Instr_IMM, SMRD Instr_SGPR, ValueType vt> {
> 
> -  // 1. Offset as 8bit DWORD immediate
> +  // 1. SI-CI: Offset as 8bit DWORD immediate
>   def : Pat <
>     (constant_load (add i64:$sbase, (i64 IMM8bitDWORD:$offset))),
>     (vt (Instr_IMM $sbase, (as_dword_i32imm $offset)))
> @@ -1993,6 +1996,28 @@ multiclass SMRD_Pattern <SMRD Instr_IMM,
>> ;
> }
> 
> +multiclass SMRD_Pattern_vi <SMRD Instr_IMM, SMRD Instr_SGPR, ValueType vt> {
> +
> +  // 1. VI: Offset as 20bit immediate in bytes
> +  def : Pat <
> +    (constant_load (add i64:$sbase, (i64 IMM20bit:$offset))),
> +    (vt (Instr_IMM $sbase, (as_i32imm $offset)))
> +  >;
> +
> +  // 2. Offset loaded in an 32bit SGPR
> +  def : Pat <
> +    (constant_load (add i64:$sbase, (i64 IMM32bit:$offset))),
> +    (vt (Instr_SGPR $sbase, (S_MOV_B32 (i32 (as_i32imm $offset)))))
> +  >;
> +
> +  // 3. No offset at all
> +  def : Pat <
> +    (constant_load i64:$sbase),
> +    (vt (Instr_IMM $sbase, 0))
> +  >;
> +}
> +
> +let Predicates = [isSICI] in {
> defm : SMRD_Pattern <S_LOAD_DWORD_IMM, S_LOAD_DWORD_SGPR, f32>;
> defm : SMRD_Pattern <S_LOAD_DWORD_IMM, S_LOAD_DWORD_SGPR, i32>;
> defm : SMRD_Pattern <S_LOAD_DWORDX2_IMM, S_LOAD_DWORDX2_SGPR, v2i32>;
> @@ -2000,6 +2025,19 @@ defm : SMRD_Pattern <S_LOAD_DWORDX4_IMM,
> defm : SMRD_Pattern <S_LOAD_DWORDX8_IMM, S_LOAD_DWORDX8_SGPR, v32i8>;
> defm : SMRD_Pattern <S_LOAD_DWORDX8_IMM, S_LOAD_DWORDX8_SGPR, v8i32>;
> defm : SMRD_Pattern <S_LOAD_DWORDX16_IMM, S_LOAD_DWORDX16_SGPR, v16i32>;
> +} // End Predicates = [isSICI]
> +
> +let Predicates = [isVI] in {
> +defm : SMRD_Pattern_vi <S_LOAD_DWORD_IMM, S_LOAD_DWORD_SGPR, f32>;
> +defm : SMRD_Pattern_vi <S_LOAD_DWORD_IMM, S_LOAD_DWORD_SGPR, i32>;
> +defm : SMRD_Pattern_vi <S_LOAD_DWORDX2_IMM, S_LOAD_DWORDX2_SGPR, v2i32>;
> +defm : SMRD_Pattern_vi <S_LOAD_DWORDX4_IMM, S_LOAD_DWORDX4_SGPR, v4i32>;
> +defm : SMRD_Pattern_vi <S_LOAD_DWORDX8_IMM, S_LOAD_DWORDX8_SGPR, v32i8>;
> +defm : SMRD_Pattern_vi <S_LOAD_DWORDX8_IMM, S_LOAD_DWORDX8_SGPR, v8i32>;
> +defm : SMRD_Pattern_vi <S_LOAD_DWORDX16_IMM, S_LOAD_DWORDX16_SGPR, v16i32>;
> +} // End Predicates = [isVI]
> +
> +let Predicates = [isSICI] in {
> 
> // 1. Offset as 8bit DWORD immediate
> def : Pat <
> @@ -2007,6 +2045,8 @@ def : Pat <
>   (S_BUFFER_LOAD_DWORD_IMM $sbase, (as_dword_i32imm $offset))
>> ;
> 
> +} // End Predicates = [isSICI]
> +
> // 2. Offset loaded in an 32bit SGPR
> def : Pat <
>   (SIload_constant v4i32:$sbase, imm:$offset),
> 
> Modified: llvm/trunk/lib/Target/R600/VIInstructions.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/VIInstructions.td?rev=223614&r1=223613&r2=223614&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/VIInstructions.td (original)
> +++ llvm/trunk/lib/Target/R600/VIInstructions.td Sun Dec  7 11:17:38 2014
> @@ -9,10 +9,6 @@
> // Instruction definitions for VI and newer.
> //===----------------------------------------------------------------------===//
> 
> -def isVI : Predicate <
> -  "Subtarget.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS"
> ->;
> -
> let SubtargetPredicate = isVI in {
> 
> def V_LDEXP_F32 : VOP3InstVI <0x288, "v_ldexp_f32", VOP_F32_F32_I32,
> @@ -54,6 +50,16 @@ def : Pat <
>> ;
> 
> //===----------------------------------------------------------------------===//
> +// SMEM Patterns
> +//===----------------------------------------------------------------------===//
> +
> +// 1. Offset as 8bit DWORD immediate
> +def : Pat <
> +  (SIload_constant v4i32:$sbase, IMM20bit:$offset),
> +  (S_BUFFER_LOAD_DWORD_IMM $sbase, (as_i32imm $offset))
> +>;
> +
> +//===----------------------------------------------------------------------===//
> // MUBUF Patterns
> //===----------------------------------------------------------------------===//
> 
> 
> 
> _______________________________________________
> 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