Skip to content

Commit 314d922

Browse files
YuriPlyakhinigcbot
authored andcommitted
Fix GEP lowering overflow issues
This change prevents usage of potentially negative values which are then zero-extended to 64 bits as indexes.
1 parent f28842c commit 314d922

File tree

4 files changed

+88
-11
lines changed

4 files changed

+88
-11
lines changed

IGC/Compiler/CISACodeGen/GenIRLowering.cpp

Lines changed: 4 additions & 1 deletion
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
@@ -441,6 +441,9 @@ bool GEPLowering::simplifyGEP(BasicBlock &BB) const {
441441
auto *Idx = GEP->getOperand(1);
442442
if (auto *ZExt = dyn_cast<ZExtInst>(Idx)) {
443443
Idx = ZExt->getOperand(0);
444+
auto *Op = dyn_cast<OverflowingBinaryOperator>(Idx);
445+
if (Op && !Op->hasNoUnsignedWrap())
446+
continue;
444447
} else if (auto *SExt = dyn_cast<SExtInst>(Idx)) {
445448
Idx = SExt->getOperand(0);
446449
Operator* Opr = dyn_cast<Operator>(Idx);

IGC/Compiler/tests/GEPLowering/gep_simplification-typed-pointers.ll

Lines changed: 5 additions & 5 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
;
@@ -36,21 +36,21 @@ define spir_kernel void @test_gep(i32 addrspace(1)* %dst, i32 addrspace(1)* %src
3636
case1:
3737
%simdLaneId16 = call i16 @llvm.genx.GenISA.simdLaneId()
3838
%simdLaneId = zext i16 %simdLaneId16 to i32
39-
%idbase1 = add nsw i32 %Offset32, %simdLaneId
39+
%idbase1 = add nsw nuw i32 %Offset32, %simdLaneId
4040
%id1.1 = zext i32 %idbase1 to i64
4141
%addr1.1 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.1
4242
%res1.0 = load i32, i32 addrspace(1)* %addr1.1, align 4
43-
%add11.1 = add nsw i32 %idbase1, 4
43+
%add11.1 = add nsw nuw i32 %idbase1, 4
4444
%id1.2 = zext i32 %add11.1 to i64
4545
%addr1.2 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.2
4646
%res1.1 = load i32, i32 addrspace(1)* %addr1.2, align 4
4747
%sum1.0 = add nsw i32 %res1.0, %res1.1
48-
%add11.2 = add nsw i32 %idbase1, 8
48+
%add11.2 = add nsw nuw i32 %idbase1, 8
4949
%id1.3 = zext i32 %add11.2 to i64
5050
%addr1.3 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.3
5151
%res1.2 = load i32, i32 addrspace(1)* %addr1.3, align 4
5252
%sum1.1 = add nsw i32 %sum1.0, %res1.2
53-
%add11.3 = add nsw i32 %idbase1, 12
53+
%add11.3 = add nsw nuw i32 %idbase1, 12
5454
%id1.4 = zext i32 %add11.3 to i64
5555
%addr1.4 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.4
5656
%res1.3 = load i32, i32 addrspace(1)* %addr1.4, align 4

IGC/Compiler/tests/GEPLowering/gep_simplification.ll

Lines changed: 5 additions & 5 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
;
@@ -36,21 +36,21 @@ define spir_kernel void @test_gep(i32 addrspace(1)* %dst, i32 addrspace(1)* %src
3636
case1:
3737
%simdLaneId16 = call i16 @llvm.genx.GenISA.simdLaneId()
3838
%simdLaneId = zext i16 %simdLaneId16 to i32
39-
%idbase1 = add nsw i32 %Offset32, %simdLaneId
39+
%idbase1 = add nsw nuw i32 %Offset32, %simdLaneId
4040
%id1.1 = zext i32 %idbase1 to i64
4141
%addr1.1 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.1
4242
%res1.0 = load i32, i32 addrspace(1)* %addr1.1, align 4
43-
%add11.1 = add nsw i32 %idbase1, 4
43+
%add11.1 = add nsw nuw i32 %idbase1, 4
4444
%id1.2 = zext i32 %add11.1 to i64
4545
%addr1.2 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.2
4646
%res1.1 = load i32, i32 addrspace(1)* %addr1.2, align 4
4747
%sum1.0 = add nsw i32 %res1.0, %res1.1
48-
%add11.2 = add nsw i32 %idbase1, 8
48+
%add11.2 = add nsw nuw i32 %idbase1, 8
4949
%id1.3 = zext i32 %add11.2 to i64
5050
%addr1.3 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.3
5151
%res1.2 = load i32, i32 addrspace(1)* %addr1.3, align 4
5252
%sum1.1 = add nsw i32 %sum1.0, %res1.2
53-
%add11.3 = add nsw i32 %idbase1, 12
53+
%add11.3 = add nsw nuw i32 %idbase1, 12
5454
%id1.4 = zext i32 %add11.3 to i64
5555
%addr1.4 = getelementptr inbounds i32, i32 addrspace(1)* %src, i64 %id1.4
5656
%res1.3 = load i32, i32 addrspace(1)* %addr1.4, align 4
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
;=========================== begin_copyright_notice ============================
2+
;
3+
; Copyright (C) 2025 Intel Corporation
4+
;
5+
; SPDX-License-Identifier: MIT
6+
;
7+
;============================ end_copyright_notice =============================
8+
;
9+
; ------------------------------------------------
10+
; REQUIRES: llvm-14-plus
11+
; RUN: igc_opt --opaque-pointers --igc-gep-lowering -S < %s 2>&1 | FileCheck %s
12+
; ------------------------------------------------
13+
; GEPLowering - verify that address arithmetic based on first GEP index is not
14+
; applied, when GEP index can be negative and zext if used on
15+
; negative index may turn it into large positive value
16+
; ------------------------------------------------
17+
18+
define spir_func void @test_gep_overflow(ptr addrspace(1) %src, i32 %conv13) {
19+
; CHECK-LABEL: @test_gep_overflow(
20+
; CHECK-NEXT: entry:
21+
; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[CONV13:%.*]], -2
22+
; CHECK-NEXT: [[IDX_EXT19:%.*]] = zext i32 [[SUB]] to i64
23+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr addrspace(1) [[SRC:%.*]] to i64
24+
; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[IDX_EXT19]], 2
25+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0]], [[TMP1]]
26+
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr addrspace(1)
27+
; CHECK-NEXT: [[SUB22:%.*]] = add nsw i32 [[CONV13]], -1
28+
; CHECK-NEXT: [[IDX_EXT35:%.*]] = zext i32 [[SUB22]] to i64
29+
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr addrspace(1) [[SRC]] to i64
30+
; CHECK-NEXT: [[TMP5:%.*]] = shl i64 [[IDX_EXT35]], 2
31+
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP4]], [[TMP5]]
32+
; CHECK-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr addrspace(1)
33+
; CHECK-NEXT: ret void
34+
;
35+
entry:
36+
%sub = add nsw i32 %conv13, -2
37+
%idx.ext19 = zext i32 %sub to i64
38+
%add.ptr20 = getelementptr inbounds float, ptr addrspace(1) %src, i64 %idx.ext19
39+
%sub22 = add nsw i32 %conv13, -1
40+
%idx.ext35 = zext i32 %sub22 to i64
41+
%add.ptr36 = getelementptr inbounds float, ptr addrspace(1) %src, i64 %idx.ext35
42+
ret void
43+
}
44+
45+
define spir_func void @test_gep_no_overflow(ptr addrspace(1) %src, i32 %conv13) {
46+
; CHECK-LABEL: @test_gep_no_overflow(
47+
; CHECK-NEXT: entry:
48+
; CHECK-NEXT: [[SUB:%.*]] = add nuw nsw i32 [[CONV13:%.*]], -2
49+
; CHECK-NEXT: [[IDX_EXT19:%.*]] = zext i32 [[SUB]] to i64
50+
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr addrspace(1) [[SRC:%.*]] to i64
51+
; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[IDX_EXT19]], 2
52+
; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP0]], [[TMP1]]
53+
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr addrspace(1)
54+
; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[TMP2]], 4
55+
; CHECK-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr addrspace(1)
56+
; CHECK-NEXT: ret void
57+
;
58+
entry:
59+
%sub = add nsw nuw i32 %conv13, -2
60+
%idx.ext19 = zext i32 %sub to i64
61+
%add.ptr20 = getelementptr inbounds float, ptr addrspace(1) %src, i64 %idx.ext19
62+
%sub22 = add nsw nuw i32 %conv13, -1
63+
%idx.ext35 = zext i32 %sub22 to i64
64+
%add.ptr36 = getelementptr inbounds float, ptr addrspace(1) %src, i64 %idx.ext35
65+
ret void
66+
}
67+
68+
!igc.functions = !{!0, !4}
69+
70+
!0 = !{ptr @test_gep_overflow, !1}
71+
!1 = !{!2, !3}
72+
!2 = !{!"function_type", i32 0}
73+
!3 = !{!"implicit_arg_desc"}
74+
!4 = !{ptr @test_gep_no_overflow, !1}

0 commit comments

Comments
 (0)