[llvm] LV/VPlan: add missing case for LogicalAnd; fix crash (PR #93553)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Tue May 28 07:09:51 PDT 2024
https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/93553
VPTypeAnalysis::inferScalarTypeForRecipe is missing the case for VPInstruction::LogicalAnd, due to which the test vplan-incomplete-cases.ll crashes. Add this missing case, and move the test in vplan-infer-not-or-type.ll to vplan-incomplete-cases.ll, showing correct codegen for trip-counts 2 and 3.
-- 8< --
Based on #93551.
>From 9261244d283fc91ce509b81ccd9f85dde579d4aa Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <r at artagnon.com>
Date: Tue, 28 May 2024 13:47:16 +0100
Subject: [PATCH 1/2] [LV] add crash-test for incomplete cases in VPlan
The test is identical to the one in vplan-infer-not-or-type.ll, except
that the trip count is now 3 instead of 2.
---
.../LoopVectorize/vplan-incomplete-cases.ll | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll b/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll
new file mode 100644
index 0000000000000..2f3ed0d69d269
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll
@@ -0,0 +1,25 @@
+; REQUIRES: asserts
+; RUN: not --crash opt %s -passes=loop-vectorize -S
+
+define void @vplan_incomplete_cases_tc3(i8 %x, i8 %y) {
+entry:
+ br label %loop.header
+
+loop.header: ; preds = %latch, %entry
+ %iv = phi i8 [ %iv.next, %latch ], [ 0, %entry ]
+ %and = and i8 %x, %y
+ %extract.t = trunc i8 %and to i1
+ br i1 %extract.t, label %latch, label %indirect.latch
+
+indirect.latch: ; preds = %loop.header
+ br label %latch
+
+latch: ; preds = %indirect.latch, loop.header
+ %iv.next = add i8 %iv, 1
+ %zext = zext i8 %iv to i32
+ %cmp = icmp ult i32 %zext, 2
+ br i1 %cmp, label %loop.header, label %exit
+
+exit: ; preds = %latch
+ ret void
+}
>From e5d61f7cf87a9b819b1db7bda8c5e5f2c2bd490e Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <r at artagnon.com>
Date: Tue, 28 May 2024 15:00:27 +0100
Subject: [PATCH 2/2] LV/VPlan: add missing case for LogicalAnd; fix crash
VPTypeAnalysis::inferScalarTypeForRecipe is missing the case for
VPInstruction::LogicalAnd, due to which the test
vplan-incomplete-cases.ll crashes. Add this missing case, and move the
test in vplan-infer-not-or-type.ll to vplan-incomplete-cases.ll, showing
correct codegen for trip-counts 2 and 3.
---
.../Transforms/Vectorize/VPlanAnalysis.cpp | 2 +
.../LoopVectorize/vplan-incomplete-cases.ll | 97 ++++++++++++++++++-
.../LoopVectorize/vplan-infer-not-or-type.ll | 64 ------------
3 files changed, 97 insertions(+), 66 deletions(-)
delete mode 100644 llvm/test/Transforms/LoopVectorize/vplan-infer-not-or-type.ll
diff --git a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
index efe8c21874a3a..860f2a33697fe 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanAnalysis.cpp
@@ -51,6 +51,8 @@ Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
"unexpected scalar type inferred for operand");
return ResTy;
}
+ case VPInstruction::LogicalAnd:
+ return IntegerType::get(Ctx, 1);
case VPInstruction::PtrAdd:
// Return the type based on the pointer argument (i.e. first operand).
return inferScalarType(R->getOperand(0));
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll b/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll
index 2f3ed0d69d269..2007155fe5485 100644
--- a/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll
+++ b/llvm/test/Transforms/LoopVectorize/vplan-incomplete-cases.ll
@@ -1,7 +1,92 @@
-; REQUIRES: asserts
-; RUN: not --crash opt %s -passes=loop-vectorize -S
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=loop-vectorize -S %s | FileCheck %s
+; This test used to crash due to missing Or/Not cases in inferScalarTypeForRecipe.
+define void @vplan_incomplete_cases_tc2(i8 %x, i8 %y) {
+; CHECK-LABEL: define void @vplan_incomplete_cases_tc2(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
+; CHECK: [[VECTOR_PH]]:
+; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
+; CHECK: [[VECTOR_BODY]]:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
+; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: [[MIDDLE_BLOCK]]:
+; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
+; CHECK: [[SCALAR_PH]]:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ 2, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
+; CHECK: [[LOOP_HEADER]]:
+; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ]
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]
+; CHECK-NEXT: [[EXTRACT_T:%.*]] = trunc i8 [[AND]] to i1
+; CHECK-NEXT: br i1 [[EXTRACT_T]], label %[[LATCH]], label %[[INDIRECT_LATCH:.*]]
+; CHECK: [[INDIRECT_LATCH]]:
+; CHECK-NEXT: br label %[[LATCH]]
+; CHECK: [[LATCH]]:
+; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
+; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV]] to i32
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ZEXT]], 1
+; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP_HEADER]], label %[[EXIT]], !llvm.loop [[LOOP3:![0-9]+]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop.header
+
+loop.header: ; preds = %latch, %entry
+ %iv = phi i8 [ %iv.next, %latch ], [ 0, %entry ]
+ %and = and i8 %x, %y
+ %extract.t = trunc i8 %and to i1
+ br i1 %extract.t, label %latch, label %indirect.latch
+
+indirect.latch: ; preds = %loop.header
+ br label %latch
+
+latch: ; preds = %indirect.latch, loop.header
+ %iv.next = add i8 %iv, 1
+ %zext = zext i8 %iv to i32
+ %cmp = icmp ult i32 %zext, 1
+ br i1 %cmp, label %loop.header, label %exit
+
+exit: ; preds = %latch
+ ret void
+}
+
+; This test used to crash due to missing the LogicalAnd case in inferScalarTypeForRecipe.
define void @vplan_incomplete_cases_tc3(i8 %x, i8 %y) {
+; CHECK-LABEL: define void @vplan_incomplete_cases_tc3(
+; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
+; CHECK: [[VECTOR_PH]]:
+; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
+; CHECK: [[VECTOR_BODY]]:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[INDEX_NEXT]] = add i32 [[INDEX]], 4
+; CHECK-NEXT: br i1 true, label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
+; CHECK: [[MIDDLE_BLOCK]]:
+; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
+; CHECK: [[SCALAR_PH]]:
+; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ 4, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
+; CHECK: [[LOOP_HEADER]]:
+; CHECK-NEXT: [[IV:%.*]] = phi i8 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ]
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[Y]]
+; CHECK-NEXT: [[EXTRACT_T:%.*]] = trunc i8 [[AND]] to i1
+; CHECK-NEXT: br i1 [[EXTRACT_T]], label %[[LATCH]], label %[[INDIRECT_LATCH:.*]]
+; CHECK: [[INDIRECT_LATCH]]:
+; CHECK-NEXT: br label %[[LATCH]]
+; CHECK: [[LATCH]]:
+; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], 1
+; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[IV]] to i32
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ZEXT]], 2
+; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP_HEADER]], label %[[EXIT]], !llvm.loop [[LOOP5:![0-9]+]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %loop.header
@@ -23,3 +108,11 @@ latch: ; preds = %indirect.latch, l
exit: ; preds = %latch
ret void
}
+;.
+; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
+; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
+; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
+; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
+; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
+; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
+;.
diff --git a/llvm/test/Transforms/LoopVectorize/vplan-infer-not-or-type.ll b/llvm/test/Transforms/LoopVectorize/vplan-infer-not-or-type.ll
deleted file mode 100644
index 102ef699cb379..0000000000000
--- a/llvm/test/Transforms/LoopVectorize/vplan-infer-not-or-type.ll
+++ /dev/null
@@ -1,64 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
-; RUN: opt < %s -passes=loop-vectorize -S | FileCheck %s
-
-; This test used to crash due to missing Or/Not cases in
-; inferScalarTypeForRecipe.
-
-define void @foo(i8 %arg.0, i8 %arg.1) {
-; CHECK-LABEL: define void @foo(
-; CHECK-SAME: i8 [[ARG_0:%.*]], i8 [[ARG_1:%.*]]) {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
-; CHECK: vector.ph:
-; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
-; CHECK: vector.body:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
-; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
-; CHECK-NEXT: br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; CHECK: middle.block:
-; CHECK-NEXT: br i1 true, label [[LOOPEXIT:%.*]], label [[SCALAR_PH]]
-; CHECK: scalar.ph:
-; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i8 [ 2, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
-; CHECK: loop.header:
-; CHECK-NEXT: [[INCREMENTOR:%.*]] = phi i8 [ [[ADD:%.*]], [[LATCH:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
-; CHECK-NEXT: [[AND:%.*]] = and i8 [[ARG_0]], [[ARG_1]]
-; CHECK-NEXT: [[EXTRACT_T:%.*]] = trunc i8 [[AND]] to i1
-; CHECK-NEXT: br i1 [[EXTRACT_T]], label [[LATCH]], label [[INDIRECT_LATCH:%.*]]
-; CHECK: indirect.latch:
-; CHECK-NEXT: br label [[LATCH]]
-; CHECK: latch:
-; CHECK-NEXT: [[ADD]] = add i8 [[INCREMENTOR]], 1
-; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[INCREMENTOR]] to i32
-; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 1
-; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_HEADER]], label [[LOOPEXIT]], !llvm.loop [[LOOP3:![0-9]+]]
-; CHECK: loop.exit:
-; CHECK-NEXT: ret void
-;
-entry:
- br label %loop.header
-
-loop.header: ; preds = %latch, %entry
- %incrementor = phi i8 [ %add, %latch ], [ 0, %entry ]
- %and = and i8 %arg.0, %arg.1
- %extract.t = trunc i8 %and to i1
- br i1 %extract.t, label %latch, label %indirect.latch
-
-indirect.latch: ; preds = %loop.header
- br label %latch
-
-latch: ; preds = %loop.header16, %loop.header
- %add = add i8 %incrementor, 1
- %conv = zext i8 %incrementor to i32
- %cmp = icmp ult i32 %conv, 1
- br i1 %cmp, label %loop.header, label %loop.exit
-
-loop.exit:
- ret void
-}
-;.
-; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
-; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
-; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
-; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
-;.
More information about the llvm-commits
mailing list