diff options
author | Alexey Bataev <a.bataev@outlook.com> | 2023-11-20 08:32:50 -0800 |
---|---|---|
committer | Alexey Bataev <a.bataev@outlook.com> | 2023-11-20 08:35:35 -0800 |
commit | f609d4ba1d940c781f4fed44f7c69422d1766f09 (patch) | |
tree | 0d6b4279ef6c7901268a58cc3fd97b159d1faac4 | |
parent | c38ae74b48c1cb8aedf384686eaa05815d366609 (diff) | |
download | llvm-f609d4ba1d940c781f4fed44f7c69422d1766f09.zip llvm-f609d4ba1d940c781f4fed44f7c69422d1766f09.tar.gz llvm-f609d4ba1d940c781f4fed44f7c69422d1766f09.tar.bz2 |
[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.
-rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 51 | ||||
-rw-r--r-- | llvm/test/Transforms/SLPVectorizer/X86/minbitwidth-transformed-operand.ll | 83 |
2 files changed, 105 insertions, 29 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 2aedc9b..94408ee 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 0000000..ac8dd65 --- /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 +} |