Skip to content

Conversation

lukel97
Copy link
Contributor

@lukel97 lukel97 commented Dec 1, 2023

This refactors the logic in transferBefore so that we're moving in the direction of "keep the existing Info, only change what is needed".

For the sake of review there are two commits in this PR: The former is needed to make the latter an NFC commit. Neither introduce any test diffs but the former is not technically NFC, hence why I did not precommit it.

  • [RISCV] Preserve AVL when previous info is ratio only in transferBefore
  • [RISCV] Don't change AVL if only zeroness is demanded. NFC

Currently if the previous info only knows the SEW/LMUL ratio, it will be just
replaced with the incoming info. However since the SEW/LMUL ratio is only
dependent on VTYPE, we are free to keep around the existing AVL.

This commit does that, and shows how in practice there is no functional change
if we do this. We need to do this in order to prevent regressions in an
upcoming commit to move AVL zeroness logic.
This patch moves the existing "keep previous AVL if only zeroness is demanded
and the AVLs are equally zero" logic into transferBefore.
@lukel97 lukel97 requested review from BeMg, preames and topperc December 1, 2023 08:34
@lukel97 lukel97 changed the title [RISCV] Don't set AVL if only zeroness is demanded. NFC [RISCV] Don't set AVL if only zeroness is demanded Dec 1, 2023
@llvmbot
Copy link
Member

llvmbot commented Dec 1, 2023

@llvm/pr-subscribers-backend-risc-v

Author: Luke Lau (lukel97)

Changes

This refactors the logic in transferBefore so that we're moving in the direction of "keep the existing Info, only change what is needed".

For the sake of review there are two commits in this PR: The former is needed to make the latter an NFC commit. Neither introduce any test diffs but the former is not technically NFC, hence why I did not precommit it.

  • [RISCV] Preserve AVL when previous info is ratio only in transferBefore
  • [RISCV] Don't change AVL if only zeroness is demanded. NFC

Full diff: https://github.com/llvm/llvm-project/pull/74049.diff

1 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp (+19-16)
diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
index 323a92cfb8c83d3..5e239ff06371e9a 100644
--- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp
@@ -1061,7 +1061,7 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
     return;
 
   const VSETVLIInfo PrevInfo = Info;
