Skip to content

Commit 1808fc1

Browse files
authored
[AArch64][InstCombine] Bail from combining SRAD on +/-1 divisor (#109274)
This fixes a crash when svdiv's third parameter is svdup_s64(1)
1 parent 73b8074 commit 1808fc1

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,7 +1978,13 @@ static std::optional<Instruction *> instCombineSVESDIV(InstCombiner &IC,
19781978
ConstantInt *SplatConstantInt = dyn_cast_or_null<ConstantInt>(SplatValue);
19791979
if (!SplatConstantInt)
19801980
return std::nullopt;
1981+
19811982
APInt Divisor = SplatConstantInt->getValue();
1983+
const int64_t DivisorValue = Divisor.getSExtValue();
1984+
if (DivisorValue == -1)
1985+
return std::nullopt;
1986+
if (DivisorValue == 1)
1987+
IC.replaceInstUsesWith(II, Vec);
19821988

19831989
if (Divisor.isPowerOf2()) {
19841990
Constant *DivisorLog2 = ConstantInt::get(Int32Ty, Divisor.logBase2());

llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-sdiv.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,29 @@ define <vscale x 4 x i32> @sdiv_i32_not_zero(<vscale x 4 x i32> %a, <vscale x 4
6868
ret <vscale x 4 x i32> %out
6969
}
7070

71+
; Vec/1 is a no-op
72+
define <vscale x 2 x i64> @divide_by_1(<vscale x 16 x i1> %p, <vscale x 2 x i64> %a) #0 {
73+
; CHECK-LABEL: @divide_by_1(
74+
; CHECK-NEXT: ret <vscale x 2 x i64> [[A:%.*]]
75+
;
76+
%1 = call <vscale x 2 x i64> @llvm.aarch64.sve.dup.x.nxv2i64(i64 1)
77+
%2 = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %p)
78+
%3 = call <vscale x 2 x i64> @llvm.aarch64.sve.sdiv.nxv2i64(<vscale x 2 x i1> %2, <vscale x 2 x i64> %a, <vscale x 2 x i64> %1)
79+
ret <vscale x 2 x i64> %3
80+
}
81+
82+
; Don't instcombine to SRAD when the divisor is -1
83+
define <vscale x 2 x i64> @divide_by_m1(<vscale x 16 x i1> %p, <vscale x 2 x i64> %a) #0 {
84+
; CHECK-LABEL: @divide_by_m1(
85+
; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[P:%.*]])
86+
; CHECK-NEXT: [[TMP2:%.*]] = call <vscale x 2 x i64> @llvm.aarch64.sve.sdiv.nxv2i64(<vscale x 2 x i1> [[TMP1]], <vscale x 2 x i64> [[A:%.*]], <vscale x 2 x i64> shufflevector (<vscale x 2 x i64> insertelement (<vscale x 2 x i64> poison, i64 -1, i64 0), <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer))
87+
; CHECK-NEXT: ret <vscale x 2 x i64> [[TMP2]]
88+
;
89+
%1 = call <vscale x 2 x i64> @llvm.aarch64.sve.dup.x.nxv2i64(i64 -1)
90+
%2 = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %p)
91+
%3 = call <vscale x 2 x i64> @llvm.aarch64.sve.sdiv.nxv2i64(<vscale x 2 x i1> %2, <vscale x 2 x i64> %a, <vscale x 2 x i64> %1)
92+
ret <vscale x 2 x i64> %3
93+
}
7194

7295
declare <vscale x 4 x i32> @llvm.aarch64.sve.sdiv.nxv4i32(<vscale x 4 x i1>, <vscale x 4 x i32>, <vscale x 4 x i32>)
7396
declare <vscale x 2 x i64> @llvm.aarch64.sve.sdiv.nxv2i64(<vscale x 2 x i1>, <vscale x 2 x i64>, <vscale x 2 x i64>)

0 commit comments

Comments
 (0)