Skip to content

Commit

Permalink
Fix an error in BBVectorize important for vectorizing pointer types.
Browse files Browse the repository at this point in the history
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).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154735 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Hal Finkel committed Apr 14, 2012
1 parent f3f5a1e commit bba23ed
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
31 changes: 31 additions & 0 deletions lib/Transforms/Vectorize/BBVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>:
Expand All @@ -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)));
}
Expand All @@ -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)));
}
Expand Down
23 changes: 23 additions & 0 deletions test/Transforms/BBVectorize/no-ldstr-conn.ll
Original file line number Diff line number Diff line change
@@ -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*>
}

0 comments on commit bba23ed

Please sign in to comment.