[llvm] [RISCV] Add an implementation of findRepresentativeClass to assign i32 to GPRRegClass for RV64. (PR #116165)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 15 16:03:10 PST 2024
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/116165
>From 4928effc2ef653e0bdc54bb79f8015c696e21436 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 13 Nov 2024 21:00:27 -0800
Subject: [PATCH 1/3] [RISCV] Add an implementation of findRepresentativeClass
to assign i32 to GPRRegClass for RV64.
This is an alternative fix for #81192. This allows the SelectionDAG
scheduler to be able to find a register class for i32 on RV64. The
default implementation of findRepresentativeClass only works for
legal types which i32 is not for RV64.
I wanted to remove i32 from the GPR register class to fix the issue,
but we need to be able to write some i32 patterns for GISel. And now
it looks like I need to add i16 to GPR. I had tried to use manual
instruction selection for some cases in GISel in #116111, but I got
some feedback recommending the use of patterns.
I did some investigation of why tablegen uses i32 in output patterns
on RV64. It appears it comes down to ForceArbitraryInstResultType
that just picks a type for the output pattern when the isel pattern
isn't specific enough. I believe it picks the smallest type(lowested
numbered) to resolve the conflict.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 18 ++++++++++++++++++
llvm/lib/Target/RISCV/RISCVISelLowering.h | 3 +++
2 files changed, 21 insertions(+)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3df8eca8cae7fb..f191b4e9cb251e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21996,6 +21996,24 @@ SDValue RISCVTargetLowering::expandIndirectJTBranch(const SDLoc &dl,
return TargetLowering::expandIndirectJTBranch(dl, Value, Addr, JTI, DAG);
}
+// Some types are listed in the GPR register class to support isel patterns for
+// GISel, but are not legal in SelectionDAG. This prevents the default
+// implementation from finding a register clss for them.
+std::pair<const TargetRegisterClass *, uint8_t>
+RISCVTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
+ MVT VT) const {
+ const TargetRegisterClass *RRC = nullptr;
+ uint8_t Cost = 1;
+ switch (VT.SimpleTy) {
+ default:
+ return TargetLowering::findRepresentativeClass(TRI, VT);
+ case MVT::i8: case MVT::i16: case MVT::i32:
+ RRC = &RISCV::GPRRegClass;
+ break;
+ }
+ return std::make_pair(RRC, Cost);
+}
+
namespace llvm::RISCVVIntrinsicsTable {
#define GET_RISCVVIntrinsicsTable_IMPL
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 9ae70d257fa442..aa73d558c048b2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -1051,6 +1051,9 @@ class RISCVTargetLowering : public TargetLowering {
SDValue emitFlushICache(SelectionDAG &DAG, SDValue InChain, SDValue Start,
SDValue End, SDValue Flags, SDLoc DL) const;
+
+ std::pair<const TargetRegisterClass *, uint8_t>
+ findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) const override;
};
namespace RISCVVIntrinsicsTable {
>From 10b08c448f93d31b855ddb430c8463b32b6d1dfa Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 13 Nov 2024 22:02:21 -0800
Subject: [PATCH 2/3] fixup! clang-format
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index f191b4e9cb251e..2e157c7ce1c7cd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -22007,7 +22007,9 @@ RISCVTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
switch (VT.SimpleTy) {
default:
return TargetLowering::findRepresentativeClass(TRI, VT);
- case MVT::i8: case MVT::i16: case MVT::i32:
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
RRC = &RISCV::GPRRegClass;
break;
}
>From 7fe0a33554a7a7a0b53ad47b52e690aa9058ddc6 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 15 Nov 2024 16:02:35 -0800
Subject: [PATCH 3/3] fixup! Add f16/bf16 by calling base class with f32.
Handle int by calling base class with XLenVT.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 28 +++++++++++++--------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2e157c7ce1c7cd..7aafb2478c660a 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -21996,24 +21996,32 @@ SDValue RISCVTargetLowering::expandIndirectJTBranch(const SDLoc &dl,
return TargetLowering::expandIndirectJTBranch(dl, Value, Addr, JTI, DAG);
}
-// Some types are listed in the GPR register class to support isel patterns for
-// GISel, but are not legal in SelectionDAG. This prevents the default
-// implementation from finding a register clss for them.
+// If an output pattern produces multiple instructions tablegen may pick an
+// arbitrary type from an instructions destination register class to use for the
+// VT of that MachineSDNode. This VT may be used to look up the representative
+// register class. If the type isn't legal, the default implementation will
+// not find a register class.
+//
+// Some integer types smaller than XLen are listed in the GPR register class to
+// support isel patterns for GISel, but are not legal in SelectionDAG. The
+// arbitrary type tablegen picks may be one of these smaller types.
+//
+// f16 and bf16 are both valid for the FPR16 or GPRF16 register class. It's
+// possible for tablegen to pick bf16 as the arbitrary type for an f16 pattern.
std::pair<const TargetRegisterClass *, uint8_t>
RISCVTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
MVT VT) const {
- const TargetRegisterClass *RRC = nullptr;
- uint8_t Cost = 1;
switch (VT.SimpleTy) {
- default:
- return TargetLowering::findRepresentativeClass(TRI, VT);
case MVT::i8:
case MVT::i16:
case MVT::i32:
- RRC = &RISCV::GPRRegClass;
- break;
+ return TargetLowering::findRepresentativeClass(TRI, Subtarget.getXLenVT());
+ case MVT::bf16:
+ case MVT::f16:
+ return TargetLowering::findRepresentativeClass(TRI, MVT::f32);
}
- return std::make_pair(RRC, Cost);
+
+ return TargetLowering::findRepresentativeClass(TRI, VT);
}
namespace llvm::RISCVVIntrinsicsTable {
More information about the llvm-commits
mailing list