[llvm] [LLVM][SelectionDAG] Allow verification of target ISD nodes. (PR #88121)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 9 06:24:06 PDT 2024
https://github.com/paulwalker-arm updated https://github.com/llvm/llvm-project/pull/88121
>From 7cabe45ae7772f514d3774a49b92a7626af7beae Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Fri, 5 Apr 2024 18:35:48 +0100
Subject: [PATCH] [LLVM][SelectionDAG] Allow verification of target ISD nodes.
Patch includes an initial implementation for AArch64 that covers a
handful of nodes where I've observed bogus nodes within the DAG.
---
llvm/include/llvm/CodeGen/TargetLowering.h | 5 +++
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 6 ++-
.../Target/AArch64/AArch64ISelLowering.cpp | 43 +++++++++++++++++++
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 4 ++
4 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index a4dc097446186a..6465110314506b 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4866,6 +4866,11 @@ class TargetLowering : public TargetLoweringBase {
bool verifyReturnAddressArgumentIsConstant(SDValue Op,
SelectionDAG &DAG) const;
+#ifndef NDEBUG
+ /// Check the given SDNode. Aborts if it is invalid.
+ virtual void verifyTargetSDNode(const SDNode *N) const {};
+#endif
+
//===--------------------------------------------------------------------===//
// Inline Asm Support hooks
//
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 1dd0fa49a460f8..b705152147afef 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1111,9 +1111,11 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
#ifndef NDEBUG
/// VerifySDNode - Check the given SDNode. Aborts if it is invalid.
-static void VerifySDNode(SDNode *N) {
+static void VerifySDNode(SDNode *N, const TargetLowering *TLI) {
switch (N->getOpcode()) {
default:
+ if (N->getOpcode() > ISD::BUILTIN_OP_END)
+ TLI->verifyTargetSDNode(N);
break;
case ISD::BUILD_PAIR: {
EVT VT = N->getValueType(0);
@@ -1157,7 +1159,7 @@ void SelectionDAG::InsertNode(SDNode *N) {
AllNodes.push_back(N);
#ifndef NDEBUG
N->PersistentId = NextPersistentId++;
- VerifySDNode(N);
+ VerifySDNode(N, TLI);
#endif
for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
DUL->NodeInserted(N);
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 819e8ccd5c33f0..9263bc2225335b 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -27907,3 +27907,46 @@ bool AArch64TargetLowering::hasInlineStackProbe(
return !Subtarget->isTargetWindows() &&
MF.getInfo<AArch64FunctionInfo>()->hasStackProbing();
}
+
+#ifndef NDEBUG
+void AArch64TargetLowering::verifyTargetSDNode(const SDNode *N) const {
+ switch (N->getOpcode()) {
+ default:
+ break;
+ case AArch64ISD::SUNPKLO:
+ case AArch64ISD::SUNPKHI:
+ case AArch64ISD::UUNPKLO:
+ case AArch64ISD::UUNPKHI: {
+ assert(N->getNumValues() == 1 && "Expected one result!");
+ assert(N->getNumOperands() == 1 && "Expected one operand!");
+ EVT VT = N->getValueType(0);
+ EVT OpVT = N->getOperand(0).getValueType();
+ assert(OpVT.isVector() && VT.isVector() && OpVT.isInteger() &&
+ VT.isInteger() && "Expected integer vectors!");
+ assert(OpVT.getSizeInBits() == VT.getSizeInBits() &&
+ "Expected vectors of equal size!");
+ // TODO: Enable assert once bogus creations have been fixed.
+ // assert(OpVT.getVectorElementCount() == VT.getVectorElementCount()*2 &&
+ // "Expected result vector with half the lanes of its input!");
+ break;
+ }
+ case AArch64ISD::TRN1:
+ case AArch64ISD::TRN2:
+ case AArch64ISD::UZP1:
+ case AArch64ISD::UZP2:
+ case AArch64ISD::ZIP1:
+ case AArch64ISD::ZIP2: {
+ assert(N->getNumValues() == 1 && "Expected one result!");
+ assert(N->getNumOperands() == 2 && "Expected two operands!");
+ EVT VT = N->getValueType(0);
+ EVT Op0VT = N->getOperand(0).getValueType();
+ EVT Op1VT = N->getOperand(1).getValueType();
+ assert(VT.isVector() && Op0VT.isVector() && Op1VT.isVector() &&
+ "Expected vectors!");
+ // TODO: Enable assert once bogus creations have been fixed.
+ // assert(VT == Op0VT && VT == Op1VT && "Expected matching vectors!");
+ break;
+ }
+ }
+}
+#endif
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 18439dc7f01020..db6e8a00d2fb5e 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -998,6 +998,10 @@ class AArch64TargetLowering : public TargetLowering {
/// True if stack clash protection is enabled for this functions.
bool hasInlineStackProbe(const MachineFunction &MF) const override;
+#ifndef NDEBUG
+ void verifyTargetSDNode(const SDNode *N) const override;
+#endif
+
private:
/// Keep a pointer to the AArch64Subtarget around so that we can
/// make the right decision when generating code for different targets.
More information about the llvm-commits
mailing list