[llvm] [Patchpoint] Implement integer result type legalization for patchpoints (PR #97278)

Csanád Hajdú via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 1 04:26:54 PDT 2024


https://github.com/Il-Capitano updated https://github.com/llvm/llvm-project/pull/97278

>From e8da3c98608accf5d0656b5acc631cdb5c1106d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Fri, 21 Jun 2024 10:18:18 +0200
Subject: [PATCH 1/2] [Patchpoint] Implement integer result type legalization
 for patchpoints

Previously, if a patchpoint had a non-native integer type result,
e.g. i8 or i16 on AArch64, or some non-power-of-two wide integer
type (e.g. i29), the type legalizer would crash.
---
 .../SelectionDAG/LegalizeIntegerTypes.cpp     | 24 +++++
 llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h |  1 +
 llvm/test/CodeGen/AArch64/arm64-anyregcc.ll   | 88 ++++++++++++++++++-
 3 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index a058b509b3aca..16af429cb6faa 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -329,6 +329,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
   case ISD::LLRINT:
     Res = PromoteIntRes_XRINT(N);
     break;
+
+  case ISD::PATCHPOINT:
+    Res = PromoteIntRes_PATCHPOINT(N);
+    break;
   }
 
   // If the result is null then the sub-method took care of registering it.
@@ -5992,6 +5996,26 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VP_REDUCE(SDNode *N) {
                      N->getOperand(1), N->getOperand(2), N->getOperand(3));
 }
 
+SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
+  EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
+  SDLoc dl(N);
+
+  assert(N->getNumValues() == 3 && "Expected 3 values for PATCHPOINT");
+  SmallVector<EVT, 3> VTs(N->values());
+  VTs[0] = NVT;
+  SDVTList VTList = DAG.getVTList(VTs);
+
+  SmallVector<SDValue> Ops(N->ops());
+  SDValue Res = DAG.getNode(ISD::PATCHPOINT, dl, VTList, Ops);
+
+  // Replace chain and glue uses with the new patchpoint.
+  SDValue From[] = {SDValue(N, 1), SDValue(N, 2)};
+  SDValue To[] = {Res.getValue(1), Res.getValue(2)};
+  DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
+
+  return Res.getValue(0);
+}
+
 SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
   SDLoc dl(N);
   SDValue V0 = GetPromotedInteger(N->getOperand(0));
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 85f947efe2c75..15075bea104d3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -375,6 +375,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
   SDValue PromoteIntRes_FunnelShift(SDNode *N);
   SDValue PromoteIntRes_VPFunnelShift(SDNode *N);
   SDValue PromoteIntRes_IS_FPCLASS(SDNode *N);
+  SDValue PromoteIntRes_PATCHPOINT(SDNode *N);
 
   // Integer Operand Promotion.
   bool PromoteIntegerOperand(SDNode *N, unsigned OpNo);
diff --git a/llvm/test/CodeGen/AArch64/arm64-anyregcc.ll b/llvm/test/CodeGen/AArch64/arm64-anyregcc.ll
index cb6586718450a..22e8088165e84 100644
--- a/llvm/test/CodeGen/AArch64/arm64-anyregcc.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-anyregcc.ll
@@ -8,11 +8,11 @@
 ; CHECK-NEXT:   .byte 0
 ; CHECK-NEXT:   .short 0
 ; Num Functions
-; CHECK-NEXT:   .long 18
+; CHECK-NEXT:   .long 22
 ; Num LargeConstants
 ; CHECK-NEXT:   .long 0
 ; Num Callsites
-; CHECK-NEXT:   .long 18
+; CHECK-NEXT:   .long 22
 
 ; Functions and stack size
 ; CHECK-NEXT:   .quad _test
@@ -39,6 +39,18 @@
 ; CHECK-NEXT:   .quad _patchpoint_spillargs
 ; CHECK-NEXT:   .quad 128
 ; CHECK-NEXT:   .quad 1
+; CHECK-NEXT:   .quad _generic_test_i1
+; CHECK-NEXT:   .quad 16
+; CHECK-NEXT:   .quad 1
+; CHECK-NEXT:   .quad _generic_test_i8
+; CHECK-NEXT:   .quad 16
+; CHECK-NEXT:   .quad 1
+; CHECK-NEXT:   .quad _generic_test_i16
+; CHECK-NEXT:   .quad 16
+; CHECK-NEXT:   .quad 1
+; CHECK-NEXT:   .quad _generic_test_i29
+; CHECK-NEXT:   .quad 16
+; CHECK-NEXT:   .quad 1
 ; CHECK-NEXT:   .quad _generic_test_i32
 ; CHECK-NEXT:   .quad 16
 ; CHECK-NEXT:   .quad 1
