[llvm] [SPIR-V] Fix validation errors for function pointers with CodeSectionINTEL storage class (PR #192973)

Arseniy Obolenskiy via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 10 09:49:49 PDT 2026


https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/192973

>From ec82d575bc233b3affb43494b25f4166c60fcd3c Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Mon, 20 Apr 2026 15:35:48 +0200
Subject: [PATCH 1/3] [SPIR-V] Fix validation errors for function pointers with
 CodeSectionINTEL storage class

CodeSectionINTEL pointers are not valid operands for PtrCastToGeneric/GenericCastToPtr (including inside OpSpecConstantOp)
---
 .../Target/SPIRV/SPIRVInstructionSelector.cpp | 35 +++++++++++++------
 llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp   | 29 +++++++++++----
 llvm/test/CodeGen/SPIRV/ctor-dtor-lowering.ll |  3 +-
 .../fp-simple-hierarchy.ll                    |  6 +---
 .../fp_no_return.ll                           |  5 +--
 .../fun-ptr-addrcast.ll                       |  9 ++---
 .../SPIRV/pointers/fun-ptr-to-itself.ll       |  7 ++--
 7 files changed, 55 insertions(+), 39 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index f1e0450bb20f9..5cf82e170ca97 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2581,13 +2581,15 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
     // are expressed by OpSpecConstantOp with an Opcode.
     // TODO: maybe insert a check whether the Kernel capability was declared and
     // so PtrCastToGeneric/GenericCastToPtr are available.
-    unsigned SpecOpcode =
-        DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC)
-            ? static_cast<uint32_t>(SPIRV::Opcode::PtrCastToGeneric)
-            : (SrcSC == SPIRV::StorageClass::Generic &&
-                       isGenericCastablePtr(DstSC)
-                   ? static_cast<uint32_t>(SPIRV::Opcode::GenericCastToPtr)
-                   : 0);
+    unsigned SpecOpcode = [&]() -> unsigned {
+      if (SrcSC == SPIRV::StorageClass::CodeSectionINTEL)
+        return static_cast<uint32_t>(SPIRV::Opcode::Bitcast);
+      if (DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC))
+        return static_cast<uint32_t>(SPIRV::Opcode::PtrCastToGeneric);
+      if (SrcSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(DstSC))
+        return static_cast<uint32_t>(SPIRV::Opcode::GenericCastToPtr);
+      return 0u;
+    }();
     // TODO: OpConstantComposite expects i8*, so we are forced to forget a
     // correct value of ResType and use general i8* instead. Maybe this should
     // be addressed in the emit-intrinsic step to infer a correct
@@ -2617,6 +2619,11 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
        SrcSC == SPIRV::StorageClass::Private))
     return BuildCOPY(ResVReg, SrcPtr, I);
 
+  // CodeSectionINTEL is not valid for PtrCastToGeneric/GenericCastToPtr
+  if (SrcSC == SPIRV::StorageClass::CodeSectionINTEL ||
+      DstSC == SPIRV::StorageClass::CodeSectionINTEL)
+    return selectUnOp(ResVReg, ResType, I, SPIRV::OpBitcast);
+
   // Casting from an eligible pointer to Generic.
   if (DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC))
     return selectUnOp(ResVReg, ResType, I, SPIRV::OpPtrCastToGeneric);
@@ -4388,16 +4395,22 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
       CompositeArgs.push_back(WrapReg);
       continue;
     }
-    // Create a new register for the wrapper
-    WrapReg = MRI->createVirtualRegister(GR.getRegClass(OpType));
+    SPIRVTypeInst WrapType = OpType;
+    if (OpType->getOpcode() == SPIRV::OpTypePointer &&
+        GR.getPointerStorageClass(OpType) ==
+            SPIRV::StorageClass::CodeSectionINTEL) {
+      WrapType = GR.changePointerStorageClass(OpType,
+                                              SPIRV::StorageClass::Function, I);
+    }
+    WrapReg = MRI->createVirtualRegister(GR.getRegClass(WrapType));
     CompositeArgs.push_back(WrapReg);
     // Decorate the wrapper register and generate a new instruction
     MRI->setType(WrapReg, LLT::pointer(0, 64));
