================ @@ -2602,6 +2605,100 @@ SDValue DAGCombiner::foldSubToAvg(SDNode *N, const SDLoc &DL) { return SDValue(); } +/// Try to fold a pointer arithmetic node. +/// This needs to be done separately from normal addition, because pointer +/// addition is not commutative. +/// This function was adapted from DAGCombiner::visitPTRADD() from the Morello +/// project, which is based on CHERI. +SDValue DAGCombiner::visitPTRADD(SDNode *N) { + SDValue N0 = N->getOperand(0); + SDValue N1 = N->getOperand(1); + EVT PtrVT = N0.getValueType(); + EVT IntVT = N1.getValueType(); + SDLoc DL(N); + + // fold (ptradd undef, y) -> undef + if (N0.isUndef()) + return N0; + + // fold (ptradd x, undef) -> undef + if (N1.isUndef()) + return DAG.getUNDEF(PtrVT); + + // fold (ptradd x, 0) -> x + if (isNullConstant(N1)) + return N0; + + 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); + bool ZOneUse = Z.hasOneUse(); + + // (ptradd (ptradd x, y), z) -> (ptradd x, (add y, z)) if: + // * x is a null pointer; or + // * y is a constant and z has one use; or + // * y is a constant and (ptradd x, y) has one use; or + // * (ptradd x, y) and z have one use and z is not a constant. + if (isNullConstant(X) || (YIsConstant && ZOneUse) || + (YIsConstant && N0OneUse) || (N0OneUse && ZOneUse && !ZIsConstant)) { + SDValue Add = DAG.getNode(ISD::ADD, DL, IntVT, {Y, Z}); + + // Calling visit() can replace the Add node with ISD::DELETED_NODE if + // there aren't any users, so keep a handle around whilst we visit it. + HandleSDNode ADDHandle(Add); + + SDValue VisitedAdd = visit(Add.getNode()); + if (VisitedAdd) { + // If visit() returns the same node, it means the SDNode was RAUW'd, and + // therefore we have to load the new value to perform the checks whether + // the reassociation fold is profitable. + if (VisitedAdd.getNode() == Add.getNode()) + Add = ADDHandle.getValue(); + else + Add = VisitedAdd; + } ---------------- arichardson wrote:
That's a good question - I believe that code might be my fault. It just seemed like the easiest way to avoid the assertion we were seeing before. I *believe* adding the Add to the worklist should result in the same end result with less code complexity. https://github.com/llvm/llvm-project/pull/105669 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits