summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2017-07-31 14:06:58 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2017-07-31 14:06:58 +0000
commit8930b4a0496763df8caa84ea6fe119dc72152e84 (patch)
tree281d670acb5f5ce9b3725e5e954b23d821c36474
parent8fc6cdfb1cbd3b25c14594077aca4f41e982de20 (diff)
downloadbcm5719-llvm-8930b4a0496763df8caa84ea6fe119dc72152e84.tar.gz
bcm5719-llvm-8930b4a0496763df8caa84ea6fe119dc72152e84.zip
[SelectionDAG][mips] Fix PR33883
PR33883 shows that calls to intrinsic functions should not have their vector arguments or returns subject to ABI changes required by the target. This resolves PR33883. Thanks to Alex Crichton for reporting the issue! Reviewers: zoran.jovanovic, atanasyan Differential Revision: https://reviews.llvm.org/D35765 llvm-svn: 309561
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp39
-rw-r--r--llvm/test/CodeGen/Mips/cconv/pr33883.ll12
2 files changed, 36 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 7aa59f5eb12..4e19ec32a3a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -99,6 +99,27 @@ LimitFPPrecision("limit-float-precision",
// store [4096 x i8] %data, [4096 x i8]* %buffer
static const unsigned MaxParallelChains = 64;
+// True if the Value passed requires ABI mangling as it is a parameter to a
+// function or a return value from a function which is not an intrinsic.
+static bool isABIRegCopy(const Value * V) {
+ const bool IsRetInst = V && isa<ReturnInst>(V);
+ const bool IsCallInst = V && isa<CallInst>(V);
+ const bool IsInLineAsm =
+ IsCallInst && static_cast<const CallInst *>(V)->isInlineAsm();
+ const bool IsIndirectFunctionCall =
+ IsCallInst && !IsInLineAsm &&
+ !static_cast<const CallInst *>(V)->getCalledFunction();
+ // It is possible that the call instruction is an inline asm statement or an
+ // indirect function call in which case the return value of
+ // getCalledFunction() would be nullptr.
+ const bool IsInstrinsicCall =
+ IsCallInst && !IsInLineAsm && !IsIndirectFunctionCall &&
+ static_cast<const CallInst *>(V)->getCalledFunction()->getIntrinsicID() !=
+ Intrinsic::not_intrinsic;
+
+ return IsRetInst || (IsCallInst && (!IsInLineAsm && !IsInstrinsicCall));
+}
+
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
const SDValue *Parts, unsigned NumParts,
MVT PartVT, EVT ValueVT, const Value *V,
@@ -1024,13 +1045,9 @@ SDValue SelectionDAGBuilder::getCopyFromRegs(const Value *V, Type *Ty) {
if (It != FuncInfo.ValueMap.end()) {
unsigned InReg = It->second;
- bool IsABIRegCopy =
- V && ((isa<CallInst>(V) &&
- !(static_cast<const CallInst *>(V))->isInlineAsm()) ||
- isa<ReturnInst>(V));
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
- DAG.getDataLayout(), InReg, Ty, IsABIRegCopy);
+ DAG.getDataLayout(), InReg, Ty, isABIRegCopy(V));
SDValue Chain = DAG.getEntryNode();
Result = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr,
V);
@@ -1219,13 +1236,9 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
// If this is an instruction which fast-isel has deferred, select it now.
if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
unsigned InReg = FuncInfo.InitializeRegForValue(Inst);
- bool IsABIRegCopy =
- V && ((isa<CallInst>(V) &&
- !(static_cast<const CallInst *>(V))->isInlineAsm()) ||
- isa<ReturnInst>(V));
RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
- Inst->getType(), IsABIRegCopy);
+ Inst->getType(), isABIRegCopy(V));
SDValue Chain = DAG.getEntryNode();
return RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
}
@@ -8275,13 +8288,9 @@ SelectionDAGBuilder::CopyValueToVirtualRegister(const Value *V, unsigned Reg) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// If this is an InlineAsm we have to match the registers required, not the
// notional registers required by the type.
- bool IsABIRegCopy =
- V && ((isa<CallInst>(V) &&
- !(static_cast<const CallInst *>(V))->isInlineAsm()) ||
- isa<ReturnInst>(V));
RegsForValue RFV(V->getContext(), TLI, DAG.getDataLayout(), Reg,
- V->getType(), IsABIRegCopy);
+ V->getType(), isABIRegCopy(V));
SDValue Chain = DAG.getEntryNode();
ISD::NodeType ExtendType = (FuncInfo.PreferredExtendType.find(V) ==
diff --git a/llvm/test/CodeGen/Mips/cconv/pr33883.ll b/llvm/test/CodeGen/Mips/cconv/pr33883.ll
new file mode 100644
index 00000000000..54d7286ab8f
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/cconv/pr33883.ll
@@ -0,0 +1,12 @@
+; RUN: llc -march=mips -mcpu=mips32 < %s -o /dev/null
+
+; Test that calls to vector intrinsics do not crash SelectionDAGBuilder.
+
+define <4 x float> @_ZN4simd3foo17hebb969c5fb39a194E(<4 x float>) {
+start:
+ %1 = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %0)
+
+ ret <4 x float> %1
+}
+
+declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)
OpenPOWER on IntegriCloud