[llvm] eca62f9 - [LoongArch] Diagnose the behavior of reading and writing registers that do not conform to the hardware register size
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 23 18:42:41 PST 2022
Author: gonglingqin
Date: 2022-11-24T10:38:44+08:00
New Revision: eca62f92045ca8d2896a1e2ee2113056a13596ef
URL: https://github.com/llvm/llvm-project/commit/eca62f92045ca8d2896a1e2ee2113056a13596ef
DIFF: https://github.com/llvm/llvm-project/commit/eca62f92045ca8d2896a1e2ee2113056a13596ef.diff
LOG: [LoongArch] Diagnose the behavior of reading and writing registers that do not conform to the hardware register size
When reading or writing a register that does not conform to the size of a
hardware register, an error message is generated instead of a compiler crash.
Differential Revision: https://reviews.llvm.org/D138008
Added:
llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll
llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll
Modified:
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/lib/Target/LoongArch/LoongArchISelLowering.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index d80d292f0691e..4f341c8cbb613 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -93,6 +93,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::CTLZ, MVT::i32, Custom);
setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom);
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i32, Custom);
+ setOperationAction(ISD::READ_REGISTER, MVT::i32, Custom);
+ setOperationAction(ISD::WRITE_REGISTER, MVT::i32, Custom);
if (Subtarget.hasBasicF() && !Subtarget.hasBasicD())
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
if (Subtarget.hasBasicF())
@@ -118,6 +120,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
} else {
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
+ setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom);
+ setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom);
}
static const ISD::CondCode FPCCToExpand[] = {
@@ -244,10 +248,30 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
return lowerFRAMEADDR(Op, DAG);
case ISD::RETURNADDR:
return lowerRETURNADDR(Op, DAG);
+ case ISD::WRITE_REGISTER:
+ return lowerWRITE_REGISTER(Op, DAG);
}
return SDValue();
}
+SDValue LoongArchTargetLowering::lowerWRITE_REGISTER(SDValue Op,
+ SelectionDAG &DAG) const {
+
+ if (Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i32) {
+ DAG.getContext()->emitError(
+ "On LA64, only 64-bit registers can be written.");
+ return Op.getOperand(0);
+ }
+
+ if (!Subtarget.is64Bit() && Op.getOperand(2).getValueType() == MVT::i64) {
+ DAG.getContext()->emitError(
+ "On LA32, only 32-bit registers can be written.");
+ return Op.getOperand(0);
+ }
+
+ return Op;
+}
+
SDValue LoongArchTargetLowering::lowerFRAMEADDR(SDValue Op,
SelectionDAG &DAG) const {
if (!isa<ConstantSDNode>(Op.getOperand(0))) {
@@ -927,6 +951,17 @@ void LoongArchTargetLowering::ReplaceNodeResults(
}
break;
}
+ case ISD::READ_REGISTER: {
+ if (Subtarget.is64Bit())
+ DAG.getContext()->emitError(
+ "On LA64, only 64-bit registers can be read.");
+ else
+ DAG.getContext()->emitError(
+ "On LA32, only 32-bit registers can be read.");
+ Results.push_back(DAG.getUNDEF(N->getValueType(0)));
+ Results.push_back(N->getOperand(0));
+ break;
+ }
}
}
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 6f98e40c41d39..4f650feee47a0 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -192,6 +192,7 @@ class LoongArchTargetLowering : public TargetLowering {
SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;
diff --git a/llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll b/llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll
new file mode 100644
index 0000000000000..7440bfe5c85a5
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/get-reg-error-la32.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: not llc < %s --mtriple=loongarch32 2>&1 | FileCheck %s
+
+define i64 @read_sp() nounwind {
+entry:
+; CHECK: On LA32, only 32-bit registers can be read.
+ %a1 = call i64 @llvm.read_register.i64(metadata !0)
+ ret i64 %a1
+}
+
+define void @write_sp(i64 %val) nounwind {
+entry:
+; CHECK: On LA32, only 32-bit registers can be written.
+ call void @llvm.write_register.i64(metadata !0, i64 %val)
+ ret void
+}
+
+declare i64 @llvm.read_register.i64(metadata) nounwind
+declare void @llvm.write_register.i64(metadata, i64) nounwind
+
+!0 = !{!"$sp\00"}
diff --git a/llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll b/llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll
new file mode 100644
index 0000000000000..9312aa9020ba9
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/get-reg-error-la64.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: not llc < %s --mtriple=loongarch64 2>&1 | FileCheck %s
+
+define i32 @read_sp() nounwind {
+entry:
+; CHECK: On LA64, only 64-bit registers can be read.
+ %a1 = call i32 @llvm.read_register.i32(metadata !0)
+ ret i32 %a1
+}
+
+define void @write_sp(i32 %val) nounwind {
+entry:
+; CHECK: On LA64, only 64-bit registers can be written.
+ call void @llvm.write_register.i32(metadata !0, i32 %val)
+ ret void
+}
+
+declare i32 @llvm.read_register.i32(metadata) nounwind
+declare void @llvm.write_register.i32(metadata, i32) nounwind
+
+!0 = !{!"$sp\00"}
More information about the llvm-commits
mailing list