Skip to content

Commit 002f0fd

Browse files
davemgreengiordano
authored andcommitted
[VectorCombine] Do not try to operate on OperandBundles. (llvm#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 llvm#110382.
1 parent edb7a55 commit 002f0fd

File tree

2 files changed

+79
-28
lines changed

2 files changed

+79
-28
lines changed

llvm/lib/Transforms/Vectorize/VectorCombine.cpp

+31-28
Original file line numberDiff line numberDiff line change
@@ -1900,33 +1900,35 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
19001900

19011901
// We need each element to be the same type of value, and check that each
19021902
// element has a single use.
1903-
if (all_of(drop_begin(Item), [Item](InstLane IL) {
1904-
Value *FrontV = Item.front().first->get();
1905-
if (!IL.first)
1906-
return true;
1907-
Value *V = IL.first->get();
1908-
if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUse())
1909-
return false;
1910-
if (V->getValueID() != FrontV->getValueID())
1911-
return false;
1912-
if (auto *CI = dyn_cast<CmpInst>(V))
1913-
if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
1914-
return false;
1915-
if (auto *CI = dyn_cast<CastInst>(V))
1916-
if (CI->getSrcTy() != cast<CastInst>(FrontV)->getSrcTy())
1917-
return false;
1918-
if (auto *SI = dyn_cast<SelectInst>(V))
1919-
if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
1920-
SI->getOperand(0)->getType() !=
1921-
cast<SelectInst>(FrontV)->getOperand(0)->getType())
1922-
return false;
1923-
if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
1924-
return false;
1925-
auto *II = dyn_cast<IntrinsicInst>(V);
1926-
return !II || (isa<IntrinsicInst>(FrontV) &&
1927-
II->getIntrinsicID() ==
1928-
cast<IntrinsicInst>(FrontV)->getIntrinsicID());
1929-
})) {
1903+
auto CheckLaneIsEquivalentToFirst = [Item](InstLane IL) {
1904+
Value *FrontV = Item.front().first->get();
1905+
if (!IL.first)
1906+
return true;
1907+
Value *V = IL.first->get();
1908+
if (auto *I = dyn_cast<Instruction>(V); I && !I->hasOneUse())
1909+
return false;
1910+
if (V->getValueID() != FrontV->getValueID())
1911+
return false;
1912+
if (auto *CI = dyn_cast<CmpInst>(V))
1913+
if (CI->getPredicate() != cast<CmpInst>(FrontV)->getPredicate())
1914+
return false;
1915+
if (auto *CI = dyn_cast<CastInst>(V))
1916+
if (CI->getSrcTy() != cast<CastInst>(FrontV)->getSrcTy())
1917+
return false;
1918+
if (auto *SI = dyn_cast<SelectInst>(V))
1919+
if (!isa<VectorType>(SI->getOperand(0)->getType()) ||
1920+
SI->getOperand(0)->getType() !=
1921+
cast<SelectInst>(FrontV)->getOperand(0)->getType())
1922+
return false;
1923+
if (isa<CallInst>(V) && !isa<IntrinsicInst>(V))
1924+
return false;
1925+
auto *II = dyn_cast<IntrinsicInst>(V);
1926+
return !II || (isa<IntrinsicInst>(FrontV) &&
1927+
II->getIntrinsicID() ==
1928+
cast<IntrinsicInst>(FrontV)->getIntrinsicID() &&
1929+
!II->hasOperandBundles());
1930+
};
1931+
if (all_of(drop_begin(Item), CheckLaneIsEquivalentToFirst)) {
19301932
// Check the operator is one that we support.
19311933
if (isa<BinaryOperator, CmpInst>(FrontU)) {
19321934
// We exclude div/rem in case they hit UB from poison lanes.
@@ -1954,7 +1956,8 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
19541956
Worklist.push_back(generateInstLaneVectorFromOperand(Item, 2));
19551957
continue;
19561958
} else if (auto *II = dyn_cast<IntrinsicInst>(FrontU);
1957-
II && isTriviallyVectorizable(II->getIntrinsicID())) {
1959+
II && isTriviallyVectorizable(II->getIntrinsicID()) &&
1960+
!II->hasOperandBundles()) {
19581961
for (unsigned Op = 0, E = II->getNumOperands() - 1; Op < E; Op++) {
19591962
if (isVectorIntrinsicWithScalarOpAtArg(II->getIntrinsicID(), Op)) {
19601963
if (!all_of(drop_begin(Item), [Item, Op](InstLane &IL) {

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

+48
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)