Skip to content

Commit c136d32

Browse files
authored
[VectorCombine] Do not try to operate on OperandBundles. (#111635)
This bails out if we see an intrinsic with an operand bundle on it, to make sure we don't process the bundles incorrectly. Fixes #110382.
1 parent 72a957b commit c136d32

File tree

2 files changed

+79
-28
lines changed

2 files changed

+79
-28
lines changed

llvm/lib/Transforms/Vectorize/VectorCombine.cpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,33 +1984,35 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
19841984

19851985
// We need each element to be the same type of value, and check that each
19861986
// element has a single use.
1987-
if (all_of(drop_begin(Item), [Item](InstLane IL) {
1988-
Value *FrontV = Item.front().first->get();
1989-
if (!IL.first)
1990-
return true;
1991-
Value *V = IL.first->get();
1992-
if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUse())
1993-
return false;
1994-
if (V->getValueID() != FrontV->getValueID())
1995-
return false;
1996-
if (auto *CI = dyn_cast<CmpInst>(V))
1997-
if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
1998-
return false;
1999-
if (auto *CI = dyn_cast<CastInst>(V))
2000-
if (CI->getSrcTy() != cast<CastInst>(FrontV)->getSrcTy())
2001-
return false;
2002-
if (auto *SI = dyn_cast<SelectInst>(V))
2003-
if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
2004-
SI->getOperand(0)->getType() !=
2005-
cast<SelectInst>(FrontV)->getOperand(0)->getType())
2006-
return false;
2007-
if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
2008-
return false;
2009-
auto *II = dyn_cast<IntrinsicInst>(V);
2010-
return !II || (isa<IntrinsicInst>(FrontV) &&
2011-
II->getIntrinsicID() ==
2012-
cast<IntrinsicInst>(FrontV)->getIntrinsicID());
2013-
})) {
1987+
auto CheckLaneIsEquivalentToFirst = [Item](InstLane IL) {
1988+
Value *FrontV = Item.front().first->get();
1989+
if (!IL.first)
1990+
return true;
1991+
Value *V = IL.first->get();
1992+
if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUse())
1993+
return false;
1994+
if (V->getValueID() != FrontV->getValueID())
1995+
return false;
1996+
if (auto *CI = dyn_cast<CmpInst>(V))
1997+
if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
1998+
return false;
1999+
if (auto *CI = dyn_cast<CastInst>(V))
2000+
if (CI->getSrcTy() != cast<CastInst>(FrontV)->getSrcTy())
2001+
return false;
2002+
if (auto *SI = dyn_cast<SelectInst>(V))
2003+
if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
2004+
SI->getOperand(0)->getType() !=
2005+
cast<SelectInst>(FrontV)->getOperand(0)->getType())
2006+
return false;
2007+
if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
2008+
return false;
2009+
auto *II = dyn_cast<IntrinsicInst>(V);
2010+
return !II || (isa<IntrinsicInst>(FrontV) &&
2011+
II->getIntrinsicID() ==
2012+
cast<IntrinsicInst>(FrontV)->getIntrinsicID() &&
2013+
!II->hasOperandBundles());
2014+
};
2015+
if (all_of(drop_begin(Item), CheckLaneIsEquivalentToFirst)) {
20142016
// Check the operator is one that we support.
20152017
if (isa<BinaryOperator, CmpInst>(FrontU)) {
20162018
// We exclude div/rem in case they hit UB from poison lanes.
@@ -2038,7 +2040,8 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
20382040
Worklist.push_back(generateInstLaneVectorFromOperand(Item, 2));
20392041
continue;
20402042
} else if (auto *II = dyn_cast<IntrinsicInst>(FrontU);
2041-
II && isTriviallyVectorizable(II->getIntrinsicID())) {
2043+
II && isTriviallyVectorizable(II->getIntrinsicID()) &&
2044+
!II->hasOperandBundles()) {
20422045
for (unsigned Op = 0, E = II->getNumOperands() - 1; Op < E; Op++) {
20432046
if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Op)) {
20442047
if (!all_of(drop_begin(Item), [Item, Op](InstLane &IL) {

llvm/test/Transforms/VectorCombine/AArch64/shuffletoidentity.ll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,4 +1066,52 @@ entry:
10661066
ret <2 x float> %4
10671067
}
10681068

1069+
define <16 x i64> @operandbundles(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c) {
1070+
; CHECK-LABEL: @operandbundles(
1071+
; CHECK-NEXT: [[CALL:%.*]] = call <4 x i64> @llvm.fshl.v4i64(<4 x i64> [[A:%.*]], <4 x i64> [[B:%.*]], <4 x i64> [[C:%.*]]) [ "jl_roots"(ptr addrspace(10) null, ptr addrspace(10) null) ]
1072+
; CHECK-NEXT: [[SHUFFLEVECTOR:%.*]] = shufflevector <4 x i64> [[CALL]], <4 x i64> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
1073+
; CHECK-NEXT: [[SHUFFLEVECTOR1:%.*]] = shufflevector <16 x i64> [[SHUFFLEVECTOR]], <16 x i64> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
1074+
; CHECK-NEXT: ret <16 x i64> [[SHUFFLEVECTOR1]]
1075+
;
1076+
%call = call <4 x i64> @llvm.fshl.v4i64(<4 x i64> %a, <4 x i64> %b, <4 x i64> %c) [ "jl_roots"(ptr addrspace(10) null, ptr addrspace(10) null) ]
1077+
%shufflevector = shufflevector <4 x i64> %call, <4 x i64> poison, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
1078+
%shufflevector1 = shufflevector <16 x i64> %shufflevector, <16 x i64> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>
1079+
ret <16 x i64> %shufflevector1
1080+
}
1081+
1082+
define <8 x i8> @operandbundles_first(<8 x i8> %a) {
1083+
; CHECK-LABEL: @operandbundles_first(
1084+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x i8> [[A:%.*]], <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1085+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
1086+
; CHECK-NEXT: [[ABT:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[AT]], i1 false) [ "jl_roots"(ptr addrspace(10) null, ptr addrspace(10) null) ]
1087+
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i8> [[AT]], <4 x i8> [[AB]], <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
1088+
; CHECK-NEXT: [[R:%.*]] = call <8 x i8> @llvm.abs.v8i8(<8 x i8> [[TMP1]], i1 false)
1089+
; CHECK-NEXT: ret <8 x i8> [[R]]
1090+
;
1091+
%ab = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1092+
%at = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
1093+
%abt = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %at, i1 false) [ "jl_roots"(ptr addrspace(10) null, ptr addrspace(10) null) ]
1094+
%abb = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %ab, i1 false)
1095+
%r = shufflevector <4 x i8> %abt, <4 x i8> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
1096+
ret <8 x i8> %r
1097+
}
1098+
1099+
define <8 x i8> @operandbundles_second(<8 x i8> %a) {
1100+
; CHECK-LABEL: @operandbundles_second(
1101+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x i8> [[A:%.*]], <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1102+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
1103+
; CHECK-NEXT: [[ABB:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[AB]], i1 false) [ "jl_roots"(ptr addrspace(10) null, ptr addrspace(10) null) ]
1104+
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i8> [[AT]], <4 x i8> [[AB]], <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
1105+
; CHECK-NEXT: [[R:%.*]] = call <8 x i8> @llvm.abs.v8i8(<8 x i8> [[TMP1]], i1 false)
1106+
; CHECK-NEXT: ret <8 x i8> [[R]]
1107+
;
1108+
%ab = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
1109+
%at = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
1110+
%abt = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %at, i1 false)
1111+
%abb = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %ab, i1 false) [ "jl_roots"(ptr addrspace(10) null, ptr addrspace(10) null) ]
1112+
%r = shufflevector <4 x i8> %abt, <4 x i8> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
1113+
ret <8 x i8> %r
1114+
}
1115+
1116+
declare <4 x i64> @llvm.fshl.v4i64(<4 x i64>, <4 x i64>, <4 x i64>)
10691117
declare void @use(<4 x i8>)

0 commit comments

Comments
 (0)