Author: adams381
Date: 2026-06-25T12:50:43-05:00
New Revision: bc3eb524b2d1dcc3e48161cd2eb80a2364fdc097

URL: 
https://github.com/llvm/llvm-project/commit/bc3eb524b2d1dcc3e48161cd2eb80a2364fdc097
DIFF: 
https://github.com/llvm/llvm-project/commit/bc3eb524b2d1dcc3e48161cd2eb80a2364fdc097.diff

LOG: [CIR] Lower __atomic_is_lock_free / __c11_atomic_is_lock_free (#205862)

`__atomic_is_lock_free` and `__c11_atomic_is_lock_free` were routed to
`errorNYI` in CIRGen, so `std::atomic<T>::is_lock_free()` failed to
compile under `-fclangir` whenever the query wasn't constant-folded --
which is what the libcxx atomics lock-free tests hit.

This mirrors classic CodeGen (`CGBuiltin.cpp`): emit a call to the
runtime entry `bool __atomic_is_lock_free(size_t size, void *ptr)`.
`__atomic_is_lock_free` forwards its pointer argument;
`__c11_atomic_is_lock_free` passes a null pointer, since an `_Atomic`
object is always suitably aligned. `__atomic_test_and_set` /
`__atomic_clear` stay NYI.

The lowered call omits the `noundef`/`zeroext` argument and return
attributes classic emits, and the declaration picks up `dso_local`.
That's the existing CIR libcall attribute gap, so the test uses split
`LLVMCIR`/`OGCG` prefixes where the two diverge and a shared skeleton
where they match.

Added: 
    clang/test/CIR/CodeGen/builtin-atomic-is-lock-free.c

Modified: 
    clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 50529a61068d5..ba2dd2dccc63b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -261,6 +261,30 @@ static void emitAtomicFenceOp(CIRGenFunction &cgf, const 
CallExpr *expr,
                                  emitAtomicOpCallBackFn);
 }
 
+// Emit a runtime call to bool __atomic_is_lock_free(size_t size, void *ptr).
+// For the __c11 builtin the pointer is null, since an _Atomic object is always
+// suitably aligned.
+static RValue emitAtomicIsLockFree(CIRGenFunction &cgf, const CallExpr *e,
+                                   unsigned builtinID) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  mlir::Location loc = cgf.getLoc(e->getExprLoc());
+
+  mlir::Type sizeTy = cgf.convertType(cgf.getContext().getSizeType());
+  mlir::Value size = cgf.emitScalarExpr(e->getArg(0));
+  mlir::Value ptr;
+  if (builtinID == Builtin::BI__atomic_is_lock_free)
+    ptr = builder.createBitcast(cgf.emitScalarExpr(e->getArg(1)),
+                                builder.getVoidPtrTy());
+  else
+    ptr = builder.getNullPtr(builder.getVoidPtrTy(), loc);
+
+  cir::FuncOp func = cgf.cgm.createRuntimeFunction(
+      cir::FuncType::get({sizeTy, builder.getVoidPtrTy()}, 
builder.getBoolTy()),
+      "__atomic_is_lock_free");
+  return RValue::get(
+      builder.createCallOp(loc, func, mlir::ValueRange{size, 
ptr}).getResult());
+}
+
 namespace {
 struct WidthAndSignedness {
   unsigned width;
@@ -2182,6 +2206,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   }
   case Builtin::BI__c11_atomic_is_lock_free:
   case Builtin::BI__atomic_is_lock_free:
+    return emitAtomicIsLockFree(*this, e, builtinID);
   case Builtin::BI__atomic_test_and_set:
   case Builtin::BI__atomic_clear:
     return errorBuiltinNYI(*this, e, builtinID);

diff  --git a/clang/test/CIR/CodeGen/builtin-atomic-is-lock-free.c 
b/clang/test/CIR/CodeGen/builtin-atomic-is-lock-free.c
new file mode 100644
index 0000000000000..2792f595275a6
--- /dev/null
+++ b/clang/test/CIR/CodeGen/builtin-atomic-is-lock-free.c
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
+// RUN: FileCheck --check-prefixes=LLVM,LLVMCIR --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefixes=LLVM,OGCG --input-file=%t.ll %s
+
+typedef struct { char buf[24]; } Big;
+
+int test_atomic(Big *p) { return __atomic_is_lock_free(sizeof(Big), p); }
+
+int test_c11(void) { return __c11_atomic_is_lock_free(sizeof(Big)); }
+
+int test_atomic_var(unsigned long n, void *p) {
+  return __atomic_is_lock_free(n, p);
+}
+
+// CIR-DAG: cir.func private dso_local @__atomic_is_lock_free(!u64i, 
!cir.ptr<!void>) -> !cir.bool
+
+// CIR-LABEL: cir.func{{.*}} @test_atomic(
+// CIR:   %[[SZ:.*]] = cir.const #cir.int<24> : !u64i
+// CIR:   %[[P:.*]] = cir.load{{.*}} : !cir.ptr<!cir.ptr<!rec_Big>>, 
!cir.ptr<!rec_Big>
+// CIR:   %[[VP:.*]] = cir.cast bitcast %[[P]] : !cir.ptr<!rec_Big> -> 
!cir.ptr<!void>
+// CIR:   cir.call @__atomic_is_lock_free(%[[SZ]], %[[VP]]) : (!u64i, 
!cir.ptr<!void>) -> !cir.bool
+
+// CIR-LABEL: cir.func{{.*}} @test_c11(
+// CIR:   %[[SZ2:.*]] = cir.const #cir.int<24> : !u64i
+// CIR:   %[[NULL:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void>
+// CIR:   cir.call @__atomic_is_lock_free(%[[SZ2]], %[[NULL]]) : (!u64i, 
!cir.ptr<!void>) -> !cir.bool
+
+// CIR-LABEL: cir.func{{.*}} @test_atomic_var(
+// CIR:   cir.call @__atomic_is_lock_free(%{{.*}}, %{{.*}}) : (!u64i, 
!cir.ptr<!void>) -> !cir.bool
+
+// LLVM-LABEL: define dso_local i32 @test_atomic(
+// LLVMCIR:      call i1 @__atomic_is_lock_free(i64 24, ptr %{{.*}})
+// OGCG:         call zeroext i1 @__atomic_is_lock_free(i64 noundef 24, ptr 
noundef %{{.*}})
+// LLVM:         zext i1 %{{.*}} to i32
+
+// LLVM-LABEL: define dso_local i32 @test_c11(
+// LLVMCIR:      call i1 @__atomic_is_lock_free(i64 24, ptr null)
+// OGCG:         call zeroext i1 @__atomic_is_lock_free(i64 noundef 24, ptr 
noundef null)
+// LLVM:         zext i1 %{{.*}} to i32
+
+// LLVM-LABEL: define dso_local i32 @test_atomic_var(
+// LLVMCIR:      call i1 @__atomic_is_lock_free(i64 %{{.*}}, ptr %{{.*}})
+// OGCG:         call zeroext i1 @__atomic_is_lock_free(i64 noundef %{{.*}}, 
ptr noundef %{{.*}})


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

Reply via email to