Skip to content

Commit d145f40

Browse files
committed
[VectorCombine] shuffleToIdentity - guard against call instructions.
The shuffleToIdentity fold needs to be a bit more careful about the difference between call instructions and intrinsics. The second can be handled, but the first should result in bailing out. This patch also adds some extra intrinsic tests from #91000. Fixes #91078
1 parent d5ca2e4 commit d145f40

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

llvm/lib/Transforms/Vectorize/VectorCombine.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,10 +1755,13 @@ bool VectorCombine::foldShuffleToIdentity(Instruction &I) {
17551755
return false;
17561756
if (IL.first->getValueID() != Item[0].first->getValueID())
17571757
return false;
1758+
if (isa<CallInst>(IL.first) && !isa<IntrinsicInst>(IL.first))
1759+
return false;
17581760
auto *II = dyn_cast<IntrinsicInst>(IL.first);
17591761
return !II ||
1760-
II->getIntrinsicID() ==
1761-
cast<IntrinsicInst>(Item[0].first)->getIntrinsicID();
1762+
(isa<IntrinsicInst>(Item[0].first) &&
1763+
II->getIntrinsicID() ==
1764+
cast<IntrinsicInst>(Item[0].first)->getIntrinsicID());
17621765
}))
17631766
return false;
17641767

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

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,92 @@ define <8 x i8> @abs(<8 x i8> %a) {
104104
; CHECK-LABEL: @abs(
105105
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x i8> [[A:%.*]], <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
106106
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
107+
; CHECK-NEXT: [[ABT:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[AT]], i1 false)
108+
; CHECK-NEXT: [[ABB:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[AB]], i1 false)
109+
; CHECK-NEXT: [[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>
110+
; CHECK-NEXT: ret <8 x i8> [[R]]
111+
;
112+
%ab = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
113+
%at = shufflevector <8 x i8> %a, <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
114+
%abt = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %at, i1 false)
115+
%abb = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %ab, i1 false)
116+
%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>
117+
ret <8 x i8> %r
118+
}
119+
120+
define <8 x half> @powi(<8 x half> %a) {
121+
; CHECK-LABEL: @powi(
122+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x half> [[A:%.*]], <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
123+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x half> [[A]], <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
124+
; CHECK-NEXT: [[ABT:%.*]] = call <4 x half> @llvm.powi.v4f16.i32(<4 x half> [[AT]], i32 10)
125+
; CHECK-NEXT: [[ABB:%.*]] = call <4 x half> @llvm.powi.v4f16.i32(<4 x half> [[AB]], i32 10)
126+
; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x half> [[ABT]], <4 x half> [[ABB]], <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
127+
; CHECK-NEXT: ret <8 x half> [[R]]
128+
;
129+
%ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
130+
%at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
131+
%abt = call <4 x half> @llvm.powi.v4f16.i32(<4 x half> %at, i32 10)
132+
%abb = call <4 x half> @llvm.powi.v4f16.i32(<4 x half> %ab, i32 10)
133+
%r = shufflevector <4 x half> %abt, <4 x half> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
134+
ret <8 x half> %r
135+
}
136+
137+
; Check that call instructions are treated separately from intrinsics.
138+
define <8 x half> @callinst(<8 x half> %a) {
139+
; CHECK-LABEL: @callinst(
140+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x half> [[A:%.*]], <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
141+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x half> [[A]], <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
142+
; CHECK-NEXT: [[ABT:%.*]] = call <4 x half> @othercall(<4 x half> [[AT]])
143+
; CHECK-NEXT: [[ABB:%.*]] = call <4 x half> @llvm.fabs.v4f16(<4 x half> [[AB]])
144+
; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x half> [[ABT]], <4 x half> [[ABB]], <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
145+
; CHECK-NEXT: ret <8 x half> [[R]]
146+
;
147+
%ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
148+
%at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
149+
%abt = call <4 x half> @othercall(<4 x half> %at)
150+
%abb = call <4 x half> @llvm.fabs.v4f16(<4 x half> %ab)
151+
%r = shufflevector <4 x half> %abt, <4 x half> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
152+
ret <8 x half> %r
153+
}
154+
define <8 x half> @callinst2(<8 x half> %a) {
155+
; CHECK-LABEL: @callinst2(
156+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x half> [[A:%.*]], <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
157+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x half> [[A]], <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
158+
; CHECK-NEXT: [[ABT:%.*]] = call <4 x half> @llvm.fabs.v4f16(<4 x half> [[AT]])
159+
; CHECK-NEXT: [[ABB:%.*]] = call <4 x half> @othercall(<4 x half> [[AB]])
160+
; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x half> [[ABT]], <4 x half> [[ABB]], <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
161+
; CHECK-NEXT: ret <8 x half> [[R]]
162+
;
163+
%ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
164+
%at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
165+
%abt = call <4 x half> @llvm.fabs.v4f16(<4 x half> %at)
166+
%abb = call <4 x half> @othercall(<4 x half> %ab)
167+
%r = shufflevector <4 x half> %abt, <4 x half> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
168+
ret <8 x half> %r
169+
}
170+
declare <4 x half> @othercall(<4 x half>)
171+
172+
define <8 x i32> @lrint(<8 x half> %a) {
173+
; CHECK-LABEL: @lrint(
174+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x half> [[A:%.*]], <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
175+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x half> [[A]], <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
176+
; CHECK-NEXT: [[ABT:%.*]] = call <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half> [[AT]])
177+
; CHECK-NEXT: [[ABB:%.*]] = call <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half> [[AB]])
178+
; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[ABT]], <4 x i32> [[ABB]], <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
179+
; CHECK-NEXT: ret <8 x i32> [[R]]
180+
;
181+
%ab = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
182+
%at = shufflevector <8 x half> %a, <8 x half> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
183+
%abt = call <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half> %at)
184+
%abb = call <4 x i32> @llvm.lrint.v4i32.v4f16(<4 x half> %ab)
185+
%r = shufflevector <4 x i32> %abt, <4 x i32> %abb, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
186+
ret <8 x i32> %r
187+
}
188+
189+
define <8 x i8> @abs_different(<8 x i8> %a) {
190+
; CHECK-LABEL: @abs_different(
191+
; CHECK-NEXT: [[AB:%.*]] = shufflevector <8 x i8> [[A:%.*]], <8 x i8> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
192+
; CHECK-NEXT: [[AT:%.*]] = shufflevector <8 x i8> [[A]], <8 x i8> poison, <4 x i32> <i32 7, i32 6, i32 5, i32 4>
107193
; CHECK-NEXT: [[ABT:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[AT]], i1 true)
108194
; CHECK-NEXT: [[ABB:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[AB]], i1 false)
109195
; CHECK-NEXT: [[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>

0 commit comments

Comments
 (0)