[llvm-branch-commits] [llvm] [SDAG][AMDGPU] Allow opting in to OOB-generating PTRADD transforms (PR #146074)
Fabian Ritter via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Aug 1 07:35:42 PDT 2025
================
@@ -2689,59 +2689,82 @@ SDValue DAGCombiner::visitPTRADD(SDNode *N) {
if (PtrVT == IntVT && isNullConstant(N0))
return N1;
- if (N0.getOpcode() != ISD::PTRADD ||
- reassociationCanBreakAddressingModePattern(ISD::PTRADD, DL, N, N0, N1))
- return SDValue();
-
- SDValue X = N0.getOperand(0);
- SDValue Y = N0.getOperand(1);
- SDValue Z = N1;
- bool N0OneUse = N0.hasOneUse();
- bool YIsConstant = DAG.isConstantIntBuildVectorOrConstantInt(Y);
- bool ZIsConstant = DAG.isConstantIntBuildVectorOrConstantInt(Z);
-
- // (ptradd (ptradd x, y), z) -> (ptradd x, (add y, z)) if:
- // * y is a constant and (ptradd x, y) has one use; or
- // * y and z are both constants.
- if ((YIsConstant && N0OneUse) || (YIsConstant && ZIsConstant)) {
- // If both additions in the original were NUW, the new ones are as well.
- SDNodeFlags Flags =
- (N->getFlags() & N0->getFlags()) & SDNodeFlags::NoUnsignedWrap;
- SDValue Add = DAG.getNode(ISD::ADD, DL, IntVT, {Y, Z}, Flags);
- AddToWorklist(Add.getNode());
- return DAG.getMemBasePlusOffset(X, Add, DL, Flags);
+ if (N0.getOpcode() == ISD::PTRADD &&
+ !reassociationCanBreakAddressingModePattern(ISD::PTRADD, DL, N, N0, N1)) {
+ SDValue X = N0.getOperand(0);
+ SDValue Y = N0.getOperand(1);
+ SDValue Z = N1;
+ bool N0OneUse = N0.hasOneUse();
+ bool YIsConstant = DAG.isConstantIntBuildVectorOrConstantInt(Y);
+ bool ZIsConstant = DAG.isConstantIntBuildVectorOrConstantInt(Z);
+
+ // (ptradd (ptradd x, y), z) -> (ptradd x, (add y, z)) if:
+ // * y is a constant and (ptradd x, y) has one use; or
+ // * y and z are both constants.
+ if ((YIsConstant && N0OneUse) || (YIsConstant && ZIsConstant)) {
+ // If both additions in the original were NUW, the new ones are as well.
+ SDNodeFlags Flags =
+ (N->getFlags() & N0->getFlags()) & SDNodeFlags::NoUnsignedWrap;
+ SDValue Add = DAG.getNode(ISD::ADD, DL, IntVT, {Y, Z}, Flags);
+ AddToWorklist(Add.getNode());
+ return DAG.getMemBasePlusOffset(X, Add, DL, Flags);
+ }
+ }
+
+ // The following combines can turn in-bounds pointer arithmetic out of bounds.
+ // That is problematic for settings like AArch64's CPA, which checks that
+ // intermediate results of pointer arithmetic remain in bounds. The target
+ // therefore needs to opt-in to enable them.
+ if (!TLI.canTransformPtrArithOutOfBounds(
+ DAG.getMachineFunction().getFunction(), PtrVT))
+ return SDValue();
+
+ if (N0.getOpcode() == ISD::PTRADD && N1.getOpcode() == ISD::Constant) {
----------------
ritter-x2a wrote:
I changed it to use `isa<ConstantSDNode>(N1)` for now and added a TODO to support vector splats. With the current state, I haven't found a way to get a splat constant as an offset for a global variable to test this situation:
The SelectionDAGBuilder automatically translates `(gep scalarptr, splat(C))` into `(splat (ptradd scalarptr, C))` and we currently don't generate PTRADDs for a GEP with a vector of pointers (`SITargetLowering::shouldPreservePtrArith` checks `PtrVT == MVT::i64`). I don't think we should implement support for vector splats without a way of testing it.
Also, `SelectionDAG::FoldSymbolOffset` needs to support vector splats so that it makes sense to support them here.
https://github.com/llvm/llvm-project/pull/146074
More information about the llvm-branch-commits
mailing list