-    GR.assignSPIRVTypeToVReg(OpType, WrapReg, *MF);
+    GR.assignSPIRVTypeToVReg(WrapType, WrapReg, *MF);
     auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
                        TII.get(SPIRV::OpSpecConstantOp))
                    .addDef(WrapReg)
-                   .addUse(GR.getSPIRVTypeID(OpType))
+                   .addUse(GR.getSPIRVTypeID(WrapType))
                    .addImm(static_cast<uint32_t>(SPIRV::Opcode::Bitcast))
                    .addUse(OpReg);
     GR.add(OpDefine, MIB);
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 9df5d18221a6d..226e752f4307e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -322,8 +322,15 @@ static SPIRVTypeInst propagateSPIRVType(MachineInstr *MI,
         MIB.setInsertPt(*MI->getParent(), MI);
         const GlobalValue *Global = MI->getOperand(1).getGlobal();
         Type *ElementTy = toTypedPointer(GR->getDeducedGlobalValueType(Global));
-        auto *Ty = TypedPointerType::get(ElementTy,
-                                         Global->getType()->getAddressSpace());
+        unsigned AddrSpace = Global->getType()->getAddressSpace();
+        // Function pointers use CodeSectionINTEL storage class in SPIR-V when
+        // the SPV_INTEL_function_pointers extension is enabled.
+        const SPIRVSubtarget &ST = MIB.getMF().getSubtarget<SPIRVSubtarget>();
+        if (isa<Function>(Global) &&
+            ST.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers))
+          AddrSpace =
+              storageClassToAddressSpace(SPIRV::StorageClass::CodeSectionINTEL);
+        auto *Ty = TypedPointerType::get(ElementTy, AddrSpace);
         SpvType = GR->getOrCreateSPIRVType(
             Ty, MIB, SPIRV::AccessQualifier::ReadWrite, true);
         break;
@@ -373,10 +380,20 @@ static SPIRVTypeInst propagateSPIRVType(MachineInstr *MI,
             RegType.isPointer() &&
             storageClassToAddressSpace(GR->getPointerStorageClass(SpvType)) !=
                 RegType.getAddressSpace()) {
-          const SPIRVSubtarget &ST =
-              MI->getParent()->getParent()->getSubtarget<SPIRVSubtarget>();
-          auto TSC = addressSpaceToStorageClass(RegType.getAddressSpace(), ST);
-          SpvType = GR->changePointerStorageClass(SpvType, TSC, *MI);
+          // Don't correct CodeSectionINTEL back to Function for function
+          // pointer G_GLOBAL_VALUE - the LLVM register has address space 0
+          // but the SPIR-V type was intentionally set to CodeSectionINTEL.
+          bool SkipCorrection =
+              MI->getOpcode() == TargetOpcode::G_GLOBAL_VALUE &&
+              GR->getPointerStorageClass(SpvType) ==
+                  SPIRV::StorageClass::CodeSectionINTEL;
+          if (!SkipCorrection) {
+            const SPIRVSubtarget &ST =
+                MI->getParent()->getParent()->getSubtarget<SPIRVSubtarget>();
+            auto TSC =
+                addressSpaceToStorageClass(RegType.getAddressSpace(), ST);
+            SpvType = GR->changePointerStorageClass(SpvType, TSC, *MI);
+          }
         }
         GR->assignSPIRVTypeToVReg(SpvType, Reg, MIB.getMF());
       }
diff --git a/llvm/test/CodeGen/SPIRV/ctor-dtor-lowering.ll b/llvm/test/CodeGen/SPIRV/ctor-dtor-lowering.ll
index abe325ee10849..cbb0932b599fb 100644
--- a/llvm/test/CodeGen/SPIRV/ctor-dtor-lowering.ll
+++ b/llvm/test/CodeGen/SPIRV/ctor-dtor-lowering.ll
@@ -2,8 +2,7 @@
 ; expected init kernel and symbols for offload compilation.
 
 ; RUN: llc -mtriple=spirv64-intel-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
-; Fix when spir-val supports the SPV_INTEL_function_pointers extension:
-; FIXME: %if spirv-tools %{ llc -O0 -mtriple=spirv64-intel-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-intel-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
 
 define void @my_constructor() addrspace(9) {
 entry:
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp-simple-hierarchy.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp-simple-hierarchy.ll
index 85eb16c07c1aa..87bb9f95709d9 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp-simple-hierarchy.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp-simple-hierarchy.ll
@@ -1,9 +1,5 @@
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
-; Fails with:
-;   Expected input to have storage class Workgroup, CrossWorkgroup or Function: SpecConstantOp
-;   %51 = OpSpecConstantOp %_ptr_Generic_uchar PtrCastToGeneric %50
-; Likely a limitation from spirv-val
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
 
 ; CHECK-DAG: OpName %[[I9:.*]] "_ZN13BaseIncrement9incrementEPi"
 ; CHECK-DAG: OpName %[[I29:.*]] "_ZN12IncrementBy29incrementEPi"
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_no_return.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_no_return.ll
index bca79e9a4270b..94ccdb063a820 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_no_return.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fp_no_return.ll
@@ -1,8 +1,5 @@
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
-; The backend seems to be generating invalid code. Fails with:
-;   OpConstantComposite Constituent <id> '18[%18]' type does not match the Result Type <id> '14[%struct_ident_t]'s member type
-; Issue https://github.com/llvm/llvm-project/issues/185412
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
 
 ; This test verifies that indirect calls with functions lacking return statements
 ; are don't cause an error.
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fun-ptr-addrcast.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fun-ptr-addrcast.ll
index bd67305968973..0ab7fe88716d0 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fun-ptr-addrcast.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_INTEL_function_pointers/fun-ptr-addrcast.ll
@@ -3,15 +3,12 @@
 ; work also for function pointers.
 
 ; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - --spirv-ext=+SPV_INTEL_function_pointers | FileCheck %s
-; Fails with:
-;   Invalid use of function type result id '7[%7]'.
-;   %_ptr_Generic_7 = OpTypePointer Generic %7
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj --spirv-ext=+SPV_INTEL_function_pointers | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj --spirv-ext=+SPV_INTEL_function_pointers | spirv-val %}
 
 ; CHECK-DAG: %[[#GENPTR:]] = OpTypePointer Generic %[[#]]
 ; CHECK-DAG: %[[#]] = OpConstantNull %[[#GENPTR]]
-; CHECK-COUNT-2: %[[#]] = OpSpecConstantOp %[[#]] PtrCastToGeneric %[[#]]
-; CHECK-COUNT-2: OpPtrCastToGeneric
+; CHECK-COUNT-2: %[[#]] = OpSpecConstantOp %[[#]] Bitcast %[[#]]
+; CHECK-COUNT-2: OpBitcast
 
 @G1 = addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) null, ptr addrspace(4) addrspacecast (ptr @foo to ptr addrspace(4)), ptr addrspace(4) addrspacecast (ptr @bar to ptr addrspace(4))] }
 @G2 = addrspace(1) constant { [3 x ptr addrspace(4)] } { [3 x ptr addrspace(4)] [ptr addrspace(4) addrspacecast (ptr null to ptr addrspace(4)), ptr addrspace(4) addrspacecast (ptr @bar to ptr addrspace(4)), ptr addrspace(4) addrspacecast (ptr @foo to ptr addrspace(4))] }
diff --git a/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll b/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll
index 6d06ef8ce576b..c622833110a93 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll
@@ -1,8 +1,5 @@
 ; RUN: llc -mtriple=spirv32-unknown-unknown -O0 %s -o - --spirv-ext=+SPV_INTEL_function_pointers | FileCheck %s
-; Fails with:
-;   `Expected input to have storage class Workgroup, CrossWorkgroup or Function: PtrCastToGeneric`
-; Seem like a spirv-val limitation.
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - --spirv-ext=+SPV_INTEL_function_pointers -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - --spirv-ext=+SPV_INTEL_function_pointers -filetype=obj | spirv-val %}
 
 ; CHECK-DAG: OpCapability FunctionPointersINTEL
 ; CHECK-DAG: OpExtension "SPV_INTEL_function_pointers"
@@ -16,7 +13,7 @@
 ; CHECK-DAG: %[[#Null:]] = OpConstantNull %[[#Int8PtrTy]]
 ; CHECK-DAG: %[[#FnPtr:]] = OpConstantFunctionPointerINTEL %[[#CodePtrTy]] %[[#FnDef:]]
 ; CHECK:     %[[#FnDef]] = OpFunction %[[#Void]] None %[[#FnTy]]
-; CHECK:     %[[#Cast:]] = OpPtrCastToGeneric %[[#GenPtrTy]] %[[#FnPtr]]
+; CHECK:     %[[#Cast:]] = OpBitcast %[[#GenPtrTy]] %[[#FnPtr]]
 ; CHECK:     %[[#BC:]] = OpBitcast %[[#GenPtrPtrTy]] %[[#Null]]
 ; CHECK:     OpStore %[[#BC]] %[[#Cast]] Aligned 8
 ; CHECK:     OpReturn

>From 2c66c6dfb799b0ad68a162d0ad7f89a6fd44efe2 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 9 Jul 2026 14:30:02 +0200
Subject: [PATCH 2/3] fix fn-ptr-addrspacecast.ll as well

---
 .../CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll     | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
index 400f6bc5e51f4..d6957e69ca92c 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
@@ -1,15 +1,12 @@
 ; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
-
-; TODO: Update when spirv-val accepts casts from CodeSectionINTEL to Generic
-; https://github.com/KhronosGroup/SPIRV-Tools/issues/6700
-; RUNx: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_INTEL_function_pointers %s -o - -filetype=obj | spirv-val %}
 
 define void @addrspacecast(ptr addrspace(9) %a) {
 ; CHECK: %[[#Int8:]] = OpTypeInt 8 0
 ; CHECK: %[[#Int8FnPtr:]] = OpTypePointer CodeSectionINTEL %[[#Int8]]
 ; CHECK: %[[#Int8GenericPtr:]] = OpTypePointer Generic %[[#Int8]]
 ; CHECK: %[[#FnParam:]] = OpFunctionParameter %[[#Int8FnPtr]]
-; CHECK: OpPtrCastToGeneric %[[#Int8GenericPtr]] %[[#FnParam]]
+; CHECK: OpBitcast %[[#Int8GenericPtr]] %[[#FnParam]]
 
   %res1 = addrspacecast ptr addrspace(9) %a to ptr addrspace(4)
   store i8 0, ptr addrspace(4) %res1
@@ -18,7 +15,7 @@ define void @addrspacecast(ptr addrspace(9) %a) {
 
 define void @addrspacecast_two(ptr addrspace(4) %b) {
 ; CHECK: %[[#FnParam2:]] = OpFunctionParameter %[[#Int8GenericPtr]]
-; CHECK: OpGenericCastToPtr %[[#Int8FnPtr]] %[[#FnParam2]]
+; CHECK: OpBitcast %[[#Int8FnPtr]] %[[#FnParam2]]
 
   %res2 = addrspacecast ptr addrspace(4) %b to ptr addrspace(9)
   %cmp = icmp eq ptr addrspace(9) %res2, null

>From fdab96031db7b15e3fd9c25d82b36e01cf4ac521 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Fri, 10 Jul 2026 18:45:54 +0200
Subject: [PATCH 3/3] adjust

---
 llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp         | 5 -----
 llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll | 4 ++--
 llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll      | 2 +-
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index faea7dbf0b33f..fe214f4b45ff0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2867,11 +2867,6 @@ bool SPIRVInstructionSelector::selectAddrSpaceCast(Register ResVReg,
        SrcSC == SPIRV::StorageClass::Private))
     return BuildCOPY(ResVReg, SrcPtr, I);
 
-  // CodeSectionINTEL is not valid for PtrCastToGeneric/GenericCastToPtr
-  if (SrcSC == SPIRV::StorageClass::CodeSectionINTEL ||
-      DstSC == SPIRV::StorageClass::CodeSectionINTEL)
-    return selectUnOp(ResVReg, ResType, I, SPIRV::OpBitcast);
-
   // Casting from an eligible pointer to Generic.
   if (DstSC == SPIRV::StorageClass::Generic && isGenericCastablePtr(SrcSC))
     return selectUnOp(ResVReg, ResType, I, SPIRV::OpPtrCastToGeneric);
diff --git a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
index d6957e69ca92c..896bced596759 100644
--- a/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
+++ b/llvm/test/CodeGen/SPIRV/GlobalISel/fn-ptr-addrspacecast.ll
@@ -6,7 +6,7 @@ define void @addrspacecast(ptr addrspace(9) %a) {
 ; CHECK: %[[#Int8FnPtr:]] = OpTypePointer CodeSectionINTEL %[[#Int8]]
 ; CHECK: %[[#Int8GenericPtr:]] = OpTypePointer Generic %[[#Int8]]
 ; CHECK: %[[#FnParam:]] = OpFunctionParameter %[[#Int8FnPtr]]
-; CHECK: OpBitcast %[[#Int8GenericPtr]] %[[#FnParam]]
+; CHECK: OpPtrCastToGeneric %[[#Int8GenericPtr]] %[[#FnParam]]
 
   %res1 = addrspacecast ptr addrspace(9) %a to ptr addrspace(4)
   store i8 0, ptr addrspace(4) %res1
@@ -15,7 +15,7 @@ define void @addrspacecast(ptr addrspace(9) %a) {
 
 define void @addrspacecast_two(ptr addrspace(4) %b) {
 ; CHECK: %[[#FnParam2:]] = OpFunctionParameter %[[#Int8GenericPtr]]
-; CHECK: OpBitcast %[[#Int8FnPtr]] %[[#FnParam2]]
+; CHECK: OpGenericCastToPtr %[[#Int8FnPtr]] %[[#FnParam2]]
 
   %res2 = addrspacecast ptr addrspace(4) %b to ptr addrspace(9)
   %cmp = icmp eq ptr addrspace(9) %res2, null
diff --git a/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll b/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll
index c622833110a93..49ac8a53ae28b 100644
--- a/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll
+++ b/llvm/test/CodeGen/SPIRV/pointers/fun-ptr-to-itself.ll
@@ -13,7 +13,7 @@
 ; CHECK-DAG: %[[#Null:]] = OpConstantNull %[[#Int8PtrTy]]
 ; CHECK-DAG: %[[#FnPtr:]] = OpConstantFunctionPointerINTEL %[[#CodePtrTy]] %[[#FnDef:]]
 ; CHECK:     %[[#FnDef]] = OpFunction %[[#Void]] None %[[#FnTy]]
-; CHECK:     %[[#Cast:]] = OpBitcast %[[#GenPtrTy]] %[[#FnPtr]]
+; CHECK:     %[[#Cast:]] = OpPtrCastToGeneric %[[#GenPtrTy]] %[[#FnPtr]]
 ; CHECK:     %[[#BC:]] = OpBitcast %[[#GenPtrPtrTy]] %[[#Null]]
 ; CHECK:     OpStore %[[#BC]] %[[#Cast]] Aligned 8
 ; CHECK:     OpReturn



More information about the llvm-commits mailing list