From c5b0391f0103eb3da7b2d48144ac01c3cf0de19c Mon Sep 17 00:00:00 2001 From: ghehg Date: Fri, 1 Nov 2024 12:04:33 -0700 Subject: [PATCH] Implement __builtin_return_address --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 15 +++++++++++++-- clang/test/CIR/CodeGen/builtins-memory.c | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 clang/test/CIR/CodeGen/builtins-memory.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 1469808bf9cd..b797626d3df6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1462,8 +1462,19 @@ RValue CIRGenFunction::buildBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm_unreachable("BI__builtin_wmemcmp NYI"); case Builtin::BI__builtin_dwarf_cfa: llvm_unreachable("BI__builtin_dwarf_cfa NYI"); - case Builtin::BI__builtin_return_address: - llvm_unreachable("BI__builtin_return_address NYI"); + case Builtin::BI__builtin_return_address: { + mlir::Location loc = getLoc(E->getExprLoc()); + mlir::Attribute frameAttr = ConstantEmitter(*this).emitAbstract( + E->getArg(0), E->getArg(0)->getType()); + int64_t frame = mlir::cast(frameAttr).getSInt(); + // The intrinsic call is expecting unsigned int arg type, void* return type + return RValue::get(builder + .create( + loc, builder.getStringAttr("llvm.returnaddress"), + VoidPtrTy, + builder.getUInt32(frame, loc).getRes()) + .getResult()); + } case Builtin::BI_ReturnAddress: llvm_unreachable("BI_ReturnAddress NYI"); case Builtin::BI__builtin_frame_address: diff --git a/clang/test/CIR/CodeGen/builtins-memory.c b/clang/test/CIR/CodeGen/builtins-memory.c new file mode 100644 index 000000000000..1625c1a1d455 --- /dev/null +++ b/clang/test/CIR/CodeGen/builtins-memory.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck %s --check-prefix=CIR --input-file=%t.cir +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck %s --check-prefix=LLVM --input-file=%t.ll + +void *test_return_address(void) { + return __builtin_return_address(1); + + // CIR-LABEL: test_return_address + // [[ARG:%.*]] = cir.const #cir.int<1> : !u32i + // {{%.*}} = cir.llvm.intrinsic "llvm.returnaddress" [[ARG]] : (!u32i) -> !cir.ptr + + // LLVM-LABEL: @test_return_address + // LLVM: {{%.*}} = call ptr @llvm.returnaddress(i32 1) +}