Index: llvm/include/llvm/CodeGen/TargetLowering.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLowering.h +++ llvm/include/llvm/CodeGen/TargetLowering.h @@ -1888,6 +1888,14 @@ /// Return the preferred function alignment. Align getPrefFunctionAlignment() const { return PrefFunctionAlignment; } + /// Return the preferred alignment for a constant pool entry for C. + virtual Align getPrefConstantPoolAlignment(const Constant *C, + bool ShouldOptForSize, + const DataLayout &DL) const { + return ShouldOptForSize ? DL.getABITypeAlign(C->getType()) : + DL.getPrefTypeAlign(C->getType()); + } + /// Return the preferred loop alignment. virtual Align getPrefLoopAlignment(MachineLoop *ML = nullptr) const; Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1807,9 +1807,8 @@ assert((TargetFlags == 0 || isTarget) && "Cannot set target flags on target-independent globals"); if (!Alignment) - Alignment = shouldOptForSize() - ? getDataLayout().getABITypeAlign(C->getType()) - : getDataLayout().getPrefTypeAlign(C->getType()); + Alignment = TLI->getPrefConstantPoolAlignment(C, shouldOptForSize(), + getDataLayout()); unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool; FoldingSetNodeID ID; AddNodeIDNode(ID, Opc, getVTList(VT), std::nullopt); Index: llvm/lib/Target/RISCV/RISCVISelLowering.h =================================================================== --- llvm/lib/Target/RISCV/RISCVISelLowering.h +++ llvm/lib/Target/RISCV/RISCVISelLowering.h @@ -673,6 +673,10 @@ MachineMemOperand::Flags Flags = MachineMemOperand::MONone, unsigned *Fast = nullptr) const override; + /// Return the preferred alignment for a constant pool entry for C. + Align getPrefConstantPoolAlignment(const Constant *C, bool ShouldOptForSize, + const DataLayout &DL) const override; + bool splitValueIntoRegisterParts( SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional CC) Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp =================================================================== --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -16586,6 +16586,32 @@ return Subtarget.enableUnalignedVectorMem(); } +Align RISCVTargetLowering::getPrefConstantPoolAlignment(const Constant *C, + bool ShouldOptForSize, + const DataLayout &DL) const { + // Generally, our goal here is to use the smallest alignment which will be + // performant. Note that this alignment is not ABI visible, and thus we + // are safe to use something smaller than ABI alignment here. + + // For vectors, we can always use the element type's alignment. + if (isa(C->getType())) { + EVT VT = getValueType(DL, C->getType()); + EVT ElemVT = VT.getVectorElementType(); + Align ElemAlign(ElemVT.getStoreSize()); +#ifndef NDEBUG + unsigned Fast = 0; + assert(allowsMemoryAccess(C->getContext(), DL, VT, 0, ElemAlign, + MachineMemOperand::MONone, &Fast) && Fast); +#endif + return ElemAlign; + } + + // Note: i64 is the only case which hits this in practice, and thus + // there's no profit to try to reduce the alignment. + return ShouldOptForSize ? DL.getABITypeAlign(C->getType()) : + DL.getPrefTypeAlign(C->getType()); +} + bool RISCVTargetLowering::splitValueIntoRegisterParts( SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional CC) const { Index: llvm/test/CodeGen/RISCV/rvv/fixed-vectors-constant-pool-alignment.ll =================================================================== --- llvm/test/CodeGen/RISCV/rvv/fixed-vectors-constant-pool-alignment.ll +++ llvm/test/CodeGen/RISCV/rvv/fixed-vectors-constant-pool-alignment.ll @@ -2,7 +2,7 @@ define void @constantpool_v16xi8(ptr %x) { ; CHECK: .section .rodata.cst16,"aM",@progbits,16 -; CHECK: .p2align 4, 0x0 +; CHECK-NOT: .p2align ; CHECK: .byte ; CHECK: .globl constantpool_v16xi8 ; CHECK: .p2align 2 @@ -12,7 +12,7 @@ define void @constantpool_v4xi32(ptr %x) { ; CHECK: .section .rodata.cst16,"aM",@progbits,16 -; CHECK: .p2align 4, 0x0 +; CHECK: .p2align 2, 0x0 ; CHECK: .word ; CHECK: .globl constantpool_v4xi32 ; CHECK: .p2align 2 @@ -25,7 +25,7 @@ ; other sequence define void @constantpool_v4xi64(ptr %x) { ; CHECK: .section .rodata.cst32,"aM",@progbits,32 -; CHECK: .p2align 5, 0x0 +; CHECK: .p2align 3, 0x0 ; CHECK: .quad ; CHECK: .globl constantpool_v4xi64 ; CHECK: .p2align 2