https://github.com/Luhaocong updated 
https://github.com/llvm/llvm-project/pull/171974

>From 9772a1690ff6d40db9f1263b812f644b095d7e66 Mon Sep 17 00:00:00 2001
From: Haocong Lu <[email protected]>
Date: Fri, 12 Dec 2025 13:55:59 +0800
Subject: [PATCH 1/2] [CIR][X86] Implement lowering for
 `_AddressOfReturnAddress` builtin

- Add new `CIR_AddrOfReturnAddrOp` and support lowering it to LLVMIR
- Add CIR CodeGen for `_AddressOfReturnAddress` X86 builtin
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 23 +++++++++++
 clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp    |  7 +++-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  9 +++++
 clang/test/CIR/CodeGen/ms-intrinsics.c        | 40 +++++++++++++++++++
 4 files changed, 78 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CIR/CodeGen/ms-intrinsics.c

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 868b813458aae..256e60c41981e 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3339,6 +3339,29 @@ def CIR_FrameAddrOp : 
CIR_FuncAddrBuiltinOp<"frame_address"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// AddrOfReturnAddrOp
+//===----------------------------------------------------------------------===//
+
+def CIR_AddrOfReturnAddrOp : CIR_Op<"address_of_return_address"> {
+  let summary = "The place stores the return address of the current function";
+
+  let description = [{
+    Represents a call to builtin function `_AddressOfReturnAddress` in CIR.
+    This builtin function returns a pointer to the place in the stack frame
+    where the return address of the current function is stored.
+
+    Examples:
+
+    ```mlir
+    %addr = address_of_return_address() : !cir.ptr<!cir.int<u, 8>>
+    ```
+  }];
+
+  let results = (outs CIR_PointerType:$result);
+  let assemblyFormat = "attr-dict `:` qualified(type($result))";
+}
+
 
//===----------------------------------------------------------------------===//
 // StackSaveOp & StackRestoreOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index f9e1f75a51143..e876d59bf1677 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1706,7 +1706,12 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
                                     cir::SyncScopeKind::SingleThread));
     return mlir::Value{};
   }
