Fix SROA to avoid unnecessary scalar conversions for 1-element vectors.

When a 1-element vector alloca is promoted, a store instruction can often be
rewritten without converting the value to a scalar and using an insertelement
instruction to stuff it into the new alloca.  This patch just adds a check
to skip that conversion when it is unnecessary.  This turns out to be really
important for some ARM Neon operations where <1 x i64> is used to get around
the fact that i64 is not a legal type.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184870 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Wilson 2013-06-25 19:09:50 +00:00
parent 2560e242c8
commit a1fe2948ed
2 changed files with 40 additions and 15 deletions

View File

@ -2591,22 +2591,23 @@ private:
bool rewriteVectorizedStoreInst(Value *V, bool rewriteVectorizedStoreInst(Value *V,
StoreInst &SI, Value *OldOp) { StoreInst &SI, Value *OldOp) {
unsigned BeginIndex = getIndex(BeginOffset); if (V->getType() != VecTy) {
unsigned EndIndex = getIndex(EndOffset); unsigned BeginIndex = getIndex(BeginOffset);
assert(EndIndex > BeginIndex && "Empty vector!"); unsigned EndIndex = getIndex(EndOffset);
unsigned NumElements = EndIndex - BeginIndex; assert(EndIndex > BeginIndex && "Empty vector!");
assert(NumElements <= VecTy->getNumElements() && "Too many elements!"); unsigned NumElements = EndIndex - BeginIndex;
Type *PartitionTy assert(NumElements <= VecTy->getNumElements() && "Too many elements!");
= (NumElements == 1) ? ElementTy Type *PartitionTy
: VectorType::get(ElementTy, NumElements); = (NumElements == 1) ? ElementTy
if (V->getType() != PartitionTy) : VectorType::get(ElementTy, NumElements);
V = convertValue(TD, IRB, V, PartitionTy); if (V->getType() != PartitionTy)
V = convertValue(TD, IRB, V, PartitionTy);
// Mix in the existing elements.
Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(),
"load");
V = insertVector(IRB, Old, V, BeginIndex, "vec");
// Mix in the existing elements.
Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(),
"load");
V = insertVector(IRB, Old, V, BeginIndex, "vec");
}
StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment()); StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment());
Pass.DeadInsts.insert(&SI); Pass.DeadInsts.insert(&SI);

View File

@ -111,3 +111,27 @@ entry:
; CHECK-NOT: alloca ; CHECK-NOT: alloca
; CHECK: and i192 ; CHECK: and i192
} }
; When promoting an alloca to a 1-element vector type, instructions that
; produce that same vector type should not be changed to insert one element
; into a new vector. <rdar://problem/14249078>
define <1 x i64> @test8(<1 x i64> %a) {
entry:
%a.addr = alloca <1 x i64>, align 8
%__a = alloca <1 x i64>, align 8
%tmp = alloca <1 x i64>, align 8
store <1 x i64> %a, <1 x i64>* %a.addr, align 8
%0 = load <1 x i64>* %a.addr, align 8
store <1 x i64> %0, <1 x i64>* %__a, align 8
%1 = load <1 x i64>* %__a, align 8
%2 = bitcast <1 x i64> %1 to <8 x i8>
%3 = bitcast <8 x i8> %2 to <1 x i64>
%vshl_n = shl <1 x i64> %3, <i64 4>
store <1 x i64> %vshl_n, <1 x i64>* %tmp
%4 = load <1 x i64>* %tmp
ret <1 x i64> %4
; CHECK: @test8
; CHECK-NOT: alloca
; CHECK-NOT: insertelement
; CHECK: ret <1 x i64>
}