[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