diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 3ebd3a4..e32fcfe 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -7966,17 +7966,26 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, // On arm64_32, pointers are 32 bits when stored in memory, but // zero-extended to 64 bits when in registers. Thus the mask is 32 bits to - // match the index type, but the pointer is 64 bits, so the the mask must be + // match the index type, but the pointer is 64 bits, so the mask must be // zero-extended up to 64 bits to match the pointer. EVT PtrVT = TLI.getValueType(DAG.getDataLayout(), I.getOperand(0)->getType()); EVT MemVT = TLI.getMemValueType(DAG.getDataLayout(), I.getOperand(0)->getType()); assert(PtrVT == Ptr.getValueType()); - assert(MemVT == Mask.getValueType()); - if (MemVT != PtrVT) + if (Mask.getValueType().getFixedSizeInBits() < MemVT.getFixedSizeInBits()) { + // For AMDGPU buffer descriptors the mask is 48 bits, but the pointer is + // 128-bit, so we have to pad the mask with ones for unused bits. + auto HighOnes = DAG.getNode( + ISD::SHL, sdl, PtrVT, DAG.getAllOnesConstant(sdl, PtrVT), + DAG.getShiftAmountConstant(Mask.getValueType().getFixedSizeInBits(), + PtrVT, sdl)); + Mask = DAG.getNode(ISD::OR, sdl, PtrVT, + DAG.getZExtOrTrunc(Mask, sdl, PtrVT), HighOnes); + } else if (Mask.getValueType() != PtrVT) Mask = DAG.getPtrExtOrTrunc(Mask, sdl, PtrVT); + assert(Mask.getValueType() == PtrVT); setValue(&I, DAG.getNode(ISD::AND, sdl, PtrVT, Ptr, Mask)); return; } |