[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:53:28 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-codegen
Author: None (khaki3)
<details>
<summary>Changes</summary>
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`.
---
Full diff: https://github.com/llvm/llvm-project/pull/175298.diff
2 Files Affected:
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+6)
- (modified) flang/test/Fir/convert-to-llvm.fir (+21)
``````````diff
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):
``````````
</details>
https://github.com/llvm/llvm-project/pull/175298
More information about the flang-commits
mailing list