Skip to content

Commit ddbad86

Browse files
authored
[Patchpoint] Implement integer result type legalization for patchpoints (#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.
1 parent 4a8f1d6 commit ddbad86

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
329329
case ISD::LLRINT:
330330
Res = PromoteIntRes_XRINT(N);
331331
break;
332+
333+
case ISD::PATCHPOINT:
334+
Res = PromoteIntRes_PATCHPOINT(N);
335+
break;
332336
}
333337

334338
// If the result is null then the sub-method took care of registering it.
@@ -6013,6 +6017,24 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VP_REDUCE(SDNode *N) {
60136017
N->getOperand(1), N->getOperand(2), N->getOperand(3));
60146018
}
60156019

6020+
SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
6021+
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6022+
SDLoc dl(N);
6023+
6024+
assert(N->getNumValues() == 3 && "Expected 3 values for PATCHPOINT");
6025+
SDVTList VTList = DAG.getVTList({NVT, MVT::Other, MVT::Glue});
6026+
6027+
SmallVector<SDValue> Ops(N->ops());
6028+
SDValue Res = DAG.getNode(ISD::PATCHPOINT, dl, VTList, Ops);
6029+
6030+
// Replace chain and glue uses with the new patchpoint.
6031+
SDValue From[] = {SDValue(N, 1), SDValue(N, 2)};
6032+
SDValue To[] = {Res.getValue(1), Res.getValue(2)};
6033+
DAG.ReplaceAllUsesOfValuesWith(From, To, 2);
6034+
6035+
return Res.getValue(0);
6036+
}
6037+
60166038
SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
60176039
SDLoc dl(N);
60186040
SDValue V0 = GetPromotedInteger(N->getOperand(0));

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
375375
SDValue PromoteIntRes_FunnelShift(SDNode *N);
376376
SDValue PromoteIntRes_VPFunnelShift(SDNode *N);
377377
SDValue PromoteIntRes_IS_FPCLASS(SDNode *N);
378+
SDValue PromoteIntRes_PATCHPOINT(SDNode *N);
378379

379380
// Integer Operand Promotion.
380381
bool PromoteIntegerOperand(SDNode *N, unsigned OpNo);

llvm/test/CodeGen/AArch64/arm64-anyregcc.ll

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
; CHECK-NEXT: .byte 0
99
; CHECK-NEXT: .short 0
1010
; Num Functions
11-
; CHECK-NEXT: .long 18
11+
; CHECK-NEXT: .long 22
1212
; Num LargeConstants
1313
; CHECK-NEXT: .long 0
1414
; Num Callsites
15-
; CHECK-NEXT: .long 18
15+
; CHECK-NEXT: .long 22
1616

1717
; Functions and stack size
1818
; CHECK-NEXT: .quad _test
@@ -39,6 +39,18 @@
3939
; CHECK-NEXT: .quad _patchpoint_spillargs
4040
; CHECK-NEXT: .quad 128
4141
; CHECK-NEXT: .quad 1
42+
; CHECK-NEXT: .quad _generic_test_i1
43+
; CHECK-NEXT: .quad 16
44+
; CHECK-NEXT: .quad 1
45+
; CHECK-NEXT: .quad _generic_test_i8
46+
; CHECK-NEXT: .quad 16
47+
; CHECK-NEXT: .quad 1
48+
; CHECK-NEXT: .quad _generic_test_i16
49+
; CHECK-NEXT: .quad 16
50+
; CHECK-NEXT: .quad 1
51+
; CHECK-NEXT: .quad _generic_test_i29
52+
; CHECK-NEXT: .quad 16
53+
; CHECK-NEXT: .quad 1
4254
; CHECK-NEXT: .quad _generic_test_i32
4355
; CHECK-NEXT: .quad 16
4456
; CHECK-NEXT: .quad 1
@@ -487,6 +499,78 @@ entry:
487499
ret i64 %result
488500
}
489501

502+
; generic_test_i1
503+
; CHECK-LABEL: .long L{{.*}}-_generic_test_i1
504+
; CHECK-NEXT: .short 0
505+
; 1 location
506+
; CHECK-NEXT: .short 1
507+
; Loc 0: Register <-- this is the return register
508+
; CHECK-NEXT: .byte 1
509+
; CHECK-NEXT: .byte 0
510+
; CHECK-NEXT: .short 4
511+
; CHECK-NEXT: .short {{[0-9]+}}
512+
; CHECK-NEXT: .short 0
513+
; CHECK-NEXT: .long 0
514+
define i1 @generic_test_i1() nounwind ssp uwtable {
515+
entry:
516+
%ret = call anyregcc i1 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i1(i64 14, i32 20, ptr null, i32 0)
517+
ret i1 %ret
518+
}
519+
520+
; generic_test_i8
521+
; CHECK-LABEL: .long L{{.*}}-_generic_test_i8
522+
; CHECK-NEXT: .short 0
523+
; 1 location
524+
; CHECK-NEXT: .short 1
525+
; Loc 0: Register <-- this is the return register
526+
; CHECK-NEXT: .byte 1
527+
; CHECK-NEXT: .byte 0
528+
; CHECK-NEXT: .short 4
529+
; CHECK-NEXT: .short {{[0-9]+}}
530+
; CHECK-NEXT: .short 0
531+
; CHECK-NEXT: .long 0
532+
define i8 @generic_test_i8() nounwind ssp uwtable {
533+
entry:
534+
%ret = call anyregcc i8 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i8(i64 14, i32 20, ptr null, i32 0)
535+
ret i8 %ret
536+
}
537+
538+
; generic_test_i16
539+
; CHECK-LABEL: .long L{{.*}}-_generic_test_i16
540+
; CHECK-NEXT: .short 0
541+
; 1 location
542+
; CHECK-NEXT: .short 1
543+
; Loc 0: Register <-- this is the return register
544+
; CHECK-NEXT: .byte 1
545+
; CHECK-NEXT: .byte 0
546+
; CHECK-NEXT: .short 4
547+
; CHECK-NEXT: .short {{[0-9]+}}
548+
; CHECK-NEXT: .short 0
549+
; CHECK-NEXT: .long 0
550+
define i16 @generic_test_i16() nounwind ssp uwtable {
551+
entry:
552+
%ret = call anyregcc i16 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i16(i64 14, i32 20, ptr null, i32 0)
553+
ret i16 %ret
554+
}
555+
556+
; generic_test_i29
557+
; CHECK-LABEL: .long L{{.*}}-_generic_test_i29
558+
; CHECK-NEXT: .short 0
559+
; 1 location
560+
; CHECK-NEXT: .short 1
561+
; Loc 0: Register <-- this is the return register
562+
; CHECK-NEXT: .byte 1
563+
; CHECK-NEXT: .byte 0
564+
; CHECK-NEXT: .short 4
565+
; CHECK-NEXT: .short {{[0-9]+}}
566+
; CHECK-NEXT: .short 0
567+
; CHECK-NEXT: .long 0
568+
define i29 @generic_test_i29() nounwind ssp uwtable {
569+
entry:
570+
%ret = call anyregcc i29 (i64, i32, ptr, i32, ...) @llvm.experimental.patchpoint.i29(i64 14, i32 20, ptr null, i32 0)
571+
ret i29 %ret
572+
}
573+
490574
; generic_test_i32
491575
; CHECK-LABEL: .long L{{.*}}-_generic_test_i32
492576
; CHECK-NEXT: .short 0

0 commit comments

Comments
 (0)