[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