[llvm] [SCEV] Commute sign extends through nsw multiplication (PR #163840)
Alireza Torabian via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 16 11:26:38 PDT 2025
https://github.com/1997alireza created https://github.com/llvm/llvm-project/pull/163840
When NSW flag is present, SCEV simplifies sext((A * B * ...)<nsw>) to (sext(A) * sext(B) * ...)<nsw>.
>From bad74244a055ccda65e39e63f90d689dd0c6d3f4 Mon Sep 17 00:00:00 2001
From: a00917109 <alireza.torabian at huawei.com>
Date: Thu, 16 Oct 2025 14:20:55 -0400
Subject: [PATCH] [SCEV] Commute sign extends through nsw multiplication
When NSW flag is present, SCEV simplifies sext((A * B * ...)<nsw>) to
(sext(A) * sext(B) * ...)<nsw>.
---
llvm/lib/Analysis/ScalarEvolution.cpp | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index a64b93d541943..bf7c214a78954 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -1988,6 +1988,20 @@ const SCEV *ScalarEvolution::getSignExtendExprImpl(const SCEV *Op, Type *Ty,
}
}
}
+
+ if (auto *SA = dyn_cast<SCEVMulExpr>(Op)) {
+ // sext((A * B * ...)<nsw>) --> (sext(A) * sext(B) * ...)<nsw>
+ if (SA->hasNoSignedWrap()) {
+ // If the multiplication does not sign overflow then we can, by
+ // definition, commute the sign extension with the multiplication
+ // operation.
+ SmallVector<const SCEV *, 4> Ops;
+ for (const auto *Op : SA->operands())
+ Ops.push_back(getSignExtendExpr(Op, Ty, Depth + 1));
+ return getMulExpr(Ops, SCEV::FlagNSW, Depth + 1);
+ }
+ }
+
// If the input value is a chrec scev, and we can prove that the value
// did not overflow the old, smaller, value, we can sign extend all of the
// operands (often constants). This allows analysis of something like
More information about the llvm-commits
mailing list