Skip to content

Commit 1461a1c

Browse files
authored
DAG: Emit an error if trying to legalize read/write register with illegal types (#145197)
This is a starting point to have better legalization failure diagnostics
1 parent a4bbfd5 commit 1461a1c

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

llvm/include/llvm/IR/DiagnosticInfo.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ enum DiagnosticKind {
6868
DK_StackSize,
6969
DK_Linker,
7070
DK_Lowering,
71+
DK_LegalizationFailure,
7172
DK_DebugMetadataVersion,
7273
DK_DebugMetadataInvalid,
7374
DK_Instrumentation,
@@ -383,6 +384,30 @@ class LLVM_ABI DiagnosticInfoWithLocationBase : public DiagnosticInfo {
383384
DiagnosticLocation Loc;
384385
};
385386

387+
class LLVM_ABI DiagnosticInfoLegalizationFailure
388+
: public DiagnosticInfoWithLocationBase {
389+
private:
390+
/// Message to be reported.
391+
const Twine &MsgStr;
392+
393+
public:
394+
DiagnosticInfoLegalizationFailure(const Twine &MsgStr LLVM_LIFETIME_BOUND,
395+
const Function &Fn,
396+
const DiagnosticLocation &Loc,
397+
DiagnosticSeverity Severity = DS_Error)
398+
: DiagnosticInfoWithLocationBase(DK_LegalizationFailure, Severity, Fn,
399+
Loc),
400+
MsgStr(MsgStr) {}
401+
402+
const Twine &getMsgStr() const { return MsgStr; }
403+
404+
void print(DiagnosticPrinter &DP) const override;
405+
406+
static bool classof(const DiagnosticInfo *DI) {
407+
return DI->getKind() == DK_LegalizationFailure;
408+
}
409+
};
410+
386411
class LLVM_ABI DiagnosticInfoGenericWithLoc
387412
: public DiagnosticInfoWithLocationBase {
388413
private:

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/CodeGen/StackMaps.h"
2323
#include "llvm/CodeGen/TargetLowering.h"
2424
#include "llvm/IR/DerivedTypes.h"
25+
#include "llvm/IR/DiagnosticInfo.h"
2526
#include "llvm/Support/ErrorHandling.h"
2627
#include "llvm/Support/KnownBits.h"
2728
#include "llvm/Support/raw_ostream.h"
@@ -357,6 +358,9 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
357358
case ISD::PATCHPOINT:
358359
Res = PromoteIntRes_PATCHPOINT(N);
359360
break;
361+
case ISD::READ_REGISTER:
362+
Res = PromoteIntRes_READ_REGISTER(N);
363+
break;
360364
}
361365

362366
// If the result is null then the sub-method took care of registering it.
@@ -2076,6 +2080,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
20762080
case ISD::PATCHPOINT:
20772081
Res = PromoteIntOp_PATCHPOINT(N, OpNo);
20782082
break;
2083+
case ISD::WRITE_REGISTER:
2084+
Res = PromoteIntOp_WRITE_REGISTER(N, OpNo);
2085+
break;
20792086
case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
20802087
case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
20812088
Res = PromoteIntOp_VP_STRIDED(N, OpNo);
@@ -2853,6 +2860,15 @@ SDValue DAGTypeLegalizer::PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo) {
28532860
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
28542861
}
28552862

2863+
SDValue DAGTypeLegalizer::PromoteIntOp_WRITE_REGISTER(SDNode *N,
2864+
unsigned OpNo) {
2865+
const Function &Fn = DAG.getMachineFunction().getFunction();
2866+
Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
2867+
"cannot use llvm.write_register with illegal type", Fn,
2868+
N->getDebugLoc()));
2869+
return N->getOperand(0);
2870+
}
2871+
28562872
SDValue DAGTypeLegalizer::PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
28572873
assert((N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD && OpNo == 3) ||
28582874
(N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE && OpNo == 4));
@@ -3127,6 +3143,10 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
31273143
case ISD::VSCALE:
31283144
ExpandIntRes_VSCALE(N, Lo, Hi);
31293145
break;
3146+
3147+
case ISD::READ_REGISTER:
3148+
ExpandIntRes_READ_REGISTER(N, Lo, Hi);
3149+
break;
31303150
}
31313151

