Skip to content

Commit 0564d06

Browse files
committed
[SDAG] Transfer gep nusw/nuw to SDAG
The resulting add is nuw if either the gep was nuw or it was nusw+nneg. Previously only inbounds+nneg was handled. Test via wasm load offsets, which seems to most directly expose these SDAG flags.
1 parent 89db3bb commit 0564d06

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4287,6 +4287,7 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
42874287
SDValue N = getValue(Op0);
42884288
SDLoc dl = getCurSDLoc();
42894289
auto &TLI = DAG.getTargetLoweringInfo();
4290+
GEPNoWrapFlags NW = cast<GEPOperator>(I).getNoWrapFlags();
42904291

42914292
// Normalize Vector GEP - all scalar operands should be converted to the
42924293
// splat vector.
@@ -4314,7 +4315,8 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43144315
// In an inbounds GEP with an offset that is nonnegative even when
43154316
// interpreted as signed, assume there is no unsigned overflow.
43164317
SDNodeFlags Flags;
4317-
if (int64_t(Offset) >= 0 && cast<GEPOperator>(I).isInBounds())
4318+
if (NW.hasNoUnsignedWrap() ||
4319+
(int64_t(Offset) >= 0 && NW.hasNoUnsignedSignedWrap()))
43184320
Flags.setNoUnsignedWrap(true);
43194321

43204322
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N,
@@ -4355,7 +4357,8 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43554357
// In an inbounds GEP with an offset that is nonnegative even when
43564358
// interpreted as signed, assume there is no unsigned overflow.
43574359
SDNodeFlags Flags;
4358-
if (Offs.isNonNegative() && cast<GEPOperator>(I).isInBounds())
4360+
if (NW.hasNoUnsignedWrap() ||
4361+
(Offs.isNonNegative() && NW.hasNoUnsignedSignedWrap()))
43594362
Flags.setNoUnsignedWrap(true);
43604363

43614364
OffsVal = DAG.getSExtOrTrunc(OffsVal, dl, N.getValueType());

llvm/test/CodeGen/WebAssembly/offset.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,26 @@ define i32 @load_i32_with_folded_gep_offset(ptr %p) {
4040
ret i32 %t
4141
}
4242

43+
; Same for nusw.
44+
45+
; CHECK-LABEL: load_i32_with_folded_gep_offset_nusw:
46+
; CHECK: i32.load $push0=, 24($0){{$}}
47+
define i32 @load_i32_with_folded_gep_offset_nusw(ptr %p) {
48+
%s = getelementptr nusw i32, ptr %p, i32 6
49+
%t = load i32, ptr %s
50+
ret i32 %t
51+
}
52+
53+
; For nuw we don't need the offset to be positive.
54+
55+
; CHECK-LABEL: load_i32_with_folded_gep_offset_nuw:
56+
; CHECK: i32.load $push0=, -24($0){{$}}
57+
define i32 @load_i32_with_folded_gep_offset_nuw(ptr %p) {
58+
%s = getelementptr nuw i32, ptr %p, i32 -6
59+
%t = load i32, ptr %s
60+
ret i32 %t
61+
}
62+
4363
; We can't fold a negative offset though, even with an inbounds gep.
4464

4565
; CHECK-LABEL: load_i32_with_unfolded_gep_negative_offset:

0 commit comments

Comments
 (0)