This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Teach VSETVLInsert to eliminate redundant vsetvli for vmv.s.x and vfmv.s.f.
ClosedPublic

Authored by jacquesguan on Dec 27 2021, 5:14 AM.

Diff Detail

Event Timeline

jacquesguan created this revision.Dec 27 2021, 5:14 AM
jacquesguan requested review of this revision.Dec 27 2021, 5:14 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 27 2021, 5:14 AM
craig.topper added inline comments.Dec 27 2021, 10:03 AM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
156

Is this used?

205

Is this used?

258

behaves -> behaviors?

259

"all two" -> both?

459

Function names should be lowercase.

And this function should be static

Ignore LMUL for scalar move instructions and update tests.

jacquesguan added inline comments.Dec 28 2021, 4:17 AM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
156

Done, now use the SEW and policy instead of VTYPE in the condition, because these instructions ignore the LMUL.

205

Done, now use the SEW and policy instead of VTYPE in the condition, because these instructions ignore the LMUL.

259

Done

459

Done

craig.topper added inline comments.Dec 28 2021, 8:59 PM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
68

Do we need to init ScalarMovOp here?

101

Drop curly braces around single line if bodies

106

This is really hasNonZeroAVL rather than positive right?

Update code according to the comments.

jacquesguan added inline comments.Dec 29 2021, 3:49 AM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
68

Done.

101

Done.

106

Done.

craig.topper added inline comments.Dec 29 2021, 3:26 PM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
156

Add this assert from hasSameVTYPE

assert(!SEWLMULRatioOnly && !Other.SEWLMULRatioOnly &&
       "Can't compare when only LMUL/SEW ratio is valid.");
258

This comment was not addressed

261

Add !Strict to this.

264

The LMUL does matter if the policy is tail agnostic. If the last vsetvli has a larger lmul than the vmv.s.x instruction, then by ignoring LMUL you gave hardware permission to replace every element except 0 of the larger lmul with all 1s. But the vmv.s.x was only allowed to replace the smaller lmul.

I think there's also an issue if the register isn't aligned to a multiple of the LMUL setting in vtype. For example, if LMUL=8, the vmv.s.x can't use v2 as its register. Section 3.4.2 of the V spec says that is reserved.

When LMUL=8, the vector register group contains eight vector registers, and instructions specifying an LMUL=8 vector register group using register numbers that are not multiples of eight are reserved.
jacquesguan added inline comments.Dec 29 2021, 6:28 PM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
264

According to the spec:

The instructions ignore LMUL and vector register groups. 
The other elements in the destination vector register ( 0 < index < VLEN/SEW) are treated as tail elements using the current tail agnostic/undisturbed policy.

I think this means that these vector scalar move instructions only perform on a single vector register what ever the LMUL is. And cause of ignoring the LMUL and vector group, it also can accept any vector register with any LMUL.

Update code according to the comments.

jacquesguan added inline comments.Dec 29 2021, 10:43 PM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
156

Done

258

Done

261

Done

craig.topper added inline comments.Dec 29 2021, 11:02 PM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
264

Thanks. I missed that.

This revision is now accepted and ready to land.Dec 29 2021, 11:14 PM

LGTM

Thanks, could you also accept the pre-commit test https://reviews.llvm.org/D116306 , so I could push them both.

This revision was landed with ongoing or failed builds.Dec 30 2021, 1:17 AM
This revision was automatically updated to reflect the committed changes.
rogfer01 added inline comments.Dec 30 2021, 3:57 AM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
470

I'm confused by the commit title.

You mention vmv.s.x which seems OK with the cases above and you also mention vfmv.s.f. But IIUC the cases listed here are for vfmv.f.s, right?

This is my understanding after this exceprt from RISCVInstrInfoVPseudos.td

//===----------------------------------------------------------------------===//
// 17.2. Floating-Point Scalar Move Instructions                                
//===----------------------------------------------------------------------===//
                                                                                
let Predicates = [HasVInstructionsAnyF] in {                                    
foreach fvti = AllFloatVectors in {                                             
  defvar instr = !cast<Instruction>("PseudoVFMV_"#fvti.ScalarSuffix#"_S_" #     
                                    fvti.LMul.MX);                              
  def : Pat<(fvti.Scalar (int_riscv_vfmv_f_s (fvti.Vector fvti.RegClass:$rs2))),
                         (instr $rs2, fvti.Log2SEW)>;                           
                                                                                
  def : Pat<(fvti.Vector (int_riscv_vfmv_s_f (fvti.Vector fvti.RegClass:$rs1),  
                         (fvti.Scalar fvti.ScalarRegClass:$rs2), VLOpFrag)),    
            (!cast<Instruction>("PseudoVFMV_S_"#fvti.ScalarSuffix#"_" #         
                                fvti.LMul.MX)                                   
             (fvti.Vector $rs1),                                                
             (fvti.Scalar fvti.ScalarRegClass:$rs2),                            
             GPR:$vl, fvti.Log2SEW)>;                                           
}                                                                               
} // Predicates = [HasVInstructionsAnyF]
jacquesguan added inline comments.Dec 30 2021, 4:36 AM
llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
470

Yes, you are right. I used wrong cases here; I will create a new revision to fix this and add more test cases for floating point. Thank you very much.