aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorPhilip Reames <preames@rivosinc.com>2024-06-19 08:40:04 -0700
committerGitHub <noreply@github.com>2024-06-19 08:40:04 -0700
commitcb76896d6e45e2c9b7ef5e47b6ec37aeca43f7a8 (patch)
tree8ab6670e0c45fa701ba92b8fa58aeea3c0829288 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parent1003f5b93e0ab0518e285b861573181942e41930 (diff)
downloadllvm-cb76896d6e45e2c9b7ef5e47b6ec37aeca43f7a8.zip
llvm-cb76896d6e45e2c9b7ef5e47b6ec37aeca43f7a8.tar.gz
llvm-cb76896d6e45e2c9b7ef5e47b6ec37aeca43f7a8.tar.bz2
[SCEVExpander] Recognize urem idiom during expansion (#96005)
If we have a urem expression, emitting it as a urem is significantly better that letting the fully expansion kick in. We have the risk of a udiv or mul which could have previously been shared, but loosing that seems like a reasonable tradeoff for being able to round trip a urem w/o modification.
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index c437a44..c7d758a 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -491,6 +491,16 @@ public:
}
Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
+ // Recognize the canonical representation of an unsimplifed urem.
+ const SCEV *URemLHS = nullptr;
+ const SCEV *URemRHS = nullptr;
+ if (SE.matchURem(S, URemLHS, URemRHS)) {
+ Value *LHS = expand(URemLHS);
+ Value *RHS = expand(URemRHS);
+ return InsertBinop(Instruction::URem, LHS, RHS, SCEV::FlagAnyWrap,
+ /*IsSafeToHoist*/ false);
+ }
+
// Collect all the add operands in a loop, along with their associated loops.
// Iterate in reverse so that constants are emitted last, all else equal, and
// so that pointer operands are inserted first, which the code below relies on