[flang-commits] [flang] [flang] Fix SelectCaseOpConversion to convert block signatures (PR #175298)
via flang-commits
flang-commits at lists.llvm.org
Sat Jan 10 00:52:58 PST 2026
https://github.com/khaki3 created https://github.com/llvm/llvm-project/pull/175298
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`.
>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] [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):
More information about the flang-commits
mailing list