[clang] [CIR] Implement lowering of atomic-func ptrs (PR #199045)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu May 21 07:48:11 PDT 2026


https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/199045

This actually is a near-zero effort implementation, since other than an assertion, we had everything correct. It isn't clear where that assertion came from (other than an over abundance of caution?).  It doesn't exist in classic codegen, which always counts on the fallthrough.

However, we ARE missing some ptr-auth work in that area, so a MissingFeatures is added to be a placeholder for it.

>From feb2f35850aa129813416371668d89c0bd76bbd7 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Thu, 21 May 2026 07:46:23 -0700
Subject: [PATCH] [CIR] Implement lowering of atomic-func ptrs

This actually is a near-zero effort implementation, since other than an
assertion, we had everything correct. It isn't clear where that
assertion came from (other than an over abundance of caution?).  It
doesn't exist in classic codegen, which always counts on the
fallthrough.

However, we ARE missing some ptr-auth work in that area, so a
MissingFeatures is added to be a placeholder for it.
---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 11 ++++++-----
 clang/test/CIR/CodeGen/call.c        | 20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 7c22a0eead2fa..35700611733ae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2353,11 +2353,12 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
         implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
       return emitCallee(implicitCast->getSubExpr());
     }
-    // When performing an indirect call through a function pointer lvalue, the
-    // function pointer lvalue is implicitly converted to an rvalue through an
-    // lvalue-to-rvalue conversion.
-    assert(implicitCast->getCastKind() == CK_LValueToRValue &&
-           "unexpected implicit cast on function pointers");
+    // Classic codegen has some handling here for ptr-auth (as a part of the
+    // large ptr-auth-qualifier PR (#100830)). In the meantime, other cast kinds
+    // can fall-through and be handled by the indirect call work below,
+    // including L-to-R value conversions and atomic conversions.
+    assert(!MissingFeatures::pointerAuthentication());
+
   } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
     // Resolve direct calls.
     if (const auto *funcDecl = dyn_cast<FunctionDecl>(declRef->getDecl()))
diff --git a/clang/test/CIR/CodeGen/call.c b/clang/test/CIR/CodeGen/call.c
index 86aebd060c3ab..70839ff8efa52 100644
--- a/clang/test/CIR/CodeGen/call.c
+++ b/clang/test/CIR/CodeGen/call.c
@@ -130,6 +130,26 @@ int f12(void) {
 // OGCG:         %{{.+}} = call i32 @f10(i32 noundef 1) #[[ATTR0:.+]]
 // OGCG-NEXT:    %{{.+}} = call i32 @f11(i32 noundef 2) #[[ATTR1:.+]]
 
+void f13(void) {
+  _Atomic(void(*)(void)) fp;
+  fp();
+}
+// CIR-LABEL: cir.func{{.*}} @f13()
+// CIR: %[[FP_ALLOCA:.*]] = cir.alloca !cir.ptr<!cir.func<()>>, !cir.ptr<!cir.ptr<!cir.func<()>>>, ["fp"]
+// CIR: %[[LOAD_FP:.*]] = cir.load align(8) atomic(seq_cst) %[[FP_ALLOCA]] : !cir.ptr<!cir.ptr<!cir.func<()>>>, !cir.ptr<!cir.func<()>>
+// CIR: cir.call %[[LOAD_FP]]() : (!cir.ptr<!cir.func<()>>) -> ()
+
+// LLVM-LABEL: define{{.*}} void @f13()
+// LLVM: %[[FP_ALLOCA:.*]] = alloca ptr
+// LLVM: %[[LOAD_FP:.*]] = load atomic ptr, ptr %[[FP_ALLOCA]] seq_cst, align 8
+// LLVM: call void %[[LOAD_FP]]()
+
+// OGCG-LABEL: define{{.*}} void @f13() 
+// OGCG: %[[FP_ALLOCA:.*]] = alloca ptr
+// OGCG: %[[LOAD_FP:.*]] = load atomic ptr, ptr %[[FP_ALLOCA]] seq_cst, align 8
+// OGCG: call void %[[LOAD_FP]]()
+
+
 // LLVM: attributes #[[ATTR0]] = { nounwind willreturn memory(read) }
 // LLVM: attributes #[[ATTR1]] = { nounwind willreturn memory(none) }
 



More information about the cfe-commits mailing list