forked from OSchip/llvm-project
[SLP]Fix non-determinism in PHI sorting.
Compare type IDs and DFS numbering for basic block instead of addresses to fix non-determinism. Differential Revision: https://reviews.llvm.org/D105031
This commit is contained in:
parent
130ea3ceb4
commit
4e1a0684f1
|
@ -8318,7 +8318,7 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
|
|||
// No need to analyze deleted, vectorized and non-vectorizable
|
||||
// instructions.
|
||||
if (!VisitedInstrs.count(P) && !R.isDeleted(P) &&
|
||||
!P->getType()->isVectorTy())
|
||||
isValidElementType(P->getType()))
|
||||
Incoming.push_back(P);
|
||||
}
|
||||
|
||||
|
@ -8346,10 +8346,15 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
|
|||
}
|
||||
|
||||
// Sort by type, parent, operands.
|
||||
stable_sort(Incoming, [&PHIToOpcodes](Value *V1, Value *V2) {
|
||||
if (V1->getType() < V2->getType())
|
||||
stable_sort(Incoming, [this, &PHIToOpcodes](Value *V1, Value *V2) {
|
||||
assert(isValidElementType(V1->getType()) &&
|
||||
isValidElementType(V2->getType()) &&
|
||||
"Expected vectorizable types only.");
|
||||
// It is fine to compare type IDs here, since we expect only vectorizable
|
||||
// types, like ints, floats and pointers, we don't care about other type.
|
||||
if (V1->getType()->getTypeID() < V2->getType()->getTypeID())
|
||||
return true;
|
||||
if (V1->getType() > V2->getType())
|
||||
if (V1->getType()->getTypeID() > V2->getType()->getTypeID())
|
||||
return false;
|
||||
ArrayRef<Value *> Opcodes1 = PHIToOpcodes[V1];
|
||||
ArrayRef<Value *> Opcodes2 = PHIToOpcodes[V2];
|
||||
|
@ -8363,10 +8368,15 @@ bool SLPVectorizerPass::vectorizeChainsInBlock(BasicBlock *BB, BoUpSLP &R) {
|
|||
continue;
|
||||
if (auto *I1 = dyn_cast<Instruction>(Opcodes1[I]))
|
||||
if (auto *I2 = dyn_cast<Instruction>(Opcodes2[I])) {
|
||||
if (I1->getParent() < I2->getParent())
|
||||
return true;
|
||||
if (I1->getParent() > I2->getParent())
|
||||
return false;
|
||||
DomTreeNodeBase<BasicBlock> *NodeI1 = DT->getNode(I1->getParent());
|
||||
DomTreeNodeBase<BasicBlock> *NodeI2 = DT->getNode(I2->getParent());
|
||||
assert(NodeI1 && "Should only process reachable instructions");
|
||||
assert(NodeI2 && "Should only process reachable instructions");
|
||||
assert((NodeI1 == NodeI2) ==
|
||||
(NodeI1->getDFSNumIn() == NodeI2->getDFSNumIn()) &&
|
||||
"Different nodes should have different DFS numbers");
|
||||
if (NodeI1 != NodeI2)
|
||||
return NodeI1->getDFSNumIn() < NodeI2->getDFSNumIn();
|
||||
InstructionsState S = getSameOpcode({I1, I2});
|
||||
if (S.getOpcode())
|
||||
continue;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
; RUN: FileCheck --input-file=%t --check-prefix=YAML %s
|
||||
|
||||
; This type is not supported by SLP
|
||||
define void @test(x86_fp80* %i1, x86_fp80* %i2, x86_fp80* %o) {
|
||||
define i1 @test(x86_fp80* %i1, x86_fp80* %i2) {
|
||||
; CHECK-LABEL: @test(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[I1_0:%.*]] = load x86_fp80, x86_fp80* [[I1:%.*]], align 16
|
||||
|
@ -19,10 +19,8 @@ define void @test(x86_fp80* %i1, x86_fp80* %i2, x86_fp80* %o) {
|
|||
; CHECK: end:
|
||||
; CHECK-NEXT: [[PHI0:%.*]] = phi x86_fp80 [ [[I1_0]], [[ENTRY:%.*]] ], [ [[I2_0]], [[THEN]] ]
|
||||
; CHECK-NEXT: [[PHI1:%.*]] = phi x86_fp80 [ [[I1_1]], [[ENTRY]] ], [ [[I2_1]], [[THEN]] ]
|
||||
; CHECK-NEXT: store x86_fp80 [[PHI0]], x86_fp80* [[O:%.*]], align 16
|
||||
; CHECK-NEXT: [[O_GEP1:%.*]] = getelementptr inbounds x86_fp80, x86_fp80* [[O]], i64 1
|
||||
; CHECK-NEXT: store x86_fp80 [[PHI1]], x86_fp80* [[O_GEP1]], align 16
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK-NEXT: [[RES:%.*]] = fcmp oeq x86_fp80 [[PHI0]], [[PHI1]]
|
||||
; CHECK-NEXT: ret i1 [[RES]]
|
||||
;
|
||||
entry:
|
||||
%i1.0 = load x86_fp80, x86_fp80* %i1, align 16
|
||||
|
@ -37,11 +35,8 @@ then:
|
|||
br label %end
|
||||
end:
|
||||
%phi0 = phi x86_fp80 [ %i1.0, %entry ], [ %i2.0, %then ]
|
||||
|
||||
%phi1 = phi x86_fp80 [ %i1.1, %entry ], [ %i2.1, %then ]
|
||||
store x86_fp80 %phi0, x86_fp80* %o, align 16
|
||||
%o.gep1 = getelementptr inbounds x86_fp80, x86_fp80* %o, i64 1
|
||||
store x86_fp80 %phi1, x86_fp80* %o.gep1, align 16
|
||||
%res = fcmp oeq x86_fp80 %phi0, %phi1
|
||||
; YAML: Pass: slp-vectorizer
|
||||
; YAML-NEXT: Name: UnsupportedType
|
||||
; YAML-NEXT: Function: test
|
||||
|
@ -49,5 +44,5 @@ end:
|
|||
; YAML-NEXT: - String: 'Cannot SLP vectorize list: type '
|
||||
; YAML-NEXT: - String: x86_fp80 is unsupported by vectorizer
|
||||
|
||||
ret void
|
||||
ret i1 %res
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue