From 1d755571108631c80b099d5bd74d84ef41d66d41 Mon Sep 17 00:00:00 2001 From: Jacques Pienaar Date: Wed, 21 Sep 2016 01:57:57 +0000 Subject: [PATCH] [NVPTX] Check if callsite is defined when computing argument allignment Summary: In getArgumentAlignment check if the ImmutableCallSite pointer CS is non-null before dereferencing. If CS is 0x0 fall back to the ABI type alignment else compute the alignment as before. Reviewers: eliben, jpienaar Subscribers: jlebar, vchuravy, cfe-commits, jholewinski Differential Revision: https://reviews.llvm.org/D9168 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282045 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/NVPTX/NVPTXISelLowering.cpp | 30 +++++++++++++++----------- lib/Target/NVPTX/NVPTXISelLowering.h | 3 ++- test/CodeGen/NVPTX/zero-cs.ll | 10 +++++++++ 3 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 test/CodeGen/NVPTX/zero-cs.ll diff --git a/lib/Target/NVPTX/NVPTXISelLowering.cpp b/lib/Target/NVPTX/NVPTXISelLowering.cpp index 696e57800182..db31d030e9c4 100644 --- a/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -1024,11 +1024,15 @@ std::string NVPTXTargetLowering::getPrototype( return O.str(); } -unsigned -NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, - const ImmutableCallSite *CS, - Type *Ty, - unsigned Idx) const { +unsigned NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, + const ImmutableCallSite *CS, + Type *Ty, unsigned Idx, + const DataLayout &DL) const { + if (!CS) { + // CallSite is zero, fallback to ABI type alignment + return DL.getABITypeAlignment(Ty); + } + unsigned Align = 0; const Value *DirectCallee = CS->getCalledFunction(); @@ -1046,7 +1050,7 @@ NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, const Value *CalleeV = cast(CalleeI)->getCalledValue(); // Ignore any bitcast instructions - while(isa(CalleeV)) { + while (isa(CalleeV)) { const ConstantExpr *CE = cast(CalleeV); if (!CE->isCast()) break; @@ -1069,7 +1073,6 @@ NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, // Call is indirect or alignment information is not available, fall back to // the ABI type alignment - auto &DL = CS->getCaller()->getParent()->getDataLayout(); return DL.getABITypeAlignment(Ty); } @@ -1126,7 +1129,8 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, ComputePTXValueVTs(*this, DAG.getDataLayout(), Ty, vtparts, &Offsets, 0); - unsigned align = getArgumentAlignment(Callee, CS, Ty, paramCount + 1); + unsigned align = + getArgumentAlignment(Callee, CS, Ty, paramCount + 1, DL); // declare .param .align .b8 .param[]; unsigned sz = DL.getTypeAllocSize(Ty); SDVTList DeclareParamVTs = DAG.getVTList(MVT::Other, MVT::Glue); @@ -1166,7 +1170,8 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } if (Ty->isVectorTy()) { EVT ObjectVT = getValueType(DL, Ty); - unsigned align = getArgumentAlignment(Callee, CS, Ty, paramCount + 1); + unsigned align = + getArgumentAlignment(Callee, CS, Ty, paramCount + 1, DL); // declare .param .align .b8 .param[]; unsigned sz = DL.getTypeAllocSize(Ty); SDVTList DeclareParamVTs = DAG.getVTList(MVT::Other, MVT::Glue); @@ -1426,7 +1431,7 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, DeclareRetOps); InFlag = Chain.getValue(1); } else { - retAlignment = getArgumentAlignment(Callee, CS, retTy, 0); + retAlignment = getArgumentAlignment(Callee, CS, retTy, 0, DL); SDVTList DeclareRetVTs = DAG.getVTList(MVT::Other, MVT::Glue); SDValue DeclareRetOps[] = { Chain, DAG.getConstant(retAlignment, dl, MVT::i32), @@ -1633,9 +1638,10 @@ SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, } else { SmallVector VTs; SmallVector Offsets; - ComputePTXValueVTs(*this, DAG.getDataLayout(), retTy, VTs, &Offsets, 0); + auto &DL = DAG.getDataLayout(); + ComputePTXValueVTs(*this, DL, retTy, VTs, &Offsets, 0); assert(VTs.size() == Ins.size() && "Bad value decomposition"); - unsigned RetAlign = getArgumentAlignment(Callee, CS, retTy, 0); + unsigned RetAlign = getArgumentAlignment(Callee, CS, retTy, 0, DL); for (unsigned i = 0, e = Ins.size(); i != e; ++i) { unsigned sz = VTs[i].getSizeInBits(); unsigned AlignI = GreatestCommonDivisor64(RetAlign, Offsets[i]); diff --git a/lib/Target/NVPTX/NVPTXISelLowering.h b/lib/Target/NVPTX/NVPTXISelLowering.h index 1c32232024d1..e433aed7781b 100644 --- a/lib/Target/NVPTX/NVPTXISelLowering.h +++ b/lib/Target/NVPTX/NVPTXISelLowering.h @@ -539,7 +539,8 @@ class NVPTXTargetLowering : public TargetLowering { SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; unsigned getArgumentAlignment(SDValue Callee, const ImmutableCallSite *CS, - Type *Ty, unsigned Idx) const; + Type *Ty, unsigned Idx, + const DataLayout &DL) const; }; } // namespace llvm diff --git a/test/CodeGen/NVPTX/zero-cs.ll b/test/CodeGen/NVPTX/zero-cs.ll new file mode 100644 index 000000000000..f9c8472d4fdf --- /dev/null +++ b/test/CodeGen/NVPTX/zero-cs.ll @@ -0,0 +1,10 @@ +; RUN: not llc < %s -march=nvptx 2>&1 | FileCheck %s +; used to seqfault and now fails with a "Cannot select" + +; CHECK: LLVM ERROR: Cannot select: t7: i32 = ExternalSymbol'__powidf2' +define double @powi() { + %1 = call double @llvm.powi.f64(double 1.000000e+00, i32 undef) + ret double %1 +} + +declare double @llvm.powi.f64(double, i32) nounwind readnone