Skip to content

Commit e02a966

Browse files
kkreczkoigcbot
authored andcommitted
Support opaque pointers in PromoteBools pass
PromoteBools was wrongly skipping RAUW operation on ptr function calls after promoting their signature and adding their users to promotion queue which lead to cleaning those users and creating undef values in subsequent users, which then in turn created dead code which was eliminated and caused wrong test results. Essentially this pass was wrongly skipping RAUW when neccessary. In cases like these: ```llvm @call = call ptr @some-function(i1 true) @bitcast = bitcast ptr @call to ptr @ptrtoint = ptrtoint ptr @bitcast to i64 ``` After pass pre fix: ```llvm @0 = call ptr @some-function(i8 1) @ptrtoint = ptrtoint ptr undef to i64 ``` Proper pass behaviour: ```llvm @0 = call ptr @some-function(i8 1) @bitcast = bitcast ptr @0 to ptr @ptrtoin = ptrtoint ptr @bitcast to i64 ```
1 parent 8ee8632 commit e02a966

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

IGC/AdaptorOCL/preprocess_spvir/PromoteBools.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*========================== begin_copyright_notice ============================
22
3-
Copyright (C) 2022-2024 Intel Corporation
3+
Copyright (C) 2022-2025 Intel Corporation
44
55
SPDX-License-Identifier: MIT
66
@@ -440,8 +440,18 @@ Value *PromoteBools::getOrCreatePromotedValue(Value *value) {
440440

441441
if (newValue != value) {
442442
promotedValuesCache[value] = newValue;
443-
auto ty = value->getType();
444-
if (!IGCLLVM::isOpaquePointerTy(ty) && ty == newValue->getType()) {
443+
444+
bool promotionChangedType = false;
445+
auto oldGV = dyn_cast<GlobalValue>(value);
446+
auto newGV = dyn_cast<GlobalValue>(newValue);
447+
448+
if (oldGV && newGV) {
449+
promotionChangedType = oldGV->getValueType() != newGV->getValueType();
450+
}
451+
452+
bool typesMatch = (value->getType() == newValue->getType());
453+
454+
if (!promotionChangedType && typesMatch) {
445455
value->replaceAllUsesWith(newValue);
446456
} else {
447457
for (const auto &user : value->users()) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
; REQUIRES: llvm-16-plus, regkeys
9+
; RUN: igc_opt --regkey "EnableOpaquePointersBackend=1" --igc-promote-bools -S < %s 2>&1 | FileCheck %s
10+
11+
; This test verifies that the pass can handle nested users of opaque pointer function calls
12+
; without generating undef values and deleting said users unnecessarily.
13+
; ------------------------------------------------
14+
; NoUndefUsersOpaque
15+
; ------------------------------------------------
16+
17+
; CHECK-LABEL: define spir_kernel void @test_kernel()
18+
; CHECK: call spir_func ptr addrspace(4) @joint_helper(i8 1)
19+
; CHECK-NOT: undef
20+
; CHECK: ptrtoint ptr addrspace(4)
21+
; CHECK: ret void
22+
23+
; CHECK-LABEL: define internal spir_func ptr addrspace(4) @joint_helper(i8 %flag)
24+
; CHECK-NOT: i1
25+
; CHECK: alloca i8, align 1, addrspace(4)
26+
; CHECK: getelementptr inbounds i8, ptr addrspace(4)
27+
; CHECK: ret ptr addrspace(4)
28+
29+
define spir_kernel void @test_kernel() #0 {
30+
entry:
31+
%call = call spir_func ptr addrspace(4) @joint_helper(i1 1) #0
32+
%bc = bitcast ptr addrspace(4) %call to ptr addrspace(4)
33+
%asint = ptrtoint ptr addrspace(4) %bc to i64
34+
ret void
35+
}
36+
37+
define internal spir_func ptr addrspace(4) @joint_helper(i1 %flag) #0 {
38+
entry:
39+
%base = alloca i1, align 1, addrspace(4)
40+
%gep = getelementptr inbounds i1, ptr addrspace(4) %base, i64 1
41+
ret ptr addrspace(4) %gep
42+
}
43+
44+
attributes #0 = { nounwind }

0 commit comments

Comments
 (0)