aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp46
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.h2
2 files changed, 33 insertions, 15 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index bfe137b..5490c3c 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -156,6 +156,17 @@ static const MCPhysReg GPRArgRegs[] = {
ARM::R0, ARM::R1, ARM::R2, ARM::R3
};
+static SDValue handleCMSEValue(const SDValue &Value, const ISD::InputArg &Arg,
+ SelectionDAG &DAG, const SDLoc &DL) {
+ assert(Arg.ArgVT.isScalarInteger());
+ assert(Arg.ArgVT.bitsLT(MVT::i32));
+ SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, Arg.ArgVT, Value);
+ SDValue Ext =
+ DAG.getNode(Arg.Flags.isSExt() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, DL,
+ MVT::i32, Trunc);
+ return Ext;
+}
+
void ARMTargetLowering::addTypeForNEON(MVT VT, MVT PromotedLdStVT) {
if (VT != PromotedLdStVT) {
setOperationAction(ISD::LOAD, VT, Promote);
@@ -2193,7 +2204,7 @@ SDValue ARMTargetLowering::LowerCallResult(
SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
- SDValue ThisVal) const {
+ SDValue ThisVal, bool isCmseNSCall) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
@@ -2271,6 +2282,15 @@ SDValue ARMTargetLowering::LowerCallResult(
(VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
Val = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), Val);
+ // On CMSE Non-secure Calls, call results (returned values) whose bitwidth
+ // is less than 32 bits must be sign- or zero-extended after the call for
+ // security reasons. Although the ABI mandates an extension done by the
+ // callee, the latter cannot be trusted to follow the rules of the ABI.
+ const ISD::InputArg &Arg = Ins[VA.getValNo()];
+ if (isCmseNSCall && Arg.ArgVT.isScalarInteger() &&
+ VA.getLocVT().isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
+ Val = handleCMSEValue(Val, Arg, DAG, dl);
+
InVals.push_back(Val);
}
@@ -2882,7 +2902,7 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// return.
return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl, DAG,
InVals, isThisReturn,
- isThisReturn ? OutVals[0] : SDValue());
+ isThisReturn ? OutVals[0] : SDValue(), isCmseNSCall);
}
/// HandleByVal - Every parameter *after* a byval parameter is passed
@@ -4485,8 +4505,6 @@ SDValue ARMTargetLowering::LowerFormalArguments(
*DAG.getContext());
CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, isVarArg));
- SmallVector<SDValue, 16> ArgValues;
- SDValue ArgValue;
Function::const_arg_iterator CurOrigArg = MF.getFunction().arg_begin();
unsigned CurArgIdx = 0;
@@ -4541,6 +4559,7 @@ SDValue ARMTargetLowering::LowerFormalArguments(
// Arguments stored in registers.
if (VA.isRegLoc()) {
EVT RegVT = VA.getLocVT();
+ SDValue ArgValue;
if (VA.needsCustom() && VA.getLocVT() == MVT::v2f64) {
// f64 and vector types are split up into multiple registers or
@@ -4604,16 +4623,6 @@ SDValue ARMTargetLowering::LowerFormalArguments(
case CCValAssign::BCvt:
ArgValue = DAG.getNode(ISD::BITCAST, dl, VA.getValVT(), ArgValue);
break;
- case CCValAssign::SExt:
- ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
- DAG.getValueType(VA.getValVT()));
- ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
- break;
- case CCValAssign::ZExt:
- ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
- DAG.getValueType(VA.getValVT()));
- ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
- break;
}
// f16 arguments have their size extended to 4 bytes and passed as if they
@@ -4623,6 +4632,15 @@ SDValue ARMTargetLowering::LowerFormalArguments(
(VA.getValVT() == MVT::f16 || VA.getValVT() == MVT::bf16))
ArgValue = MoveToHPR(dl, DAG, VA.getLocVT(), VA.getValVT(), ArgValue);
+ // On CMSE Entry Functions, formal integer arguments whose bitwidth is
+ // less than 32 bits must be sign- or zero-extended in the callee for
+ // security reasons. Although the ABI mandates an extension done by the
+ // caller, the latter cannot be trusted to follow the rules of the ABI.
+ const ISD::InputArg &Arg = Ins[VA.getValNo()];
+ if (AFI->isCmseNSEntryFunction() && Arg.ArgVT.isScalarInteger() &&
+ RegVT.isScalarInteger() && Arg.ArgVT.bitsLT(MVT::i32))
+ ArgValue = handleCMSEValue(ArgValue, Arg, DAG, dl);
+
InVals.push_back(ArgValue);
} else { // VA.isRegLoc()
// Only arguments passed on the stack should make it here.
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index 62a52bd..a255e9b 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -894,7 +894,7 @@ class VectorType;
const SmallVectorImpl<ISD::InputArg> &Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals, bool isThisReturn,
- SDValue ThisVal) const;
+ SDValue ThisVal, bool isCmseNSCall) const;
bool supportSplitCSR(MachineFunction *MF) const override {
return MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS &&