|
| 1 | +From 2ffa8bb80d2806aaa913dcd2a35a8f298d511458 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Simeon David Schaub < [email protected]> |
| 3 | +Date: Tue, 19 Aug 2025 11:14:53 +0200 |
| 4 | +Subject: [PATCH] [SPIR-V] fix return type for OpAtomicCompareExchange |
| 5 | + |
| 6 | +fixes #152863 |
| 7 | + |
| 8 | +Tests were written with some help from Copilot |
| 9 | +--- |
| 10 | + lib/Target/SPIRV/SPIRVBuiltins.cpp | 3 +- |
| 11 | + .../AtomicCompareExchange64BitPhiNode.ll | 35 +++++++++++++++++++ |
| 12 | + 2 files changed, 36 insertions(+), 2 deletions(-) |
| 13 | + create mode 100644 llvm/test/CodeGen/SPIRV/AtomicCompareExchange64BitPhiNode.ll |
| 14 | + |
| 15 | +diff --git a/lib/Target/SPIRV/SPIRVBuiltins.cpp b/lib/Target/SPIRV/SPIRVBuiltins.cpp |
| 16 | +index 95fa7bc3894f..4bc5c4ab377b 100644 |
| 17 | +--- a/lib/Target/SPIRV/SPIRVBuiltins.cpp |
| 18 | ++++ b/lib/Target/SPIRV/SPIRVBuiltins.cpp |
| 19 | +@@ -791,10 +791,9 @@ static bool buildAtomicCompareExchangeInst( |
| 20 | + MRI->setRegClass(Tmp, GR->getRegClass(SpvDesiredTy)); |
| 21 | + GR->assignSPIRVTypeToVReg(SpvDesiredTy, Tmp, MIRBuilder.getMF()); |
| 22 | + |
| 23 | +- SPIRVType *IntTy = GR->getOrCreateSPIRVIntegerType(32, MIRBuilder); |
| 24 | + MIRBuilder.buildInstr(Opcode) |
| 25 | + .addDef(Tmp) |
| 26 | +- .addUse(GR->getSPIRVTypeID(IntTy)) |
| 27 | ++ .addUse(GR->getSPIRVTypeID(SpvDesiredTy)) |
| 28 | + .addUse(ObjectPtr) |
| 29 | + .addUse(ScopeReg) |
| 30 | + .addUse(MemSemEqualReg) |
| 31 | +diff --git a/test/CodeGen/SPIRV/AtomicCompareExchange64BitPhiNode.ll b/test/CodeGen/SPIRV/AtomicCompareExchange64BitPhiNode.ll |
| 32 | +new file mode 100644 |
| 33 | +index 000000000000..63023c63958d |
| 34 | +--- /dev/null |
| 35 | ++++ b/test/CodeGen/SPIRV/AtomicCompareExchange64BitPhiNode.ll |
| 36 | +@@ -0,0 +1,35 @@ |
| 37 | ++; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV |
| 38 | ++; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o %t.spv -filetype=obj |
| 39 | ++; RUN: spirv-val %t.spv |
| 40 | ++ |
| 41 | ++; Regression test for issue https://github.com/llvm/llvm-project/issues/152863 |
| 42 | ++; Ensure OpAtomicCompareExchange returns the correct i64 type when used in phi nodes. |
| 43 | ++; Previously, this would generate invalid SPIR-V where the atomic operation returned |
| 44 | ++; uint (32-bit) but the phi node expected ulong (64-bit), causing validation errors. |
| 45 | ++ |
| 46 | ++; CHECK-SPIRV-DAG: %[[#Long:]] = OpTypeInt 64 0 |
| 47 | ++; CHECK-SPIRV-DAG: %[[#Ptr:]] = OpTypePointer CrossWorkgroup %[[#Long]] |
| 48 | ++; CHECK-SPIRV-DAG: %[[#Void:]] = OpTypeVoid |
| 49 | ++; CHECK-SPIRV-DAG: %[[#Int:]] = OpTypeInt 32 0 |
| 50 | ++; CHECK-SPIRV-DAG: %[[#Zero64:]] = OpConstantNull %[[#Long]] |
| 51 | ++; CHECK-SPIRV-DAG: %[[#Scope:]] = OpConstant %[[#Int]] 2 |
| 52 | ++; CHECK-SPIRV-DAG: %[[#MemSem:]] = OpConstant %[[#Int]] 0 |
| 53 | ++ |
| 54 | ++; Verify that both the phi node and atomic operation use the same i64 type |
| 55 | ++; CHECK-SPIRV: %[[#ValuePhi:]] = OpPhi %[[#Long]] %[[#Zero64]] %[[#]] %[[#AtomicResult:]] %[[#]] |
| 56 | ++; CHECK-SPIRV: %[[#AtomicResult]] = OpAtomicCompareExchange %[[#Long]] %[[#]] %[[#Scope]] %[[#MemSem]] %[[#MemSem]] %[[#Zero64]] %[[#ValuePhi]] |
| 57 | ++ |
| 58 | ++target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1" |
| 59 | ++target triple = "spirv64-unknown-unknown" |
| 60 | ++ |
| 61 | ++declare i64 @_Z14atomic_cmpxchgPU8CLglobalVlll(ptr addrspace(1), i64, i64) |
| 62 | ++ |
| 63 | ++define spir_kernel void @test_atomic_cmpxchg_phi(ptr addrspace(1) %ptr) { |
| 64 | ++conversion: |
| 65 | ++ br label %L6 |
| 66 | ++ |
| 67 | ++L6: ; preds = %L6, %conversion |
| 68 | ++ %value_phi = phi i64 [ 0, %conversion ], [ %1, %L6 ] |
| 69 | ++ %1 = call i64 @_Z14atomic_cmpxchgPU8CLglobalVlll(ptr addrspace(1) %ptr, i64 %value_phi, i64 0) |
| 70 | ++ br label %L6 |
| 71 | ++} |
| 72 | +-- |
| 73 | +2.50.1 |
| 74 | + |
0 commit comments