31323152
// If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -5471,6 +5491,18 @@ void DAGTypeLegalizer::ExpandIntRes_VSCALE(SDNode *N, SDValue &Lo,
54715491
SplitInteger(Res, Lo, Hi);
54725492
}
54735493

5494+
void DAGTypeLegalizer::ExpandIntRes_READ_REGISTER(SDNode *N, SDValue &Lo,
5495+
SDValue &Hi) {
5496+
const Function &Fn = DAG.getMachineFunction().getFunction();
5497+
Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
5498+
"cannot use llvm.read_register with illegal type", Fn, N->getDebugLoc()));
5499+
ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
5500+
EVT LoVT, HiVT;
5501+
std::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
5502+
Lo = DAG.getPOISON(LoVT);
5503+
Hi = DAG.getPOISON(HiVT);
5504+
}
5505+
54745506
//===----------------------------------------------------------------------===//
54755507
// Integer Operand Expansion
54765508
//===----------------------------------------------------------------------===//
@@ -5537,6 +5569,9 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
55375569
case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
55385570
Res = ExpandIntOp_VP_STRIDED(N, OpNo);
55395571
break;
5572+
case ISD::WRITE_REGISTER:
5573+
Res = ExpandIntOp_WRITE_REGISTER(N, OpNo);
5574+
break;
55405575
}
55415576

55425577
// If the result is null, the sub-method took care of registering results etc.
@@ -5935,6 +5970,15 @@ SDValue DAGTypeLegalizer::ExpandIntOp_VP_STRIDED(SDNode *N, unsigned OpNo) {
59355970
return SDValue(DAG.UpdateNodeOperands(N, NewOps), 0);
59365971
}
59375972

5973+
SDValue DAGTypeLegalizer::ExpandIntOp_WRITE_REGISTER(SDNode *N, unsigned OpNo) {
5974+
const Function &Fn = DAG.getMachineFunction().getFunction();
5975+
Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
5976+
"cannot use llvm.write_register with illegal type", Fn,
5977+
N->getDebugLoc()));
5978+
5979+
return N->getOperand(0);
5980+
}
5981+
59385982
SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SPLICE(SDNode *N) {
59395983
SDLoc dl(N);
59405984

@@ -6332,6 +6376,16 @@ SDValue DAGTypeLegalizer::PromoteIntRes_PATCHPOINT(SDNode *N) {
63326376
return Res.getValue(0);
63336377
}
63346378

6379+
SDValue DAGTypeLegalizer::PromoteIntRes_READ_REGISTER(SDNode *N) {
6380+
const Function &Fn = DAG.getMachineFunction().getFunction();
6381+
Fn.getContext().diagnose(DiagnosticInfoLegalizationFailure(
6382+
"cannot use llvm.read_register with illegal type", Fn, N->getDebugLoc()));
6383+
6384+
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
6385+
ReplaceValueWith(SDValue(N, 1), N->getOperand(0));
6386+
return DAG.getPOISON(NVT);
6387+
}
6388+
63356389
SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) {
63366390
SDLoc dl(N);
63376391
SDValue V0 = GetPromotedInteger(N->getOperand(0));

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
378378
SDValue PromoteIntRes_VPFunnelShift(SDNode *N);
379379
SDValue PromoteIntRes_IS_FPCLASS(SDNode *N);
380380
SDValue PromoteIntRes_PATCHPOINT(SDNode *N);
381+
SDValue PromoteIntRes_READ_REGISTER(SDNode *N);
381382
SDValue PromoteIntRes_VECTOR_FIND_LAST_ACTIVE(SDNode *N);
382383
SDValue PromoteIntRes_GET_ACTIVE_LANE_MASK(SDNode *N);
383384
SDValue PromoteIntRes_PARTIAL_REDUCE_MLA(SDNode *N);
@@ -428,6 +429,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
428429
SDValue PromoteIntOp_SET_ROUNDING(SDNode *N);
429430
SDValue PromoteIntOp_STACKMAP(SDNode *N, unsigned OpNo);
430431
SDValue PromoteIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
432+
SDValue PromoteIntOp_WRITE_REGISTER(SDNode *N, unsigned OpNo);
431433
SDValue PromoteIntOp_VP_STRIDED(SDNode *N, unsigned OpNo);
432434
SDValue PromoteIntOp_VP_SPLICE(SDNode *N, unsigned OpNo);
433435
SDValue PromoteIntOp_VECTOR_HISTOGRAM(SDNode *N, unsigned OpNo);
@@ -511,6 +513,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
511513
void ExpandIntRes_FunnelShift (SDNode *N, SDValue &Lo, SDValue &Hi);
512514

513515
void ExpandIntRes_VSCALE (SDNode *N, SDValue &Lo, SDValue &Hi);
516+
void ExpandIntRes_READ_REGISTER(SDNode *N, SDValue &Lo, SDValue &Hi);
514517

515518
void ExpandShiftByConstant(SDNode *N, const APInt &Amt,
516519
SDValue &Lo, SDValue &Hi);
@@ -534,6 +537,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
534537
SDValue ExpandIntOp_STACKMAP(SDNode *N, unsigned OpNo);
535538
SDValue ExpandIntOp_PATCHPOINT(SDNode *N, unsigned OpNo);
536539
SDValue ExpandIntOp_VP_STRIDED(SDNode *N, unsigned OpNo);
540+
SDValue ExpandIntOp_WRITE_REGISTER(SDNode *N, unsigned OpNo);
537541

538542
void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
539543
ISD::CondCode &CCCode, const SDLoc &dl);

