[llvm] [SLP]Fix unscheduled-deps assertion for cmp with identical operands (PR #217495)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 19 17:28:47 PDT 2026


https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/217495

Same-operands cmps (icmp sge %x, %x) took the reordered dependency
counting path, which undercounts the second use while scheduling
releases one dep per operand column. Treat them as non-commutative so
each use is checked against its own edge.

Fixes #217408


>From 40cbd8bfd605332bc815c4348852fa2d7ae8bd75 Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Wed, 19 Aug 2026 17:28:23 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 .../Transforms/Vectorize/SLPVectorizer.cpp    |  6 ++++--
 .../X86/cmp-with-same-operands.ll             | 20 +++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/cmp-with-same-operands.ll

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index df14bbe334425..3c44cd976fad6 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -4622,7 +4622,8 @@ class slpvectorizer::BoUpSLP {
           }
           // The commutative user with the same operands can be safely
           // considered as non-commutative, operands reordering does not change
-          // the semantics.
+          // the semantics. Same for cmps with the same operands: inverting
+          // the predicate does not change the operand columns in this case.
           assert(
               (!IsCommutativeUser ||
                (((isCommutative(User) && isCommutableOperand(User, User, 0) &&
@@ -4636,7 +4637,8 @@ class slpvectorizer::BoUpSLP {
           bool IsCommutativeWithSameOps =
               IsCommutativeUser && User->getOperand(0) == User->getOperand(1);
           if ((!IsCommutativeUser || IsCommutativeWithSameOps) &&
-              !isa<CmpInst>(User)) {
+              (!isa<CmpInst>(User) ||
+               User->getOperand(0) == User->getOperand(1))) {
             if (CurNumOps != NumOps)
               continue;
             // A reassociated node flattens the operand chain, so the operand
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/cmp-with-same-operands.ll b/llvm/test/Transforms/SLPVectorizer/X86/cmp-with-same-operands.ll
new file mode 100644
index 0000000000000..e2e8edad685b4
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/cmp-with-same-operands.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+define i1 @test(i16 %a) {
+; CHECK-LABEL: define i1 @test(
+; CHECK-SAME: i16 [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[AND:%.*]] = and i16 [[A]], 0
+; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i16 [[AND]], 0
+; CHECK-NEXT:    [[XOR:%.*]] = xor i16 [[AND]], 0
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i16 [[XOR]], [[XOR]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+entry:
+  %and = and i16 %a, 0
+  %tobool = icmp ne i16 %and, 0
+  %xor = xor i16 %and, 0
+  %cmp = icmp sge i16 %xor, %xor
+  ret i1 %cmp
+}



More information about the llvm-commits mailing list