forked from OSchip/llvm-project
Fix an error in BBVectorize important for vectorizing pointer types.
When vectorizing pointer types it is important to realize that potential pairs cannot be connected via the address pointer argument of a load or store. This is because even after vectorization, the address is still a scalar because the address of the higher half of the pair is implicit from the address of the lower half (it need not be, and should not be, explicitly computed). llvm-svn: 154735
This commit is contained in:
parent
f589519a67
commit
83c9796033
|
@ -858,16 +858,33 @@ namespace {
|
|||
std::vector<Value *> &PairableInsts,
|
||||
std::multimap<ValuePair, ValuePair> &ConnectedPairs,
|
||||
ValuePair P) {
|
||||
StoreInst *SI, *SJ;
|
||||
|
||||
// For each possible pairing for this variable, look at the uses of
|
||||
// the first value...
|
||||
for (Value::use_iterator I = P.first->use_begin(),
|
||||
E = P.first->use_end(); I != E; ++I) {
|
||||
if (isa<LoadInst>(*I)) {
|
||||
// A pair cannot be connected to a load because the load only takes one
|
||||
// operand (the address) and it is a scalar even after vectorization.
|
||||
continue;
|
||||
} else if ((SI = dyn_cast<StoreInst>(*I)) &&
|
||||
P.first == SI->getPointerOperand()) {
|
||||
// Similarly, a pair cannot be connected to a store through its
|
||||
// pointer operand.
|
||||
continue;
|
||||
}
|
||||
|
||||
VPIteratorPair IPairRange = CandidatePairs.equal_range(*I);
|
||||
|
||||
// For each use of the first variable, look for uses of the second
|
||||
// variable...
|
||||
for (Value::use_iterator J = P.second->use_begin(),
|
||||
E2 = P.second->use_end(); J != E2; ++J) {
|
||||
if ((SJ = dyn_cast<StoreInst>(*J)) &&
|
||||
P.second == SJ->getPointerOperand())
|
||||
continue;
|
||||
|
||||
VPIteratorPair JPairRange = CandidatePairs.equal_range(*J);
|
||||
|
||||
// Look for <I, J>:
|
||||
|
@ -883,6 +900,10 @@ namespace {
|
|||
// Look for cases where just the first value in the pair is used by
|
||||
// both members of another pair (splatting).
|
||||
for (Value::use_iterator J = P.first->use_begin(); J != E; ++J) {
|
||||
if ((SJ = dyn_cast<StoreInst>(*J)) &&
|
||||
P.first == SJ->getPointerOperand())
|
||||
continue;
|
||||
|
||||
if (isSecondInIteratorPair<Value*>(*J, IPairRange))
|
||||
ConnectedPairs.insert(VPPair(P, ValuePair(*I, *J)));
|
||||
}
|
||||
|
@ -893,9 +914,19 @@ namespace {
|
|||
// both members of another pair (splatting).
|
||||
for (Value::use_iterator I = P.second->use_begin(),
|
||||
E = P.second->use_end(); I != E; ++I) {
|
||||
if (isa<LoadInst>(*I))
|
||||
continue;
|
||||
else if ((SI = dyn_cast<StoreInst>(*I)) &&
|
||||
P.second == SI->getPointerOperand())
|
||||
continue;
|
||||
|
||||
VPIteratorPair IPairRange = CandidatePairs.equal_range(*I);
|
||||
|
||||
for (Value::use_iterator J = P.second->use_begin(); J != E; ++J) {
|
||||
if ((SJ = dyn_cast<StoreInst>(*J)) &&
|
||||
P.second == SJ->getPointerOperand())
|
||||
continue;
|
||||
|
||||
if (isSecondInIteratorPair<Value*>(*J, IPairRange))
|
||||
ConnectedPairs.insert(VPPair(P, ValuePair(*I, *J)));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
; RUN: opt < %s -bb-vectorize -bb-vectorize-req-chain-depth=2 -instcombine -gvn -S | FileCheck %s
|
||||
|
||||
; Make sure that things (specifically getelementptr) are not connected to loads
|
||||
; and stores via the address operand (which would be bad because the address
|
||||
; is really a scalar even after vectorization)
|
||||
define i64 @test2(i64 %a) nounwind uwtable readonly {
|
||||
entry:
|
||||
%a1 = inttoptr i64 %a to i64*
|
||||
%a2 = getelementptr i64* %a1, i64 1
|
||||
%a3 = getelementptr i64* %a1, i64 2
|
||||
%v2 = load i64* %a2, align 8
|
||||
%v3 = load i64* %a3, align 8
|
||||
%v2a = add i64 %v2, 5
|
||||
%v3a = add i64 %v3, 7
|
||||
store i64 %v2a, i64* %a2, align 8
|
||||
store i64 %v3a, i64* %a3, align 8
|
||||
%r = add i64 %v2, %v3
|
||||
ret i64 %r
|
||||
; CHECK: @test2
|
||||
; CHECK-NOT: getelementptr <2 x i64*>
|
||||
}
|
||||
|
Loading…
Reference in New Issue