Skip to content

Commit 326d4e9

Browse files
committed
[SLP]Check if the copyable element is a sub instruciton with abs in isCommutable
Need to check if the non-copyable element is an instruction before actually trying to check its NSW attribute.
1 parent 66d5f6a commit 326d4e9

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,8 @@ static bool isSplat(ArrayRef<Value *> VL) {
537537
/// \param I The instruction to check for commutativity
538538
/// \param ValWithUses The value whose uses are analyzed for special
539539
/// patterns
540-
static bool isCommutative(Instruction *I, Value *ValWithUses) {
540+
static bool isCommutative(Instruction *I, Value *ValWithUses,
541+
bool IsCopyable = false) {
541542
if (auto *Cmp = dyn_cast<CmpInst>(I))
542543
return Cmp->isCommutative();
543544
if (auto *BO = dyn_cast<BinaryOperator>(I))
@@ -546,7 +547,7 @@ static bool isCommutative(Instruction *I, Value *ValWithUses) {
546547
!ValWithUses->hasNUsesOrMore(UsesLimit) &&
547548
all_of(
548549
ValWithUses->uses(),
549-
[](const Use &U) {
550+
[&](const Use &U) {
550551
// Commutative, if icmp eq/ne sub, 0
551552
CmpPredicate Pred;
552553
if (match(U.getUser(),
@@ -555,10 +556,11 @@ static bool isCommutative(Instruction *I, Value *ValWithUses) {
555556
return true;
556557
// Commutative, if abs(sub nsw, true) or abs(sub, false).
557558
ConstantInt *Flag;
559+
auto *I = dyn_cast<BinaryOperator>(U.get());
558560
return match(U.getUser(),
559561
m_Intrinsic<Intrinsic::abs>(
560562
m_Specific(U.get()), m_ConstantInt(Flag))) &&
561-
(!cast<Instruction>(U.get())->hasNoSignedWrap() ||
563+
((!IsCopyable && I && !I->hasNoSignedWrap()) ||
562564
Flag->isOne());
563565
})) ||
564566
(BO->getOpcode() == Instruction::FSub &&
@@ -3164,7 +3166,8 @@ class BoUpSLP {
31643166
bool IsInverseOperation = false;
31653167
if (S.isCopyableElement(VL[Lane])) {
31663168
// The value is a copyable element.
3167-
IsInverseOperation = !isCommutative(MainOp, VL[Lane]);
3169+
IsInverseOperation =
3170+
!isCommutative(MainOp, VL[Lane], /*IsCopyable=*/true);
31683171
} else {
31693172
assert(I && "Expected instruction");
31703173
auto [SelectedOp, Ops] = convertTo(I, S);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
2+
; RUN: opt -passes=slp-vectorizer -S -slp-threshold=-100 -mtriple=arm64-apple-macosx15.0.0 < %s | FileCheck %s
3+
4+
define i1 @test(i32 %shr.i.i90, i32 %x) {
5+
; CHECK-LABEL: define i1 @test(
6+
; CHECK-SAME: i32 [[SHR_I_I90:%.*]], i32 [[X:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*:]]
8+
; CHECK-NEXT: [[TMP0:%.*]] = insertelement <2 x i32> poison, i32 [[X]], i32 0
9+
; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> [[TMP0]], i32 [[SHR_I_I90]], i32 1
10+
; CHECK-NEXT: [[TMP1:%.*]] = sub <2 x i32> [[TMP6]], <i32 2, i32 0>
11+
; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[TMP1]], i1 true)
12+
; CHECK-NEXT: [[TMP3:%.*]] = zext <2 x i32> [[TMP2]] to <2 x i64>
13+
; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt <2 x i64> [[TMP3]], <i64 100, i64 300>
14+
; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
15+
; CHECK-NEXT: ret i1 [[TMP5]]
16+
;
17+
entry:
18+
%cond.i.i = tail call i32 @llvm.abs.i32(i32 %shr.i.i90, i1 true)
19+
%conv.i.i91 = zext i32 %cond.i.i to i64
20+
%sub32.i.i = sub i32 %x, 2
21+
%cond41.i.i = tail call i32 @llvm.abs.i32(i32 %sub32.i.i, i1 true)
22+
%conv42.i.i = zext i32 %cond41.i.i to i64
23+
%cmp.not.i.2.i.i = icmp ugt i64 %conv.i.i91, 300
24+
%cmp.not.i.3.i.i = icmp ugt i64 %conv42.i.i, 100
25+
ret i1 %cmp.not.i.3.i.i
26+
}
27+
28+
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
29+
declare i32 @llvm.abs.i32(i32, i1 immarg) #0

0 commit comments

Comments
 (0)