@@ -487,6 +499,78 @@ entry:
   ret i64 %result
 }
 
+; generic_test_i1
+; CHECK-LABEL:  .long   L{{.*}}-_generic_test_i1
+; CHECK-NEXT:   .short  0
+; 1 location
+; CHECK-NEXT:   .short  1
+; Loc 0: Register <-- this is the return register
+; CHECK-NEXT:   .byte 1
+; CHECK-NEXT:   .byte 0
+; CHECK-NEXT:   .short 4
+; CHECK-NEXT:   .short {{[0-9]+}}
+; CHECK-NEXT:   .short 0
+; CHECK-NEXT:   .long 0
+define i1 @generic_test_i1() nounwind ssp uwtable {
+entry:
+  %ret = call anyregcc i1 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i1(i64 14, i32 20, ptr null, i32 0)
+  ret i1 %ret
+}
+
+; generic_test_i8
+; CHECK-LABEL:  .long   L{{.*}}-_generic_test_i8
+; CHECK-NEXT:   .short  0
+; 1 location
+; CHECK-NEXT:   .short  1
+; Loc 0: Register <-- this is the return register
+; CHECK-NEXT:   .byte 1
+; CHECK-NEXT:   .byte 0
+; CHECK-NEXT:   .short 4
+; CHECK-NEXT:   .short {{[0-9]+}}
+; CHECK-NEXT:   .short 0
+; CHECK-NEXT:   .long 0
+define i8 @generic_test_i8() nounwind ssp uwtable {
+entry:
+  %ret = call anyregcc i8 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i8(i64 14, i32 20, ptr null, i32 0)
+  ret i8 %ret
+}
+
+; generic_test_i16
+; CHECK-LABEL:  .long   L{{.*}}-_generic_test_i16
+; CHECK-NEXT:   .short  0
+; 1 location
+; CHECK-NEXT:   .short  1
+; Loc 0: Register <-- this is the return register
+; CHECK-NEXT:   .byte 1
+; CHECK-NEXT:   .byte 0
+; CHECK-NEXT:   .short 4
+; CHECK-NEXT:   .short {{[0-9]+}}
+; CHECK-NEXT:   .short 0
+; CHECK-NEXT:   .long 0
+define i16 @generic_test_i16() nounwind ssp uwtable {
+entry:
+  %ret = call anyregcc i16 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i16(i64 14, i32 20, ptr null, i32 0)
+  ret i16 %ret
+}
+
+; generic_test_i29
+; CHECK-LABEL:  .long   L{{.*}}-_generic_test_i29
+; CHECK-NEXT:   .short  0
+; 1 location
+; CHECK-NEXT:   .short  1
+; Loc 0: Register <-- this is the return register
+; CHECK-NEXT:   .byte 1
+; CHECK-NEXT:   .byte 0
+; CHECK-NEXT:   .short 4
+; CHECK-NEXT:   .short {{[0-9]+}}
+; CHECK-NEXT:   .short 0
+; CHECK-NEXT:   .long 0
+define i29 @generic_test_i29() nounwind ssp uwtable {
+entry:
+  %ret = call anyregcc i29 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i29(i64 14, i32 20, ptr null, i32 0)
+  ret i29 %ret
+}
+
 ; generic_test_i32
 ; CHECK-LABEL:  .long   L{{.*}}-_generic_test_i32
 ; CHECK-NEXT:   .short  0

>From 04c33496c12ad5db0f9197321af9086eb451449a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Mon, 1 Jul 2024 13:22:21 +0200
Subject: [PATCH 2/2] Address review feedback

---
 llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 16af429cb6faa..6416d2387353a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -6001,9 +6001,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
   SDLoc dl(N);
 
   assert(N->getNumValues() == 3 && "Expected 3 values for PATCHPOINT");
-  SmallVector<EVT, 3> VTs(N->values());
-  VTs[0] = NVT;
-  SDVTList VTList = DAG.getVTList(VTs);
+  SDVTList VTList = DAG.getVTList({NVT, MVT::Other, MVT::Glue});
 
   SmallVector<SDValue> Ops(N->ops());
   SDValue Res = DAG.getNode(ISD::PATCHPOINT, dl, VTList, Ops);



More information about the llvm-commits mailing list