-  if (Info.hasSEWLMULRatioOnly() || !Info.isValid() || Info.isUnknown())
+  if (!Info.isValid() || Info.isUnknown())
     Info = NewInfo;
 
   if (!RISCVII::hasVLOp(TSFlags)) {
@@ -1073,7 +1073,16 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
   const VSETVLIInfo IncomingInfo =
       adjustIncoming(PrevInfo, NewInfo, Demanded, MRI);
 
-  if (Demanded.usedVL())
+  // If MI only demands that VL has the same zeroness, we only need to set the
+  // AVL if the zeroness differs.  This removes a vsetvli entirely if the types
+  // match or allows use of cheaper avl preserving variant if VLMAX doesn't
+  // change. If VLMAX might change, we couldn't use the 'vsetvli x0, x0, vtype"
+  // variant, so we avoid the transform to prevent extending live range of an
+  // avl register operand.
+  // TODO: We can probably relax this for immediates.
+  bool EquallyZero = IncomingInfo.hasEquallyZeroAVL(PrevInfo, *MRI) &&
+                     IncomingInfo.hasSameVLMAX(PrevInfo);
+  if (Demanded.VLAny || (Demanded.VLZeroness && !EquallyZero))
     Info.setAVL(IncomingInfo);
 
   Info.setVTYPE(
@@ -1086,6 +1095,14 @@ void RISCVInsertVSETVLI::transferBefore(VSETVLIInfo &Info,
           IncomingInfo.getTailAgnostic(),
       (Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
           IncomingInfo.getMaskAgnostic());
+
+  // If we only knew the sew/lmul ratio previously, replace the VTYPE but keep
+  // the AVL.
+  if (Info.hasSEWLMULRatioOnly()) {
+    VSETVLIInfo RatiolessInfo = IncomingInfo;
+    RatiolessInfo.setAVL(Info);
+    Info = RatiolessInfo;
+  }
 }
 
 static VSETVLIInfo adjustIncoming(VSETVLIInfo PrevInfo, VSETVLIInfo NewInfo,
@@ -1104,20 +1121,6 @@ static VSETVLIInfo adjustIncoming(VSETVLIInfo PrevInfo, VSETVLIInfo NewInfo,
     Demanded.LMUL = true;
   }
 
-  // If we only demand VL zeroness (i.e. vmv.s.x and vmv.x.s), then there are
-  // only two behaviors, VL = 0 and VL > 0. We can discard the user requested
-  // AVL and just use the last one if we can prove it equally zero. This
-  // removes a vsetvli entirely if the types match or allows use of cheaper avl
-  // preserving variant if VLMAX doesn't change. If VLMAX might change, we
-  // couldn't use the 'vsetvli x0, x0, vtype" variant, so we avoid the transform
-  // to prevent extending live range of an avl register operand.
-  // TODO: We can probably relax this for immediates.
-  if (Demanded.VLZeroness && !Demanded.VLAny && PrevInfo.isValid() &&
-      PrevInfo.hasEquallyZeroAVL(Info, *MRI) && Info.hasSameVLMAX(PrevInfo)) {
-    Info.setAVL(PrevInfo);
-    Demanded.demandVL();
-  }
-
   return Info;
 }
 

// couldn't use the 'vsetvli x0, x0, vtype" variant, so we avoid the transform
// to prevent extending live range of an avl register operand.
// TODO: We can probably relax this for immediates.
if (Demanded.VLZeroness && !Demanded.VLAny && PrevInfo.isValid() &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this code actually has a bug. If PrevInfo is SEWLMULRatioOnly, inspecting it's AVL is highly suspect. That AVL is purely a garbage value, and I don't know we're even guaranteed for it to be the prior active AVL (consider a meet on a branch with different AVLs).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wrong here. I had misread the definition of SEWLMULRatioOnly. This flag is only set in the merge if the AVL is the same, and thus well defined.

Copy link
Collaborator

@preames preames left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM w/suggestion.

(Demanded.MaskPolicy ? IncomingInfo : Info).getMaskAgnostic() ||
IncomingInfo.getMaskAgnostic());

// If we only knew the sew/lmul ratio previously, replace the VTYPE but keep
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any value having this here as opposed to as an early exit before we call adjustIncoming?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to handle the case where the AVL might be preserved so we can't bail before the AVL gets set on line 1084. We could maybe do an early exit after that though, before we set VTYPE.

As a side note, this is a bit awkward because calling setVTYPE isn't enough to clear the hasSEWLMULRatioOnly bit. Hence why we need to copy over incoming info.

@lukel97 lukel97 merged commit 6707b33 into llvm:main Dec 12, 2023
@topperc
Copy link
Collaborator

topperc commented Jan 5, 2024

I recently pulled this patch in our downstream and I'm seeing an assertion failure

llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp:561: unsigned int (anonymous namespace)::VSETVLIInfo::encodeVTYPE() const: Assertion `isValid() && !isUnknown() && !SEWLMULRatioOnly && "Can't encode VTYPE for uninitialized or unknown"' failed.

@topperc
Copy link
Collaborator

topperc commented Jan 5, 2024

Here's a reduced case I got out of llvm-reduce https://godbolt.org/z/WMTPcoe7z

lukel97 added a commit to lukel97/llvm-project that referenced this pull request Jan 5, 2024
We may attempt to do PRE on a block where one predecessor's exit info is
unknown, and one predecssor's exit info has the SEW/LMUL ratio only.

This should be avoided since we can't insert a vsetvli if we don't know its
exact VTYPE (yet).

Normally PRE would bail in these cases because coincidentally it wouldn't have
been profitable since not enough transitions would have been removed. However
after 6707b33, a PseudoVMV_X_S may now be enough to convince PRE that it is
indeed profitable, triggering the assertion when inserting vsetvli.

This fixes the issue described in
llvm#74049 (comment) by
bailing if the available info has the SEW/LMUL ratio only (i.e we don't know
the exact VTYPE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants