[llvm] f609d4b - [SLP]Fix PR72833: do not crash if only operand is casted but the use

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 20 08:41:12 PST 2023


Author: Alexey Bataev
Date: 2023-11-20T08:35:35-08:00
New Revision: f609d4ba1d940c781f4fed44f7c69422d1766f09

URL: https://github.com/llvm/llvm-project/commit/f609d4ba1d940c781f4fed44f7c69422d1766f09
DIFF: https://github.com/llvm/llvm-project/commit/f609d4ba1d940c781f4fed44f7c69422d1766f09.diff

LOG: [SLP]Fix PR72833: do not crash if only operand is casted but the use
instruction.

Need to check if only operand is casted, not the user instruction
itself, if the types of the operands does not match the actual type.

Added: 
    llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 2aedc9b4054d429..94408eefdf499da 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11110,7 +11110,8 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
         Builder.SetCurrentDebugLocation(PH->getDebugLoc());
         Value *Vec = vectorizeOperand(E, i, /*PostponedPHIs=*/true);
         if (VecTy != Vec->getType()) {
-          assert(It != MinBWs.end() && "Expected item in MinBWs.");
+          assert(MinBWs.contains(PH->getIncomingValue(i)) &&
+                 "Expected item in MinBWs.");
           Vec = Builder.CreateIntCast(Vec, VecTy, It->second.second);
         }
         NewPhi->addIncoming(Vec, IBB);
@@ -11362,13 +11363,11 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
         return E->VectorizedValue;
       }
       if (L->getType() != R->getType()) {
-        assert(It != MinBWs.end() && "Expected item in MinBWs.");
-        if (L == R) {
-          R = L = Builder.CreateIntCast(L, VecTy, IsSigned);
-        } else {
-          L = Builder.CreateIntCast(L, VecTy, IsSigned);
-          R = Builder.CreateIntCast(R, VecTy, IsSigned);
-        }
+        assert((MinBWs.contains(VL0->getOperand(0)) ||
+                MinBWs.contains(VL0->getOperand(1))) &&
+               "Expected item in MinBWs.");
+        L = Builder.CreateIntCast(L, VecTy, IsSigned);
+        R = Builder.CreateIntCast(R, VecTy, IsSigned);
       }
 
       CmpInst::Predicate P0 = cast<CmpInst>(VL0)->getPredicate();
@@ -11401,13 +11400,11 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
         return E->VectorizedValue;
       }
       if (True->getType() != False->getType()) {
-        assert(It != MinBWs.end() && "Expected item in MinBWs.");
-        if (True == False) {
-          True = False = Builder.CreateIntCast(True, VecTy, IsSigned);
-        } else {
-          True = Builder.CreateIntCast(True, VecTy, IsSigned);
-          False = Builder.CreateIntCast(False, VecTy, IsSigned);
-        }
+        assert((MinBWs.contains(VL0->getOperand(1)) ||
+                MinBWs.contains(VL0->getOperand(2))) &&
+               "Expected item in MinBWs.");
+        True = Builder.CreateIntCast(True, VecTy, IsSigned);
+        False = Builder.CreateIntCast(False, VecTy, IsSigned);
       }
 
       Value *V = Builder.CreateSelect(Cond, True, False);
