diff options
author | Craig Topper <craig.topper@sifive.com> | 2021-01-17 23:29:43 -0800 |
---|---|---|
committer | Craig Topper <craig.topper@sifive.com> | 2021-01-17 23:29:51 -0800 |
commit | cfec6cd50c36f3db2fcd4084a8ef4df834a4eb24 (patch) | |
tree | b737cb42f914451b94b151fec5ab0c0729b096bb /llvm/lib/CodeGen/Analysis.cpp | |
parent | bcc1dee60019f3a488a04dc7f701f7a692040fed (diff) | |
download | llvm-cfec6cd50c36f3db2fcd4084a8ef4df834a4eb24.zip llvm-cfec6cd50c36f3db2fcd4084a8ef4df834a4eb24.tar.gz llvm-cfec6cd50c36f3db2fcd4084a8ef4df834a4eb24.tar.bz2 |
[IR] Allow scalable vectors in structs to support intrinsics returning multiple values.
RISC-V would like to use a struct of scalable vectors to return multiple
values from intrinsics. This woud also be needed for target independent
intrinsics like llvm.sadd.overflow.
This patch removes the existing restriction for this. I've modified
StructType::isSized to consider a struct containing scalable vectors
as unsized so the verifier won't allow loads/stores/allocas of these
structs.
Reviewed By: sdesmalen
Differential Revision: https://reviews.llvm.org/D94142
Diffstat (limited to 'llvm/lib/CodeGen/Analysis.cpp')
-rw-r--r-- | llvm/lib/CodeGen/Analysis.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp index cfd53bf..48b69c8 100644 --- a/llvm/lib/CodeGen/Analysis.cpp +++ b/llvm/lib/CodeGen/Analysis.cpp @@ -88,19 +88,25 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, uint64_t StartingOffset) { // Given a struct type, recursively traverse the elements. if (StructType *STy = dyn_cast<StructType>(Ty)) { - const StructLayout *SL = DL.getStructLayout(STy); + // If the Offsets aren't needed, don't query the struct layout. This allows + // us to support structs with scalable vectors for operations that don't + // need offsets. + const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr; for (StructType::element_iterator EB = STy->element_begin(), EI = EB, EE = STy->element_end(); - EI != EE; ++EI) + EI != EE; ++EI) { + // Don't compute the element offset if we didn't get a StructLayout above. + uint64_t EltOffset = SL ? SL->getElementOffset(EI - EB) : 0; ComputeValueVTs(TLI, DL, *EI, ValueVTs, MemVTs, Offsets, - StartingOffset + SL->getElementOffset(EI - EB)); + StartingOffset + EltOffset); + } return; } // Given an array type, recursively traverse the elements. if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { Type *EltTy = ATy->getElementType(); - uint64_t EltSize = DL.getTypeAllocSize(EltTy); + uint64_t EltSize = DL.getTypeAllocSize(EltTy).getFixedValue(); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) ComputeValueVTs(TLI, DL, EltTy, ValueVTs, MemVTs, Offsets, StartingOffset + i * EltSize); @@ -131,16 +137,21 @@ void llvm::computeValueLLTs(const DataLayout &DL, Type &Ty, uint64_t StartingOffset) { // Given a struct type, recursively traverse the elements. if (StructType *STy = dyn_cast<StructType>(&Ty)) { - const StructLayout *SL = DL.getStructLayout(STy); - for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) + // If the Offsets aren't needed, don't query the struct layout. This allows + // us to support structs with scalable vectors for operations that don't + // need offsets. + const StructLayout *SL = Offsets ? DL.getStructLayout(STy) : nullptr; + for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) { + uint64_t EltOffset = SL ? SL->getElementOffset(I) : 0; computeValueLLTs(DL, *STy->getElementType(I), ValueTys, Offsets, - StartingOffset + SL->getElementOffset(I)); + StartingOffset + EltOffset); + } return; } // Given an array type, recursively traverse the elements. if (ArrayType *ATy = dyn_cast<ArrayType>(&Ty)) { Type *EltTy = ATy->getElementType(); - uint64_t EltSize = DL.getTypeAllocSize(EltTy); + uint64_t EltSize = DL.getTypeAllocSize(EltTy).getFixedValue(); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) computeValueLLTs(DL, *EltTy, ValueTys, Offsets, StartingOffset + i * EltSize); |