[SCEV] Preserve divisibility and min/max information in applyLoopGuards
authorAlon Kom <alon.kom@mobileye.com>
Tue, 31 Jan 2023 08:21:53 +0000 (10:21 +0200)
committerkomalon1 <alon.kom@mobileye.com>
Mon, 20 Mar 2023 10:04:05 +0000 (12:04 +0200)
commit8e5aa969d0e9960bfc3d4e14144899076895e1b4
tree43078163cb13195be9c163e2f3dbae6990bc0c59
parent682808d9c9c81306c0a08a1fdb496b4f572566b4
[SCEV] Preserve divisibility and min/max information in applyLoopGuards

applyLoopGuards doesn't always preserve information when there are multiple assumes.

This patch tries to deal with multiple assumes regarding a SCEV's divisibility and min/max values, and rewrite it into a SCEV that still preserves all of the information.
For example, let the trip count of the loop be TC. Consider the 3 following assumes:

1. __builtin_assume(TC % 8 == 0);
2. __builtin_assume(TC > 0);
3. __builtin_assume(TC < 100);

Before this patch, depending on the assume processing order applyLoopGuards could create the following SCEV:
max(min((8 * (TC / 8)) , 99), 1)

Looking at this SCEV, it doesn't preserve the divisibility by 8 information.

After this patch, depending on the assume processing order applyLoopGuards could create the following SCEV:
max(min((8 * (TC / 8)) , 96), 8)

By aligning up 1 to 8, and aligning down 99 to 96, the new SCEV still preserves all of the original assumes.

Differential Revision: https://reviews.llvm.org/D144947
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/trip-multiple-guard-info.ll
llvm/unittests/Analysis/ScalarEvolutionTest.cpp