Skip to content

Commit 4c29521

Browse files
[SPIR-V] fix return type for OpAtomicCompareExchange (#154297)
fixes #152863 Tests were written with some help from Copilot --------- Co-authored-by: Victor Lomuller <[email protected]>
1 parent c856e8d commit 4c29521

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,10 +802,9 @@ static bool buildAtomicCompareExchangeInst(
802802
MRI->setRegClass(Tmp, GR->getRegClass(SpvDesiredTy));
803803
GR->assignSPIRVTypeToVReg(SpvDesiredTy, Tmp, MIRBuilder.getMF());
804804

805-
SPIRVType *IntTy = GR->getOrCreateSPIRVIntegerType(32, MIRBuilder);
806805
MIRBuilder.buildInstr(Opcode)
807806
.addDef(Tmp)
808-
.addUse(GR->getSPIRVTypeID(IntTy))
807+
.addUse(GR->getSPIRVTypeID(SpvDesiredTy))
809808
.addUse(ObjectPtr)
810809
.addUse(ScopeReg)
811810
.addUse(MemSemEqualReg)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; Regression test for issue https://github.com/llvm/llvm-project/issues/152863
5+
; Ensure OpAtomicCompareExchange returns the correct i64 type when used in phi nodes.
6+
; Previously, this would generate invalid SPIR-V where the atomic operation returned
7+
; uint (32-bit) but the phi node expected ulong (64-bit), causing validation errors.
8+
9+
; CHECK-SPIRV-DAG: %[[#Long:]] = OpTypeInt 64 0
10+
; CHECK-SPIRV-DAG: %[[#Ptr:]] = OpTypePointer CrossWorkgroup %[[#Long]]
11+
; CHECK-SPIRV-DAG: %[[#Zero64:]] = OpConstantNull %[[#Long]]
12+
13+
; Verify that both the phi node and atomic operation use the same i64 type
14+
; CHECK-SPIRV: %[[#ValuePhi:]] = OpPhi %[[#Long]] %[[#Zero64]] %[[#]] %[[#AtomicResult:]] %[[#]]
15+
; CHECK-SPIRV: %[[#AtomicResult]] = OpAtomicCompareExchange %[[#Long]] %[[#]] %[[#]] %[[#]] %[[#]] %[[#Zero64]] %[[#ValuePhi]]
16+
17+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"
18+
target triple = "spirv64-unknown-unknown"
19+
20+
declare i64 @_Z14atomic_cmpxchgPU8CLglobalVlll(ptr addrspace(1), i64, i64)
21+
22+
define spir_kernel void @test_atomic_cmpxchg_phi(ptr addrspace(1) %ptr) {
23+
conversion:
24+
br label %L6
25+
26+
L6: ; preds = %L6, %conversion
27+
%value_phi = phi i64 [ 0, %conversion ], [ %1, %L6 ]
28+
%1 = call i64 @_Z14atomic_cmpxchgPU8CLglobalVlll(ptr addrspace(1) %ptr, i64 %value_phi, i64 0)
29+
br label %L6
30+
}

0 commit comments

Comments
 (0)