Currently, we only remove dead blocks and non-feasible edges in IPSCCP, but not in SCCP. I'm not aware of any strong reason for that difference, so this patch updates SCCP to perform the CFG cleanup as well. Compile-time impact seems to be pretty minimal, in the 0.05% geomean range on CTMark. For the test case from https://reviews.llvm.org/D126962#3611579 the result after -sccp now looks like this: define void @test(i1 %c) { entry: br i1 %c, label %unreachable, label %next next: unreachable unreachable: call void @bar() unreachable } -jump-threading does nothing on this, but -simplifycfg will produce the optimal result. Differential Revision: https://reviews.llvm.org/D128796
75 lines
2.0 KiB
LLVM
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 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
|
|
}
|
|
|