Nikita Popov 4ab87ffd1e
[SCCP] Enable PredicateInfo for non-interprocedural SCCP (#153003)
SCCP can use PredicateInfo to constrain ranges based on assume and
branch conditions. Currently, this is only enabled during IPSCCP.

This enables it for SCCP as well, which runs after functions have
already been simplified, while IPSCCP runs pre-inline. To a large
degree, CVP already handles range-based optimizations, but SCCP is more
reliable for the cases it can handle. In particular, SCCP works reliably
inside loops, which is something that CVP struggles with due to LVI
cycles.

I have made various optimizations to make PredicateInfo more efficient,
but unfortunately this still has significant compile-time cost (around
0.1-0.2%).
2025-08-19 10:59:38 +02:00

75 lines
2.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=sccp -S | FileCheck %s
; This is a basic correctness check for constant propagation. The add
; instruction should be eliminated.
define i32 @test1(i1 %B) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: BB1:
; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: BB2:
; CHECK-NEXT: br label [[BB3]]
; CHECK: BB3:
; CHECK-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BB1]] ], [ 1, [[BB2]] ]
; CHECK-NEXT: ret i32 [[RET]]
;
br i1 %B, label %BB1, label %BB2
BB1: ; preds = %0
%Val = add i32 0, 0 ; <i32> [#uses=1]
br label %BB3
BB2: ; preds = %0
br label %BB3
BB3: ; preds = %BB2, %BB1
%Ret = phi i32 [ %Val, %BB1 ], [ 1, %BB2 ] ; <i32> [#uses=1]
ret i32 %Ret
}
; This is the test case taken from appel's book that illustrates a hard case
; that SCCP gets right.
;
define i32 @test2(i32 %i0, i32 %j0) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: BB1:
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: BB2:
; CHECK-NEXT: [[K2:%.*]] = phi i32 [ [[K3:%.*]], [[BB7:%.*]] ], [ 0, [[BB1:%.*]] ]
; CHECK-NEXT: [[KCOND:%.*]] = icmp slt i32 [[K2]], 100
; CHECK-NEXT: br i1 [[KCOND]], label [[BB3:%.*]], label [[BB4:%.*]]
; CHECK: BB3:
; CHECK-NEXT: br label [[BB5:%.*]]
; CHECK: BB4:
; CHECK-NEXT: ret i32 1
; CHECK: BB5:
; CHECK-NEXT: [[K3]] = add nsw i32 [[K2]], 1
; CHECK-NEXT: br label [[BB7]]
; CHECK: BB7:
; CHECK-NEXT: br label [[BB2]]
;
BB1:
br label %BB2
BB2:
%j2 = phi i32 [ %j4, %BB7 ], [ 1, %BB1 ]
%k2 = phi i32 [ %k4, %BB7 ], [ 0, %BB1 ]
%kcond = icmp slt i32 %k2, 100
br i1 %kcond, label %BB3, label %BB4
BB3:
%jcond = icmp slt i32 %j2, 20
br i1 %jcond, label %BB5, label %BB6
BB4:
ret i32 %j2
BB5:
%k3 = add i32 %k2, 1
br label %BB7
BB6:
%k5 = add i32 %k2, 1
br label %BB7
BB7:
%j4 = phi i32 [ 1, %BB5 ], [ %k2, %BB6 ]
%k4 = phi i32 [ %k3, %BB5 ], [ %k5, %BB6 ]
br label %BB2
}