From 07a5d3dc3d99ad2bf5c1122787d37ec0e17adde6 Mon Sep 17 00:00:00 2001 From: Justin Holewinski Date: Mon, 11 Nov 2013 19:28:19 +0000 Subject: [NVPTX] Properly handle bitcast ConstantExpr when checking for the alignment of function parameters git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194410 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/NVPTX/NVPTXISelLowering.cpp | 51 +++++++++++++++++++++++++--------- test/CodeGen/NVPTX/bug17709.ll | 26 +++++++++++++++++ 2 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 test/CodeGen/NVPTX/bug17709.ll diff --git a/lib/Target/NVPTX/NVPTXISelLowering.cpp b/lib/Target/NVPTX/NVPTXISelLowering.cpp index 55caaad65b..98b9ce6e26 100644 --- a/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ b/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -471,22 +471,47 @@ NVPTXTargetLowering::getArgumentAlignment(SDValue Callee, Type *Ty, unsigned Idx) const { const DataLayout *TD = getDataLayout(); - unsigned align = 0; - GlobalAddressSDNode *Func = dyn_cast(Callee.getNode()); + unsigned Align = 0; + const Value *DirectCallee = CS->getCalledFunction(); + + if (!DirectCallee) { + // We don't have a direct function symbol, but that may be because of + // constant cast instructions in the call. + const Instruction *CalleeI = CS->getInstruction(); + assert(CalleeI && "Call target is not a function or derived value?"); + + // With bitcast'd call targets, the instruction will be the call + if (isa(CalleeI)) { + // Check if we have call alignment metadata + if (llvm::getAlign(*cast(CalleeI), Idx, Align)) + return Align; + + const Value *CalleeV = cast(CalleeI)->getCalledValue(); + // Ignore any bitcast instructions + while(isa(CalleeV)) { + const ConstantExpr *CE = cast(CalleeV); + if (!CE->isCast()) + break; + // Look through the bitcast + CalleeV = cast(CalleeV)->getOperand(0); + } - if (Func) { // direct call - assert(CS->getCalledFunction() && - "direct call cannot find callee"); - if (!llvm::getAlign(*(CS->getCalledFunction()), Idx, align)) - align = TD->getABITypeAlignment(Ty); - } - else { // indirect call - const CallInst *CallI = dyn_cast(CS->getInstruction()); - if (!llvm::getAlign(*CallI, Idx, align)) - align = TD->getABITypeAlignment(Ty); + // We have now looked past all of the bitcasts. Do we finally have a + // Function? + if (isa(CalleeV)) + DirectCallee = CalleeV; + } } - return align; + // Check for function alignment information if we found that the + // ultimate target is a Function + if (DirectCallee) + if (llvm::getAlign(*cast(DirectCallee), Idx, Align)) + return Align; + + // Call is indirect or alignment information is not available, fall back to + // the ABI type alignment + return TD->getABITypeAlignment(Ty); } SDValue NVPTXTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, diff --git a/test/CodeGen/NVPTX/bug17709.ll b/test/CodeGen/NVPTX/bug17709.ll new file mode 100644 index 0000000000..92f0fcb11e --- /dev/null +++ b/test/CodeGen/NVPTX/bug17709.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -march=nvptx -mcpu=sm_20 | FileCheck %s + +; ModuleID = '__kernelgen_main_module' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64" +target triple = "nvptx64-nvidia-cuda" + +define linker_private ptx_device { double, double } @__utils1_MOD_trace(%"struct.array2_complex(kind=8).43.5.57"* noalias %m) { +entry: + ;unreachable + %t0 = insertvalue {double, double} undef, double 1.0, 0 + %t1 = insertvalue {double, double} %t0, double 1.0, 1 + ret { double, double } %t1 +} + +%struct.descriptor_dimension.0.52 = type { i64, i64, i64 } +%"struct.array2_complex(kind=8).37.18.70" = type { i8*, i64, i64, [2 x %struct.descriptor_dimension.0.52] } +%"struct.array2_complex(kind=8).43.5.57" = type { i8*, i64, i64, [2 x %struct.descriptor_dimension.0.52] } +@replacementOfAlloca8 = private global %"struct.array2_complex(kind=8).37.18.70" zeroinitializer, align 4096 + +; CHECK: .visible .entry __kernelgen_main +define ptx_kernel void @__kernelgen_main(i32* nocapture %args, i32*) { +entry: + %1 = tail call ptx_device { double, double } bitcast ({ double, double } (%"struct.array2_complex(kind=8).43.5.57"*)* @__utils1_MOD_trace to { double, double } (%"struct.array2_complex(kind=8).37.18.70"*)*)(%"struct.array2_complex(kind=8).37.18.70"* noalias @replacementOfAlloca8) + ret void +} + -- cgit v1.2.3