[llvm-branch-commits] [SLP]Drop samesign of narrowed bit test compares (PR #235287)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Oct 24 05:16:31 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-vectorizers

Author: Alexey Bataev (alexey-bataev)

<details>
<summary>Changes</summary>

The bit tests compare and L, R, which sign-extends from the narrow type only
if both L and R do, so its sign may change after narrowing.

Fixes https://github.com/llvm/llvm-project/pull/233124#issuecomment-6382644843

Assisted-by: Cursor


---
Full diff: https://github.com/llvm/llvm-project/pull/235287.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+14-9) 
- (modified) llvm/test/Transforms/SLPVectorizer/X86/bit-test-narrowed-samesign.ll (+2-2) 


``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index e23d074965678..496a511ba0f61 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -18219,8 +18219,8 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
             cast<CmpInst>(E->getAltOp())->getPredicate(), CostKind, Op0Info,
             Op1Info, E->getAltOp());
       } else {
-        Type *SrcTy = getWidenedType(E->getMainOp()->getOperand(0)->getType(),
-                                     VL.size());
+        Type *SrcTy =
+            getWidenedType(E->getMainOp()->getOperand(0)->getType(), VL.size());
         TTI::CastContextHint CCH =
             GetCastContextHint(E->getMainOp()->getOperand(0));
         unsigned Opcode0 = E->getOpcode();
@@ -18262,12 +18262,12 @@ BoUpSLP::getEntryCost(const TreeEntry *E, ArrayRef<Value *> VectorizedVals,
         }
         // Same casts of the demoted operand, no need to shuffle.
         if (Opcode0 == Opcode1)
-          return VecCost + TTIRef.getCastInstrCost(Opcode0, VecTy, SrcTy, CCH,
-                                                   CostKind);
-        VecCost += TTIRef.getCastInstrCost(Opcode0, VecTy, SrcTy, CCH,
-                                           CostKind, E->getMainOp());
-        VecCost += TTIRef.getCastInstrCost(Opcode1, VecTy, SrcTy, CCH,
-                                           CostKind, E->getAltOp());
+          return VecCost +
+                 TTIRef.getCastInstrCost(Opcode0, VecTy, SrcTy, CCH, CostKind);
+        VecCost += TTIRef.getCastInstrCost(Opcode0, VecTy, SrcTy, CCH, CostKind,
+                                           E->getMainOp());
+        VecCost += TTIRef.getCastInstrCost(Opcode1, VecTy, SrcTy, CCH, CostKind,
+                                           E->getAltOp());
       }
       SmallVector<int> Mask;
       E->buildAltOpShuffleMask(
@@ -24372,10 +24372,15 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
     // a known-zero narrow sign bit), or a converted lane's adjusted constant
     // flips the sign.
     if (auto *ICmp = dyn_cast<ICmpInst>(I); ICmp && It == MinBWs.end()) {
+      // The bit tests compare and L, R, which sign-extends from the narrow
+      // type only if both L and R do.
+      bool IsSigned0 =
+          GetOperandSignedness(0) &&
+          (none_of(E->Scalars, IsaPred<TruncInst>) || GetOperandSignedness(1));
       bool SignChange =
           ICmp->getOperand(0)->getType()->getScalarType() !=
               VL0->getOperand(0)->getType()->getScalarType() &&
-          ((!GetOperandSignedness(0) &&
+          ((!IsSigned0 &&
             !isKnownNonNegative(ICmp->getOperand(0), SimplifyQuery(*DL))) ||
            (!GetOperandSignedness(1) &&
             !isKnownNonNegative(ICmp->getOperand(1), SimplifyQuery(*DL))));
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/bit-test-narrowed-samesign.ll b/llvm/test/Transforms/SLPVectorizer/X86/bit-test-narrowed-samesign.ll
index 55beaeb6ee0c2..48783e7e96832 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/bit-test-narrowed-samesign.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/bit-test-narrowed-samesign.ll
@@ -7,7 +7,7 @@ define void @samesign_ne_sext_mask_sign_bit(ptr noalias %pa, ptr noalias %dst) {
 ; CHECK-NEXT:  [[ENTRY:.*:]]
 ; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i8>, ptr [[PA]], align 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i8> [[TMP0]], <i8 -128, i8 -128, i8 -128, i8 1>
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp samesign ne <4 x i8> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <4 x i8> [[TMP1]], zeroinitializer
 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> splat (i32 3), <4 x i32> splat (i32 5)
 ; CHECK-NEXT:    store <4 x i32> [[TMP3]], ptr [[DST]], align 4
 ; CHECK-NEXT:    ret void
@@ -51,7 +51,7 @@ define void @samesign_eq_sext_mask_sign_bit(ptr noalias %pa, ptr noalias %dst) {
 ; CHECK-NEXT:  [[ENTRY:.*:]]
 ; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i8>, ptr [[PA]], align 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i8> [[TMP0]], <i8 -128, i8 -128, i8 -128, i8 1>
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp samesign eq <4 x i8> [[TMP1]], <i8 0, i8 0, i8 0, i8 1>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <4 x i8> [[TMP1]], <i8 0, i8 0, i8 0, i8 1>
 ; CHECK-NEXT:    [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> splat (i32 3), <4 x i32> splat (i32 5)
 ; CHECK-NEXT:    store <4 x i32> [[TMP3]], ptr [[DST]], align 4
 ; CHECK-NEXT:    ret void

``````````

</details>


https://github.com/llvm/llvm-project/pull/235287


More information about the llvm-branch-commits mailing list