[llvm] [RISCV] Avoid redundant SchedRead on _TIED VPseudos (PR #113940)

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 28 10:38:23 PDT 2024


https://github.com/mshockwave updated https://github.com/llvm/llvm-project/pull/113940

>From 9ef4814e02be8f3a4bf5b23480cb689f538ae828 Mon Sep 17 00:00:00 2001
From: Min Hsu <min.hsu at sifive.com>
Date: Mon, 21 Oct 2024 12:07:33 -0700
Subject: [PATCH 1/2] [RISCV] Avoid redundant SchedRead on _TIED VPseudos

_TIED and _MASK_TIED pseudos have one less operand compared to other
pseudos, thus we shouldn't attach the same number of SchedRead for these
instructions.
---
 llvm/lib/Target/RISCV/RISCVInstrInfoV.td | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
index 4e8619c5ec2392..e63a23899152fa 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
@@ -104,13 +104,26 @@ class SchedCommon<list<SchedWrite> writes, list<SchedRead> reads,
                   string mx = "WorstCase", int sew = 0, bit forceMasked = 0,
                   bit forcePassthruRead = 0> : Sched<[]> {
   defvar isMasked = !ne(!find(NAME, "_MASK"), -1);
+  defvar isTied = !ne(!find(NAME, "_TIED"), -1);
   defvar isMaskedOrForceMasked = !or(forceMasked, isMasked);
+  defvar isTiedMasked = !and(isMaskedOrForceMasked, isTied);
   defvar passthruRead = !if(!or(!eq(mx, "WorstCase"), !eq(sew, 0)),
                             !cast<SchedRead>("ReadVPassthru_" # mx),
                             !cast<SchedRead>("ReadVPassthru_" # mx # "_E" #sew));
-  defvar needsPassthruRead = !or(isMaskedOrForceMasked, forcePassthruRead);
+  // We don't need passthru operand if it's already _TIED without mask.
+  defvar needsForcePassthruRead = !and(forcePassthruRead, !not(isTied));
+  defvar needsPassthruRead = !or(isMaskedOrForceMasked, needsForcePassthruRead);
+  // If this is a _TIED + masked operation, $rs2 (i.e. the first operand) is
+  // merged with the mask.
+  // NOTE: the following if statement is written in such a weird way because
+  // TableGen's `!if` doesn't have a proper short-circuit behavior, so if the
+  // predicate of this `!if` cannot be resolved right away, `!tail(reads)` will
+  // still be resolved right away even when `reads` is empty, which leads to
+  // an assertion failure.
+  defvar readsWithTiedMask =
+      !if(isTiedMasked, !if(!not(!empty(reads)), !tail(reads), reads), reads);
   defvar readsWithMask =
-      !if(isMaskedOrForceMasked, !listconcat(reads, [ReadVMask]), reads);
+      !if(isMaskedOrForceMasked, !listconcat(readsWithTiedMask, [ReadVMask]), reads);
   defvar allReads =
       !if(needsPassthruRead, !listconcat([passthruRead], readsWithMask), reads);
   let SchedRW = !listconcat(writes, allReads);

>From 10c049e6503c9ecfc98c2941d2996b3304e6a986 Mon Sep 17 00:00:00 2001
From: Min Hsu <min.hsu at sifive.com>
Date: Mon, 28 Oct 2024 10:37:57 -0700
Subject: [PATCH 2/2] Add more clarifications in the comments

---
 llvm/lib/Target/RISCV/RISCVInstrInfoV.td | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
index e63a23899152fa..8e0c4826ac00de 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td
@@ -116,9 +116,11 @@ class SchedCommon<list<SchedWrite> writes, list<SchedRead> reads,
   // If this is a _TIED + masked operation, $rs2 (i.e. the first operand) is
   // merged with the mask.
   // NOTE: the following if statement is written in such a weird way because
-  // TableGen's `!if` doesn't have a proper short-circuit behavior, so if the
-  // predicate of this `!if` cannot be resolved right away, `!tail(reads)` will
-  // still be resolved right away even when `reads` is empty, which leads to
+  // should we want to write something like
+  // `!if(!and(!not(!empty(reads), isTiedMasked), !tail(reads), reads)`
+  // since `!if` doesn't have a proper short-circuit behavior, if the
+  // condition of this `!if` cannot be resolved right away, `!tail(reads)` will
+  // be immediately evaluated anyway even when `reads` is empty, which leads to
   // an assertion failure.
   defvar readsWithTiedMask =
       !if(isTiedMasked, !if(!not(!empty(reads)), !tail(reads), reads), reads);



More information about the llvm-commits mailing list