[llvm] d04d645 - [RISCV] Add SchedRead for merge operand

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 13 12:30:47 PDT 2023


Author: Michael Maitland
Date: 2023-08-13T12:25:22-07:00
New Revision: d04d645f0eee10d9fe0ccdff9bd83212fb9dfc78

URL: https://github.com/llvm/llvm-project/commit/d04d645f0eee10d9fe0ccdff9bd83212fb9dfc78
DIFF: https://github.com/llvm/llvm-project/commit/d04d645f0eee10d9fe0ccdff9bd83212fb9dfc78.diff

LOG: [RISCV] Add SchedRead for merge operand

Prior to this patch, SchedReads were not modeled for instructions that
did not have a MASK suffix. This patch adds a SchedRead for all
instructions that have a merge operand.

@reames is doing work to fold TA and TU instructions into a single
instruction. This means that a single instruction may or may not
actually read the merge operand (TU must read merge operand). It is
possible that a TA instruction needs to read the merge operand, for
instance if TA is implemented as TU. Therefore, it makes sense to
represent the read of the merge operand for both TA and TU instructions.

In the case that a subtarget wants to model TA read different from TU
read, the subtarget should use a SchedVariant, which has access to the
MachineInstr.

Without this patch, the current SchedReads are off by one for
instructions that have a merge operand.

I am concerned is that `forceMergeOpRead` is passed to `SchedXXX`, but
the `SchedXXX` is not defined next to the ins and outs. This leads us to
walk the class hierarchy to determine whether `forceMergeOpRead` needs to be
be true. I worry that this will make this change harder to review, and
it may not be clear that `forceMergeOpRead` needs to be updated if any
future changes add or remove merge operands. I thought about moving the SchedXXX
definitions to where the ins and outs occur (as a seperate patch), but the
drawback of this is that we have to pass around lots of new arguments through
class heirarchies. One improvement on this is to use a single custom data
structure to pass through the heirarchies the eventually gets used by the
SchedXXX. If any reviewers care to share their own opinion on this concern, or
suggest a different solution to this concern, it would be greatly appreciated.
In any case, this concern is NFC.

Differential Revision: https://reviews.llvm.org/D157650

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfoV.td
    llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
index dbed51c779d9c2..45d5255e0244b9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
@@ -106,70 +106,77 @@ def simm5_plus1_nonzero : ImmLeaf<XLenVT,
 //                  in order.
 //   `reads`        SchedReads that are listed for each explicit use operand.
 //   `forceMasked`  Forced to be masked (e.g. Add-with-Carry Instructions).
+//   `forceMergeOpRead` Force to have read for merge operand.
 class SchedCommon<list<SchedWrite> writes, list<SchedRead> reads,
