[flang-commits] [flang] [flang] Fix SelectCaseOpConversion to convert block signatures (PR #175298)

via flang-commits flang-commits at lists.llvm.org
Mon Jan 12 06:52:10 PST 2026


https://github.com/khaki3 updated https://github.com/llvm/llvm-project/pull/175298

>From 8dccf037cabcaeb38e9132c103778f092cf9df82 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Sat, 10 Jan 2026 00:40:09 -0800
Subject: [PATCH 1/2] [flang] Fix SelectCaseOpConversion to convert block
 signatures

When fir.select_case branches to blocks with arguments that have FIR
types (e.g., !fir.ref), the block signature must be converted to LLVM
types before creating the branch. Otherwise, the branch passes LLVM
types (!llvm.ptr) but the block expects FIR types, causing a type
mismatch error.

This adds block signature conversion similar to what SelectOpConversionBase
already does for fir.select and fir.select_rank.
---
 flang/lib/Optimizer/CodeGen/CodeGen.cpp |  6 ++++++
 flang/test/Fir/convert-to-llvm.fir      | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index cf046a0bfcea8..66713e251af8f 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -3566,6 +3566,12 @@ struct SelectCaseOpConversion : public fir::FIROpConversion<fir::SelectCaseOp> {
       mlir::Block *dest = caseOp.getSuccessor(t);
       std::optional<mlir::ValueRange> destOps =
           caseOp.getSuccessorOperands(adaptor.getOperands(), t);
+      // Convert block signature if needed
+      if (destOps && !destOps->empty()) {
+        if (auto conversion = getTypeConverter()->convertBlockSignature(dest))
+          dest = rewriter.applySignatureConversion(dest, *conversion,
+                                                   getTypeConverter());
+      }
       std::optional<mlir::ValueRange> cmpOps =
           *caseOp.getCompareOperands(adaptor.getOperands(), t);
       mlir::Attribute attr = cases[t];
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 864368740be02..4108b3b11e2b9 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -2954,3 +2954,24 @@ func.func @select_with_cast(%arg1 : i8, %arg2 : i16, %arg3: i64, %arg4: index) -
 // CHECK:         ^bb5:
 // CHECK:           llvm.return
 // CHECK:         }
+
+// -----
+
+// Test `fir.select_case` with block arguments requiring type conversion.
+
+func.func @select_case_block_args(%arg0: !fir.ref<i32>, %arg1: !fir.ref<!fir.array<2xi32>>, %arg2: !fir.ref<!fir.array<2xi32>>) {
+  %0 = fir.load %arg0 : !fir.ref<i32>
+  %c1 = arith.constant 1 : i32
+  %c2 = arith.constant 2 : i32
+  fir.select_case %0 : i32 [#fir.point, %c1, ^bb1(%arg1 : !fir.ref<!fir.array<2xi32>>),
+                            #fir.point, %c2, ^bb1(%arg2 : !fir.ref<!fir.array<2xi32>>),
+                            unit, ^bb2]
+^bb1(%1: !fir.ref<!fir.array<2xi32>>):
+  cf.br ^bb2
+^bb2:
+  return
+}
+
+// CHECK-LABEL: llvm.func @select_case_block_args
+// CHECK: llvm.cond_br %{{.*}}, ^{{.*}}(%{{.*}} : !llvm.ptr), ^{{.*}}
+// CHECK: ^{{.*}}(%{{.*}}: !llvm.ptr):

>From 1613ad4542ef0c29d314c4df63f94faaec96d5d0 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Mon, 12 Jan 2026 06:51:54 -0800
Subject: [PATCH 2/2] Remove unnecessary braces from SelectCaseOpConversion fix

---
 flang/lib/Optimizer/CodeGen/CodeGen.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 66713e251af8f..bbb0514058ba2 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -3567,11 +3567,10 @@ struct SelectCaseOpConversion : public fir::FIROpConversion<fir::SelectCaseOp> {
       std::optional<mlir::ValueRange> destOps =
           caseOp.getSuccessorOperands(adaptor.getOperands(), t);
       // Convert block signature if needed
-      if (destOps && !destOps->empty()) {
+      if (destOps && !destOps->empty())
         if (auto conversion = getTypeConverter()->convertBlockSignature(dest))
           dest = rewriter.applySignatureConversion(dest, *conversion,
                                                    getTypeConverter());
-      }
       std::optional<mlir::ValueRange> cmpOps =
           *caseOp.getCompareOperands(adaptor.getOperands(), t);
       mlir::Attribute attr = cases[t];



More information about the flang-commits mailing list