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 <[email protected]>
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) }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to