Skip to content

Commit 137cd1d

Browse files
kkreczkoigcbot
authored andcommitted
Fix constant folding in PredefinedConstantResolving
PredefinedConstantResolving pass caused type mismatch assertion in tests while moving to opaque pointers. It happened when there was a type difference between a global variable and it's load instruction user. With typed pointers the pass was skipped in this scenario because user of same global was bitcast and then it's user was load. What this pass tried to do was doing RAUW operation on load to replace it with global constant. This fix changes pass's behaviour by enabling constant folding even when there is a type difference between load instruction and global constant. Example crashing ir: ```llvm @global = constant [3 x i64] [i64 16, i64 32, i64 64] define void @func(i64 %0) { %2 = load i64, ptr @global ; <-- crash ret void } ```
1 parent f7a18fd commit 137cd1d

File tree

2 files changed

+75
-11
lines changed

2 files changed

+75
-11
lines changed

IGC/Compiler/CISACodeGen/ResolvePredefinedConstant.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*========================== begin_copyright_notice ============================
22
3-
Copyright (C) 2017-2021 Intel Corporation
3+
Copyright (C) 2017-2025 Intel Corporation
44
55
SPDX-License-Identifier: MIT
66
@@ -14,6 +14,7 @@ SPDX-License-Identifier: MIT
1414
#include <llvm/IR/Module.h>
1515
#include <llvm/IR/Instructions.h>
1616
#include <llvm/Pass.h>
17+
#include <llvm/Analysis/ConstantFolding.h>
1718
#include "common/LLVMWarningsPop.hpp"
1819

1920
using namespace llvm;
@@ -39,7 +40,7 @@ ModulePass *IGC::createResolvePredefinedConstantPass() { return new PredefinedCo
3940
char PredefinedConstantResolving::ID = 0;
4041

4142
#define PASS_FLAG "igc-predefined-constant-resolve"
42-
#define PASS_DESC "Resolve compiler predefeind constants"
43+
#define PASS_DESC "Resolve compiler predefined constants"
4344
#define PASS_CFG_ONLY false
4445
#define PASS_ANALYSIS false
4546
namespace IGC {
@@ -49,23 +50,24 @@ IGC_INITIALIZE_PASS_END(PredefinedConstantResolving, PASS_FLAG, PASS_DESC, PASS_
4950

5051
bool PredefinedConstantResolving::runOnModule(Module &M) {
5152
bool Changed = false;
53+
const DataLayout &DL = M.getDataLayout();
54+
5255
for (auto &GV : M.globals()) {
53-
if (!GV.isConstant())
54-
continue;
55-
if (!GV.hasUniqueInitializer())
56+
if (!GV.isConstant() || !GV.hasUniqueInitializer())
5657
continue;
57-
// We don't use fancy data structure to reduce the lookup overhead due to
58-
// the current limited size of compiler pre-defined constants.
5958

6059
Constant *C = GV.getInitializer();
6160
for (auto I = GV.user_begin(); I != GV.user_end(); /* empty */) {
62-
// Ensure we understand how the predefined constant is used.
6361
LoadInst *LI = dyn_cast<LoadInst>(*I++);
6462
if (!LI)
6563
continue;
66-
LI->replaceAllUsesWith(C);
67-
LI->eraseFromParent();
68-
Changed = true;
64+
65+
if (Constant *Folded = ConstantFoldLoadFromConst(C, LI->getType(), DL)) {
66+
LI->replaceAllUsesWith(Folded);
67+
LI->eraseFromParent();
68+
Changed = true;
69+
}
70+
6971
}
7072
}
7173
return Changed;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
9+
; REQUIRES: regkeys, llvm-16-plus
10+
;
11+
; RUN: igc_opt --regkey "EnableOpaquePointersBackend=1" --igc-predefined-constant-resolve 2>&1 -S < %s | FileCheck %s
12+
; ------------------------------------------------
13+
; PredefinedConstantResolving
14+
; ------------------------------------------------
15+
16+
; This test checks whether the PredefinedConstantResolving pass correctly folds constants with matching or not matching types
17+
18+
@global_int = internal addrspace(1) constant i32 1337, align 4
19+
@global_i8s_arr = internal addrspace(1) constant [8 x i8] [i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8], align 8
20+
@global_i64s_arr = internal addrspace(1) constant [3 x i64] [i64 16, i64 32, i64 64], align 8
21+
22+
; CHECK-LABEL: @test_i64_from_i64_array(
23+
; CHECK: store i64 16,
24+
; CHECK-NOT: load
25+
define spir_kernel void @test_i64_from_i64_array(ptr addrspace(1) %out) {
26+
entry:
27+
%local = load i64, ptr addrspace(1) @global_i64s_arr, align 8
28+
store i64 %local, ptr addrspace(1) %out, align 8
29+
ret void
30+
}
31+
32+
; CHECK-LABEL: @test_direct_i32(
33+
; CHECK: store i32 1337,
34+
; CHECK-NOT: load
35+
define spir_kernel void @test_direct_i32(ptr addrspace(1) %out) {
36+
entry:
37+
%local = load i32, ptr addrspace(1) @global_int
38+
store i32 %local, ptr addrspace(1) %out, align 4
39+
ret void
40+
}
41+
42+
; CHECK-LABEL: @test_i64_from_i8_array(
43+
; CHECK: store i64 578437695752307201,
44+
; CHECK-NOT: load
45+
define spir_kernel void @test_i64_from_i8_array(ptr addrspace(1) %out) {
46+
entry:
47+
%local = load i64, ptr addrspace(1) @global_i8s_arr, align 8
48+
store i64 %local, ptr addrspace(1) %out, align 8
49+
ret void
50+
}
51+
52+
; CHECK-LABEL: @test_i8_from_i64_array(
53+
; CHECK: store i8 16,
54+
; CHECK-NOT: load
55+
define spir_kernel void @test_i8_from_i64_array(ptr addrspace(1) %out) {
56+
entry:
57+
%local = load i8, ptr addrspace(1) @global_i64s_arr, align 1
58+
store i8 %local, ptr addrspace(1) %out, align 1
59+
ret void
60+
}
61+
62+
attributes #0 = { convergent noinline nounwind optnone "less-precise-fpmad"="true" "visaStackCall" }

0 commit comments

Comments
 (0)