@@ -11471,13 +11468,11 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
         return E->VectorizedValue;
       }
       if (LHS->getType() != RHS->getType()) {
-        assert(It != MinBWs.end() && "Expected item in MinBWs.");
-        if (LHS == RHS) {
-          RHS = LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned);
-        } else {
-          LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned);
-          RHS = Builder.CreateIntCast(RHS, VecTy, IsSigned);
-        }
+        assert((MinBWs.contains(VL0->getOperand(0)) ||
+                MinBWs.contains(VL0->getOperand(1))) &&
+               "Expected item in MinBWs.");
+        LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned);
+        RHS = Builder.CreateIntCast(RHS, VecTy, IsSigned);
       }
 
       Value *V = Builder.CreateBinOp(
@@ -11710,13 +11705,11 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
         return E->VectorizedValue;
       }
       if (LHS && RHS && LHS->getType() != RHS->getType()) {
-        assert(It != MinBWs.end() && "Expected item in MinBWs.");
-        if (LHS == RHS) {
-          RHS = LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned);
-        } else {
-          LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned);
-          RHS = Builder.CreateIntCast(RHS, VecTy, IsSigned);
-        }
+        assert((MinBWs.contains(VL0->getOperand(0)) ||
+                MinBWs.contains(VL0->getOperand(1))) &&
+               "Expected item in MinBWs.");
+        LHS = Builder.CreateIntCast(LHS, VecTy, IsSigned);
+        RHS = Builder.CreateIntCast(RHS, VecTy, IsSigned);
       }
 
       Value *V0, *V1;

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll
new file mode 100644
index 000000000000000..ac8dd659d4aefc9
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll
@@ -0,0 +1,83 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -passes=slp-vectorizer -S -slp-threshold=-6 -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+define void @test(i64 %d.promoted.i) {
+; CHECK-LABEL: define void @test(
+; CHECK-SAME: i64 [[D_PROMOTED_I:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> <i64 poison, i64 0>, i64 [[D_PROMOTED_I]], i32 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i64> zeroinitializer, [[TMP0]]
+; CHECK-NEXT:    [[TMP2:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i1>
+; CHECK-NEXT:    [[TMP3:%.*]] = mul <2 x i1> [[TMP2]], zeroinitializer
+; CHECK-NEXT:    [[TMP4:%.*]] = or <2 x i1> [[TMP3]], zeroinitializer
+; CHECK-NEXT:    [[TMP5:%.*]] = or <2 x i1> [[TMP4]], zeroinitializer
+; CHECK-NEXT:    [[TMP6:%.*]] = or <2 x i1> [[TMP5]], zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = or <2 x i1> [[TMP6]], zeroinitializer
+; CHECK-NEXT:    [[TMP8:%.*]] = or <2 x i1> [[TMP7]], zeroinitializer
+; CHECK-NEXT:    [[TMP9:%.*]] = or <2 x i1> [[TMP8]], zeroinitializer
+; CHECK-NEXT:    [[TMP10:%.*]] = or <2 x i1> [[TMP9]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0
+; CHECK-NEXT:    [[TMP12:%.*]] = sext i1 [[TMP11]] to i32
+; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1
+; CHECK-NEXT:    [[TMP14:%.*]] = sext i1 [[TMP13]] to i32
+; CHECK-NEXT:    [[TMP15:%.*]] = or i32 [[TMP12]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = and i32 [[TMP15]], 0
+; CHECK-NEXT:    store i32 [[TMP16]], ptr null, align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %add.1.i = add i64 0, 0
+  %and.1.i = and i64 %add.1.i, %d.promoted.i
+  %conv12.1.i = trunc i64 %and.1.i to i32
+  %mul.i.1.i = mul i32 %conv12.1.i, 0
+  %conv12.i = trunc i64 0 to i32
+  %mul.i.i = mul i32 %conv12.i, 0
+  %conv14104.i = or i32 %mul.i.1.i, %mul.i.i
+  %conv12.2.i = trunc i64 0 to i32
+  %mul.i.2.i = mul i32 %conv12.2.i, 0
+  %0 = or i32 %conv14104.i, %mul.i.2.i
+  %conv12.182.i = trunc i64 0 to i32
+  %mul.i.183.i = mul i32 %conv12.182.i, 0
+  %1 = or i32 %0, %mul.i.183.i
+  %conv12.1.1.i = trunc i64 0 to i32
+  %mul.i.1.1.i = mul i32 %conv12.1.1.i, 0
+  %2 = or i32 %1, %mul.i.1.1.i
+  %conv12.2.1.i = trunc i64 0 to i32
+  %mul.i.2.1.i = mul i32 %conv12.2.1.i, 0
+  %3 = or i32 %2, %mul.i.2.1.i
+  %conv12.297.i = trunc i64 0 to i32
+  %mul.i.298.i = mul i32 %conv12.297.i, 0
+  %4 = or i32 %3, %mul.i.298.i
+  %conv12.1.2.i = trunc i64 0 to i32
+  %mul.i.1.2.i = mul i32 %conv12.1.2.i, 0
+  %5 = or i32 %4, %mul.i.1.2.i
+  %add.1.i.1 = add i64 0, 0
+  %and.1.i.1 = and i64 %add.1.i.1, 0
+  %conv12.1.i.1 = trunc i64 %and.1.i.1 to i32
+  %mul.i.1.i.1 = mul i32 %conv12.1.i.1, 0
+  %conv12.i.1 = trunc i64 0 to i32
+  %mul.i.i.1 = mul i32 %conv12.i.1, 0
+  %conv14104.i.1 = or i32 %mul.i.1.i.1, %mul.i.i.1
+  %conv12.2.i.1 = trunc i64 0 to i32
+  %mul.i.2.i.1 = mul i32 %conv12.2.i.1, 0
+  %6 = or i32 %conv14104.i.1, %mul.i.2.i.1
+  %conv12.182.i.1 = trunc i64 0 to i32
+  %mul.i.183.i.1 = mul i32 %conv12.182.i.1, 0
+  %7 = or i32 %6, %mul.i.183.i.1
+  %conv12.1.1.i.1 = trunc i64 0 to i32
+  %mul.i.1.1.i.1 = mul i32 %conv12.1.1.i.1, 0
+  %8 = or i32 %7, %mul.i.1.1.i.1
+  %conv12.2.1.i.1 = trunc i64 0 to i32
+  %mul.i.2.1.i.1 = mul i32 %conv12.2.1.i.1, 0
+  %9 = or i32 %8, %mul.i.2.1.i.1
+  %conv12.297.i.1 = trunc i64 0 to i32
+  %mul.i.298.i.1 = mul i32 %conv12.297.i.1, 0
+  %10 = or i32 %9, %mul.i.298.i.1
+  %conv12.1.2.i.1 = trunc i64 0 to i32
+  %mul.i.1.2.i.1 = mul i32 %conv12.1.2.i.1, 0
+  %11 = or i32 %10, %mul.i.1.2.i.1
+  %12 = or i32 %5, %11
+  %13 = and i32 %12, 0
+  store i32 %13, ptr null, align 4
+  ret void
+}


        


More information about the llvm-commits mailing list