-                  string mx = "WorstCase", int sew = 0, bit forceMasked = 0>
-    : Sched<[]> {
+                  string mx = "WorstCase", int sew = 0, bit forceMasked = 0,
+                  bit forceMergeOpRead = 0> : Sched<[]> {
   defvar isMasked = !ne(!find(NAME, "_MASK"), -1);
   defvar isMaskedOrForceMasked = !or(forceMasked, isMasked);
-  defvar mergeOp = !if(!or(!eq(mx, "WorstCase"), !eq(sew, 0)),
+  defvar mergeRead = !if(!or(!eq(mx, "WorstCase"), !eq(sew, 0)),
                             !cast<SchedRead>("ReadVMergeOp_" # mx),
                             !cast<SchedRead>("ReadVMergeOp_" # mx # "_E" #sew));
-  defvar allReads = !if(isMaskedOrForceMasked,
-                        !listconcat([mergeOp], reads, [ReadVMask]),
-                        reads);
+  defvar needsMergeRead = !or(isMaskedOrForceMasked, forceMergeOpRead);
+  defvar readsWithMask =
+      !if(isMaskedOrForceMasked, !listconcat(reads, [ReadVMask]), reads);
+  defvar allReads =
+      !if(needsMergeRead, !listconcat([mergeRead], readsWithMask), reads);
   let SchedRW = !listconcat(writes, allReads);
 }
 
 // Common class of scheduling definitions for n-ary instructions.
 // The scheudling resources are relevant to LMUL and may be relevant to SEW.
-class SchedNary<string write, list<string> reads,
-                string mx, int sew = 0, bit forceMasked = 0>:
-  SchedCommon<[!cast<SchedWrite>(
-                 !if(sew, write # "_" # mx # "_E" # sew,
+class SchedNary<string write, list<string> reads, string mx, int sew = 0,
+                bit forceMasked = 0, bit forceMergeOpRead = 0>
+    : SchedCommon<[!cast<SchedWrite>(
+                      !if(sew,
+                          write # "_" # mx # "_E" # sew,
                           write # "_" # mx))],
-              !foreach(read, reads,
-                !cast<SchedRead>(
-                  !if(sew, read # "_" # mx # "_E" # sew,
-                           read # "_" # mx))),
-              mx, sew, forceMasked>;
+                  !foreach(read, reads,
+                           !cast<SchedRead>(!if(sew, read #"_" #mx #"_E" #sew,
+                                                 read #"_" #mx))),
+                  mx, sew, forceMasked, forceMergeOpRead>;
 
 // Classes with postfix "MC" are only used in MC layer.
 // For these classes, we assume that they are with the worst case costs and
 // `ReadVMask` is always needed (with some exceptions).
 
 // For instructions with no operand.
-class SchedNullary<string write, string mx, int sew = 0, bit forceMasked = 0>:
-  SchedNary<write, [], mx, sew, forceMasked>;
+class SchedNullary<string write, string mx, int sew = 0, bit forceMasked = 0,
+                   bit forceMergeOpRead = 0>:
+  SchedNary<write, [], mx, sew, forceMasked, forceMergeOpRead>;
 class SchedNullaryMC<string write, bit forceMasked = 1>:
   SchedNullary<write, "WorstCase", forceMasked=forceMasked>;
 
 // For instructions with one operand.
 class SchedUnary<string write, string read0, string mx, int sew = 0,
-                 bit forceMasked = 0>:
-  SchedNary<write, [read0], mx, sew, forceMasked>;
+                 bit forceMasked = 0, bit forceMergeOpRead = 0>:
+  SchedNary<write, [read0], mx, sew, forceMasked, forceMergeOpRead>;
 class SchedUnaryMC<string write, string read0, bit forceMasked = 1>:
   SchedUnary<write, read0, "WorstCase", forceMasked=forceMasked>;
 
 // For instructions with two operands.
-class SchedBinary<string write, string read0, string read1,
-                  string mx, int sew = 0, bit forceMasked = 0>:
-  SchedNary<write, [read0, read1], mx, sew, forceMasked>;
+class SchedBinary<string write, string read0, string read1, string mx,
+                  int sew = 0, bit forceMasked = 0, bit forceMergeOpRead = 0>
+    : SchedNary<write, [read0, read1], mx, sew, forceMasked, forceMergeOpRead>;
 class SchedBinaryMC<string write, string read0, string read1,
                     bit forceMasked = 1>:
   SchedBinary<write, read0, read1, "WorstCase", forceMasked=forceMasked>;
 
 // For instructions with three operands.
 class SchedTernary<string write, string read0, string read1, string read2,
-                   string mx, int sew = 0, bit forceMasked = 0>:
-  SchedNary<write, [read0, read1, read2], mx, sew, forceMasked>;
+                   string mx, int sew = 0, bit forceMasked = 0,
+                   bit forceMergeOpRead = 0>
+    : SchedNary<write, [read0, read1, read2], mx, sew, forceMasked,
+                forceMergeOpRead>;
 class SchedTernaryMC<string write, string read0, string read1, string read2,
                      int sew = 0, bit forceMasked = 1>:
   SchedNary<write, [read0, read1, read2], "WorstCase", sew, forceMasked>;
 
 // For reduction instructions.
-class SchedReduction<string write, string read, string mx, int sew>:
-  SchedCommon<[!cast<SchedWrite>(write # "_" # mx # "_E" # sew)],
-              !listsplat(!cast<SchedRead>(read), 3), mx, sew>;
+class SchedReduction<string write, string read, string mx, int sew,
+                     bit forceMergeOpRead = 0>
+    : SchedCommon<[!cast<SchedWrite>(write #"_" #mx #"_E" #sew)],
+                  !listsplat(!cast<SchedRead>(read), 3), mx, sew, forceMergeOpRead>;
 class SchedReductionMC<string write, string readV, string readV0>:
   SchedCommon<[!cast<SchedWrite>(write # "_WorstCase")],
               [!cast<SchedRead>(readV), !cast<SchedRead>(readV0)],

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
index dce03b6a52cfac..f16ae08e5931ec 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td
@@ -1900,9 +1900,9 @@ multiclass VPseudoVPOP_M {
     defvar mx = mti.LMul.MX;
     let VLMul = mti.LMul.value in {
       def "_M_" # mti.BX : VPseudoUnaryNoMaskGPROut,
-                           SchedBinary<"WriteVMPopV", "ReadVMPopV", "ReadVMPopV", mx>;
+          SchedBinary<"WriteVMPopV", "ReadVMPopV", "ReadVMPopV", mx>;
       def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMaskGPROut,
-                                     SchedBinary<"WriteVMPopV", "ReadVMPopV", "ReadVMPopV", mx>;
+          SchedBinary<"WriteVMPopV", "ReadVMPopV", "ReadVMPopV", mx>;
     }
   }
 }
@@ -1911,10 +1911,10 @@ multiclass VPseudoV1ST_M {
   foreach mti = AllMasks in {
     defvar mx = mti.LMul.MX;
     let VLMul = mti.LMul.value in {
-      def "_M_" # mti.BX : VPseudoUnaryNoMaskGPROut,
-                           SchedBinary<"WriteVMFFSV", "ReadVMFFSV", "ReadVMFFSV", mx>;
+      def "_M_" #mti.BX : VPseudoUnaryNoMaskGPROut,
+          SchedBinary<"WriteVMFFSV", "ReadVMFFSV", "ReadVMFFSV", mx>;
       def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMaskGPROut,
-                                     SchedBinary<"WriteVMFFSV", "ReadVMFFSV", "ReadVMFFSV", mx>;
+          SchedBinary<"WriteVMFFSV", "ReadVMFFSV", "ReadVMFFSV", mx>;
     }
   }
 }
@@ -1925,9 +1925,11 @@ multiclass VPseudoVSFS_M {
     defvar mx = mti.LMul.MX;
     let VLMul = mti.LMul.value in {
       def "_M_" # mti.BX : VPseudoUnaryNoMask<VR, VR, constraint>,
-                           SchedUnary<"WriteVMSFSV", "ReadVMSFSV", mx>;
+                           SchedUnary<"WriteVMSFSV", "ReadVMSFSV", mx,
+                                      forceMergeOpRead=true>;
       def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMask<VR, VR, constraint>,
-                                     SchedUnary<"WriteVMSFSV", "ReadVMSFSV", mx>;
+                                     SchedUnary<"WriteVMSFSV", "ReadVMSFSV", mx,
+                                                forceMergeOpRead=true>;
     }
   }
 }
@@ -1937,10 +1939,11 @@ multiclass VPseudoVID_V {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_V_" # mx : VPseudoNullaryNoMask<m.vrclass>,
-                         SchedNullary<"WriteVMIdxV", mx>;
+                         SchedNullary<"WriteVMIdxV", mx, forceMergeOpRead=true>;
       def "_V_" # mx # "_MASK" : VPseudoNullaryMask<m.vrclass>,
                                    RISCVMaskedPseudo<MaskIdx=1>,
-                                   SchedNullary<"WriteVMIdxV", mx>;
+                                   SchedNullary<"WriteVMIdxV", mx,
+                                                forceMergeOpRead=true>;
     }
   }
 }
@@ -1960,10 +1963,12 @@ multiclass VPseudoVIOT_M {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_" # mx : VPseudoUnaryNoMask<m.vrclass, VR, constraint>,
-                       SchedUnary<"WriteVMIotV", "ReadVMIotV", mx>;
+                       SchedUnary<"WriteVMIotV", "ReadVMIotV", mx,
+                                  forceMergeOpRead=true>;
       def "_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, VR, constraint>,
                                  RISCVMaskedPseudo<MaskIdx=2>,
-                                 SchedUnary<"WriteVMIotV", "ReadVMIotV", mx>;
+                                 SchedUnary<"WriteVMIotV", "ReadVMIotV", mx,
+                                            forceMergeOpRead=true>;
     }
   }
 }
@@ -1976,9 +1981,10 @@ multiclass VPseudoVCPR_V {
       foreach e = sews in {
         defvar suffix = "_" # m.MX # "_E" # e;
         let SEW = e in
-        def _VM # suffix : VPseudoUnaryAnyMask<m.vrclass, m.vrclass>,
-                           SchedBinary<"WriteVCompressV", "ReadVCompressV", "ReadVCompressV",
-                                       mx, e>;
+        def _VM # suffix
+          : VPseudoUnaryAnyMask<m.vrclass, m.vrclass>,
+            SchedBinary<"WriteVCompressV", "ReadVCompressV", "ReadVCompressV",
+                        mx, e>;
       }
   }
 }
@@ -2121,9 +2127,11 @@ multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> {
         defvar emul = !cast<LMULInfo>("V_" # emulMX);
         defvar sews = SchedSEWSet<mx>.val;
         foreach e = sews in {
-          defm _VV : VPseudoBinaryEmul<m.vrclass, m.vrclass, emul.vrclass, m, emul, Constraint, e>,
-                     SchedBinary<"WriteVRGatherVV", "ReadVRGatherVV_data", "ReadVRGatherVV_index",
-                                 mx, e>;
+          defm _VV
+              : VPseudoBinaryEmul<m.vrclass, m.vrclass, emul.vrclass, m, emul,
+                                  Constraint, e>,
+                SchedBinary<"WriteVRGatherVV", "ReadVRGatherVV_data",
+                            "ReadVRGatherVV_index", mx, e, forceMergeOpRead=true>;
         }
       }
     }
@@ -2141,7 +2149,8 @@ multiclass VPseudoBinaryV_VX_RM<LMULInfo m, string Constraint = ""> {
 multiclass VPseudoVSLD1_VX<string Constraint = ""> {
   foreach m = MxList in {
     defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>,
-                 SchedBinary<"WriteVISlide1X", "ReadVISlideV", "ReadVISlideX", m.MX>;
+                 SchedBinary<"WriteVISlide1X", "ReadVISlideV", "ReadVISlideX",
+                             m.MX, forceMergeOpRead=true>;
   }
 }
 
@@ -2159,9 +2168,10 @@ multiclass VPseudoBinaryV_VF_RM<LMULInfo m, FPR_Info f, string Constraint = "",
 multiclass VPseudoVSLD1_VF<string Constraint = ""> {
   foreach f = FPList in {
     foreach m = f.MxList in {
-      defm "_V" # f.FX :
-        VPseudoBinary<m.vrclass, m.vrclass, f.fprclass, m, Constraint>,
-        SchedBinary<"WriteVFSlide1F", "ReadVFSlideV", "ReadVFSlideF", m.MX>;
+      defm "_V" #f.FX
+          : VPseudoBinary<m.vrclass, m.vrclass, f.fprclass, m, Constraint>,
+            SchedBinary<"WriteVFSlide1F", "ReadVFSlideV", "ReadVFSlideF", m.MX,
+                      forceMergeOpRead=true>;
     }
   }
 }
@@ -2179,7 +2189,7 @@ multiclass VPseudoVALU_MM {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_MM_" # mx : VPseudoBinaryNoMask<VR, VR, VR, "">,
-                          SchedBinary<"WriteVMALUV", "ReadVMALUV", "ReadVMALUV", mx>;
+                        SchedBinary<"WriteVMALUV", "ReadVMALUV", "ReadVMALUV", mx>;
     }
   }
 }
@@ -2328,10 +2338,12 @@ multiclass VPseudoVMRG_FM {
   foreach f = FPList in {
     foreach m = f.MxList in {
       defvar mx = m.MX;
-      def "_V" # f.FX # "M_" # mx:
-        VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
-                                 m.vrclass, f.fprclass, m, CarryIn=1, Constraint="">,
-        SchedBinary<"WriteVFMergeV", "ReadVFMergeV", "ReadVFMergeF", mx, forceMasked=1>;
+      def "_V" # f.FX # "M_" # mx
+          : VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, m.vrclass,
+                                     f.fprclass, m, CarryIn=1,
+                                     Constraint = "">,
+          SchedBinary<"WriteVFMergeV", "ReadVFMergeV", "ReadVFMergeF", mx,
+                      forceMasked=1, forceMergeOpRead=true>;
     }
   }
 }
@@ -2357,11 +2369,14 @@ multiclass VPseudoUnaryVMV_V_X_I {
       defvar mx = m.MX;
       let VLMul = m.value in {
         def "_V_" # mx : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
-                         SchedUnary<"WriteVIMovV", "ReadVIMovV", mx>;
+                         SchedUnary<"WriteVIMovV", "ReadVIMovV", mx,
+                                    forceMergeOpRead=true>;
         def "_X_" # mx : VPseudoUnaryNoMask<m.vrclass, GPR>,
-                         SchedUnary<"WriteVIMovX", "ReadVIMovX", mx>;
+                         SchedUnary<"WriteVIMovX", "ReadVIMovX", mx,
+                                    forceMergeOpRead=true>;
         def "_I_" # mx : VPseudoUnaryNoMask<m.vrclass, simm5>,
-                         SchedNullary<"WriteVIMovI", mx>;
+                         SchedNullary<"WriteVIMovI", mx,
+                                      forceMergeOpRead=true>;
       }
     }
   }
@@ -2374,7 +2389,7 @@ multiclass VPseudoVMV_F {
       let VLMul = m.value in {
         def "_" # f.FX # "_" # mx :
           VPseudoUnaryNoMask<m.vrclass, f.fprclass>,
-          SchedUnary<"WriteVFMovV", "ReadVFMovF", mx>;
+          SchedUnary<"WriteVFMovV", "ReadVFMovF", mx, forceMergeOpRead=true>;
       }
     }
   }
@@ -2385,10 +2400,12 @@ multiclass VPseudoVCLS_V {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_V_" # mx : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
-                       SchedUnary<"WriteVFClassV", "ReadVFClassV", mx>;
+                       SchedUnary<"WriteVFClassV", "ReadVFClassV", mx,
+                                  forceMergeOpRead=true>;
       def "_V_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, m.vrclass>,
                                  RISCVMaskedPseudo<MaskIdx=2>,
-                                 SchedUnary<"WriteVFClassV", "ReadVFClassV", mx>;
+                                 SchedUnary<"WriteVFClassV", "ReadVFClassV", mx,
+                                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2403,10 +2420,13 @@ multiclass VPseudoVSQR_V_RM {
         defvar suffix = "_" # mx # "_E" # e;
         let SEW = e in {
           def "_V" # suffix : VPseudoUnaryNoMaskRoundingMode<m.vrclass, m.vrclass>,
-                              SchedUnary<"WriteVFSqrtV", "ReadVFSqrtV", mx, e>;
-          def "_V" # suffix # "_MASK" : VPseudoUnaryMaskRoundingMode<m.vrclass, m.vrclass>,
-                                        RISCVMaskedPseudo<MaskIdx=2>,
-                                        SchedUnary<"WriteVFSqrtV", "ReadVFSqrtV", mx, e>;
+                              SchedUnary<"WriteVFSqrtV", "ReadVFSqrtV", mx, e,
+                                         forceMergeOpRead=true>;
+          def "_V" #suffix # "_MASK"
+              : VPseudoUnaryMaskRoundingMode<m.vrclass, m.vrclass>,
+                RISCVMaskedPseudo<MaskIdx = 2>,
+                SchedUnary<"WriteVFSqrtV", "ReadVFSqrtV", mx, e,
+                           forceMergeOpRead=true>;
         }
       }
   }
@@ -2416,11 +2436,13 @@ multiclass VPseudoVRCP_V {
   foreach m = MxListF in {
     defvar mx = m.MX;
     let VLMul = m.value in {
-      def "_V_" # mx : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
-                         SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx>;
-      def "_V_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, m.vrclass>,
-                                 RISCVMaskedPseudo<MaskIdx=2>,
-                                 SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx>;
+      def "_V_" # mx
+          : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
+            SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>;
+      def "_V_" # mx # "_MASK"
+          : VPseudoUnaryMask<m.vrclass, m.vrclass>,
+            RISCVMaskedPseudo<MaskIdx = 2>,
+            SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>;
     }
   }
 }
@@ -2429,11 +2451,13 @@ multiclass VPseudoVRCP_V_RM {
   foreach m = MxListF in {
     defvar mx = m.MX;
     let VLMul = m.value in {
-      def "_V_" # mx : VPseudoUnaryNoMaskRoundingMode<m.vrclass, m.vrclass>,
-                         SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx>;
-      def "_V_" # mx # "_MASK" : VPseudoUnaryMaskRoundingMode<m.vrclass, m.vrclass>,
-                                 RISCVMaskedPseudo<MaskIdx=2>,
-                                 SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx>;
+      def "_V_" # mx
+          : VPseudoUnaryNoMaskRoundingMode<m.vrclass, m.vrclass>,
+            SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>;
+      def "_V_" # mx # "_MASK"
+          : VPseudoUnaryMaskRoundingMode<m.vrclass, m.vrclass>,
+            RISCVMaskedPseudo<MaskIdx = 2>,
+            SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>;
     }
   }
 }
@@ -2444,11 +2468,11 @@ multiclass PseudoVEXT_VF2 {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_" # mx : VPseudoUnaryNoMask<m.vrclass, m.f2vrclass, constraints>,
-                     SchedUnary<"WriteVExtV", "ReadVExtV", mx>;
+                     SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>;
       def "_" # mx # "_MASK" :
         VPseudoUnaryMask<m.vrclass, m.f2vrclass, constraints>,
         RISCVMaskedPseudo<MaskIdx=2>,
-        SchedUnary<"WriteVExtV", "ReadVExtV", mx>;
+        SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>;
     }
   }
 }
@@ -2459,11 +2483,11 @@ multiclass PseudoVEXT_VF4 {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_" # mx : VPseudoUnaryNoMask<m.vrclass, m.f4vrclass, constraints>,
-                     SchedUnary<"WriteVExtV", "ReadVExtV", mx>;
+                     SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>;
       def "_" # mx # "_MASK" :
         VPseudoUnaryMask<m.vrclass, m.f4vrclass, constraints>,
         RISCVMaskedPseudo<MaskIdx=2>,
-        SchedUnary<"WriteVExtV", "ReadVExtV", mx>;
+        SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>;
     }
   }
 }
@@ -2474,11 +2498,11 @@ multiclass PseudoVEXT_VF8 {
     defvar mx = m.MX;
     let VLMul = m.value in {
       def "_" # mx : VPseudoUnaryNoMask<m.vrclass, m.f8vrclass, constraints>,
-                     SchedUnary<"WriteVExtV", "ReadVExtV", mx>;
+                     SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>;
       def "_" # mx # "_MASK" :
         VPseudoUnaryMask<m.vrclass, m.f8vrclass, constraints>,
         RISCVMaskedPseudo<MaskIdx=2>,
-        SchedUnary<"WriteVExtV", "ReadVExtV", mx>;
+        SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>;
     }
   }
 }
@@ -2521,15 +2545,16 @@ multiclass VPseudoVGTR_VV_VX_VI<Operand ImmType = simm5, string Constraint = "">
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VX<m, Constraint>,
               SchedBinary<"WriteVRGatherVX", "ReadVRGatherVX_data",
-                          "ReadVRGatherVX_index", mx>;
+                          "ReadVRGatherVX_index", mx, forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>,
-              SchedUnary<"WriteVRGatherVI", "ReadVRGatherVI_data", mx>;
+              SchedUnary<"WriteVRGatherVI", "ReadVRGatherVI_data", mx,
+                         forceMergeOpRead=true>;
 
     defvar sews = SchedSEWSet<mx>.val;
     foreach e = sews in {
       defm "" : VPseudoBinaryV_VV<m, Constraint, e>,
                 SchedBinary<"WriteVRGatherVV", "ReadVRGatherVV_data",
-                              "ReadVRGatherVV_index", mx, e>;
+                              "ReadVRGatherVV_index", mx, e, forceMergeOpRead=true>;
     }
   }
 }
@@ -2538,11 +2563,13 @@ multiclass VPseudoVSALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV<m, Constraint>,
-              SchedBinary<"WriteVSALUV", "ReadVSALUV", "ReadVSALUX", mx>;
+              SchedBinary<"WriteVSALUV", "ReadVSALUV", "ReadVSALUX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX<m, Constraint>,
-              SchedBinary<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX", mx>;
+              SchedBinary<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>,
-              SchedUnary<"WriteVSALUI", "ReadVSALUV", mx>;
+              SchedUnary<"WriteVSALUI", "ReadVSALUV", mx, forceMergeOpRead=true>;
   }
 }
 
@@ -2551,11 +2578,13 @@ multiclass VPseudoVSHT_VV_VX_VI<Operand ImmType = simm5, string Constraint = "">
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV<m, Constraint>,
-              SchedBinary<"WriteVShiftV", "ReadVShiftV", "ReadVShiftV", mx>;
+              SchedBinary<"WriteVShiftV", "ReadVShiftV", "ReadVShiftV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX<m, Constraint>,
-              SchedBinary<"WriteVShiftX", "ReadVShiftV", "ReadVShiftX", mx>;
+              SchedBinary<"WriteVShiftX", "ReadVShiftV", "ReadVShiftX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>,
-              SchedUnary<"WriteVShiftI", "ReadVShiftV", mx>;
+              SchedUnary<"WriteVShiftI", "ReadVShiftV", mx, forceMergeOpRead=true>;
   }
 }
 
@@ -2563,11 +2592,13 @@ multiclass VPseudoVSSHT_VV_VX_VI_RM<Operand ImmType = simm5, string Constraint =
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV_RM<m, Constraint>,
-              SchedBinary<"WriteVSShiftV", "ReadVSShiftV", "ReadVSShiftV", mx>;
+              SchedBinary<"WriteVSShiftV", "ReadVSShiftV", "ReadVSShiftV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX_RM<m, Constraint>,
-              SchedBinary<"WriteVSShiftX", "ReadVSShiftV", "ReadVSShiftX", mx>;
+              SchedBinary<"WriteVSShiftX", "ReadVSShiftV", "ReadVSShiftX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VI_RM<ImmType, m, Constraint>,
-              SchedUnary<"WriteVSShiftI", "ReadVSShiftV", mx>;
+              SchedUnary<"WriteVSShiftI", "ReadVSShiftV", mx, forceMergeOpRead=true>;
   }
 }
 
