Skip to content

Commit 4a58a77

Browse files
wenju-hesys-ce-bb
authored andcommitted
Remove tail from atomic_compare_exchange_strong_explicit call (#2395)
In translation from __spirv_AtomicCompareExchange to OpenCL builtin atomic_compare_exchange_strong_explicit, a new alloca `expected` is created and read/written in the OpenCL builtin. The OpenCL builtin call can't have tail marker since the marker requires that callee doesn't access alloca from the caller. Otherwise llvm alias analysis deduces that the alloca isn't accessed by the call, and instcombine pass replaces the load from the alloca after the call with the value stored to the alloca before the call. Original commit: KhronosGroup/SPIRV-LLVM-Translator@1ff4a764cd0f97c
1 parent 949feed commit 4a58a77

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

llvm-spirv/lib/SPIRV/SPIRVToOCL20.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ void SPIRVToOCL20Base::visitCallSPIRVAtomicCmpExchg(CallInst *CI) {
210210
&*CI->getParent()->getParent()->getEntryBlock().getFirstInsertionPt());
211211
PExpected->setAlignment(Align(MemTy->getScalarSizeInBits() / 8));
212212

213+
// Tail call implies that the callee doesn't access alloca from the caller.
214+
// The newly created alloca invalidates the tail call semantics.
215+
CI->setTailCall(false);
216+
213217
// OpAtomicCompareExchangeWeak is not "weak" at all, but instead has the same
214218
// semantics as OpAtomicCompareExchange.
215219
mutateCallInst(CI, "atomic_compare_exchange_strong_explicit")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; REQUIRES: pass-plugin
2+
; UNSUPPORTED: target={{.*windows.*}}
3+
4+
; RUN: opt %load_spirv_lib -passes=spirv-to-ocl20 %s -S -o - | FileCheck %s
5+
6+
; Check that tail marker is removed from atomic_compare_exchange_strong_explicit call.
7+
8+
; CHECK: = call spir_func {{.*}}atomic_compare_exchange_strong_explicit
9+
10+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
11+
12+
%"class.sycl::_V1::id" = type { %"class.sycl::_V1::detail::array" }
13+
%"class.sycl::_V1::detail::array" = type { [1 x i64] }
14+
15+
define spir_kernel void @test(ptr addrspace(1) noundef align 8 %_arg_data_accessor, ptr noundef byval(%"class.sycl::_V1::id") align 8 %_arg_data_accessor4) {
16+
entry:
17+
%0 = load i64, ptr %_arg_data_accessor4, align 8
18+
%add.ptr = getelementptr inbounds ptr addrspace(4), ptr addrspace(1) %_arg_data_accessor, i64 %0
19+
%arrayidx.ascast = addrspacecast ptr addrspace(1) %add.ptr to ptr addrspace(4)
20+
br label %do.body
21+
22+
do.body:
23+
%call1 = tail call spir_func noundef i64 @_Z18__spirv_AtomicLoadPKmN5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE(ptr addrspace(4) noundef %arrayidx.ascast, i32 noundef 2, i32 noundef 912)
24+
%1 = inttoptr i64 %call1 to ptr addrspace(4)
25+
%add.ptr.i = getelementptr inbounds i32, ptr addrspace(4) %1, i64 1
26+
%2 = ptrtoint ptr addrspace(4) %add.ptr.i to i64
27+
%call2 = tail call spir_func noundef i64 @_Z29__spirv_AtomicCompareExchangePmN5__spv5Scope4FlagENS0_19MemorySemanticsMask4FlagES4_mm(ptr addrspace(4) noundef %arrayidx.ascast, i32 noundef 2, i32 noundef 912, i32 noundef 912, i64 noundef %2, i64 noundef %call1)
28+
%3 = icmp eq i64 %call2, %call1
29+
br i1 %3, label %exit, label %do.body
30+
31+
exit:
32+
ret void
33+
}
34+
35+
declare spir_func noundef i64 @_Z18__spirv_AtomicLoadPKmN5__spv5Scope4FlagENS1_19MemorySemanticsMask4FlagE(ptr addrspace(4) noundef, i32 noundef, i32 noundef)
36+
37+
declare spir_func noundef i64 @_Z29__spirv_AtomicCompareExchangePmN5__spv5Scope4FlagENS0_19MemorySemanticsMask4FlagES4_mm(ptr addrspace(4) noundef, i32 noundef, i32 noundef, i32 noundef, i64 noundef, i64 noundef)

0 commit comments

Comments
 (0)