llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (aalhwc) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/121332.diff 3 Files Affected: - (modified) clang/include/clang/Basic/Builtins.td (+6) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+24) - (added) clang/test/CodeGen/builtin-stackaddress.c (+13) ``````````diff 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(); +} `````````` </details> https://github.com/llvm/llvm-project/pull/121332 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits