[llvm] [SCEV] Handle all PtrtoIntExpr construction in CastSinkingRewriter (NFC) (PR #174435)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 12 03:51:56 PST 2026
================
@@ -1007,26 +1007,73 @@ SCEVAddRecExpr::evaluateAtIteration(ArrayRef<const SCEV *> Operands,
// SCEV Expression folder implementations
//===----------------------------------------------------------------------===//
-const SCEV *ScalarEvolution::getLosslessPtrToIntExpr(const SCEV *Op,
- unsigned Depth) {
- assert(Depth <= 1 &&
- "getLosslessPtrToIntExpr() should self-recurse at most once.");
+/// The SCEVCastSinkingRewriter takes a scalar evolution expression,
+/// which computes a pointer-typed value, and rewrites the whole expression
+/// tree so that *all* the computations are done on integers, and the only
+/// pointer-typed operands in the expression are SCEVUnknown.
+/// The CreatePtrCast callback is invoked to create the actual conversion
+/// (ptrtoint or ptrtoaddr) at the SCEVUnknown leaves.
+class SCEVCastSinkingRewriter
+ : public SCEVRewriteVisitor<SCEVCastSinkingRewriter> {
+ using Base = SCEVRewriteVisitor<SCEVCastSinkingRewriter>;
+ using ConversionFn = std::function<const SCEV *(const SCEVUnknown *)>;
+ Type *TargetTy;
+ ConversionFn CreatePtrCast;
- // We could be called with an integer-typed operands during SCEV rewrites.
- // Since the operand is an integer already, just perform zext/trunc/self cast.
- if (!Op->getType()->isPointerTy())
- return Op;
+public:
+ SCEVCastSinkingRewriter(ScalarEvolution &SE, Type *TargetTy,
+ ConversionFn CreatePtrCast)
+ : Base(SE), TargetTy(TargetTy), CreatePtrCast(std::move(CreatePtrCast)) {}
- // What would be an ID for such a SCEV cast expression?
- FoldingSetNodeID ID;
- ID.AddInteger(scPtrToInt);
- ID.AddPointer(Op);
+ static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
+ Type *TargetTy, ConversionFn CreatePtrCast) {
+ SCEVCastSinkingRewriter Rewriter(SE, TargetTy, std::move(CreatePtrCast));
+ return Rewriter.visit(Scev);
+ }
- void *IP = nullptr;
+ const SCEV *visit(const SCEV *S) {
+ Type *STy = S->getType();
+ // If the expression is not pointer-typed, just keep it as-is.
+ if (!STy->isPointerTy())
+ return S;
+ // Else, recursively sink the cast down into it.
+ return Base::visit(S);
+ }
- // Is there already an expression for such a cast?
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
- return S;
+ const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ bool Changed = false;
+ for (const auto *Op : Expr->operands()) {
+ Operands.push_back(visit(Op));
+ Changed |= Op != Operands.back();
+ }
+ return !Changed ? Expr : SE.getAddExpr(Operands, Expr->getNoWrapFlags());
+ }
+
+ const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
----------------
fhahn wrote:
will check and drop separately
https://github.com/llvm/llvm-project/pull/174435
More information about the llvm-commits
mailing list