llvm/lib/IR/DiagnosticInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
8181
DP << " at line " << getLocCookie();
8282
}
8383

84+
void DiagnosticInfoLegalizationFailure::print(DiagnosticPrinter &DP) const {
85+
DP << getLocationStr() << ": " << getMsgStr();
86+
}
87+
8488
DiagnosticInfoRegAllocFailure::DiagnosticInfoRegAllocFailure(
8589
const Twine &MsgStr, const Function &Fn, const DiagnosticLocation &DL,
8690
DiagnosticSeverity Severity)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: not llc -mtriple=amdgcn -mcpu=gfx900 -filetype=null %s 2>&1 | FileCheck %s
2+
3+
; CHECK: error: <unknown>:0:0: cannot use llvm.read_register with illegal type
4+
define amdgpu_kernel void @test_read_register_i9(ptr addrspace(1) %out) nounwind {
5+
%reg = call i9 @llvm.read_register.i9(metadata !0)
6+
store i9 %reg, ptr addrspace(1) %out
7+
ret void
8+
}
9+
10+
; CHECK: error: <unknown>:0:0: cannot use llvm.write_register with illegal type
11+
define amdgpu_kernel void @test_write_register_i9(ptr addrspace(1) %out) nounwind {
12+
call void @llvm.write_register.i9(metadata !0, i9 42)
13+
ret void
14+
}
15+
16+
; CHECK: error: <unknown>:0:0: cannot use llvm.read_register with illegal type
17+
define amdgpu_kernel void @test_read_register_i128(ptr addrspace(1) %out) nounwind {
18+
%reg = call i128 @llvm.read_register.i128(metadata !0)
19+
store i128 %reg, ptr addrspace(1) %out
20+
ret void
21+
}
22+
23+
; CHECK: error: <unknown>:0:0: cannot use llvm.write_register with illegal type
24+
define amdgpu_kernel void @test_write_register_i128(ptr addrspace(1) %out) nounwind {
25+
call void @llvm.write_register.i128(metadata !0, i128 42)
26+
ret void
27+
}
28+
29+
!0 = !{!"m0"}

0 commit comments

Comments
 (0)