Index: llvm/include/llvm/CodeGen/SelectionDAG.h =================================================================== --- llvm/include/llvm/CodeGen/SelectionDAG.h +++ llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1595,6 +1595,9 @@ void dump() const; + /// Create a stack temporary based on the size in bytes and the alignment + SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment); + /// Create a stack temporary, suitable for holding the specified value type. /// If minAlign is specified, the slot size will have at least that alignment. SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -38,6 +38,7 @@ #include "llvm/CodeGen/SelectionDAGAddressAnalysis.h" #include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/CodeGen/SelectionDAGTargetInfo.h" +#include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -1995,28 +1996,39 @@ MachinePointerInfo(VD)); } -SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) { - MachineFrameInfo &MFI = getMachineFunction().getFrameInfo(); - unsigned ByteSize = VT.getStoreSize(); - Type *Ty = VT.getTypeForEVT(*getContext()); - unsigned StackAlign = - std::max((unsigned)getDataLayout().getPrefTypeAlignment(Ty), minAlign); +SDValue SelectionDAG::CreateStackTemporary(TypeSize Bytes, Align Alignment) { + // Scalable vectors need a special StackID to distinguish them from other + // (fixed size) stack objects. + unsigned StackId = 0; + if (Bytes.isScalable()) { + const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); + StackId = TFI->getStackIDForScalableVectors(); + } - int FrameIdx = MFI.CreateStackObject(ByteSize, StackAlign, false); + MachineFrameInfo &MFI = MF->getFrameInfo(); + int FrameIdx = + MFI.CreateStackObject(Bytes, Alignment, false, nullptr, StackId); return getFrameIndex(FrameIdx, TLI->getFrameIndexTy(getDataLayout())); } +SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) { + const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); + Type *Ty = VT.getTypeForEVT(*getContext()); + const Align PrefAlign = getDataLayout().getPrefTypeAlign(Ty); + const Align StackAlign = TFI->getStackAlign(); + const Align Alignment = + std::max(std::min(PrefAlign, StackAlign), Align(minAlign)); + return CreateStackTemporary(VT.getStoreSize(), Alignment); +} + SDValue SelectionDAG::CreateStackTemporary(EVT VT1, EVT VT2) { - unsigned Bytes = std::max(VT1.getStoreSize(), VT2.getStoreSize()); + const TypeSize Bytes = std::max(VT1.getStoreSize(), VT2.getStoreSize()); Type *Ty1 = VT1.getTypeForEVT(*getContext()); Type *Ty2 = VT2.getTypeForEVT(*getContext()); - const DataLayout &DL = getDataLayout(); - unsigned Align = - std::max(DL.getPrefTypeAlignment(Ty1), DL.getPrefTypeAlignment(Ty2)); - - MachineFrameInfo &MFI = getMachineFunction().getFrameInfo(); - int FrameIdx = MFI.CreateStackObject(Bytes, Align, false); - return getFrameIndex(FrameIdx, TLI->getFrameIndexTy(getDataLayout())); + const DataLayout DL = getDataLayout(); + Align Alignment = + std::max(DL.getPrefTypeAlign(Ty1), DL.getPrefTypeAlign(Ty2)); + return CreateStackTemporary(Bytes, Alignment); } SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1, SDValue N2, Index: llvm/test/CodeGen/AArch64/sve-insert-element.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-insert-element.ll +++ llvm/test/CodeGen/AArch64/sve-insert-element.ll @@ -133,3 +133,13 @@ %b = insertelement undef, i8 %a, i32 0 ret %b } + +; TODO: The code generated for this function is still incorrect, hence there +; is only a single CHECK line to ensure we use 'addvl' for scalable stack +; objects. +define @test_lanex_32xi8( %a, i32 %x) { +; CHECK-LABEL: test_lanex_32xi8 +; CHECK: addvl sp, sp, #-2 + %b = insertelement %a, i8 30, i32 %x + ret %b +}