mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
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:
parent
2560e242c8
commit
a1fe2948ed
@ -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);
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user