Fei Peng f803e463f9
Reland "Redesign Straight-Line Strength Reduction (SLSR) (#162930)" (#169614)
This PR implements parts of
https://github.com/llvm/llvm-project/issues/162376

- **Broader equivalence than constant index deltas**:
- Add Base-delta and Stride-delta matching for Add and GEP forms using
ScalarEvolution deltas.
- Reuse enabled for both constant and variable deltas when an available
IR value dominates the user.
- **Dominance-aware dictionary instead of linear scans**:
  - Tuple-keyed candidate dictionary grouped by basic block.
- Walk the immediate-dominator chain to find the nearest dominating
basis quickly and deterministically.
- **Simple cost model and best-rewrite selection**:
- Score candidate expressions and rewrites; select the highest-profit
rewrite per instruction.
- Skip rewriting when expressions are already foldable or
high-efficiency.
- **Path compression for better ILP**:
- Compress chains of rewrites to a deeper dominating basis when a
constant delta exists along the path, reducing dependent bumps on
critical paths.
- **Dependency-aware rewrite ordering**:
- Build a dependency graph (basis, stride, variable delta producers) and
rewrite in topological order.
- This dependency graph will be needed by the next PR that adds partial
strength reduction.
- **Correctness enhencment**
- Fix a correctness issue that reusing instructions with the same SCEV
may introduce poison.

---------

Co-authored-by: Kazu Hirata <kazu@google.com>
2025-12-08 16:07:27 -06:00

33 lines
785 B
LLVM

; RUN: opt < %s -passes="slsr" -S | FileCheck %s
target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
%struct.B = type { i16 }
%struct.A = type { %struct.B, %struct.B }
define i32 @pick(i32 %0, ptr %addr) {
; `d` can be optimized by 2 approaches
; 1. a = 1 + 1 * %0
; d = 1 + 8 * %0
; = a + 7 * %0
; 2. c = (8 * %0) + 3
; d = (8 * %0) + 1
; = c - 2
; Pick candidate (2) as it can save 1 instruction from (7 * %0)
;
; CHECK-LABEL: pick
; CHECK: [[A:%.*]] = add i32 %0, 1
; CHECK: [[B:%.*]] = shl i32 %0, 3
; CHECK: [[C:%.*]] = add i32 [[B]], 3
; CHECK: store i32 [[C]], ptr %addr
; CHECK: [[D:%.*]] = add i32 [[C]], -2
; CHECK: ret i32 %d
%a = add i32 %0, 1
%b = shl i32 %0, 3
%c = add i32 %b, 3
store i32 %c, ptr %addr
%d = add i32 %b, 1
ret i32 %d
}