Skip to content
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][GISel] Attempt to simplify how we handle type legality for F and D extensions. #72174

Merged
merged 2 commits into from
Nov 14, 2023

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Nov 13, 2023

Add helper that creates a lambda similar to typeIs, but containing the predicate check for hasStdExtF and hasStdD. We can use this with legalIf and all to reduce the number of manual lambdas we need to write.

…and D extensions.

Add helper that creates a lambda similar to typeIs, but containing
the predicate check for hasStdExtF and hasStdD. We can use this
with legalIf and all to reduce the number of manual lambdas we need to write.
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 13, 2023

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

Author: Craig Topper (topperc)

Changes

Add helper that creates a lambda similar to typeIs, but containing the predicate check for hasStdExtF and hasStdD. We can use this with legalIf and all to reduce the number of manual lambdas we need to write.


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

1 Files Affected:

  • (modified) llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp (+16-32)
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index c6654873118f98f..ffe35e39b9f3a91 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -23,6 +23,15 @@
 using namespace llvm;
 using namespace LegalityPredicates;
 
+static LegalityPredicate typeIsLegalScalarFP(unsigned TypeIdx,
+                                             const RISCVSubtarget &ST) {
+  return [=, &ST](const LegalityQuery &Query) {
+    return Query.Types[TypeIdx].isScalar() &&
+           ((ST.hasStdExtF() && Query.Types[TypeIdx].getSizeInBits() == 32) ||
+            (ST.hasStdExtD() && Query.Types[TypeIdx].getSizeInBits() == 64));
+  };
+}
+
 RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
   const unsigned XLen = ST.getXLen();
   const LLT sXLen = LLT::scalar(XLen);
@@ -212,51 +221,26 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
 
   getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FNEG,
                                G_FABS, G_FSQRT, G_FMAXNUM, G_FMINNUM})
-      .legalIf([=, &ST](const LegalityQuery &Query) -> bool {
-        return (ST.hasStdExtF() && typeIs(0, s32)(Query)) ||
-               (ST.hasStdExtD() && typeIs(0, s64)(Query));
-      });
+      .legalIf(typeIsLegalScalarFP(0, ST));
 
   getActionDefinitionsBuilder(G_FPTRUNC).legalIf(
-      [=, &ST](const LegalityQuery &Query) -> bool {
-        return (ST.hasStdExtD() && typeIs(0, s32)(Query) &&
-                typeIs(1, s64)(Query));
-      });
+      all(typeIsLegalScalarFP(0, ST), typeIsLegalScalarFP(1, ST)));
   getActionDefinitionsBuilder(G_FPEXT).legalIf(
-      [=, &ST](const LegalityQuery &Query) -> bool {
-        return (ST.hasStdExtD() && typeIs(0, s64)(Query) &&
-                typeIs(1, s32)(Query));
-      });
+      all(typeIsLegalScalarFP(0, ST), typeIsLegalScalarFP(1, ST)));
 
   getActionDefinitionsBuilder(G_FCMP)
-      .legalIf([=, &ST](const LegalityQuery &Query) -> bool {
-        return typeIs(0, sXLen)(Query) &&
-               ((ST.hasStdExtF() && typeIs(1, s32)(Query)) ||
-                (ST.hasStdExtD() && typeIs(1, s64)(Query)));
-      })
+      .legalIf(all(typeIs(0, sXLen), typeIsLegalScalarFP(1, ST)))
       .clampScalar(0, sXLen, sXLen);
 
-  getActionDefinitionsBuilder(G_FCONSTANT)
-      .legalIf([=, &ST](const LegalityQuery &Query) -> bool {
-        return (ST.hasStdExtF() && typeIs(0, s32)(Query)) ||
-               (ST.hasStdExtD() && typeIs(0, s64)(Query));
-      });
+  getActionDefinitionsBuilder(G_FCONSTANT).legalIf(typeIsLegalScalarFP(0, ST));
 
   getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
-      .legalIf([=, &ST](const LegalityQuery &Query) -> bool {
-        return typeInSet(0, {s32, sXLen})(Query) &&
-               ((ST.hasStdExtF() && typeIs(1, s32)(Query)) ||
-                (ST.hasStdExtD() && typeIs(1, s64)(Query)));
-      })
+      .legalIf(all(typeInSet(0, {s32, sXLen}), typeIsLegalScalarFP(1, ST)))
       .widenScalarToNextPow2(0)
       .clampScalar(0, s32, sXLen);
 
   getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
-      .legalIf([=, &ST](const LegalityQuery &Query) -> bool {
-        return ((ST.hasStdExtF() && typeIs(0, s32)(Query)) ||
-                (ST.hasStdExtD() && typeIs(0, s64)(Query))) &&
-               typeInSet(1, {s32, sXLen})(Query);
-      })
+      .legalIf(all(typeIsLegalScalarFP(0, ST), typeInSet(1, {s32, sXLen})))
       .widenScalarToNextPow2(1)
       .clampScalar(1, s32, sXLen);
 

return (ST.hasStdExtD() && typeIs(0, s32)(Query) &&
typeIs(1, s64)(Query));
});
all(typeIsLegalScalarFP(0, ST), typeIsLegalScalarFP(1, ST)));
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is slighty different than the original logic. In RISC-V, hasStdExtD implies hasStdExtF and I assume a G_FPTRUNC where the source type isn't larger than the dest type is ill-formed. So I assume if the source type is legal and the dest type is legal the whole thing should be legal.

Same for G_FPEXT.

Copy link
Contributor

Choose a reason for hiding this comment

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

Simplifying this check has no performance gain, so maybe we should just keep as is? I expect things could get funky when we have to reason about the assumptions we made here when it is time to add Zfh and Zfhmin support.

@@ -23,6 +23,15 @@
using namespace llvm;
using namespace LegalityPredicates;

static LegalityPredicate typeIsLegalScalarFP(unsigned TypeIdx,
Copy link
Contributor

Choose a reason for hiding this comment

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

When we add support for Zfh or Zfhmin in GISel, will you modify this function to check whether we hasZfh || hasZfhmin? What will happen if we only want to legalize an opcode when hasZfh but not when !hasZfh && hasZfhmin? Given these questions, is typeIsLegalScalarFP the correct name for this function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This function will only get Zfh added to it. typeIsScalarFPArith? G_FTRUNC/G_FPEXT are the only ones touched by this patch that need Zfhmin.

Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer typeIsScalarFPArith to typeIsLegalScalarFP since it doesn't have the word legal in it. I think the word legal is unnecessary since it will go into a legalIf which makes it redundant. I like ScalarFPArith better than ScalarFP since it will suggest that not all ScalarFP instructions use it.

Copy link
Contributor

@michaelmaitland michaelmaitland left a comment

Choose a reason for hiding this comment

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

LGTM

@topperc topperc merged commit 3161102 into llvm:main Nov 14, 2023
2 of 3 checks passed
@topperc topperc deleted the pr/fp-legality branch November 14, 2023 03:19
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
…and D extensions. (llvm#72174)

Add helper that creates a lambda similar to typeIs, but containing the
predicate check for hasStdExtF and hasStdD. We can use this with legalIf
and all to reduce the number of manual lambdas we need to write.
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.

None yet

3 participants