[clang] [Clang] Add GCC's __builtin_stack_address() to Clang (#82632). (PR #121332)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 30 02:51:45 PST 2024
https://github.com/aalhwc created https://github.com/llvm/llvm-project/pull/121332
This new builtin returns the value of the stack pointer register, mirroring GCC's __builtin_stack_address(). This implementation initially supports only the x86 and x86_64 architectures. Support for other architectures can be added in future patches.
>From 7c4f49391753b22dd2e2ce96e9ad6a6cd6c9ae40 Mon Sep 17 00:00:00 2001
From: aalhwc <aalhwc at gmail.com>
Date: Mon, 30 Dec 2024 05:03:59 -0500
Subject: [PATCH] [Clang] Add GCC's __builtin_stack_address() to Clang
(#82632).
This new builtin returns the value of the stack pointer register,
mirroring GCC's __builtin_stack_address(). This implementation initially
supports only the x86 and x86_64 architectures. Support for other
architectures can be added in future patches.
---
clang/include/clang/Basic/Builtins.td | 6 ++++++
clang/lib/CodeGen/CGBuiltin.cpp | 24 +++++++++++++++++++++++
clang/test/CodeGen/builtin-stackaddress.c | 13 ++++++++++++
3 files changed, 43 insertions(+)
create mode 100644 clang/test/CodeGen/builtin-stackaddress.c
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index b5b47ae2746011..69aed2e6b2f0ca 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -899,6 +899,12 @@ def FrameAddress : Builtin {
let Prototype = "void*(_Constant unsigned int)";
}
+def StackAddress : Builtin {
+ let Spellings = ["__builtin_stack_address"];
+ let Attributes = [NoThrow];
+ let Prototype = "void*()";
+}
+
def ClearCache : Builtin {
let Spellings = ["__builtin___clear_cache"];
let Attributes = [NoThrow];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4d4b7428abd505..d691958852699e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4782,6 +4782,30 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy);
return RValue::get(Builder.CreateCall(F, Depth));
}
+ case Builtin::BI__builtin_stack_address: {
+ IntegerType *SPRegType;
+ StringRef SPRegName;
+ switch (getTarget().getTriple().getArch()) {
+ case Triple::x86:
+ SPRegType = Int32Ty;
+ SPRegName = "esp";
+ break;
+ case Triple::x86_64:
+ SPRegType = Int64Ty;
+ SPRegName = "rsp";
+ break;
+ default:
+ llvm_unreachable("Intrinsic __builtin_stack_address is not supported for "
+ "the target architecture");
+ }
+ Function *F = CGM.getIntrinsic(Intrinsic::read_register, {SPRegType});
+ Value *SPRegValue = MetadataAsValue::get(
+ getLLVMContext(),
+ MDNode::get(getLLVMContext(),
+ {MDString::get(getLLVMContext(), SPRegName)}));
+ Value *Call = Builder.CreateCall(F, SPRegValue);
+ return RValue::get(Builder.CreateIntToPtr(Call, Int8PtrTy));
+ }
case Builtin::BI__builtin_extract_return_addr: {
Value *Address = EmitScalarExpr(E->getArg(0));
Value *Result = getTargetHooks().decodeReturnAddress(*this, Address);
diff --git a/clang/test/CodeGen/builtin-stackaddress.c b/clang/test/CodeGen/builtin-stackaddress.c
new file mode 100644
index 00000000000000..5b1ddad45f21a1
--- /dev/null
+++ b/clang/test/CodeGen/builtin-stackaddress.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=X86 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck -check-prefix=X86_64 %s
+
+void* a() {
+ // X86_64: [[INT_SP:%.*]] = call i64 @llvm.read_register.i64(metadata [[SPREG:![0-9]+]])
+ // X86_64: inttoptr i64 [[INT_SP]]
+ // X86_64: [[SPREG]] = !{!"rsp"}
+ //
+ // X86: [[INT_SP:%.*]] = call i32 @llvm.read_register.i32(metadata [[SPREG:![0-9]+]])
+ // X86: inttoptr i32 [[INT_SP]]
+ // X86: [[SPREG]] = !{!"esp"}
+ return __builtin_stack_address();
+}
More information about the cfe-commits
mailing list