Skip to content

DAG: Preserve more flags when expanding gep #110815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4386,34 +4386,50 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) {
// it.
IdxN = DAG.getSExtOrTrunc(IdxN, dl, N.getValueType());

SDNodeFlags ScaleFlags;
// The multiplication of an index by the type size does not wrap the
// pointer index type in a signed sense (mul nsw).
ScaleFlags.setNoSignedWrap(NW.hasNoUnsignedSignedWrap());

// The multiplication of an index by the type size does not wrap the
// pointer index type in an unsigned sense (mul nuw).
ScaleFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());

if (ElementScalable) {
EVT VScaleTy = N.getValueType().getScalarType();
SDValue VScale = DAG.getNode(
ISD::VSCALE, dl, VScaleTy,
DAG.getConstant(ElementMul.getZExtValue(), dl, VScaleTy));
if (IsVectorGEP)
VScale = DAG.getSplatVector(N.getValueType(), dl, VScale);
IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale);
IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, VScale,
ScaleFlags);
} else {
// If this is a multiply by a power of two, turn it into a shl
// immediately. This is a very common case.
if (ElementMul != 1) {
if (ElementMul.isPowerOf2()) {
unsigned Amt = ElementMul.logBase2();
IdxN = DAG.getNode(ISD::SHL, dl,
N.getValueType(), IdxN,
DAG.getConstant(Amt, dl, IdxN.getValueType()));
IdxN = DAG.getNode(ISD::SHL, dl, N.getValueType(), IdxN,
DAG.getConstant(Amt, dl, IdxN.getValueType()),
ScaleFlags);
} else {
SDValue Scale = DAG.getConstant(ElementMul.getZExtValue(), dl,
IdxN.getValueType());
IdxN = DAG.getNode(ISD::MUL, dl,
N.getValueType(), IdxN, Scale);
IdxN = DAG.getNode(ISD::MUL, dl, N.getValueType(), IdxN, Scale,
ScaleFlags);
}
}
}

N = DAG.getNode(ISD::ADD, dl,
N.getValueType(), N, IdxN);
// The successive addition of the current address, truncated to the
// pointer index type and interpreted as an unsigned number, and each
// offset, also interpreted as an unsigned number, does not wrap the
// pointer index type (add nuw).
SDNodeFlags AddFlags;
AddFlags.setNoUnsignedWrap(NW.hasNoUnsignedWrap());

N = DAG.getNode(ISD::ADD, dl, N.getValueType(), N, IdxN, AddFlags);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ define void @pointer_add_unknown_offset(ptr %base, i32 %offset) !dbg !7 {
; CHECK-NEXT: [[COPY:%[0-9]+]]:i64regs = COPY $i1
; CHECK-NEXT: [[COPY1:%[0-9]+]]:i64regs = COPY $i0
; CHECK-NEXT: [[SRAri:%[0-9]+]]:i64regs = SRAri [[COPY]], 0
; CHECK-NEXT: [[SLLXri:%[0-9]+]]:i64regs = SLLXri killed [[SRAri]], 2
; CHECK-NEXT: [[SLLXri:%[0-9]+]]:i64regs = nsw SLLXri killed [[SRAri]], 2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arsenm - is the change in this PR supposed to be specific to this target?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. It just introduces the flags, which may or may not survive to the end of the target's selection

Copy link
Member

@fpetrogalli fpetrogalli Oct 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please come up with a regression test for another Target, say for example AArch64?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test change is incidental, this test was not the point. The real tests are supposed to be from 671cbcf (but in the final version of the patch, the codegen changes no longer manifest)

; 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
; 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
; 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
Expand Down
Loading