Skip to content

Commit 3771bbf

Browse files
committed
[instCombine][bugfix] Fix crash caused by using of cast in instCombineSVECmpNE.
Func instCombineSVECmpNE is used to identify specific pattern of instruction 'svecmene', and then predict its result, use the result to replace instruction 'svecmene'. The specific pattern can be descriped below: 1.The svecmpne must compare all elements of vec. 2.The svecmpne inst compare its ves with zero. 3.The vec in svecmpne inst is generated by inst dupqlane, and the copy value of this dupqlane must be zero. In NO.3 above, func instCombineSVECmpNE uses 'cast' to transform op1 of dupqlane without checking if the cast is success, then generate a crash in some situation.
1 parent 26ca782 commit 3771bbf

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,8 @@ static std::optional<Instruction *> instCombineSVECmpNE(InstCombiner &IC,
11741174
return std::nullopt;
11751175

11761176
// Where the dupq is a lane 0 replicate of a vector insert
1177-
if (!cast<ConstantInt>(DupQLane->getArgOperand(1))->isZero())
1177+
auto *DupQLaneIdx = dyn_cast<ConstantInt>(DupQLane->getArgOperand(1));
1178+
if (!DupQLaneIdx || !DupQLaneIdx->isZero())
11781179
return std::nullopt;
11791180

11801181
auto *VecIns = dyn_cast<IntrinsicInst>(DupQLane->getArgOperand(0));
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: opt -S -mtriple=aarch64-unknown-linux-gnu -O2 < %s | FileCheck %s
2+
3+
define dso_local i64 @func(i64 noundef %0, i64 noundef %1) local_unnamed_addr {
4+
%3 = add nsw i64 %1, %0
5+
%4 = mul nsw i64 %3, 3
6+
ret i64 %4
7+
}
8+
9+
define <vscale x 16 x i1> @testInstCombineSVECmpNE() {
10+
%1 = tail call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
11+
%2 = tail call <vscale x 16 x i8> @llvm.aarch64.sve.index.nxv16i8(i8 42, i8 1)
12+
%3 = tail call i64 @func(i64 noundef 1, i64 noundef 2)
13+
%4 = tail call <vscale x 16 x i8> @llvm.aarch64.sve.dupq.lane.nxv16i8(<vscale x 16 x i8> %2 , i64 %3)
14+
%5 = tail call <vscale x 16 x i1> @llvm.aarch64.sve.cmpne.nxv16i8(<vscale x 16 x i1> %1, <vscale x 16 x i8> %4, <vscale x 16 x i8> zeroinitializer)
15+
ret <vscale x 16 x i1> %5
16+
; CHECK: %4 = tail call <vscale x 16 x i1> @llvm.aarch64.sve.cmpne.nxv16i8(<vscale x 16 x i1> %1, <vscale x 16 x i8> %3, <vscale x 16 x i8> zeroinitializer)
17+
; CHECK-NEXT: ret <vscale x 16 x i1> %4
18+
}
19+
20+
declare <vscale x 16 x i8> @llvm.aarch64.sve.index.nxv16i8(i8, i8)
21+
declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 immarg)
22+
declare <vscale x 16 x i8> @llvm.aarch64.sve.dupq.lane.nxv16i8(<vscale x 16 x i8>, i64)
23+
declare <vscale x 16 x i1> @llvm.aarch64.sve.cmpne.nxv16i8(<vscale x 16 x i1>, <vscale x 16 x i8>, <vscale x 16 x i8>)

0 commit comments

Comments
 (0)