Skip to content

Commit 56474da

Browse files
committed
DAG: Preserve more flags when expanding gep
This allows selecting the addressing mode for stack instructions in cases where we need to prove the sign bit is zero.
1 parent 95b7c37 commit 56474da

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4386,34 +4386,59 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
43864386
// it.
43874387
IdxN = DAG.getSExtOrTrunc(IdxN, dl, N.getValueType());
43884388

4389+
SDNodeFlags ScaleFlags;
4390+
// The multiplication of an index by the type size does not wrap the
4391+
// pointer index type in a signed sense (mul nsw).
4392+
if (NW.hasNoUnsignedSignedWrap())
4393+
ScaleFlags.setNoSignedWrap(true);
4394+
4395+
// The multiplication of an index by the type size does not wrap the
4396+
// pointer index type in an unsigned sense (mul nuw).
4397+
if (NW.hasNoUnsignedWrap())
4398+
ScaleFlags.setNoUnsignedWrap(true);
4399+
43894400
if (ElementScalable) {
43904401
EVT VScaleTy = N.getValueType().getScalarType();
43914402
SDValue VScale = DAG.getNode(
43924403
ISD::VSCALE, dl, VScaleTy,
43934404
DAG.getConstant(ElementMul.getZExtValue(), dl, VScaleTy));
43944405
if (IsVectorGEP)
43954406
VScale = DAG.getSplatVector(N.getValueType(), dl, VScale);
4396-
IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale);
4407+
IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale,
4408+
ScaleFlags);
43974409
} else {
43984410
// If this is a multiply by a power of two, turn it into a shl
43994411
// immediately. This is a very common case.
44004412
if (ElementMul != 1) {
44014413
if (ElementMul.isPowerOf2()) {
44024414
unsigned Amt = ElementMul.logBase2();
4403-
IdxN = DAG.getNode(ISD::SHL, dl,
4404-
N.getValueType(), IdxN,
4405-
DAG.getConstant(Amt, dl, IdxN.getValueType()));
4415+
IdxN = DAG.getNode(ISD::SHL, dl, N.getValueType(), IdxN,
4416+
DAG.getConstant(Amt, dl, IdxN.getValueType()),
4417+
ScaleFlags);
44064418
} else {
44074419
SDValue Scale = DAG.getConstant(ElementMul.getZExtValue(), dl,
44084420
IdxN.getValueType());
4409-
IdxN = DAG.getNode(ISD::MUL, dl,
4410-
N.getValueType(), IdxN, Scale);
4421+
IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, Scale,
4422+
ScaleFlags);
44114423
}
44124424
}
44134425
}
44144426

4415-
N = DAG.getNode(ISD::ADD, dl,
4416-
N.getValueType(), N, IdxN);
4427+
SDNodeFlags AddFlags;
4428+
4429+
// The successive addition of each offset (without adding the base
4430+
// address) does not wrap the pointer index type in a signed sense (add
4431+
// nsw).
4432+
if (NW.hasNoUnsignedSignedWrap())
4433+
AddFlags.setNoSignedWrap(true);
4434+
4435+
// The successive addition of each offset (without adding the base
4436+
// address) does not wrap the pointer index type in an unsigned sense (add
4437+
// nuw).
4438+
if (NW.hasNoUnsignedWrap())
4439+
AddFlags.setNoUnsignedWrap(true);
4440+
4441+
N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, IdxN, AddFlags);
44174442
}
44184443
}
44194444

llvm/test/CodeGen/AMDGPU/gep-flags-stack-offsets.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@ define void @gep_inbounds_nuw_alloca(i32 %idx, i32 %val) #0 {
118118
; GFX8-NEXT: v_lshlrev_b32_e32 v0, 2, v0
119119
; GFX8-NEXT: v_lshrrev_b32_e64 v2, 6, s32
120120
; GFX8-NEXT: v_add_u32_e32 v0, vcc, v2, v0
121-
; GFX8-NEXT: v_add_u32_e32 v0, vcc, 16, v0
122-
; GFX8-NEXT: buffer_store_dword v1, v0, s[0:3], 0 offen
121+
; GFX8-NEXT: buffer_store_dword v1, v0, s[0:3], 0 offen offset:16
123122
; GFX8-NEXT: s_waitcnt vmcnt(0)
124123
; GFX8-NEXT: s_setpc_b64 s[30:31]
125124
;
@@ -145,8 +144,7 @@ define void @gep_nusw_nuw_alloca(i32 %idx, i32 %val) #0 {
145144
; GFX8-NEXT: v_lshlrev_b32_e32 v0, 2, v0
146145
; GFX8-NEXT: v_lshrrev_b32_e64 v2, 6, s32
147146
; GFX8-NEXT: v_add_u32_e32 v0, vcc, v2, v0
148-
; GFX8-NEXT: v_add_u32_e32 v0, vcc, 16, v0
149-
; GFX8-NEXT: buffer_store_dword v1, v0, s[0:3], 0 offen
147+
; GFX8-NEXT: buffer_store_dword v1, v0, s[0:3], 0 offen offset:16
150148
; GFX8-NEXT: s_waitcnt vmcnt(0)
151149
; GFX8-NEXT: s_setpc_b64 s[30:31]
152150
;

llvm/test/DebugInfo/Sparc/pointer-add-unknown-offset-debug-info.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ define void @pointer_add_unknown_offset(ptr %base, i32 %offset) !dbg !7 {
1212
; CHECK-NEXT: [[COPY:%[0-9]+]]:i64regs = COPY $i1
1313
; CHECK-NEXT: [[COPY1:%[0-9]+]]:i64regs = COPY $i0
1414
; CHECK-NEXT: [[SRAri:%[0-9]+]]:i64regs = SRAri [[COPY]], 0
15-
; CHECK-NEXT: [[SLLXri:%[0-9]+]]:i64regs = SLLXri killed [[SRAri]], 2
15+
; CHECK-NEXT: [[SLLXri:%[0-9]+]]:i64regs = nsw SLLXri killed [[SRAri]], 2
1616
; CHECK-NEXT: DBG_VALUE_LIST !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), [[COPY1]], [[SLLXri]], debug-location !16
1717
; CHECK-NEXT: DBG_VALUE_LIST !14, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_plus_uconst, 3, DW_OP_stack_value), [[COPY1]], [[SLLXri]], debug-location !16
1818
; CHECK-NEXT: DBG_VALUE_LIST !15, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 2, DW_OP_plus, DW_OP_LLVM_arg, 1, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_plus, DW_OP_stack_value), [[COPY1]], [[COPY1]], [[SLLXri]], [[SLLXri]], debug-location !16

0 commit comments

Comments
 (0)