[llvm] [SPIRV] Dummy implementation of the `returnaddress` and `frameaddress` intrinsics (PR #195976)

Victor Mustya via llvm-commits llvm-commits at lists.llvm.org
Tue May 5 18:58:27 PDT 2026


https://github.com/vmustya created https://github.com/llvm/llvm-project/pull/195976

The SPIR-V specification doesn't define any operations for the
return and frame address. The valid implementation in this case is to
produce a null pointer.

>From 8c93f02e6eb150faa00c9f927eb1d346c6d41bc5 Mon Sep 17 00:00:00 2001
From: Victor Mustya <victor.mustya at intel.com>
Date: Tue, 5 May 2026 18:54:48 -0700
Subject: [PATCH] [SPIRV] Dummy implementation of the `returnaddress` and
 `frameaddress` intrinsics

The SPIR-V specification doesn't define any operations for the
return and frame address. The valid implementation in this case is to
produce a null pointer.
---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp |  9 +++++++
 llvm/test/CodeGen/SPIRV/returnaddress.ll      | 26 +++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 llvm/test/CodeGen/SPIRV/returnaddress.ll

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index aee3a29c6e42b..43e6b80422066 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -5136,6 +5136,15 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
       return selectMaskedScatter(I);
     return diagnoseUnsupported(
         I, "llvm.masked.scatter requires SPV_INTEL_masked_gather_scatter");
+  case Intrinsic::returnaddress:
+  case Intrinsic::frameaddress: {
+    // SPIR-V does not have a stack or return address. Lower to null.
+    auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
+                   .addDef(ResVReg)
+                   .addUse(GR.getSPIRVTypeID(ResType));
+    MIB.constrainAllUses(TII, TRI, RBI);
+    return true;
+  }
   default: {
     std::string DiagMsg;
     raw_string_ostream OS(DiagMsg);
diff --git a/llvm/test/CodeGen/SPIRV/returnaddress.ll b/llvm/test/CodeGen/SPIRV/returnaddress.ll
new file mode 100644
index 0000000000000..138212ad60b2c
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/returnaddress.ll
@@ -0,0 +1,26 @@
+; RUN: llc -mtriple=spirv64-unknown-unknown -O0 < %s | FileCheck %s
+; RUN: llc -mtriple=spirv32-unknown-unknown -O0 < %s | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown < %s -o - -filetype=obj | spirv-val %}
+
+; SPIR-V does not have a stack or return address concept.
+; llvm.returnaddress and llvm.frameaddress are lowered to null (OpConstantNull).
+
+declare ptr @llvm.returnaddress(i32)
+declare ptr @llvm.frameaddress(i32)
+
+; CHECK-DAG: %[[#PTR_TY:]] = OpTypePointer
+; CHECK-DAG: %[[#NULL:]] = OpConstantNull %[[#PTR_TY]]
+
+; CHECK: %[[#]] = OpFunction
+; CHECK: OpReturnValue %[[#NULL]]
+define ptr @test_returnaddress() {
+  %ret = call ptr @llvm.returnaddress(i32 0)
+  ret ptr %ret
+}
+
+; CHECK: %[[#]] = OpFunction
+; CHECK: OpReturnValue %[[#NULL]]
+define ptr @test_frameaddress() {
+  %ret = call ptr @llvm.frameaddress(i32 0)
+  ret ptr %ret
+}



More information about the llvm-commits mailing list