-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV] Split convert to FP pseudos by SEW #88568
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Michael Maitland (michaelmaitland) Changes
I plan to commit each commit separate once approved. Patch is 51.87 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88568.diff 7 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 5a572002091ff3..27387595164a46 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -17642,8 +17642,7 @@ static MachineBasicBlock *emitSelectPseudo(MachineInstr &MI,
static MachineBasicBlock *emitVFROUND_NOEXCEPT_MASK(MachineInstr &MI,
MachineBasicBlock *BB,
- unsigned CVTXOpc,
- unsigned CVTFOpc) {
+ unsigned CVTXOpc) {
DebugLoc DL = MI.getDebugLoc();
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
@@ -17674,6 +17673,85 @@ static MachineBasicBlock *emitVFROUND_NOEXCEPT_MASK(MachineInstr &MI,
/*IsImp*/ true));
// Emit a VFCVT_F_X
+ RISCVII::VLMUL LMul = RISCVII::getLMul(MI.getDesc().TSFlags);
+ unsigned Log2SEW = MI.getOperand(RISCVII::getSEWOpNum(MI.getDesc())).getImm();
+ // There is no E8 variant for VFCVT_F_X.
+ assert(Log2SEW >= 4);
+ // Since MI (VFROUND) isn't SEW specific, we cannot use a macro to make
+ // handling of different (LMUL, SEW) pairs easier because we need to pull the
+ // SEW immediate from MI, and that information is not avaliable during macro
+ // expansion.
+ unsigned CVTFOpc;
+ if (Log2SEW == 4) {
+ switch (LMul) {
+ case RISCVII::LMUL_1:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M1_E16_MASK;
+ break;
+ case RISCVII::LMUL_2:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M2_E16_MASK;
+ break;
+ case RISCVII::LMUL_4:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M4_E16_MASK;
+ break;
+ case RISCVII::LMUL_8:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M8_E16_MASK;
+ break;
+ case RISCVII::LMUL_F2:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_MF2_E16_MASK;
+ break;
+ case RISCVII::LMUL_F4:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_MF4_E16_MASK;
+ break;
+ case RISCVII::LMUL_F8:
+ case RISCVII::LMUL_RESERVED:
+ llvm_unreachable("Unexpected LMUL and SEW combination value for MI.");
+ }
+ } else if (Log2SEW == 5) {
+ switch (LMul) {
+ case RISCVII::LMUL_1:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M1_E32_MASK;
+ break;
+ case RISCVII::LMUL_2:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M2_E32_MASK;
+ break;
+ case RISCVII::LMUL_4:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M4_E32_MASK;
+ break;
+ case RISCVII::LMUL_8:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M8_E32_MASK;
+ break;
+ case RISCVII::LMUL_F2:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_MF2_E32_MASK;
+ break;
+ case RISCVII::LMUL_F4:
+ case RISCVII::LMUL_F8:
+ case RISCVII::LMUL_RESERVED:
+ llvm_unreachable("Unexpected LMUL and SEW combination value for MI.");
+ }
+ } else if (Log2SEW == 6) {
+ switch (LMul) {
+ case RISCVII::LMUL_1:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M1_E64_MASK;
+ break;
+ case RISCVII::LMUL_2:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M2_E64_MASK;
+ break;
+ case RISCVII::LMUL_4:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M4_E64_MASK;
+ break;
+ case RISCVII::LMUL_8:
+ CVTFOpc = RISCV::PseudoVFCVT_F_X_V_M8_E64_MASK;
+ break;
+ case RISCVII::LMUL_F2:
+ case RISCVII::LMUL_F4:
+ case RISCVII::LMUL_F8:
+ case RISCVII::LMUL_RESERVED:
+ llvm_unreachable("Unexpected LMUL and SEW combination value for MI.");
+ }
+ } else {
+ llvm_unreachable("Unexpected LMUL and SEW combination value for MI.");
+ }
+
BuildMI(*BB, MI, DL, TII.get(CVTFOpc))
.add(MI.getOperand(0))
.add(MI.getOperand(1))
@@ -17883,23 +17961,17 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
Subtarget);
case RISCV::PseudoVFROUND_NOEXCEPT_V_M1_MASK:
- return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M1_MASK,
- RISCV::PseudoVFCVT_F_X_V_M1_MASK);
+ return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M1_MASK);
case RISCV::PseudoVFROUND_NOEXCEPT_V_M2_MASK:
- return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M2_MASK,
- RISCV::PseudoVFCVT_F_X_V_M2_MASK);
+ return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M2_MASK);
case RISCV::PseudoVFROUND_NOEXCEPT_V_M4_MASK:
- return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M4_MASK,
- RISCV::PseudoVFCVT_F_X_V_M4_MASK);
+ return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M4_MASK);
case RISCV::PseudoVFROUND_NOEXCEPT_V_M8_MASK:
- return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M8_MASK,
- RISCV::PseudoVFCVT_F_X_V_M8_MASK);
+ return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_M8_MASK);
case RISCV::PseudoVFROUND_NOEXCEPT_V_MF2_MASK:
- return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_MF2_MASK,
- RISCV::PseudoVFCVT_F_X_V_MF2_MASK);
+ return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_MF2_MASK);
case RISCV::PseudoVFROUND_NOEXCEPT_V_MF4_MASK:
- return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_MF4_MASK,
- RISCV::PseudoVFCVT_F_X_V_MF4_MASK);
+ return emitVFROUND_NOEXCEPT_MASK(MI, BB, RISCV::PseudoVFCVT_X_F_V_MF4_MASK);
case RISCV::PseudoFROUND_H:
case RISCV::PseudoFROUND_H_INX:
case RISCV::PseudoFROUND_S:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index a5f56a1c209c68..5d8b091392bea6 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -3580,12 +3580,14 @@ multiclass VPseudoConversion<VReg RetClass,
VReg Op1Class,
LMULInfo MInfo,
string Constraint = "",
+ int sew = 0,
int TargetConstraintType = 1> {
+ defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX);
let VLMul = MInfo.value in {
- def "_" # MInfo.MX : VPseudoUnaryNoMask<RetClass, Op1Class, Constraint, TargetConstraintType>;
- def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMask<RetClass, Op1Class,
- Constraint, TargetConstraintType>,
- RISCVMaskedPseudo<MaskIdx=2>;
+ def suffix : VPseudoUnaryNoMask<RetClass, Op1Class, Constraint, TargetConstraintType>;
+ def suffix # "_MASK" : VPseudoUnaryMask<RetClass, Op1Class,
+ Constraint, TargetConstraintType>,
+ RISCVMaskedPseudo<MaskIdx=2>;
}
}
@@ -3593,12 +3595,15 @@ multiclass VPseudoConversionRoundingMode<VReg RetClass,
VReg Op1Class,
LMULInfo MInfo,
string Constraint = "",
+ int sew = 0,
int TargetConstraintType = 1> {
let VLMul = MInfo.value in {
- def "_" # MInfo.MX : VPseudoUnaryNoMaskRoundingMode<RetClass, Op1Class, Constraint, TargetConstraintType>;
- def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMaskRoundingMode<RetClass, Op1Class,
- Constraint, TargetConstraintType>,
- RISCVMaskedPseudo<MaskIdx=2>;
+ defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX);
+ def suffix : VPseudoUnaryNoMaskRoundingMode<RetClass, Op1Class, Constraint, TargetConstraintType>;
+ def suffix # "_MASK" : VPseudoUnaryMaskRoundingMode<RetClass, Op1Class,
+ Constraint,
+ TargetConstraintType>,
+ RISCVMaskedPseudo<MaskIdx=2>;
}
}
@@ -3607,13 +3612,15 @@ multiclass VPseudoConversionRM<VReg RetClass,
VReg Op1Class,
LMULInfo MInfo,
string Constraint = "",
+ int sew = 0,
int TargetConstraintType = 1> {
let VLMul = MInfo.value in {
- def "_" # MInfo.MX : VPseudoUnaryNoMask_FRM<RetClass, Op1Class,
- Constraint, TargetConstraintType>;
- def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMask_FRM<RetClass, Op1Class,
- Constraint, TargetConstraintType>,
- RISCVMaskedPseudo<MaskIdx=2>;
+ defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX);
+ def suffix : VPseudoUnaryNoMask_FRM<RetClass, Op1Class,
+ Constraint, TargetConstraintType>;
+ def suffix # "_MASK" : VPseudoUnaryMask_FRM<RetClass, Op1Class,
+ Constraint, TargetConstraintType>,
+ RISCVMaskedPseudo<MaskIdx=2>;
}
}
@@ -3660,17 +3667,19 @@ multiclass VPseudoVFROUND_NOEXCEPT_V {
multiclass VPseudoVCVTF_V_RM {
foreach m = MxListF in {
- defm _V : VPseudoConversionRoundingMode<m.vrclass, m.vrclass, m>,
- SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1>.val in
+ defm _V : VPseudoConversionRoundingMode<m.vrclass, m.vrclass, m, sew=e>,
+ SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
multiclass VPseudoVCVTF_RM_V {
foreach m = MxListF in {
- defm _V : VPseudoConversionRM<m.vrclass, m.vrclass, m>,
- SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1>.val in
+ defm _V : VPseudoConversionRM<m.vrclass, m.vrclass, m, sew=e>,
+ SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
@@ -3704,18 +3713,22 @@ multiclass VPseudoVWCVTI_RM_V {
multiclass VPseudoVWCVTF_V {
defvar constraint = "@earlyclobber $rd";
foreach m = MxListW in {
- defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, TargetConstraintType=3>,
- SchedUnary<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=0, isWidening=1>.val in
+ defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, sew=e,
+ TargetConstraintType=3>,
+ SchedUnary<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
multiclass VPseudoVWCVTD_V {
defvar constraint = "@earlyclobber $rd";
foreach m = MxListFW in {
- defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, TargetConstraintType=3>,
- SchedUnary<"WriteVFWCvtFToFV", "ReadVFWCvtFToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1, isWidening=1>.val in
+ defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, sew=e,
+ TargetConstraintType=3>,
+ SchedUnary<"WriteVFWCvtFToFV", "ReadVFWCvtFToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
@@ -3749,36 +3762,45 @@ multiclass VPseudoVNCVTI_RM_W {
multiclass VPseudoVNCVTF_W_RM {
defvar constraint = "@earlyclobber $rd";
foreach m = MxListFW in {
- defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>,
- SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1, isWidening=1>.val in
+ defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m,
+ constraint, sew=e,
+ TargetConstraintType=2>,
+ SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
multiclass VPseudoVNCVTF_RM_W {
defvar constraint = "@earlyclobber $rd";
foreach m = MxListFW in {
- defm _W : VPseudoConversionRM<m.vrclass, m.wvrclass, m, constraint>,
- SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1, isWidening=1>.val in
+ defm _W : VPseudoConversionRM<m.vrclass, m.wvrclass, m, constraint, sew=e>,
+ SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
multiclass VPseudoVNCVTD_W {
defvar constraint = "@earlyclobber $rd";
foreach m = MxListFW in {
- defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>,
- SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1, isWidening=1>.val in
+ defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint, sew=e,
+ TargetConstraintType=2>,
+ SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
multiclass VPseudoVNCVTD_W_RM {
defvar constraint = "@earlyclobber $rd";
foreach m = MxListFW in {
- defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>,
- SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX,
- forceMergeOpRead=true>;
+ foreach e = SchedSEWSet<m.MX, isF=1, isWidening=1>.val in
+ defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m,
+ constraint, sew=e,
+ TargetConstraintType=2>,
+ SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX, e,
+ forceMergeOpRead=true>;
}
}
@@ -4889,14 +4911,17 @@ multiclass VPatConversionTA<string intrinsic,
ValueType result_type,
ValueType op1_type,
ValueType mask_type,
- int sew,
+ int log2sew,
LMULInfo vlmul,
VReg result_reg_class,
- VReg op1_reg_class> {
+ VReg op1_reg_class,
+ bit isSEWAware = 0> {
def : VPatUnaryNoMask<intrinsic, inst, kind, result_type, op1_type,
- sew, vlmul, result_reg_class, op1_reg_class>;
+ log2sew, vlmul, result_reg_class, op1_reg_class,
+ isSEWAware>;
def : VPatUnaryMask<intrinsic, inst, kind, result_type, op1_type,
- mask_type, sew, vlmul, result_reg_class, op1_reg_class>;
+ mask_type, log2sew, vlmul, result_reg_class, op1_reg_class,
+ isSEWAware>;
}
multiclass VPatConversionTARoundingMode<string intrinsic,
@@ -4905,14 +4930,17 @@ multiclass VPatConversionTARoundingMode<string intrinsic,
ValueType result_type,
ValueType op1_type,
ValueType mask_type,
- int sew,
+ int log2sew,
LMULInfo vlmul,
VReg result_reg_class,
- VReg op1_reg_class> {
+ VReg op1_reg_class,
+ bit isSEWAware = 0> {
def : VPatUnaryNoMaskRoundingMode<intrinsic, inst, kind, result_type, op1_type,
- sew, vlmul, result_reg_class, op1_reg_class>;
+ log2sew, vlmul, result_reg_class,
+ op1_reg_class, isSEWAware>;
def : VPatUnaryMaskRoundingMode<intrinsic, inst, kind, result_type, op1_type,
- mask_type, sew, vlmul, result_reg_class, op1_reg_class>;
+ mask_type, log2sew, vlmul, result_reg_class,
+ op1_reg_class, isSEWAware>;
}
multiclass VPatBinaryV_VV<string intrinsic, string instruction,
@@ -5905,15 +5933,16 @@ multiclass VPatConversionVI_VF_RM<string intrinsic,
}
}
-multiclass VPatConversionVF_VI_RM<string intrinsic,
- string instruction> {
+multiclass VPatConversionVF_VI_RM<string intrinsic, string instruction,
+ bit isSEWAware = 0> {
foreach fvti = AllFloatVectors in {
defvar ivti = GetIntVTypeInfo<fvti>.Vti;
let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates,
GetVTypePredicates<ivti>.Predicates) in
defm : VPatConversionTARoundingMode<intrinsic, instruction, "V",
fvti.Vector, ivti.Vector, fvti.Mask, ivti.Log2SEW,
- ivti.LMul, fvti.RegClass, ivti.RegClass>;
+ ivti.LMul, fvti.RegClass, ivti.RegClass,
+ isSEWAware>;
}
}
@@ -5941,7 +5970,8 @@ multiclass VPatConversionWI_VF_RM<string intrinsic, string instruction> {
}
}
-multiclass VPatConversionWF_VI<string intrinsic, string instruction> {
+multiclass VPatConversionWF_VI<string intrinsic, string instruction,
+ bit isSEWAware = 0> {
foreach vtiToWti = AllWidenableIntToFloatVectors in {
defvar vti = vtiToWti.Vti;
defvar fwti = vtiToWti.Wti;
@@ -5949,11 +5979,12 @@ multiclass VPatConversionWF_VI<string intrinsic, string instruction> {
GetVTypePredicates<fwti>.Predicates) in
defm : VPatConversionTA<intrinsic, instruction, "V",
fwti.Vector, vti.Vector, fwti.Mask, vti.Log2SEW,
- vti.LMul, fwti.RegClass, vti.RegClass>;
+ vti.LMul, fwti.RegClass, vti.RegClass, isSEWAware>;
}
}
-multiclass VPatConversionWF_VF<string intrinsic, string instruction> {
+multiclass VPatConversionWF_VF<string intrinsic, string instruction,
+ bit isSEWAware = 0> {
foreach fvtiToFWti = AllWidenableFloatVectors in {
defvar fvti = fvtiToFWti.Vti;
defvar fwti = fvtiToFWti.Wti;
@@ -5963,11 +5994,12 @@ multiclass VPatConversionWF_VF<string intrinsic, string instruction> {
GetVTypePredicates<fwti>.Predicates)) in
defm : VPatConversionTA<intrinsic, instruction, "V",
fwti.Vector, fvti.Vector, fwti.Mask, fvti.Log2SEW,
- fvti.LMul, fwti.RegClass, fvti.RegClass>;
+ fvti.LMul, fwti.RegClass, fvti.RegClass, isSEWAware>;
}
}
-multiclass VPatConversionWF_VF_BF <string intrinsic, string instruction> {
+multiclass VPatConversionWF_VF_BF <string intrinsic, string instruction,
+ bit isSEWAware = 0> {
foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in
{
defvar fvti = fvtiToFWti.Vti;
@@ -5976,7 +6008,7 @@ multiclass VPatConversionWF_VF_BF <string intrinsic, string instruction> {
GetVTypePredicates<fwti>.Predicates) in
defm : VPatConversionTA<intrinsic, instruction, "V",
fwti.Vector, fvti.Vector, fwti.Mask, fvti.Log2SEW,
- ...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
// expansion. | ||
unsigned CVTFOpc; | ||
if (Log2SEW == 4) { | ||
switch (LMul) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to add a SearchTable/SearchIndex for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I plan to commit each commit separate once approved.