[llvm] e5c143f - [SLP]Drop nsw when reordering a sub feeding icmp eq/ne 0
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 16:03:03 PDT 2026
Author: Alexey Bataev
Date: 2026-07-16T19:02:58-04:00
New Revision: e5c143f96b37f2215a0b07d46df7600d06a372f4
URL: https://github.com/llvm/llvm-project/commit/e5c143f96b37f2215a0b07d46df7600d06a372f4
DIFF: https://github.com/llvm/llvm-project/commit/e5c143f96b37f2215a0b07d46df7600d06a372f4.diff
LOG: [SLP]Drop nsw when reordering a sub feeding icmp eq/ne 0
A sub used only by icmp eq/ne 0 is treated as commutative, so SLP may
swap its operands, and nsw does not survive a - b -> b - a (a - b can
be INT_MIN while b - a overflows).
Fixes #210177
Reviewers:
Pull Request: https://github.com/llvm/llvm-project/pull/210205
Added:
Modified:
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
llvm/test/Transforms/SLPVectorizer/sub-nsw-icmp-eq-zero-reorder.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index ef144aa2403e7..6698395bf963b 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -23483,6 +23483,21 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
return !SI || isCommutative(SI);
})))
I->setHasNoUnsignedWrap(/*b=*/false);
+ // A sub feeding icmp eq/ne 0 may have its operands swapped; nsw does not
+ // survive a - b -> b - a (a - b can be INT_MIN while b - a overflows).
+ if (!MinBWs.contains(E) && Opcode == Instruction::Sub &&
+ any_of(Scalars, [](Value *Scalar) {
+ auto *SI = dyn_cast<Instruction>(Scalar);
+ if (!SI || SI->getOpcode() != Instruction::Sub || !isCommutative(SI))
+ return false;
+ return any_of(SI->uses(), [](const Use &U) {
+ CmpPredicate Pred;
+ return match(U.getUser(),
+ m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
+ ICmpInst::isEquality(Pred);
+ });
+ }))
+ I->setHasNoSignedWrap(/*b=*/false);
// Interchanging add/sub negates the constant: nsw only survives if the
// constant isn't INT_MIN (negating it would overflow); nuw never
// survives a nonzero constant, since that flips the valid range from
diff --git a/llvm/test/Transforms/SLPVectorizer/sub-nsw-icmp-eq-zero-reorder.ll b/llvm/test/Transforms/SLPVectorizer/sub-nsw-icmp-eq-zero-reorder.ll
index 344ad155110b6..4b2730d64cfc8 100644
--- a/llvm/test/Transforms/SLPVectorizer/sub-nsw-icmp-eq-zero-reorder.ll
+++ b/llvm/test/Transforms/SLPVectorizer/sub-nsw-icmp-eq-zero-reorder.ll
@@ -14,7 +14,7 @@ define <4 x i1> @sub_nsw_icmp_eq_zero(i8 %a0, i8 %a1, i8 %a2, i8 %a3, ptr %pl) {
; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[A1]], i64 1
; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[A2]], i64 2
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x i8> [[TMP3]], i8 [[A3]], i64 3
-; CHECK-NEXT: [[TMP5:%.*]] = sub nsw <4 x i8> [[TMP0]], [[TMP4]]
+; CHECK-NEXT: [[TMP5:%.*]] = sub <4 x i8> [[TMP0]], [[TMP4]]
; CHECK-NEXT: [[TMP6:%.*]] = icmp eq <4 x i8> [[TMP5]], zeroinitializer
; CHECK-NEXT: ret <4 x i1> [[TMP6]]
;
More information about the llvm-commits
mailing list