[llvm] [LoopVectorize][LAA] Hoist load in memory IV to allow vectorization (PR #168312)
Felipe Magno de Almeida via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 10 17:05:46 PST 2025
felipealmeida wrote:
Hello Florian,
[snip]
> Would it be possible to share a build-able reproducer? From looking at the code, I am surprised that we are not able to determine no-alias via TBAA metadata given that it looks like we are accessing 16 and 64 bit integers, which should be have different TBAA nodes.
So, SPEC 2017 is using -fno-strict-alising, which bypasses TBAAs.
Below is one that I was able to get together that reproduces it.
```
#include <cstdlib>
#include <algorithm>
struct MemoryManager
{
void* allocate(size_t size);
};
template <class C>
struct MyConstructWithNoMemoryManager
{
static C* construct(C* address, MemoryManager& /* mgr */)
{
return (C*) new (address) C;
}
static C* construct(C* address, const C& theRhs, MemoryManager& /* mgr */)
{
return (C*) new (address) C(theRhs);
}
};
template <class C>
struct MyMemoryManagedConstructionTraits
{
typedef MyConstructWithNoMemoryManager<C> Constructor;
};
template <class Type, class ConstructionTraits = MyMemoryManagedConstructionTraits<Type> >
struct MyXalanVector
{
typedef Type value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef MyXalanVector<value_type, ConstructionTraits> ThisType;
typedef typename ConstructionTraits::Constructor Constructor;
MyXalanVector(
MemoryManager& theManager ,
size_type initialAllocation = size_type(0));
MyXalanVector(
const ThisType& theSource,
MemoryManager& theManager ,
size_type theInitialAllocation = size_type(0)) :
m_memoryManager(&theManager),
m_size(0),
m_allocation(0),
m_data(0)
{
if (theSource.m_size > 0) {
ThisType theTemp(theManager, local_max(theSource.m_size, theInitialAllocation));
theTemp.insert(theTemp.begin(), theSource.begin(), theSource.end());
swap(theTemp);
}
else if (theInitialAllocation > 0) {
m_data = allocate(theInitialAllocation);
m_allocation = theInitialAllocation;
}
}
value_type*
allocate(size_type size);
void
insert(
iterator thePosition,
size_type theCount,
const value_type& theData) ;
pointer
ensureCapacity(size_type theSize);
void
insert(
iterator thePosition,
const_iterator theFirst,
const_iterator theLast)
{
const size_type theInsertSize =
std::distance(theFirst, theLast);
if (theInsertSize == 0) return;
const size_type theTotalSize = size() + theInsertSize;
if (thePosition == end()) {
pointer thePointer = ensureCapacity(theTotalSize);
while (theFirst != theLast) {
Constructor::construct(thePointer, *theFirst, *m_memoryManager);
++thePointer;
++m_size;
++theFirst;
}
} else {
if (theTotalSize > capacity()) {
ThisType theTemp(*m_memoryManager, theTotalSize);
theTemp.insert(theTemp.end(), begin(), thePosition);
theTemp.insert(theTemp.end(), theFirst, theLast);
theTemp.insert(theTemp.end(), thePosition, end());
swap(theTemp);
} else {
const iterator theOriginalEnd = end();
const size_type theRightSplitSize =
std::distance(thePosition, theOriginalEnd);
if (theRightSplitSize <= theInsertSize) {
const const_iterator toInsertSplit = theFirst + theRightSplitSize;
const_iterator toInsertIter = toInsertSplit;
while (toInsertIter != theLast) {
doPushBack(*toInsertIter);
++toInsertIter;
}
toInsertIter = thePosition;
while (toInsertIter != theOriginalEnd) {
doPushBack(*toInsertIter);
++toInsertIter;
}
std:: copy(theFirst, toInsertSplit, thePosition);
} else {
const_iterator toMoveIter = end() - theInsertSize;
while (toMoveIter != theOriginalEnd) {
doPushBack(*toMoveIter);
++toMoveIter;
}
std:: copy_backward(thePosition, theOriginalEnd - theInsertSize, theOriginalEnd);
std:: copy(theFirst, theLast, thePosition);
}
}
}
}
size_type size() const;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
pointer endPointer();
const_pointer endPointer() const;
size_type capacity() const;
void doPushBack(const value_type& data);
void doReserve(size_type theSize);
size_type local_max(size_type theLHS, size_type theRHS);
void swap(ThisType& theOther);
MemoryManager* m_memoryManager;
size_type m_size;
size_type m_allocation;
value_type* m_data;
};
typedef MyXalanVector<unsigned short> vector;
vector & foo1();
size_t theTotalSize();
void foobar()
{
vector & self = foo1();
vector theTemp(self, *self.m_memoryManager, theTotalSize());
}
```
I'm compiling using this: `clang++ -std=c++11 --target=aarch64-linux-gnu -c -o ElemAttribute.o -O3 -fno-strict-aliasing ElemAttribute.cpp`
https://github.com/llvm/llvm-project/pull/168312
More information about the llvm-commits
mailing list