[flang-commits] [flang] [flang][fir] fix fir.if canonicalization pattern from #205353 (PR #205757)

via flang-commits flang-commits at lists.llvm.org
Thu Jun 25 02:23:12 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: jeanPerier

<details>
<summary>Changes</summary>

Address https://github.com/llvm/llvm-project/pull/205353/files#r3468970484

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


2 Files Affected:

- (modified) flang/lib/Optimizer/Dialect/FIROps.cpp (+5-1) 
- (modified) flang/test/Fir/present-absent-if-fold.fir (+31) 


``````````diff
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index ba047e71d6aa3..469d36b3c79b0 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -5736,7 +5736,11 @@ struct FoldPresentAbsentIfOp : public mlir::OpRewritePattern<fir::IfOp> {
     auto elseResult = mlir::dyn_cast<fir::ResultOp>(elseBlock.getTerminator());
     if (!elseResult || elseResult.getNumOperands() != 1)
       return mlir::failure();
-    if (!elseResult.getOperand(0).getDefiningOp<fir::AbsentOp>())
+    auto absentOp = elseResult.getOperand(0).getDefiningOp<fir::AbsentOp>();
+    if (!absentOp)
+      return mlir::failure();
+    if (elseBlock.getOperations().size() == 2 &&
+        absentOp.getOperation() != &elseBlock.front())
       return mlir::failure();
 
     rewriter.replaceOp(ifOp, optionalVal);
diff --git a/flang/test/Fir/present-absent-if-fold.fir b/flang/test/Fir/present-absent-if-fold.fir
index 19fd7859f4a23..1fed8be86a4a1 100644
--- a/flang/test/Fir/present-absent-if-fold.fir
+++ b/flang/test/Fir/present-absent-if-fold.fir
@@ -33,6 +33,21 @@ func.func @fold_present_absent_if_ref(%var: !fir.ref<i32>) -> !fir.ref<i32> {
   return %if_result : !fir.ref<i32>
 }
 
+// CHECK-LABEL: func.func @fold_present_if_absent_csed(
+// CHECK-SAME:     %[[VAR:.*]]: !fir.ref<i32>) -> !fir.ref<i32> {
+// CHECK-NOT: fir.if
+// CHECK: return %[[VAR]] : !fir.ref<i32>
+func.func @fold_present_if_absent_csed(%var: !fir.ref<i32>) -> !fir.ref<i32> {
+  %absent = fir.absent !fir.ref<i32>
+  %present = fir.is_present %var : (!fir.ref<i32>) -> i1
+  %if_result = fir.if %present -> (!fir.ref<i32>) {
+    fir.result %var : !fir.ref<i32>
+  } else {
+    fir.result %absent : !fir.ref<i32>
+  }
+  return %if_result : !fir.ref<i32>
+}
+
 func.func private @side_effect() -> ()
 
 // CHECK-LABEL: func.func @no_fold_call_in_then(
@@ -64,3 +79,19 @@ func.func @no_fold_call_in_else(%var: !fir.ref<i32>) -> !fir.ref<i32> {
   }
   return %if_result : !fir.ref<i32>
 }
+
+
+// CHECK-LABEL: func.func @no_fold_call_in_else_csed(
+// CHECK: fir.is_present
+// CHECK: fir.if
+func.func @no_fold_call_in_else_csed(%var: !fir.ref<i32>) -> !fir.ref<i32> {
+  %absent = fir.absent !fir.ref<i32>
+  %present = fir.is_present %var : (!fir.ref<i32>) -> i1
+  %if_result = fir.if %present -> (!fir.ref<i32>) {
+    fir.result %var : !fir.ref<i32>
+  } else {
+    fir.call @side_effect() : () -> ()
+    fir.result %absent : !fir.ref<i32>
+  }
+  return %if_result : !fir.ref<i32>
+}

``````````

</details>


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


More information about the flang-commits mailing list