[flang-commits] [flang] [flang] fix codegen of fir.select with only default case (PR #181373)

via flang-commits flang-commits at lists.llvm.org
Fri Feb 13 07:26:27 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-codegen

Author: None (jeanPerier)

<details>
<summary>Changes</summary>

The case where fir.select only has a "unit" block target (i.e., it is a switch with only the default case) was not handled correctly in codegen.

This for instance fixes compiler crash when compiling (invalid) code like the following:

```
subroutine repro 
  integer :: never_assigned_format
  read (6,never_assigned_format,rec=1)
end subroutine
call repro 
end
```

Note that such bad programs are already getting a warning with `-Wused-undefined-variable`.

---
Full diff: https://github.com/llvm/llvm-project/pull/181373.diff


2 Files Affected:

- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+8) 
- (modified) flang/test/Fir/select.fir (+14) 


``````````diff
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 625701725003f..f9d469f869619 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -3750,6 +3750,14 @@ struct SelectOpConversionBase : public fir::FIROpConversion<OP> {
       defaultDestination = *convertedBlock;
     }
 
+    // Deal with the case where there is only a default destination.  Handle it
+    // now because emitting empty case values is not legal.
+    if (caseValues.empty()) {
+      rewriter.replaceOpWithNewOp<mlir::LLVM::BrOp>(select, defaultOperands,
+                                                    defaultDestination);
+      return mlir::success();
+    }
+
     selector =
         this->integerCast(loc, rewriter, rewriter.getI64Type(), selector);
 
diff --git a/flang/test/Fir/select.fir b/flang/test/Fir/select.fir
index 5e88048446407..b342b7cff1c6a 100644
--- a/flang/test/Fir/select.fir
+++ b/flang/test/Fir/select.fir
@@ -67,3 +67,17 @@ func.func @h(%a : i32) -> i32 {
    // CHECK: ret i32
    return %x : i32
 }
+
+func.func @empty_cases(%arg0 : i32) {
+  fir.select %arg0 : i32 [unit, ^bb1]
+^bb1:  // pred: ^bb0
+  fir.call @crash() fastmath<contract> : () -> ()
+  fir.unreachable
+}
+func.func private @crash()
+
+//CHECK-LABEL: @empty_cases(i32 %0) {
+//CHECK:  br label %[[BLOCK:.*]]
+//CHECK: [[BLOCK]]:
+//CHECK:  call void @crash()
+//CHECK:  unreachable

``````````

</details>


https://github.com/llvm/llvm-project/pull/181373


More information about the flang-commits mailing list