-  case X86::BI_AddressOfReturnAddress:
+  case X86::BI_AddressOfReturnAddress: {
+    mlir::Location loc = getLoc(expr->getExprLoc());
+    mlir::Value addr =
+        cir::AddrOfReturnAddrOp::create(builder, loc, allocaInt8PtrTy);
+    return builder.createCast(loc, cir::CastKind::bitcast, addr, voidPtrTy);
+  }
   case X86::BI__stosb:
   case X86::BI__ud2:
   case X86::BI__int2c:
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 7d854997848aa..73f9e5390b886 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1653,6 +1653,15 @@ mlir::LogicalResult 
CIRToLLVMFrameAddrOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMAddrOfReturnAddrOpLowering::matchAndRewrite(
+    cir::AddrOfReturnAddrOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  const mlir::Type llvmPtrTy = getTypeConverter()->convertType(op.getType());
+  replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.addressofreturnaddress",
+                                   llvmPtrTy, adaptor.getOperands());
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite(
     cir::LoadOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/ms-intrinsics.c 
b/clang/test/CIR/CodeGen/ms-intrinsics.c
new file mode 100644
index 0000000000000..fa6872c207c92
--- /dev/null
+++ b/clang/test/CIR/CodeGen/ms-intrinsics.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -x c++ -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-cir -o %t.cir %s
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+// RUN: %clang_cc1 -x c++ -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -Wno-implicit-function-declaration 
-fclangir -emit-llvm -o %t.ll %s
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 -x c -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -emit-llvm -Wall -Werror %s -o - \
+// RUN:   | FileCheck %s -check-prefix=OGCG
+// RUN: %clang_cc1 -x c++ -ffreestanding -fms-extensions -fms-compatibility 
-fms-compatibility-version=17.00 \
+// RUN:   -triple x86_64-unknown-linux -emit-llvm -Wall -Werror %s -o - \
+// RUN:   | FileCheck %s -check-prefix=OGCG
+
+// This test mimics clang/test/CodeGen/ms-intrinsics.c, which eventually
+// CIR shall be able to support fully.
+
+void *_AddressOfReturnAddress(void);
+
+#if defined(__i386__) || defined(__x86_64__) || defined (__aarch64__)
+void *test_AddressOfReturnAddress(void) {
+  // CIR-LABEL: test_AddressOfReturnAddress
+  // CIR: %[[ADDR:.*]] = cir.address_of_return_address : !cir.ptr<!u8i>
+  // CIR: %{{.*}} = cir.cast bitcast %[[ADDR]] : !cir.ptr<!u8i> -> 
!cir.ptr<!void>
+
+  // LLVM-LABEL: test_AddressOfReturnAddress
+  // LLVM: call ptr @llvm.addressofreturnaddress.p0()
+
+  // OGCG-LABEL: test_AddressOfReturnAddress
+  // OGCG: call ptr @llvm.addressofreturnaddress.p0()
+  return _AddressOfReturnAddress();
+}
+#endif

>From 795ab27307ee53278f6a22638ea15a21e1b30a43 Mon Sep 17 00:00:00 2001
From: Haocong Lu <[email protected]>
Date: Thu, 18 Dec 2025 16:58:32 +0800
Subject: [PATCH 2/2] [CIR][X86] Fix error return type of FrameAddrOp

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 26 ++++++++---------
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp       | 28 +++++++++++--------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  4 +--
 clang/test/CIR/CodeGen/ms-intrinsics.c        | 16 ++++++++++-
 clang/test/CIR/CodeGenBuiltins/builtins.cpp   |  3 +-
 5 files changed, 49 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 256e60c41981e..bda773b41ac5c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3281,15 +3281,7 @@ def CIR_CopyOp : CIR_Op<"copy",[
 // ReturnAddrOp and FrameAddrOp
 
//===----------------------------------------------------------------------===//
 
-class CIR_FuncAddrBuiltinOp<string mnemonic> : CIR_Op<mnemonic, []> {
-  let arguments = (ins CIR_UInt32:$level);
-  let results = (outs CIR_VoidPtrType:$result);
-  let assemblyFormat = [{
-    `(` $level `)` attr-dict
-  }];
-}
-
-def CIR_ReturnAddrOp : CIR_FuncAddrBuiltinOp<"return_address"> {
+def CIR_ReturnAddrOp : CIR_Op<"return_address"> {
   let summary =
       "The return address of the current function, or of one of its callers";
 
@@ -3306,12 +3298,16 @@ def CIR_ReturnAddrOp : 
CIR_FuncAddrBuiltinOp<"return_address"> {
     Examples:
 
     ```mlir
-    %p = return_address(%level) -> !cir.ptr<!void>
+    %p = return_address(%level) : !cir.ptr<!void>
     ```
   }];
+
+  let arguments = (ins CIR_UInt32:$level);
+  let results = (outs CIR_VoidPtrType:$result);
+  let assemblyFormat = "`(` $level `)` attr-dict";
 }
 
-def CIR_FrameAddrOp : CIR_FuncAddrBuiltinOp<"frame_address"> {
+def CIR_FrameAddrOp : CIR_Op<"frame_address"> {
   let summary =
       "The frame address of the current function, or of one of its callers";
 
@@ -3334,9 +3330,13 @@ def CIR_FrameAddrOp : 
CIR_FuncAddrBuiltinOp<"frame_address"> {
     Examples:
 
     ```mlir
-    %p = frame_address(%level) -> !cir.ptr<!void>
+    %p = frame_address(%level) : !cir.ptr<!u8i>
     ```
   }];
+
+  let arguments = (ins CIR_UInt32:$level);
+  let results = (outs CIR_PointerType:$result);
+  let assemblyFormat = "`(` $level `)` attr-dict `:` qualified(type($result))";
 }
 
 
//===----------------------------------------------------------------------===//
@@ -3354,7 +3354,7 @@ def CIR_AddrOfReturnAddrOp : 
CIR_Op<"address_of_return_address"> {
     Examples:
 
     ```mlir
-    %addr = address_of_return_address() : !cir.ptr<!cir.int<u, 8>>
+    %addr = address_of_return_address() : !cir.ptr<!u8i>
     ```
   }];
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index b4f02c97f539a..b737c9e618d62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -869,20 +869,26 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
     break; // Handled as library calls below.
   case Builtin::BI__builtin_dwarf_cfa:
     return errorBuiltinNYI(*this, e, builtinID);
-  case Builtin::BI__builtin_return_address:
-  case Builtin::BI_ReturnAddress:
-  case Builtin::BI__builtin_frame_address: {
-    mlir::Location loc = getLoc(e->getExprLoc());
+  case Builtin::BI__builtin_return_address: {
     llvm::APSInt level = e->getArg(0)->EvaluateKnownConstInt(getContext());
-    if (builtinID == Builtin::BI__builtin_return_address) {
-      return RValue::get(cir::ReturnAddrOp::create(
-          builder, loc,
-          builder.getConstAPInt(loc, builder.getUInt32Ty(), level)));
-    }
-    return RValue::get(cir::FrameAddrOp::create(
-        builder, loc,
+    return RValue::get(cir::ReturnAddrOp::create(
+        builder, getLoc(e->getExprLoc()),
         builder.getConstAPInt(loc, builder.getUInt32Ty(), level)));
   }
+  case Builtin::BI_ReturnAddress: {
+    return RValue::get(cir::ReturnAddrOp::create(
+        builder, getLoc(e->getExprLoc()),
+        builder.getConstInt(loc, builder.getUInt32Ty(), 0)));
+  }
+  case Builtin::BI__builtin_frame_address: {
+    llvm::APSInt level = e->getArg(0)->EvaluateKnownConstInt(getContext());
+    mlir::Location loc = getLoc(e->getExprLoc());
+    mlir::Value addr = cir::FrameAddrOp::create(
+        builder, loc, allocaInt8PtrTy,
+        builder.getConstAPInt(loc, builder.getUInt32Ty(), level));
+    return RValue::get(
+        builder.createCast(loc, cir::CastKind::bitcast, addr, voidPtrTy));
+  }
   case Builtin::BI__builtin_extract_return_addr:
   case Builtin::BI__builtin_frob_return_addr:
   case Builtin::BI__builtin_dwarf_sp_column:
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 73f9e5390b886..22c6e87f53311 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1638,7 +1638,7 @@ mlir::LogicalResult 
CIRToLLVMCallOpLowering::matchAndRewrite(
 mlir::LogicalResult CIRToLLVMReturnAddrOpLowering::matchAndRewrite(
     cir::ReturnAddrOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
+  const mlir::Type llvmPtrTy = getTypeConverter()->convertType(op.getType());
   replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.returnaddress",
                                    llvmPtrTy, adaptor.getOperands());
   return mlir::success();
@@ -1647,7 +1647,7 @@ mlir::LogicalResult 
CIRToLLVMReturnAddrOpLowering::matchAndRewrite(
 mlir::LogicalResult CIRToLLVMFrameAddrOpLowering::matchAndRewrite(
     cir::FrameAddrOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
+  const mlir::Type llvmPtrTy = getTypeConverter()->convertType(op.getType());
   replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.frameaddress", 
llvmPtrTy,
                                    adaptor.getOperands());
   return mlir::success();
diff --git a/clang/test/CIR/CodeGen/ms-intrinsics.c 
b/clang/test/CIR/CodeGen/ms-intrinsics.c
index fa6872c207c92..61c867a946743 100644
--- a/clang/test/CIR/CodeGen/ms-intrinsics.c
+++ b/clang/test/CIR/CodeGen/ms-intrinsics.c
@@ -23,9 +23,24 @@
 // CIR shall be able to support fully.
 
 void *_AddressOfReturnAddress(void);
+void *_ReturnAddress(void);
+
+void *test_ReturnAddress(void) {
+  return _ReturnAddress();
+  // CIR-LABEL: test_ReturnAddress
+  // CIR: [[ARG:%.*]] = cir.const #cir.int<0> : !u32i
+  // CIR: {{%.*}} = cir.return_address([[ARG]])
+
+  // LLVM-LABEL: test_ReturnAddress
+  // LLVM: {{%.*}} = call ptr @llvm.returnaddress(i32 0)
+
+  // OGCG-LABEL: test_ReturnAddress
+  // OGCG: {{%.*}} = call ptr @llvm.returnaddress(i32 0)
+}
 
 #if defined(__i386__) || defined(__x86_64__) || defined (__aarch64__)
 void *test_AddressOfReturnAddress(void) {
+  return _AddressOfReturnAddress();
   // CIR-LABEL: test_AddressOfReturnAddress
   // CIR: %[[ADDR:.*]] = cir.address_of_return_address : !cir.ptr<!u8i>
   // CIR: %{{.*}} = cir.cast bitcast %[[ADDR]] : !cir.ptr<!u8i> -> 
!cir.ptr<!void>
@@ -35,6 +50,5 @@ void *test_AddressOfReturnAddress(void) {
 
   // OGCG-LABEL: test_AddressOfReturnAddress
   // OGCG: call ptr @llvm.addressofreturnaddress.p0()
-  return _AddressOfReturnAddress();
 }
 #endif
diff --git a/clang/test/CIR/CodeGenBuiltins/builtins.cpp 
b/clang/test/CIR/CodeGenBuiltins/builtins.cpp
index 0e434809fe6be..1c28c94a20413 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtins.cpp
+++ b/clang/test/CIR/CodeGenBuiltins/builtins.cpp
@@ -32,7 +32,8 @@ extern "C" void *test_frame_address(void) {
 
   // CIR-LABEL: test_frame_address
   // CIR: [[ARG:%.*]] = cir.const #cir.int<1> : !u32i
-  // CIR: {{%.*}} = cir.frame_address([[ARG]])
+  // CIR: %[[ADDR:.*]] = cir.frame_address([[ARG]]) : !cir.ptr<!u8i>
+  // CIR: {{%.*}} = cir.cast bitcast %[[ADDR]] : !cir.ptr<!u8i> -> 
!cir.ptr<!void>
 
   // LLVM-LABEL: @test_frame_address
   // LLVM: {{%.*}} = call ptr @llvm.frameaddress.p0(i32 1)

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

Reply via email to