[Mlir-commits] [mlir] [mlir][cf] Fix APInt comparison crash in `foldSwitch` (PR #206407)
Longsheng Mou
llvmlistbot at llvm.org
Sun Jun 28 23:45:53 PDT 2026
https://github.com/CoTinker created https://github.com/llvm/llvm-project/pull/206407
Fix crash when switch value and case values have different APInt bit width. Fixes #205234.
>From 37f933ad2c687f38cd7799731ae93d75509056b3 Mon Sep 17 00:00:00 2001
From: Longsheng Mou <longshengmou at gmail.com>
Date: Mon, 29 Jun 2026 14:41:02 +0800
Subject: [PATCH 1/2] [mlir][cf] Fix APInt comparison crash
Fix crash when switch value and case values have different APInt bit width.
---
mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
index 435c37bc95aac..53cf35f0599fe 100644
--- a/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
+++ b/mlir/lib/Dialect/ControlFlow/IR/ControlFlowOps.cpp
@@ -808,9 +808,10 @@ dropSwitchCasesThatMatchDefault(SwitchOp op, PatternRewriter &rewriter) {
/// -> br ^bb2
static void foldSwitch(SwitchOp op, PatternRewriter &rewriter,
const APInt &caseValue) {
+ uint64_t caseLimitedValue = caseValue.getLimitedValue();
auto caseValues = op.getCaseValues();
for (const auto &it : llvm::enumerate(caseValues->getValues<APInt>())) {
- if (it.value() == caseValue) {
+ if (it.value().getLimitedValue() == caseLimitedValue) {
rewriter.replaceOpWithNewOp<BranchOp>(
op, op.getCaseDestinations()[it.index()],
op.getCaseOperands(it.index()));
>From 57fb513fbb3549cebda9bc44c901fd8bd8560f1d Mon Sep 17 00:00:00 2001
From: Longsheng Mou <longshengmou at gmail.com>
Date: Mon, 29 Jun 2026 14:42:49 +0800
Subject: [PATCH 2/2] add test
---
.../Dialect/ControlFlow/canonicalize.mlir | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/mlir/test/Dialect/ControlFlow/canonicalize.mlir b/mlir/test/Dialect/ControlFlow/canonicalize.mlir
index c8cf5931a1297..b5a0e98b9bdc8 100644
--- a/mlir/test/Dialect/ControlFlow/canonicalize.mlir
+++ b/mlir/test/Dialect/ControlFlow/canonicalize.mlir
@@ -263,6 +263,32 @@ func.func @switch_on_const_with_match(%caseOperand0 : f32, %caseOperand1 : f32,
"foo.bb4Terminator"(%bb4Arg) : (f32) -> ()
}
+// CHECK-LABEL: func @switch_on_const_with_match_diff_width(
+// CHECK-SAME: %[[CASE_OPERAND_0:[a-zA-Z0-9_]+]]
+// CHECK-SAME: %[[CASE_OPERAND_1:[a-zA-Z0-9_]+]]
+// CHECK-SAME: %[[CASE_OPERAND_2:[a-zA-Z0-9_]+]]
+func.func @switch_on_const_with_match_diff_width(%caseOperand0 : f32, %caseOperand1 : f32, %caseOperand2 : f32) {
+ // add predecessors for all blocks to avoid other canonicalizations.
+ "foo.pred"() [^bb1, ^bb2, ^bb3, ^bb4] : () -> ()
+ ^bb1:
+ // CHECK-NOT: cf.switch
+ // CHECK: cf.br ^[[BB4:[a-zA-Z0-9_]+]](%[[CASE_OPERAND_2]]
+ %c0_i32 = llvm.mlir.constant(1 : index) : i32
+ cf.switch %c0_i32 : i32, [
+ default: ^bb2(%caseOperand0 : f32),
+ -1: ^bb3(%caseOperand1 : f32),
+ 1: ^bb4(%caseOperand2 : f32)
+ ]
+ ^bb2(%bb2Arg : f32):
+ "foo.bb2Terminator"(%bb2Arg) : (f32) -> ()
+ ^bb3(%bb3Arg : f32):
+ "foo.bb3Terminator"(%bb3Arg) : (f32) -> ()
+ // CHECK: ^[[BB4]]({{.*}}):
+ // CHECK-NEXT: "foo.bb4Terminator"
+ ^bb4(%bb4Arg : f32):
+ "foo.bb4Terminator"(%bb4Arg) : (f32) -> ()
+}
+
// CHECK-LABEL: func @switch_passthrough(
// CHECK-SAME: %[[FLAG:[a-zA-Z0-9_]+]]
// CHECK-SAME: %[[CASE_OPERAND_0:[a-zA-Z0-9_]+]]
More information about the Mlir-commits
mailing list