[clang] [CIR][SSCP] Return null callable region for function declarations (PR #228641)

Konstantinos Parasyris via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 2 19:56:36 PDT 2026


https://github.com/koparasy created https://github.com/llvm/llvm-project/pull/228641

Declarations and aliases have empty bodies; returning them made SCCP treat external calls as never returning  and fold their results to constants.

>From 20e89eba834040e2884d08e20776c84c8106e92c Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <konstantinos.parasyris at intel.com>
Date: Fri, 2 Oct 2026 19:53:48 -0700
Subject: [PATCH] [CIR] Return null callable region for function declarations

Declarations and aliases have empty bodies; returning them
made SCCP treat external calls as never returning  and fold
their results to constants.
---
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       |  7 +++--
 .../CIR/Transforms/sccp-external-call.cir     | 26 +++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CIR/Transforms/sccp-external-call.cir

diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 15cebd358040e..51b5bd1c58f4b 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -3092,8 +3092,11 @@ bool cir::FuncOp::isCxxTrivialMemberFunction() {
 }
 
 mlir::Region *cir::FuncOp::getCallableRegion() {
-  // TODO(CIR): This function will have special handling for aliases and a
-  // check for an external function, once those features have been upstreamed.
+  // Declarations and aliases have no body to analyze or inline. Returning the
+  // empty region would make interprocedural analyses (e.g. SCCP) treat calls
+  // to them as having no returns, leaving their results uninitialized.
+  if (getBody().empty())
+    return nullptr;
   return &getBody();
 }
 
diff --git a/clang/test/CIR/Transforms/sccp-external-call.cir b/clang/test/CIR/Transforms/sccp-external-call.cir
new file mode 100644
index 0000000000000..23253ef7a5a08
--- /dev/null
+++ b/clang/test/CIR/Transforms/sccp-external-call.cir
@@ -0,0 +1,26 @@
+// Regression test: SCCP must treat a call to a declaration as producing an
+// unknown value. cir::FuncOp::getCallableRegion() must return null for
+// declarations; otherwise the call result is never initialized and joining it
+// with a constant arm folds the whole ternary to that constant.
+// RUN: cir-opt %s --sccp | FileCheck %s
+
+module {
+  cir.func private @g() -> !cir.bool
+
+  cir.func @f(%arg0: !cir.bool) -> !cir.bool {
+    %0 = cir.ternary(%arg0, true {
+      %1 = cir.call @g() : () -> !cir.bool
+      cir.yield %1 : !cir.bool
+    }, false {
+      %1 = cir.const #cir.bool<false> : !cir.bool
+      cir.yield %1 : !cir.bool
+    }) : (!cir.bool) -> !cir.bool
+    cir.return %0 : !cir.bool
+  }
+}
+
+// CHECK: cir.func{{.*}} @f
+// CHECK:   %[[#ret:]] = cir.ternary
+// CHECK:     %[[#call:]] = cir.call @g()
+// CHECK:     cir.yield %[[#call]]
+// CHECK:   cir.return %[[#ret]] : !cir.bool



More information about the cfe-commits mailing list