diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -19641,28 +19641,30 @@ The third is the explicit vector length of the operation. The return type and underlying type of the base pointer are the same vector types. +The :ref:`align ` parameter attribute can be provided for the first +operand. + Semantics: """""""""" The '``llvm.vp.load``' intrinsic reads a vector from memory in the same way as the '``llvm.masked.load``' intrinsic, where the mask is taken from the -combination of the '``mask``' and '``evl``' operands in the usual VP way. Of -the '``llvm.masked.load``' operands not set by '``llvm.vp.load``': the -'``passthru``' operand is implicitly ``undef``; the '``alignment``' operand is -taken as the ABI alignment of the return type as specified by the -:ref:`datalayout string`. +combination of the '``mask``' and '``evl``' operands in the usual VP way. +Certain '``llvm.masked.load``' operands do not have corresponding operands in +'``llvm.vp.load``': the '``passthru``' operand is implicitly ``undef``; the +'``alignment``' operand is taken as the ``align`` parameter attribute, if +provided. The default alignment is taken as the ABI alignment of the return +type as specified by the :ref:`datalayout string`. Examples: """"""""" .. code-block:: text - %r = call <8 x i8> @llvm.vp.load.v8i8.p0v8i8(<8 x i8>* %ptr, <8 x i1> %mask, i32 %evl) + %r = call <8 x i8> @llvm.vp.load.v8i8.p0v8i8(<8 x i8>* align 2 %ptr, <8 x i1> %mask, i32 %evl) ;; For all lanes below %evl, %r is lane-wise equivalent to %also.r - ;; Note that since the alignment is ultimately up to the data layout - ;; string, 8 (the default) is used as an example. - %also.r = call <8 x i8> @llvm.masked.load.v8i8.p0v8i8(<8 x i8>* %ptr, i32 8, <8 x i1> %mask, <8 x i8> undef) + %also.r = call <8 x i8> @llvm.masked.load.v8i8.p0v8i8(<8 x i8>* %ptr, i32 2, <8 x i1> %mask, <8 x i8> undef) .. _int_vp_store: @@ -19696,28 +19698,30 @@ same number of elements as the return type. The fourth is the explicit vector length of the operation. +The :ref:`align ` parameter attribute can be provided for the +second operand. + Semantics: """""""""" The '``llvm.vp.store``' intrinsic reads a vector from memory in the same way as the '``llvm.masked.store``' intrinsic, where the mask is taken from the combination of the '``mask``' and '``evl``' operands in the usual VP way. The -'``alignment``' operand of the '``llvm.masked.store``' intrinsic is not set by -'``llvm.vp.store``': it is taken as the ABI alignment of the type of the +alignment of the operation (corresponding to the '``alignment``' operand of +'``llvm.masked.store``') is specified by the ``align`` parameter attribute (see +above). If it is not provided then the ABI alignment of the type of the '``value``' operand as specified by the :ref:`datalayout -string`. +string` is used instead. Examples: """"""""" .. code-block:: text - call void @llvm.vp.store.v8i8.p0v8i8(<8 x i8> %val, <8 x i8>* %ptr, <8 x i1> %mask, i32 %evl) + call void @llvm.vp.store.v8i8.p0v8i8(<8 x i8> %val, <8 x i8>* align 4 %ptr, <8 x i1> %mask, i32 %evl) ;; For all lanes below %evl, the call above is lane-wise equivalent to the call below. - ;; Note that since the alignment is ultimately up to the data layout - ;; string, 8 (the default) is used as an example. - call void @llvm.masked.store.v8i8.p0v8i8(<8 x i8> %val, <8 x i8>* %ptr, i32 8, <8 x i1> %mask) + call void @llvm.masked.store.v8i8.p0v8i8(<8 x i8> %val, <8 x i8>* %ptr, i32 4, <8 x i1> %mask) .. _int_vp_gather: diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -568,9 +568,9 @@ void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic); void visitConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI); void visitVPLoadGather(const VPIntrinsic &VPIntrin, EVT VT, - SmallVector &OpValues, bool isGather); + SmallVector &OpValues, bool IsGather); void visitVPStoreScatter(const VPIntrinsic &VPIntrin, - SmallVector &OpValues, bool isScatter); + SmallVector &OpValues, bool IsScatter); void visitVectorPredicationIntrinsic(const VPIntrinsic &VPIntrin); void visitVAStart(const CallInst &I); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -7317,16 +7317,18 @@ void SelectionDAGBuilder::visitVPLoadGather(const VPIntrinsic &VPIntrin, EVT VT, SmallVector &OpValues, - bool isGather) { + bool IsGather) { SDLoc DL = getCurSDLoc(); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); Value *PtrOperand = VPIntrin.getArgOperand(0); - MaybeAlign Alignment = DAG.getEVTAlign(VT); + MaybeAlign Alignment = VPIntrin.getPointerAlignment(); + if (!Alignment) + Alignment = DAG.getEVTAlign(VT); AAMDNodes AAInfo = VPIntrin.getAAMetadata(); const MDNode *Ranges = VPIntrin.getMetadata(LLVMContext::MD_range); SDValue LD; bool AddToChain = true; - if (!isGather) { + if (!IsGather) { // Do not serialize variable-length loads of constant memory with // anything. MemoryLocation ML; @@ -7380,15 +7382,17 @@ void SelectionDAGBuilder::visitVPStoreScatter(const VPIntrinsic &VPIntrin, SmallVector &OpValues, - bool isScatter) { + bool IsScatter) { SDLoc DL = getCurSDLoc(); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); Value *PtrOperand = VPIntrin.getArgOperand(1); EVT VT = OpValues[0].getValueType(); - MaybeAlign Alignment = DAG.getEVTAlign(VT); + MaybeAlign Alignment = VPIntrin.getPointerAlignment(); + if (!Alignment) + Alignment = DAG.getEVTAlign(VT); AAMDNodes AAInfo = VPIntrin.getAAMetadata(); SDValue ST; - if (!isScatter) { + if (!IsScatter) { MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand( MachinePointerInfo(PtrOperand), MachineMemOperand::MOStore, VT.getStoreSize().getKnownMinSize(), *Alignment, AAInfo);