@@ -2575,11 +2606,13 @@ multiclass VPseudoVALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = "">
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV<m, Constraint>,
-            SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", mx>;
+            SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", mx,
+                        forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX<m, Constraint>,
-            SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx>;
+            SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx,
+                        forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>,
-            SchedUnary<"WriteVIALUI", "ReadVIALUV", mx>;
+            SchedUnary<"WriteVIALUI", "ReadVIALUV", mx, forceMergeOpRead=true>;
   }
 }
 
@@ -2587,9 +2620,11 @@ multiclass VPseudoVSALU_VV_VX {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV<m>,
-              SchedBinary<"WriteVSALUV", "ReadVSALUV", "ReadVSALUV", mx>;
+              SchedBinary<"WriteVSALUV", "ReadVSALUV", "ReadVSALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX<m>,
-              SchedBinary<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX", mx>;
+              SchedBinary<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2597,9 +2632,11 @@ multiclass VPseudoVSMUL_VV_VX_RM {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV_RM<m>,
-              SchedBinary<"WriteVSMulV", "ReadVSMulV", "ReadVSMulV", mx>;
+              SchedBinary<"WriteVSMulV", "ReadVSMulV", "ReadVSMulV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX_RM<m>,
-              SchedBinary<"WriteVSMulX", "ReadVSMulV", "ReadVSMulX", mx>;
+              SchedBinary<"WriteVSMulX", "ReadVSMulV", "ReadVSMulX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2607,9 +2644,11 @@ multiclass VPseudoVAALU_VV_VX_RM {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VV_RM<m>,
-              SchedBinary<"WriteVAALUV", "ReadVAALUV", "ReadVAALUV", mx>;
+              SchedBinary<"WriteVAALUV", "ReadVAALUV", "ReadVAALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX_RM<m>,
-              SchedBinary<"WriteVAALUX", "ReadVAALUV", "ReadVAALUX", mx>;
+              SchedBinary<"WriteVAALUX", "ReadVAALUV", "ReadVAALUX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2649,13 +2688,15 @@ multiclass VPseudoVDIV_VV_VX {
 multiclass VPseudoVFMUL_VV_VF_RM {
   foreach m = MxListF in {
     defm "" : VPseudoBinaryFV_VV_RM<m>,
-              SchedBinary<"WriteVFMulV", "ReadVFMulV", "ReadVFMulV", m.MX>;
+              SchedBinary<"WriteVFMulV", "ReadVFMulV", "ReadVFMulV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF_RM<m, f>,
-                SchedBinary<"WriteVFMulF", "ReadVFMulV", "ReadVFMulF", m.MX>;
+                SchedBinary<"WriteVFMulF", "ReadVFMulV", "ReadVFMulF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2666,14 +2707,16 @@ multiclass VPseudoVFDIV_VV_VF_RM {
     defvar sews = SchedSEWSet<mx, isF=1>.val;
     foreach e = sews in {
       defm "" : VPseudoBinaryFV_VV_RM<m, "", e>,
-                SchedBinary<"WriteVFDivV", "ReadVFDivV", "ReadVFDivV", mx, e>;
+                SchedBinary<"WriteVFDivV", "ReadVFDivV", "ReadVFDivV", mx, e,
+                            forceMergeOpRead=true>;
     }
   }
 
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF_RM<m, f, "", f.SEW>,
-                SchedBinary<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF", m.MX, f.SEW>;
+                SchedBinary<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF", m.MX, f.SEW,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2682,7 +2725,8 @@ multiclass VPseudoVFRDIV_VF_RM {
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF_RM<m, f, "", f.SEW>,
-                SchedBinary<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF", m.MX, f.SEW>;
+                SchedBinary<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF", m.MX, f.SEW,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2690,22 +2734,26 @@ multiclass VPseudoVFRDIV_VF_RM {
 multiclass VPseudoVALU_VV_VX {
  foreach m = MxList in {
     defm "" : VPseudoBinaryV_VV<m>,
-            SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", m.MX>;
+            SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", m.MX,
+                        forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VX<m>,
-            SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", m.MX>;
+            SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", m.MX,
+                        forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVSGNJ_VV_VF {
   foreach m = MxListF in {
     defm "" : VPseudoBinaryFV_VV<m>,
-              SchedBinary<"WriteVFSgnjV", "ReadVFSgnjV", "ReadVFSgnjV", m.MX>;
+              SchedBinary<"WriteVFSgnjV", "ReadVFSgnjV", "ReadVFSgnjV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF<m, f>,
-                SchedBinary<"WriteVFSgnjF", "ReadVFSgnjV", "ReadVFSgnjF", m.MX>;
+                SchedBinary<"WriteVFSgnjF", "ReadVFSgnjV", "ReadVFSgnjF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2713,13 +2761,15 @@ multiclass VPseudoVSGNJ_VV_VF {
 multiclass VPseudoVMAX_VV_VF {
   foreach m = MxListF in {
     defm "" : VPseudoBinaryFV_VV<m>,
-              SchedBinary<"WriteVFMinMaxV", "ReadVFMinMaxV", "ReadVFMinMaxV", m.MX>;
+              SchedBinary<"WriteVFMinMaxV", "ReadVFMinMaxV", "ReadVFMinMaxV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF<m, f>,
-                SchedBinary<"WriteVFMinMaxF", "ReadVFMinMaxV", "ReadVFMinMaxF", m.MX>;
+                SchedBinary<"WriteVFMinMaxF", "ReadVFMinMaxV", "ReadVFMinMaxF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2727,13 +2777,15 @@ multiclass VPseudoVMAX_VV_VF {
 multiclass VPseudoVALU_VV_VF {
   foreach m = MxListF in {
     defm "" : VPseudoBinaryFV_VV<m>,
-              SchedBinary<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV", m.MX>;
+              SchedBinary<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF<m, f>,
-                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX>;
+                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2741,13 +2793,15 @@ multiclass VPseudoVALU_VV_VF {
 multiclass VPseudoVALU_VV_VF_RM {
   foreach m = MxListF in {
     defm "" : VPseudoBinaryFV_VV_RM<m>,
-              SchedBinary<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV", m.MX>;
+              SchedBinary<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF_RM<m, f>,
-                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX>;
+                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2756,7 +2810,8 @@ multiclass VPseudoVALU_VF {
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF<m, f>,
-                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX>;
+                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2765,7 +2820,8 @@ multiclass VPseudoVALU_VF_RM {
   foreach f = FPList in {
     foreach m = f.MxList in {
       defm "" : VPseudoBinaryV_VF_RM<m, f>,
-                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX>;
+                SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX,
+                            forceMergeOpRead=true>;
     }
   }
 }
@@ -2774,9 +2830,10 @@ multiclass VPseudoVALU_VX_VI<Operand ImmType = simm5> {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VX<m>,
-              SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx>;
+              SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_VI<ImmType, m>,
-              SchedUnary<"WriteVIALUI", "ReadVIALUV", mx>;
+              SchedUnary<"WriteVIALUI", "ReadVIALUV", mx, forceMergeOpRead=true>;
   }
 }
 
@@ -2784,9 +2841,11 @@ multiclass VPseudoVWALU_VV_VX {
   foreach m = MxListW in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryW_VV<m>,
-              SchedBinary<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV", mx>;
+              SchedBinary<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryW_VX<m>,
-              SchedBinary<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX", mx>;
+              SchedBinary<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2800,22 +2859,26 @@ multiclass VPseudoVWMUL_VV_VX {
   foreach m = MxListW in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryW_VV<m>,
-              SchedBinary<"WriteVIWMulV", "ReadVIWMulV", "ReadVIWMulV", mx>;
+              SchedBinary<"WriteVIWMulV", "ReadVIWMulV", "ReadVIWMulV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryW_VX<m>,
-              SchedBinary<"WriteVIWMulX", "ReadVIWMulV", "ReadVIWMulX", mx>;
+              SchedBinary<"WriteVIWMulX", "ReadVIWMulV", "ReadVIWMulX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVWMUL_VV_VF_RM {
   foreach m = MxListFW in {
     defm "" : VPseudoBinaryW_VV_RM<m>,
-              SchedBinary<"WriteVFWMulV", "ReadVFWMulV", "ReadVFWMulV", m.MX>;
+              SchedBinary<"WriteVFWMulV", "ReadVFWMulV", "ReadVFWMulV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPListW in {
     foreach m = f.MxListFW in {
       defm "" : VPseudoBinaryW_VF_RM<m, f>,
-                SchedBinary<"WriteVFWMulF", "ReadVFWMulV", "ReadVFWMulF", m.MX>;
+                SchedBinary<"WriteVFWMulF", "ReadVFWMulV", "ReadVFWMulF", m.MX,
+                          forceMergeOpRead=true>;
     }
   }
 }
@@ -2824,22 +2887,26 @@ multiclass VPseudoVWALU_WV_WX {
   foreach m = MxListW in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryW_WV<m>,
-              SchedBinary<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV", mx>;
+              SchedBinary<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryW_WX<m>,
-              SchedBinary<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX", mx>;
+              SchedBinary<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVFWALU_VV_VF_RM {
   foreach m = MxListFW in {
     defm "" : VPseudoBinaryW_VV_RM<m>,
-              SchedBinary<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV", m.MX>;
+              SchedBinary<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV", m.MX,
+                          forceMergeOpRead=true>;
   }
 
   foreach f = FPListW in {
     foreach m = f.MxListFW in {
       defm "" : VPseudoBinaryW_VF_RM<m, f>,
-                SchedBinary<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF", m.MX>;
+                SchedBinary<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF", m.MX,
+                          forceMergeOpRead=true>;
     }
   }
 }
@@ -2847,12 +2914,14 @@ multiclass VPseudoVFWALU_VV_VF_RM {
 multiclass VPseudoVFWALU_WV_WF_RM {
   foreach m = MxListFW in {
     defm "" : VPseudoBinaryW_WV_RM<m>,
-              SchedBinary<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV", m.MX>;
+              SchedBinary<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV", m.MX,
+                          forceMergeOpRead=true>;
   }
   foreach f = FPListW in {
     foreach m = f.MxListFW in {
       defm "" : VPseudoBinaryW_WF_RM<m, f>,
-                SchedBinary<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF", m.MX>;
+                SchedBinary<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF", m.MX,
+                          forceMergeOpRead=true>;
     }
   }
 }
@@ -2863,15 +2932,18 @@ multiclass VPseudoVMRG_VM_XM_IM {
     def "_VVM" # "_" # m.MX:
       VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
                                m.vrclass, m.vrclass, m, 1, "">,
-      SchedBinary<"WriteVIMergeV", "ReadVIMergeV", "ReadVIMergeV", mx>;
+      SchedBinary<"WriteVIMergeV", "ReadVIMergeV", "ReadVIMergeV", mx,
+                          forceMergeOpRead=true>;
     def "_VXM" # "_" # m.MX:
       VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
                                m.vrclass, GPR, m, 1, "">,
-      SchedBinary<"WriteVIMergeX", "ReadVIMergeV", "ReadVIMergeX", mx>;
+      SchedBinary<"WriteVIMergeX", "ReadVIMergeV", "ReadVIMergeX", mx,
+                          forceMergeOpRead=true>;
     def "_VIM" # "_" # m.MX:
       VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
                                m.vrclass, simm5, m, 1, "">,
-      SchedUnary<"WriteVIMergeI", "ReadVIMergeV", mx>;
+      SchedUnary<"WriteVIMergeI", "ReadVIMergeV", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2879,11 +2951,14 @@ multiclass VPseudoVCALU_VM_XM_IM {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoTiedBinaryV_VM<m>,
-              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx>;
+              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoTiedBinaryV_XM<m>,
-              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx>;
+              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoTiedBinaryV_IM<m>,
-              SchedUnary<"WriteVICALUI", "ReadVICALUV", mx>;
+              SchedUnary<"WriteVICALUI", "ReadVICALUV", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2891,9 +2966,11 @@ multiclass VPseudoVCALU_VM_XM {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoTiedBinaryV_VM<m>,
-              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx>;
+              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoTiedBinaryV_XM<m>,
-              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx>;
+              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2901,11 +2978,14 @@ multiclass VPseudoVCALUM_VM_XM_IM<string Constraint> {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=1, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, forceMasked=1>;
+              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, forceMasked=1,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=1, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, forceMasked=1>;
+              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, forceMasked=1,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_IM<m, CarryOut=1, CarryIn=1, Constraint=Constraint>,
-              SchedUnary<"WriteVICALUI", "ReadVICALUV", mx, forceMasked=1>;
+              SchedUnary<"WriteVICALUI", "ReadVICALUV", mx, forceMasked=1,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2913,9 +2993,11 @@ multiclass VPseudoVCALUM_VM_XM<string Constraint> {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=1, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, forceMasked=1>;
+              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, forceMasked=1,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=1, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, forceMasked=1>;
+              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, forceMasked=1,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2923,11 +3005,14 @@ multiclass VPseudoVCALUM_V_X_I<string Constraint> {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=0, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx>;
+              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=0, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx>;
+              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_IM<m, CarryOut=1, CarryIn=0, Constraint=Constraint>,
-              SchedUnary<"WriteVICALUI", "ReadVICALUV", mx>;
+              SchedUnary<"WriteVICALUI", "ReadVICALUV", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2935,9 +3020,11 @@ multiclass VPseudoVCALUM_V_X<string Constraint> {
   foreach m = MxList in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=0, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx>;
+              SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=0, Constraint=Constraint>,
-              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx>;
+              SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2945,11 +3032,14 @@ multiclass VPseudoVNCLP_WV_WX_WI_RM {
   foreach m = MxListW in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_WV_RM<m>,
-              SchedBinary<"WriteVNClipV", "ReadVNClipV", "ReadVNClipV", mx>;
+              SchedBinary<"WriteVNClipV", "ReadVNClipV", "ReadVNClipV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_WX_RM<m>,
-              SchedBinary<"WriteVNClipX", "ReadVNClipV", "ReadVNClipX", mx>;
+              SchedBinary<"WriteVNClipX", "ReadVNClipV", "ReadVNClipX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_WI_RM<m>,
-              SchedUnary<"WriteVNClipI", "ReadVNClipV", mx>;
+              SchedUnary<"WriteVNClipI", "ReadVNClipV", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -2957,11 +3047,14 @@ multiclass VPseudoVNSHT_WV_WX_WI {
   foreach m = MxListW in {
     defvar mx = m.MX;
     defm "" : VPseudoBinaryV_WV<m>,
-              SchedBinary<"WriteVNShiftV", "ReadVNShiftV", "ReadVNShiftV", mx>;
+              SchedBinary<"WriteVNShiftV", "ReadVNShiftV", "ReadVNShiftV", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_WX<m>,
-              SchedBinary<"WriteVNShiftX", "ReadVNShiftV", "ReadVNShiftX", mx>;
+              SchedBinary<"WriteVNShiftX", "ReadVNShiftV", "ReadVNShiftX", mx,
+                          forceMergeOpRead=true>;
     defm "" : VPseudoBinaryV_WI<m>,
-              SchedUnary<"WriteVNShiftI", "ReadVNShiftV", mx>;
+              SchedUnary<"WriteVNShiftI", "ReadVNShiftV", mx,
+                          forceMergeOpRead=true>;
   }
 }
 
@@ -3205,7 +3298,7 @@ multiclass VPseudoVWMAC_VV_VF_BF_RM {
     defvar mx = m.MX;
     defvar WriteVFWMulAddV_MX = !cast<SchedWrite>("WriteVFWMulAddV_" # mx);
     defvar ReadVFWMulAddV_MX = !cast<SchedRead>("ReadVFWMulAddV_" # mx);
-
+    // FIXME: should use SchedTernary
     defm "" : VPseudoTernaryW_VV_RM<m>,
               Sched<[WriteVFWMulAddV_MX, ReadVFWMulAddV_MX,
                      ReadVFWMulAddV_MX, ReadVFWMulAddV_MX, ReadVMask]>;
@@ -3218,6 +3311,7 @@ multiclass VPseudoVWMAC_VV_VF_BF_RM {
       defvar ReadVFWMulAddV_MX = !cast<SchedRead>("ReadVFWMulAddV_" # mx);
       defvar ReadVFWMulAddF_MX = !cast<SchedRead>("ReadVFWMulAddF_" # mx);
 
+      // FIXME: should use SchedTernary
       defm "" : VPseudoTernaryW_VF_RM<m, f>,
                 Sched<[WriteVFWMulAddF_MX, ReadVFWMulAddV_MX,
                        ReadVFWMulAddF_MX, ReadVFWMulAddV_MX, ReadVMask]>;
@@ -3405,42 +3499,48 @@ multiclass VPseudoConversionNoExcept<VReg RetClass,
 multiclass VPseudoVCVTI_V {
   foreach m = MxListF in {
     defm _V : VPseudoConversion<m.vrclass, m.vrclass, m>,
-              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVCVTI_V_RM {
   foreach m = MxListF in {
     defm _V : VPseudoConversionRoundingMode<m.vrclass, m.vrclass, m>,
-              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVCVTI_RM_V {
   foreach m = MxListF in {
     defm _V : VPseudoConversionRM<m.vrclass, m.vrclass, m>,
-              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVFROUND_NOEXCEPT_V {
   foreach m = MxListF in {
     defm _V : VPseudoConversionNoExcept<m.vrclass, m.vrclass, m>,
-              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVCVTF_V_RM {
   foreach m = MxListF in {
     defm _V : VPseudoConversionRoundingMode<m.vrclass, m.vrclass, m>,
-              SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX>;
+              SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
 multiclass VPseudoVCVTF_RM_V {
   foreach m = MxListF in {
     defm _V : VPseudoConversionRM<m.vrclass, m.vrclass, m>,
-              SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX>;
+              SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3448,7 +3548,8 @@ multiclass VPseudoVWCVTI_V {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>,
-              SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3456,7 +3557,8 @@ multiclass VPseudoVWCVTI_V_RM {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _V : VPseudoConversionRoundingMode<m.wvrclass, m.vrclass, m, constraint>,
-              SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3464,7 +3566,8 @@ multiclass VPseudoVWCVTI_RM_V {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _V : VPseudoConversionRM<m.wvrclass, m.vrclass, m, constraint>,
-              SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3472,7 +3575,8 @@ multiclass VPseudoVWCVTF_V {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListW in {
     defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>,
-              SchedUnary<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV", m.MX>;
+              SchedUnary<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3480,7 +3584,8 @@ multiclass VPseudoVWCVTD_V {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>,
-              SchedUnary<"WriteVFWCvtFToFV", "ReadVFWCvtFToFV", m.MX>;
+              SchedUnary<"WriteVFWCvtFToFV", "ReadVFWCvtFToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3488,7 +3593,8 @@ multiclass VPseudoVNCVTI_W {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListW in {
     defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>,
-              SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3496,7 +3602,8 @@ multiclass VPseudoVNCVTI_W_RM {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListW in {
     defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint>,
-              SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3504,7 +3611,8 @@ multiclass VPseudoVNCVTI_RM_W {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListW in {
     defm _W : VPseudoConversionRM<m.vrclass, m.wvrclass, m, constraint>,
-              SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX>;
+              SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3512,7 +3620,8 @@ multiclass VPseudoVNCVTF_W_RM {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint>,
-              SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX>;
+              SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3520,7 +3629,8 @@ 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>;
+              SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3528,7 +3638,8 @@ multiclass VPseudoVNCVTD_W {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>,
-              SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX>;
+              SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 
@@ -3536,7 +3647,8 @@ multiclass VPseudoVNCVTD_W_RM {
   defvar constraint = "@earlyclobber $rd";
   foreach m = MxListFW in {
     defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint>,
-              SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX>;
+              SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX,
+                         forceMergeOpRead=true>;
   }
 }
 


        


More information about the llvm-commits mailing list