[llvm] [RISCV][GlobalISel] Legalize G_ADD, G_SUB, G_AND, G_OR, G_XOR on RISC-V Vector Extension (PR #71400)
Jiahan Xie via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 10 07:54:28 PST 2023
================
@@ -31,15 +31,55 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
+ const LLT nxv1s8 = LLT::scalable_vector(1, s8);
+ const LLT nxv2s8 = LLT::scalable_vector(2, s8);
+ const LLT nxv4s8 = LLT::scalable_vector(4, s8);
+ const LLT nxv8s8 = LLT::scalable_vector(8, s8);
+ const LLT nxv16s8 = LLT::scalable_vector(16, s8);
+ const LLT nxv32s8 = LLT::scalable_vector(32, s8);
+ const LLT nxv64s8 = LLT::scalable_vector(64, s8);
+
+ const LLT nxv1s16 = LLT::scalable_vector(1, s16);
+ const LLT nxv2s16 = LLT::scalable_vector(2, s16);
+ const LLT nxv4s16 = LLT::scalable_vector(4, s16);
+ const LLT nxv8s16 = LLT::scalable_vector(8, s16);
+ const LLT nxv16s16 = LLT::scalable_vector(16, s16);
+ const LLT nxv32s16 = LLT::scalable_vector(32, s16);
+
+ const LLT nxv1s32 = LLT::scalable_vector(1, s32);
+ const LLT nxv2s32 = LLT::scalable_vector(2, s32);
+ const LLT nxv4s32 = LLT::scalable_vector(4, s32);
+ const LLT nxv8s32 = LLT::scalable_vector(8, s32);
+ const LLT nxv16s32 = LLT::scalable_vector(16, s32);
+
+ const LLT nxv1s64 = LLT::scalable_vector(1, s64);
+ const LLT nxv2s64 = LLT::scalable_vector(2, s64);
+ const LLT nxv4s64 = LLT::scalable_vector(4, s64);
+ const LLT nxv8s64 = LLT::scalable_vector(8, s64);
+
using namespace TargetOpcode;
+ const std::initializer_list<LLT> scalarLegalTypes = {s32, sXLen};
+ const std::initializer_list<LLT> vExtendedLegalTypes = {
+ s32, sXLen, nxv1s8, nxv2s8, nxv4s8, nxv8s8,
+ nxv16s8, nxv32s8, nxv64s8, nxv1s16, nxv2s16, nxv4s16,
+ nxv8s16, nxv16s16, nxv32s16, nxv1s32, nxv2s32, nxv4s32,
+ nxv8s32, nxv16s32, nxv1s64, nxv2s64, nxv4s64, nxv8s64};
+
+ auto LegalTypes = [&]() -> const std::initializer_list<LLT> & {
+ if (ST.hasVInstructions()) {
+ return vExtendedLegalTypes;
+ } else {
+ return scalarLegalTypes;
+ }
+ }();
+
getActionDefinitionsBuilder({G_ADD, G_SUB, G_AND, G_OR, G_XOR})
- .legalFor({s32, sXLen})
+ .legalFor(LegalTypes)
----------------
jiahanxie353 wrote:
Yes!
And as per @michaelmaitland 's comment:
> although I'm not 100% sure you can use legalFor and legalIf together. You will have to see if that is possible.
Yes, we can, and [AArch64 is using it](https://github.com/llvm/llvm-project/blob/28ace78d0b838acfd406bc9b5f521fae3e206491/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp#L999). And I want to adopt this approach as well because it's more neag.
My proposed solution is:
```C++
getActionDefinitionsBuilder({G_ADD, G_SUB, G_AND, G_OR, G_XOR})
.legalFor({s32, sXLen})
.legalIf(all(
LegalityPredicate([=, &ST](const LegalityQuery &Q)
{return ST.hasVInstructions();}),
typeInSet(0, vExtendedLegalTypes))
)
.widenScalarToNextPow2(0)
.clampScalar(0, s32, sXLen);
```
However, turns out it [fails `G_ANYEXT` when I run the test cases](https://github.com/llvm/llvm-project/blob/4ba50a783b4d6cbfc93d989e4d2bdfe4e4726e4a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/rv64/legalize-add.mir#L14).
Trying to reproduce the minimum error, I changed my code to:
```C++
getActionDefinitionsBuilder({G_ADD, G_SUB, G_AND, G_OR, G_XOR})
.legalFor({s32, sXLen})
.legalIf(
return true;
)
.widenScalarToNextPow2(0)
.clampScalar(0, s32, sXLen);
```
because I thought if I return `true` all the time, the semantics still remain the same as if `legalIf` was not applied.
But it still fails `G_ANYEXT`.
Do you have any insight?
https://github.com/llvm/llvm-project/pull/71400
More information about the llvm-commits
mailing list