diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2024-10-09 13:51:52 +0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-09 13:51:52 +0400 |
| commit | ced15cd418d96fc3d078e687bdcc5875656c71f6 (patch) | |
| tree | feb6d5d063bbb32e54ec89e0c75d5d711e00be74 | |
| parent | 671cbcf6420a9dfc81754d8dc683619f6f396ed8 (diff) | |
DAG: Preserve more flags when expanding gep (#110815)
This allows selecting the addressing mode for stack instructions
in cases where we need to prove the sign bit is zero.
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 32 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/Sparc/pointer-add-unknown-offset-debug-info.ll | 2 |
2 files changed, 25 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 25213f587116..a981e9cc7928 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4386,6 +4386,15 @@ 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( @@ -4393,27 +4402,34 @@ void SelectionDAGBuilder::visitGetElementPtr(const User &I) { 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); } } diff --git a/llvm/test/DebugInfo/Sparc/pointer-add-unknown-offset-debug-info.ll b/llvm/test/DebugInfo/Sparc/pointer-add-unknown-offset-debug-info.ll index 63d7391bd7d4..5fe5a90a9731 100644 --- a/llvm/test/DebugInfo/Sparc/pointer-add-unknown-offset-debug-info.ll +++ b/llvm/test/DebugInfo/Sparc/pointer-add-unknown-offset-debug-info.ll @@ -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 ; 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 |
