[Mlir-commits] [flang] [mlir] [Flang][OpenMP] Don't generate code for unreachable target regions. (PR #178937)

Pranav Bhandarkar llvmlistbot at llvm.org
Fri Jan 30 21:11:06 PST 2026


================
@@ -0,0 +1,166 @@
+//===- MarkUnreachableTargets.cpp ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass marks OpenMP target operations that are in unreachable code
+// with an attribute. This allows device compilation to skip generating code
+// for such ops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/OpenMP/Passes.h"
+
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace flangomp {
+#define GEN_PASS_DEF_MARKUNREACHABLETARGETSPASS
+#include "flang/Optimizer/OpenMP/Passes.h.inc"
+} // namespace flangomp
+
+using namespace mlir;
+
+namespace {
+
+/// Check if an operation is nested inside a fir.if with a constant false
+/// condition.
+static bool isInUnreachableIfBlock(Operation *op) {
+  Operation *current = op;
+
+  // Walk up through parent operations
+  while (current) {
+    Operation *parentOp = current->getParentOp();
+    if (!parentOp)
+      break;
+
+    // Check for fir.if with constant false condition
+    if (auto firIf = dyn_cast<fir::IfOp>(parentOp)) {
+      if (auto constOp =
+              firIf.getCondition().getDefiningOp<arith::ConstantOp>()) {
+        if (auto intAttr = dyn_cast<IntegerAttr>(constOp.getValue())) {
+          // If condition is false (0) and op is in the "then" region
+          if (intAttr.getInt() == 0 &&
+              current->getParentRegion() == &firIf.getThenRegion())
+            return true;
+          // If condition is true (non-zero) and op is in the "else" region
+          if (intAttr.getInt() != 0 && !firIf.getElseRegion().empty() &&
+              current->getParentRegion() == &firIf.getElseRegion())
+            return true;
+        }
+      }
+    }
+
+    current = parentOp;
+  }
+
+  return false;
+}
+
+/// Check if a block is unreachable due to constant condition branches.
+/// A block is unreachable only if ALL predecessors lead to it through
+/// unreachable paths (i.e., constant false conditions).
+/// This handles patterns like:
+///   %false = arith.constant false
+///   cf.cond_br %false, ^bb1, ^bb2
+/// where ^bb1 is unreachable.
+static bool isBlockUnreachable(Block *block) {
----------------
bhandarkar-pranav wrote:

`const Block *`

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


More information about the Mlir-commits mailing list