Skip to content

Commit

Permalink
[Patchpoint] Implement integer result type legalization for patchpoin…
Browse files Browse the repository at this point in the history
…ts (#97278)

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.
  • Loading branch information
Il-Capitano authored Jul 11, 2024
1 parent 4a8f1d6 commit ddbad86
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 2 deletions.
22 changes: 22 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -6013,6 +6017,24 @@ 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");
SDVTList VTList = DAG.getVTList({NVT, MVT::Other, MVT::Glue});

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));
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
88 changes: 86 additions & 2 deletions llvm/test/CodeGen/AArch64/arm64-anyregcc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit ddbad86

Please sign in to comment.