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] [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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
