@@ -906,23 +906,33 @@ InstructionCost RISCVTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst,
906
906
if (!IsVectorType || !IsTypeLegal)
907
907
return BaseT::getCastInstrCost (Opcode, Dst, Src, CCH, CostKind, I);
908
908
909
+ std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost (Dst);
910
+
909
911
int ISD = TLI->InstructionOpcodeToISD (Opcode);
910
912
assert (ISD && " Invalid opcode" );
911
913
912
- // FIXME: Need to consider vsetvli and lmul.
913
914
int PowDiff = (int )Log2_32 (Dst->getScalarSizeInBits ()) -
914
915
(int )Log2_32 (Src->getScalarSizeInBits ());
915
916
switch (ISD) {
916
917
case ISD::SIGN_EXTEND:
917
- case ISD::ZERO_EXTEND:
918
- if (Src->getScalarSizeInBits () == 1 ) {
918
+ case ISD::ZERO_EXTEND: {
919
+ const unsigned SrcEltSize = Src->getScalarSizeInBits ();
920
+ if (SrcEltSize == 1 ) {
919
921
// We do not use vsext/vzext to extend from mask vector.
920
922
// Instead we use the following instructions to extend from mask vector:
921
923
// vmv.v.i v8, 0
922
924
// vmerge.vim v8, v8, -1, v0
923
- return 2 ;
925
+ return getRISCVInstructionCost ({RISCV::VMV_V_I, RISCV::VMERGE_VIM},
926
+ DstLT.second , CostKind);
924
927
}
925
- return 1 ;
928
+ if (PowDiff > 3 )
929
+ return BaseT::getCastInstrCost (Opcode, Dst, Src, CCH, CostKind, I);
930
+ unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
931
+ unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
932
+ unsigned Op =
933
+ (ISD == ISD::SIGN_EXTEND) ? SExtOp[PowDiff - 1 ] : ZExtOp[PowDiff - 1 ];
934
+ return getRISCVInstructionCost (Op, DstLT.second , CostKind);
935
+ }
926
936
case ISD::TRUNCATE:
927
937
if (Dst->getScalarSizeInBits () == 1 ) {
928
938
// We do not use several vncvt to truncate to mask vector. So we could
0 commit comments