mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
Generate an error message instead of asserting or segfaulting when we have a
scalar-to-vector conversion that we cannot handle. For instance, when an invalid constraint is used in an inline asm statement. <rdar://problem/12284092> llvm-svn: 164657
This commit is contained in:
parent
3e79cb01e7
commit
9a7fa167f9
@ -89,7 +89,7 @@ static const unsigned MaxParallelChains = 64;
|
||||
|
||||
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
const SDValue *Parts, unsigned NumParts,
|
||||
EVT PartVT, EVT ValueVT);
|
||||
EVT PartVT, EVT ValueVT, const Value *V);
|
||||
|
||||
/// getCopyFromParts - Create a value that contains the specified legal parts
|
||||
/// combined into the value they represent. If the parts combine to a type
|
||||
@ -99,9 +99,11 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc DL,
|
||||
const SDValue *Parts,
|
||||
unsigned NumParts, EVT PartVT, EVT ValueVT,
|
||||
const Value *V,
|
||||
ISD::NodeType AssertOp = ISD::DELETED_NODE) {
|
||||
if (ValueVT.isVector())
|
||||
return getCopyFromPartsVector(DAG, DL, Parts, NumParts, PartVT, ValueVT);
|
||||
return getCopyFromPartsVector(DAG, DL, Parts, NumParts,
|
||||
PartVT, ValueVT, V);
|
||||
|
||||
assert(NumParts > 0 && "No parts to assemble!");
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
@ -125,9 +127,9 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc DL,
|
||||
|
||||
if (RoundParts > 2) {
|
||||
Lo = getCopyFromParts(DAG, DL, Parts, RoundParts / 2,
|
||||
PartVT, HalfVT);
|
||||
PartVT, HalfVT, V);
|
||||
Hi = getCopyFromParts(DAG, DL, Parts + RoundParts / 2,
|
||||
RoundParts / 2, PartVT, HalfVT);
|
||||
RoundParts / 2, PartVT, HalfVT, V);
|
||||
} else {
|
||||
Lo = DAG.getNode(ISD::BITCAST, DL, HalfVT, Parts[0]);
|
||||
Hi = DAG.getNode(ISD::BITCAST, DL, HalfVT, Parts[1]);
|
||||
@ -143,7 +145,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc DL,
|
||||
unsigned OddParts = NumParts - RoundParts;
|
||||
EVT OddVT = EVT::getIntegerVT(*DAG.getContext(), OddParts * PartBits);
|
||||
Hi = getCopyFromParts(DAG, DL,
|
||||
Parts + RoundParts, OddParts, PartVT, OddVT);
|
||||
Parts + RoundParts, OddParts, PartVT, OddVT, V);
|
||||
|
||||
// Combine the round and odd parts.
|
||||
Lo = Val;
|
||||
@ -172,7 +174,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc DL,
|
||||
assert(ValueVT.isFloatingPoint() && PartVT.isInteger() &&
|
||||
!PartVT.isVector() && "Unexpected split");
|
||||
EVT IntVT = EVT::getIntegerVT(*DAG.getContext(), ValueVT.getSizeInBits());
|
||||
Val = getCopyFromParts(DAG, DL, Parts, NumParts, PartVT, IntVT);
|
||||
Val = getCopyFromParts(DAG, DL, Parts, NumParts, PartVT, IntVT, V);
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,14 +212,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc DL,
|
||||
llvm_unreachable("Unknown mismatch!");
|
||||
}
|
||||
|
||||
/// getCopyFromParts - Create a value that contains the specified legal parts
|
||||
/// combined into the value they represent. If the parts combine to a type
|
||||
/// larger then ValueVT then AssertOp can be used to specify whether the extra
|
||||
/// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
|
||||
/// (ISD::AssertSext).
|
||||
/// getCopyFromPartsVector - Create a value that contains the specified legal
|
||||
/// parts combined into the value they represent. If the parts combine to a
|
||||
/// type larger then ValueVT then AssertOp can be used to specify whether the
|
||||
/// extra bits are known to be zero (ISD::AssertZext) or sign extended from
|
||||
/// ValueVT (ISD::AssertSext).
|
||||
static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
const SDValue *Parts, unsigned NumParts,
|
||||
EVT PartVT, EVT ValueVT) {
|
||||
EVT PartVT, EVT ValueVT, const Value *V) {
|
||||
assert(ValueVT.isVector() && "Not a vector value");
|
||||
assert(NumParts > 0 && "No parts to assemble!");
|
||||
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
|
||||
@ -243,7 +245,7 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
// as appropriate.
|
||||
for (unsigned i = 0; i != NumParts; ++i)
|
||||
Ops[i] = getCopyFromParts(DAG, DL, &Parts[i], 1,
|
||||
PartVT, IntermediateVT);
|
||||
PartVT, IntermediateVT, V);
|
||||
} else if (NumParts > 0) {
|
||||
// If the intermediate type was expanded, build the intermediate
|
||||
// operands from the parts.
|
||||
@ -252,7 +254,7 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
unsigned Factor = NumParts / NumIntermediates;
|
||||
for (unsigned i = 0; i != NumIntermediates; ++i)
|
||||
Ops[i] = getCopyFromParts(DAG, DL, &Parts[i * Factor], Factor,
|
||||
PartVT, IntermediateVT);
|
||||
PartVT, IntermediateVT, V);
|
||||
}
|
||||
|
||||
// Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the
|
||||
@ -300,8 +302,19 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
return DAG.getNode(ISD::BITCAST, DL, ValueVT, Val);
|
||||
|
||||
// Handle cases such as i8 -> <1 x i1>
|
||||
assert(ValueVT.getVectorNumElements() == 1 &&
|
||||
"Only trivial scalar-to-vector conversions should get here!");
|
||||
if (ValueVT.getVectorNumElements() != 1) {
|
||||
LLVMContext &Ctx = *DAG.getContext();
|
||||
Twine ErrMsg("non-trivial scalar-to-vector conversion");
|
||||
if (const Instruction *I = dyn_cast_or_null<Instruction>(V)) {
|
||||
if (const CallInst *CI = dyn_cast<CallInst>(I))
|
||||
if (isa<InlineAsm>(CI->getCalledValue()))
|
||||
ErrMsg = ErrMsg + ", possible invalid constraint for vector type";
|
||||
Ctx.emitError(I, ErrMsg);
|
||||
} else {
|
||||
Ctx.emitError(ErrMsg);
|
||||
}
|
||||
report_fatal_error("Cannot handle scalar-to-vector conversion!");
|
||||
}
|
||||
|
||||
if (ValueVT.getVectorNumElements() == 1 &&
|
||||
ValueVT.getVectorElementType() != PartVT) {
|
||||
@ -313,9 +326,6 @@ static SDValue getCopyFromPartsVector(SelectionDAG &DAG, DebugLoc DL,
|
||||
return DAG.getNode(ISD::BUILD_VECTOR, DL, ValueVT, Val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void getCopyToPartsVector(SelectionDAG &DAG, DebugLoc dl,
|
||||
SDValue Val, SDValue *Parts, unsigned NumParts,
|
||||
EVT PartVT);
|
||||
@ -622,7 +632,8 @@ namespace {
|
||||
/// If the Flag pointer is NULL, no flag is used.
|
||||
SDValue getCopyFromRegs(SelectionDAG &DAG, FunctionLoweringInfo &FuncInfo,
|
||||
DebugLoc dl,
|
||||
SDValue &Chain, SDValue *Flag) const;
|
||||
SDValue &Chain, SDValue *Flag,
|
||||
const Value *V = 0) const;
|
||||
|
||||
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
|
||||
/// specified value into the registers specified by this object. This uses
|
||||
@ -648,7 +659,8 @@ namespace {
|
||||
SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
|
||||
FunctionLoweringInfo &FuncInfo,
|
||||
DebugLoc dl,
|
||||
SDValue &Chain, SDValue *Flag) const {
|
||||
SDValue &Chain, SDValue *Flag,
|
||||
const Value *V) const {
|
||||
// A Value with type {} or [0 x %t] needs no registers.
|
||||
if (ValueVTs.empty())
|
||||
return SDValue();
|
||||
@ -722,7 +734,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
|
||||
}
|
||||
|
||||
Values[Value] = getCopyFromParts(DAG, dl, Parts.begin(),
|
||||
NumRegs, RegisterVT, ValueVT);
|
||||
NumRegs, RegisterVT, ValueVT, V);
|
||||
Part += NumRegs;
|
||||
Parts.clear();
|
||||
}
|
||||
@ -994,7 +1006,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
|
||||
unsigned InReg = It->second;
|
||||
RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType());
|
||||
SDValue Chain = DAG.getEntryNode();
|
||||
N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL);
|
||||
N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL, V);
|
||||
resolveDanglingDebugInfo(V, N);
|
||||
return N;
|
||||
}
|
||||
@ -1149,7 +1161,7 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
|
||||
unsigned InReg = FuncInfo.InitializeRegForValue(Inst);
|
||||
RegsForValue RFV(*DAG.getContext(), TLI, InReg, Inst->getType());
|
||||
SDValue Chain = DAG.getEntryNode();
|
||||
return RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL);
|
||||
return RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL, V);
|
||||
}
|
||||
|
||||
llvm_unreachable("Can't get register for value!");
|
||||
@ -6336,7 +6348,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
|
||||
// and set it as the value of the call.
|
||||
if (!RetValRegs.Regs.empty()) {
|
||||
SDValue Val = RetValRegs.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(),
|
||||
Chain, &Flag);
|
||||
Chain, &Flag, CS.getInstruction());
|
||||
|
||||
// FIXME: Why don't we do this for inline asms with MRVs?
|
||||
if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) {
|
||||
@ -6376,7 +6388,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
|
||||
RegsForValue &OutRegs = IndirectStoresToEmit[i].first;
|
||||
const Value *Ptr = IndirectStoresToEmit[i].second;
|
||||
SDValue OutVal = OutRegs.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(),
|
||||
Chain, &Flag);
|
||||
Chain, &Flag, IA);
|
||||
StoresToEmit.push_back(std::make_pair(OutVal, Ptr));
|
||||
}
|
||||
|
||||
@ -6572,7 +6584,7 @@ TargetLowering::LowerCallTo(TargetLowering::CallLoweringInfo &CLI) const {
|
||||
unsigned NumRegs = getNumRegisters(CLI.RetTy->getContext(), VT);
|
||||
|
||||
ReturnValues.push_back(getCopyFromParts(CLI.DAG, CLI.DL, &InVals[CurReg],
|
||||
NumRegs, RegisterVT, VT,
|
||||
NumRegs, RegisterVT, VT, NULL,
|
||||
AssertOp));
|
||||
CurReg += NumRegs;
|
||||
}
|
||||
@ -6753,7 +6765,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
|
||||
EVT RegVT = TLI.getRegisterType(*CurDAG->getContext(), VT);
|
||||
ISD::NodeType AssertOp = ISD::DELETED_NODE;
|
||||
SDValue ArgValue = getCopyFromParts(DAG, dl, &InVals[0], 1,
|
||||
RegVT, VT, AssertOp);
|
||||
RegVT, VT, NULL, AssertOp);
|
||||
|
||||
MachineFunction& MF = SDB->DAG.getMachineFunction();
|
||||
MachineRegisterInfo& RegInfo = MF.getRegInfo();
|
||||
@ -6794,7 +6806,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) {
|
||||
|
||||
ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i],
|
||||
NumParts, PartVT, VT,
|
||||
AssertOp));
|
||||
NULL, AssertOp));
|
||||
}
|
||||
|
||||
i += NumParts;
|
||||
|
11
test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv.ll
Normal file
11
test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv.ll
Normal file
@ -0,0 +1,11 @@
|
||||
; RUN: llc < %s -march=arm -mcpu=cortex-a8 2>&1 | FileCheck %s
|
||||
|
||||
; Check for error message:
|
||||
; CHECK: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
|
||||
|
||||
define void @f() nounwind ssp {
|
||||
%1 = call { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } asm "vldm $4, { ${0:q}, ${1:q}, ${2:q}, ${3:q} }", "=r,=r,=r,=r,r"(i64* undef) nounwind, !srcloc !0
|
||||
ret void
|
||||
}
|
||||
|
||||
!0 = metadata !{i32 318437}
|
Loading…
Reference in New Issue
Block a user