Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 09c8b06

Browse files
committed
Merging r309561:
------------------------------------------------------------------------ r309561 | sdardis | 2017-07-31 07:06:58 -0700 (Mon, 31 Jul 2017) | 14 lines [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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@309767 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 498863b commit 09c8b06

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,27 @@ LimitFPPrecision("limit-float-precision",
9999
// store [4096 x i8] %data, [4096 x i8]* %buffer
100100
static const unsigned MaxParallelChains = 64;
101101

102+
// True if the Value passed requires ABI mangling as it is a parameter to a
103+
// function or a return value from a function which is not an intrinsic.
104+
static bool isABIRegCopy(const Value * V) {
105+
const bool IsRetInst = V && isa<ReturnInst>(V);
106+
const bool IsCallInst = V && isa<CallInst>(V);
107+
const bool IsInLineAsm =
108+
IsCallInst && static_cast<const CallInst *>(V)->isInlineAsm();
109+
const bool IsIndirectFunctionCall =
110+
IsCallInst && !IsInLineAsm &&
111+
!static_cast<const CallInst *>(V)->getCalledFunction();
112+
// It is possible that the call instruction is an inline asm statement or an
113+
// indirect function call in which case the return value of
114+
// getCalledFunction() would be nullptr.
115+
const bool IsInstrinsicCall =
116+
IsCallInst && !IsInLineAsm && !IsIndirectFunctionCall &&
117+
static_cast<const CallInst *>(V)->getCalledFunction()->getIntrinsicID() !=
118+
Intrinsic::not_intrinsic;
119+
120+
return IsRetInst || (IsCallInst && (!IsInLineAsm && !IsInstrinsicCall));
121+
}
122+
102123
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, const SDLoc &DL,
103124
const SDValue *Parts, unsigned NumParts,
104125
MVT PartVT, EVT ValueVT, const Value *V,
@@ -1026,13 +1047,9 @@ SDValue SelectionDAGBuilder::getCopyFromRegs(const Value *V, Type *Ty) {
10261047

10271048
if (It != FuncInfo.ValueMap.end()) {
10281049
unsigned InReg = It->second;
1029-
bool IsABIRegCopy =
1030-
V && ((isa<CallInst>(V) &&
1031-
!(static_cast<const CallInst *>(V))->isInlineAsm()) ||
1032-
isa<ReturnInst>(V));
10331050

10341051
RegsForValue RFV(*DAG.getContext(), DAG.getTargetLoweringInfo(),
1035-
DAG.getDataLayout(), InReg, Ty, IsABIRegCopy);
1052+
DAG.getDataLayout(), InReg, Ty, isABIRegCopy(V));
10361053
SDValue Chain = DAG.getEntryNode();
10371054
Result = RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr,
10381055
V);
@@ -1221,13 +1238,9 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
12211238
// If this is an instruction which fast-isel has deferred, select it now.
12221239
if (const Instruction *Inst = dyn_cast<Instruction>(V)) {
12231240
unsigned InReg = FuncInfo.InitializeRegForValue(Inst);
1224-
bool IsABIRegCopy =
1225-
V && ((isa<CallInst>(V) &&
1226-
!(static_cast<const CallInst *>(V))->isInlineAsm()) ||
1227-
isa<ReturnInst>(V));
12281241

12291242
RegsForValue RFV(*DAG.getContext(), TLI, DAG.getDataLayout(), InReg,
1230-
Inst->getType(), IsABIRegCopy);
1243+
Inst->getType(), isABIRegCopy(V));
12311244
SDValue Chain = DAG.getEntryNode();
12321245
return RFV.getCopyFromRegs(DAG, FuncInfo, getCurSDLoc(), Chain, nullptr, V);
12331246
}
@@ -8281,13 +8294,9 @@ SelectionDAGBuilder::CopyValueToVirtualRegister(const Value *V, unsigned Reg) {
82818294
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
82828295
// If this is an InlineAsm we have to match the registers required, not the
82838296
// notional registers required by the type.
8284-
bool IsABIRegCopy =
8285-
V && ((isa<CallInst>(V) &&
8286-
!(static_cast<const CallInst *>(V))->isInlineAsm()) ||
8287-
isa<ReturnInst>(V));
82888297

82898298
RegsForValue RFV(V->getContext(), TLI, DAG.getDataLayout(), Reg,
8290-
V->getType(), IsABIRegCopy);
8299+
V->getType(), isABIRegCopy(V));
82918300
SDValue Chain = DAG.getEntryNode();
82928301

82938302
ISD::NodeType ExtendType = (FuncInfo.PreferredExtendType.find(V) ==

test/CodeGen/Mips/cconv/pr33883.ll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llc -march=mips -mcpu=mips32 < %s -o /dev/null
2+
3+
; Test that calls to vector intrinsics do not crash SelectionDAGBuilder.
4+
5+
define <4 x float> @_ZN4simd3foo17hebb969c5fb39a194E(<4 x float>) {
6+
start:
7+
%1 = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %0)
8+
9+
ret <4 x float> %1
10+
}
11+
12+
declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)

0 commit comments

Comments
 (0)