Skip to content

Commit d8595da

Browse files
committed
Handle GEPs with negative offset and 'nuw' attribute
This commit fixes incorrect DAG replacement when the 'nuw' attribute is added to inbounds GEPs with a negative offset. - If the offset is negative and the 'nuw' attribute is present, the 'nuw' flag is set to false. Change-Id: I4c72171545ba3b98a20473eefdb29bab10505bed
1 parent fb2960a commit d8595da

File tree

2 files changed

+236
-3
lines changed

2 files changed

+236
-3
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4363,10 +4363,15 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43634363
// In an inbounds GEP with an offset that is nonnegative even when
43644364
// interpreted as signed, assume there is no unsigned overflow.
43654365
SDNodeFlags Flags;
4366-
if (NW.hasNoUnsignedWrap() ||
4367-
(Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()))
4366+
if (NW.hasNoUnsignedWrap()) {
4367+
if (!Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()) {
4368+
Flags.setNoUnsignedWrap(false);
4369+
} else {
4370+
Flags.setNoUnsignedWrap(true);
4371+
}
4372+
} else if (Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()) {
43684373
Flags.setNoUnsignedWrap(true);
4369-
4374+
}
43704375
OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());
43714376

43724377
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, OffsVal, Flags);
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
;RUN: llc -stop-after="hexagon-isel" < %s | FileCheck %s
2+
3+
;CHECK: %54:intregs = L2_loadrub_io %27, -1
4+
target triple = "hexagon"
5+
6+
@global = external dso_local local_unnamed_addr global ptr, align 4
7+
8+
; Function Attrs: nofree norecurse nosync nounwind memory(read, argmem: readwrite, inaccessiblemem: none)
9+
define dso_local void @quux(i32 noundef %arg, ptr nocapture noundef readonly %arg1, ptr nocapture noundef writeonly %arg2, i32 noundef %arg3) local_unnamed_addr #0 {
10+
bb:
11+
%getelementptr = getelementptr inbounds nuw i8, ptr %arg1, i32 29
12+
%load = load i8, ptr %getelementptr, align 1, !tbaa !3
13+
%icmp = icmp eq i8 %load, 3
14+
br i1 %icmp, label %bb4, label %bb170
15+
16+
bb4: ; preds = %bb
17+
%load5 = load ptr, ptr @global, align 4, !tbaa !9
18+
%getelementptr6 = getelementptr inbounds nuw i8, ptr %arg1, i32 4
19+
%load7 = load ptr, ptr %getelementptr6, align 4, !tbaa !10
20+
%getelementptr8 = getelementptr inbounds nuw i8, ptr %load7, i32 8
21+
%load9 = load i32, ptr %getelementptr8, align 4, !tbaa !11
22+
%getelementptr10 = getelementptr inbounds nuw i8, ptr %load5, i32 %load9
23+
%getelementptr11 = getelementptr inbounds i8, ptr %getelementptr10, i32 -1
24+
%sub = sub i32 0, %arg3
25+
%getelementptr12 = getelementptr inbounds i8, ptr %getelementptr10, i32 %sub
26+
%getelementptr13 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 4
27+
%load14 = load i8, ptr %getelementptr13, align 1, !tbaa !14
28+
%zext = zext i8 %load14 to i32
29+
%getelementptr15 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 2
30+
%load16 = load i8, ptr %getelementptr15, align 1, !tbaa !14
31+
%zext17 = zext i8 %load16 to i32
32+
%sub18 = sub nsw i32 %zext, %zext17
33+
%shl = shl i32 %arg3, 2
34+
%getelementptr19 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %shl
35+
%load20 = load i8, ptr %getelementptr19, align 1, !tbaa !14
36+
%zext21 = zext i8 %load20 to i32
37+
%shl22 = shl i32 %arg3, 1
38+
%getelementptr23 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %shl22
39+
%load24 = load i8, ptr %getelementptr23, align 1, !tbaa !14
40+
%zext25 = zext i8 %load24 to i32
41+
%sub26 = sub nsw i32 %zext21, %zext25
42+
%getelementptr27 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 5
43+
%load28 = load i8, ptr %getelementptr27, align 1, !tbaa !14
44+
%zext29 = zext i8 %load28 to i32
45+
%getelementptr30 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 1
46+
%load31 = load i8, ptr %getelementptr30, align 1, !tbaa !14
47+
%zext32 = zext i8 %load31 to i32
48+
%sub33 = sub nsw i32 %zext29, %zext32
49+
%shl34 = shl nsw i32 %sub33, 1
50+
%add = add nsw i32 %shl34, %sub18
51+
%mul = mul i32 %arg3, 5
52+
%getelementptr35 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %mul
53+
%load36 = load i8, ptr %getelementptr35, align 1, !tbaa !14
54+
%zext37 = zext i8 %load36 to i32
55+
%getelementptr38 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %arg3
56+
%load39 = load i8, ptr %getelementptr38, align 1, !tbaa !14
57+
%zext40 = zext i8 %load39 to i32
58+
%sub41 = sub nsw i32 %zext37, %zext40
59+
%shl42 = shl nsw i32 %sub41, 1
60+
%add43 = add nsw i32 %shl42, %sub26
61+
%getelementptr44 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 6
62+
%load45 = load i8, ptr %getelementptr44, align 1, !tbaa !14
63+
%zext46 = zext i8 %load45 to i32
64+
%load47 = load i8, ptr %getelementptr12, align 1, !tbaa !14
65+
%zext48 = zext i8 %load47 to i32
66+
%sub49 = sub nsw i32 %zext46, %zext48
67+
%mul50 = mul nsw i32 %sub49, 3
68+
%add51 = add nsw i32 %mul50, %add
69+
%mul53 = mul i32 %arg3, 6
70+
%getelementptr54 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %mul53
71+
%load55 = load i8, ptr %getelementptr54, align 1, !tbaa !14
72+
%zext56 = zext i8 %load55 to i32
73+
%load57 = load i8, ptr %getelementptr11, align 1, !tbaa !14
74+
%zext58 = zext i8 %load57 to i32
75+
%sub59 = sub nsw i32 %zext56, %zext58
76+
%mul60 = mul nsw i32 %sub59, 3
77+
%add61 = add nsw i32 %mul60, %add43
78+
%getelementptr62 = getelementptr inbounds i8, ptr %getelementptr12, i32 7
79+
%load63 = load i8, ptr %getelementptr62, align 1, !tbaa !14
80+
%zext64 = zext i8 %load63 to i32
81+
%getelementptr65 = getelementptr inbounds nuw i8, ptr %getelementptr12, i32 -1
82+
%load66 = load i8, ptr %getelementptr65, align 1, !tbaa !14
83+
%zext67 = zext i8 %load66 to i32
84+
%sub68 = sub nsw i32 %zext64, %zext67
85+
%shl69 = shl nsw i32 %sub68, 2
86+
%add70 = add nsw i32 %shl69, %add51
87+
%mul71 = mul i32 %arg3, 7
88+
%getelementptr72 = getelementptr inbounds i8, ptr %getelementptr11, i32 %mul71
89+
%load73 = load i8, ptr %getelementptr72, align 1, !tbaa !14
90+
%zext74 = zext i8 %load73 to i32
91+
%sub75 = sub i32 0, %arg3
92+
%getelementptr76 = getelementptr inbounds nuw i8, ptr %getelementptr11, i32 %sub75
93+
%load77 = load i8, ptr %getelementptr76, align 1, !tbaa !14
94+
%zext78 = zext i8 %load77 to i32
95+
%sub79 = sub nsw i32 %zext74, %zext78
96+
%shl80 = shl nsw i32 %sub79, 2
97+
%add81 = add nsw i32 %shl80, %add61
98+
%add82 = add nuw nsw i32 %zext74, %zext64
99+
%shl83 = shl nuw nsw i32 %add82, 4
100+
%mul84 = mul nsw i32 %add70, 17
101+
%add85 = add nsw i32 %mul84, 16
102+
%ashr = ashr i32 %add85, 5
103+
%mul86 = mul nsw i32 %add81, 17
104+
%add87 = add nsw i32 %mul86, 16
105+
%ashr88 = ashr i32 %add87, 5
106+
%add89 = add nuw nsw i32 %shl83, 16
107+
%mul90 = mul nsw i32 %ashr, -3
108+
%shl91 = shl nsw i32 %ashr, 1
109+
%mul92 = mul nsw i32 %ashr, 3
110+
%shl93 = shl nsw i32 %ashr, 2
111+
%shl94 = shl nsw i32 %ashr, 1
112+
br label %bb95
113+
114+
bb95: ; preds = %bb95, %bb4
115+
%phi = phi ptr [ %arg2, %bb4 ], [ %getelementptr167, %bb95 ]
116+
%phi96 = phi i32 [ 0, %bb4 ], [ %add168, %bb95 ]
117+
%add97 = add nsw i32 %phi96, -3
118+
%mul98 = mul nsw i32 %add97, %ashr88
119+
%add99 = add i32 %add89, %mul98
120+
%add100 = add i32 %add99, %mul90
121+
%ashr101 = ashr i32 %add100, 5
122+
%and = and i32 %add100, 8192
123+
%icmp102 = icmp eq i32 %and, 0
124+
%icmp103 = icmp slt i32 %ashr101, 0
125+
%select = select i1 %icmp103, i32 0, i32 255
126+
%select104 = select i1 %icmp102, i32 %ashr101, i32 %select
127+
%trunc = trunc i32 %select104 to i8
128+
store i8 %trunc, ptr %phi, align 1, !tbaa !14
129+
%getelementptr105 = getelementptr inbounds nuw i8, ptr %phi, i32 1
130+
%sub106 = sub i32 %add99, %shl94
131+
%ashr107 = ashr i32 %sub106, 5
132+
%and108 = and i32 %sub106, 8192
133+
%icmp109 = icmp eq i32 %and108, 0
134+
%icmp110 = icmp slt i32 %ashr107, 0
135+
%select111 = select i1 %icmp110, i32 0, i32 255
136+
%select112 = select i1 %icmp109, i32 %ashr107, i32 %select111
137+
%trunc113 = trunc i32 %select112 to i8
138+
store i8 %trunc113, ptr %getelementptr105, align 1, !tbaa !14
139+
%getelementptr114 = getelementptr inbounds nuw i8, ptr %phi, i32 2
140+
%sub115 = sub i32 %add99, %ashr
141+
%ashr116 = ashr i32 %sub115, 5
142+
%and117 = and i32 %sub115, 8192
143+
%icmp118 = icmp eq i32 %and117, 0
144+
%icmp119 = icmp slt i32 %ashr116, 0
145+
%select120 = select i1 %icmp119, i32 0, i32 255
146+
%select121 = select i1 %icmp118, i32 %ashr116, i32 %select120
147+
%trunc122 = trunc i32 %select121 to i8
148+
store i8 %trunc122, ptr %getelementptr114, align 1, !tbaa !14
149+
%getelementptr123 = getelementptr inbounds nuw i8, ptr %phi, i32 3
150+
%ashr124 = ashr i32 %add99, 5
151+
%and125 = and i32 %add99, 8192
152+
%icmp126 = icmp eq i32 %and125, 0
153+
%icmp127 = icmp slt i32 %ashr124, 0
154+
%select128 = select i1 %icmp127, i32 0, i32 255
155+
%select129 = select i1 %icmp126, i32 %ashr124, i32 %select128
156+
%trunc130 = trunc i32 %select129 to i8
157+
store i8 %trunc130, ptr %getelementptr123, align 1, !tbaa !14
158+
%getelementptr131 = getelementptr inbounds nuw i8, ptr %phi, i32 4
159+
%add132 = add i32 %add99, %ashr
160+
%ashr133 = ashr i32 %add132, 5
161+
%and134 = and i32 %add132, 8192
162+
%icmp135 = icmp eq i32 %and134, 0
163+
%icmp136 = icmp slt i32 %ashr133, 0
164+
%select137 = select i1 %icmp136, i32 0, i32 255
165+
%select138 = select i1 %icmp135, i32 %ashr133, i32 %select137
166+
%trunc139 = trunc i32 %select138 to i8
167+
store i8 %trunc139, ptr %getelementptr131, align 1, !tbaa !14
168+
%getelementptr140 = getelementptr inbounds nuw i8, ptr %phi, i32 5
169+
%add141 = add i32 %add99, %shl91
170+
%ashr142 = ashr i32 %add141, 5
171+
%and143 = and i32 %add141, 8192
172+
%icmp144 = icmp eq i32 %and143, 0
173+
%icmp145 = icmp slt i32 %ashr142, 0
174+
%select146 = select i1 %icmp145, i32 0, i32 255
175+
%select147 = select i1 %icmp144, i32 %ashr142, i32 %select146
176+
%trunc148 = trunc i32 %select147 to i8
177+
store i8 %trunc148, ptr %getelementptr140, align 1, !tbaa !14
178+
%getelementptr149 = getelementptr inbounds nuw i8, ptr %phi, i32 6
179+
%add150 = add i32 %add99, %mul92
180+
%ashr151 = ashr i32 %add150, 5
181+
%and152 = and i32 %add150, 8192
182+
%icmp153 = icmp eq i32 %and152, 0
183+
%icmp154 = icmp slt i32 %ashr151, 0
184+
%select155 = select i1 %icmp154, i32 0, i32 255
185+
%select156 = select i1 %icmp153, i32 %ashr151, i32 %select155
186+
%trunc157 = trunc i32 %select156 to i8
187+
store i8 %trunc157, ptr %getelementptr149, align 1, !tbaa !14
188+
%getelementptr158 = getelementptr inbounds nuw i8, ptr %phi, i32 7
189+
%add159 = add i32 %add99, %shl93
190+
%ashr160 = ashr i32 %add159, 5
191+
%and161 = and i32 %add159, 8192
192+
%icmp162 = icmp eq i32 %and161, 0
193+
%icmp163 = icmp slt i32 %ashr160, 0
194+
%select164 = select i1 %icmp163, i32 0, i32 255
195+
%select165 = select i1 %icmp162, i32 %ashr160, i32 %select164
196+
%trunc166 = trunc i32 %select165 to i8
197+
store i8 %trunc166, ptr %getelementptr158, align 1, !tbaa !14
198+
%getelementptr167 = getelementptr inbounds nuw i8, ptr %phi, i32 8
199+
%add168 = add nuw nsw i32 %phi96, 1
200+
%icmp169 = icmp eq i32 %add168, 8
201+
br i1 %icmp169, label %bb170, label %bb95, !llvm.loop !15
202+
203+
bb170: ; preds = %bb95, %bb
204+
ret void
205+
}
206+
207+
attributes #0 = { nofree norecurse nosync nounwind memory(read, argmem: readwrite, inaccessiblemem: none) "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="hexagonv68" "target-features"="+v68,-long-calls" }
208+
209+
!llvm.module.flags = !{!0, !1}
210+
!llvm.ident = !{!2}
211+
212+
!0 = !{i32 1, !"wchar_size", i32 4}
213+
!1 = !{i32 7, !"frame-pointer", i32 2}
214+
!2 = !{!"QuIC LLVM Hexagon Clang version 8.9 Engineering Release: hexagon-clang-89"}
215+
!3 = !{!4, !6, i64 29}
216+
!4 = !{!"MB_STRUCT", !5, i64 0, !5, i64 4, !5, i64 8, !8, i64 12, !8, i64 16, !8, i64 20, !8, i64 24, !6, i64 28, !6, i64 29, !5, i64 32}
217+
!5 = !{!"any pointer", !6, i64 0}
218+
!6 = !{!"omnipotent char", !7, i64 0}
219+
!7 = !{!"Simple C/C++ TBAA"}
220+
!8 = !{!"int", !6, i64 0}
221+
!9 = !{!5, !5, i64 0}
222+
!10 = !{!4, !5, i64 4}
223+
!11 = !{!12, !8, i64 8}
224+
!12 = !{!"BLOCK_STRUCT_CHROM", !5, i64 0, !5, i64 4, !8, i64 8, !13, i64 12, !13, i64 14, !6, i64 16, !6, i64 17, !6, i64 18, !6, i64 19}
225+
!13 = !{!"short", !6, i64 0}
226+
!14 = !{!6, !6, i64 0}
227+
!15 = distinct !{!15, !16}
228+
!16 = !{!"llvm.loop.mustprogress"}

0 commit comments

Comments
 (0)