That transformation is lossy, as discussed in https://github.com/llvm/llvm-project/issues/53853 and https://github.com/rust-lang/rust/issues/85133#issuecomment-904185574 This is an alternative to D119839, which would add a limited IPSCCP into SimplifyCFG. Unlike lowering switch to lookup, we still want this transformation to happen relatively early, but after giving a chance for the things like CVP to do their thing. It seems like deferring it just until the IPSCCP is enough for the tests at hand, but perhaps we need to be more aggressive and disable it until CVP. Fixes https://github.com/llvm/llvm-project/issues/53853 Refs. https://github.com/rust-lang/rust/issues/85133 Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D119854
138 lines
3.2 KiB
LLVM
138 lines
3.2 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -O1 -S < %s -enable-new-pm=0 | FileCheck %s
|
|
; RUN: opt -O2 -S < %s -enable-new-pm=0 | FileCheck %s
|
|
; RUN: opt -O3 -S < %s -enable-new-pm=0 | FileCheck %s
|
|
; RUN: opt -passes='default<O1>' -S < %s | FileCheck %s
|
|
; RUN: opt -passes='default<O2>' -S < %s | FileCheck %s
|
|
; RUN: opt -passes='default<O3>' -S < %s | FileCheck %s
|
|
|
|
; We are worse at propagating correlation facts when in select form
|
|
; as compared to the PHI form, so if we lower switches to early,
|
|
; we may make further optimizations problematic.
|
|
|
|
; propagate value to bb2.
|
|
define i64 @test1(i64 %x) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i64 0, i64 10
|
|
; CHECK-NEXT: ret i64 [[SWITCH_SELECT]]
|
|
;
|
|
entry:
|
|
switch i64 %x, label %bb3 [
|
|
i64 0, label %bb1
|
|
i64 1, label %bb2
|
|
]
|
|
bb1:
|
|
ret i64 0
|
|
bb2:
|
|
%0 = icmp eq i64 %x, 100
|
|
br i1 %0, label %bb4, label %bb5
|
|
bb3:
|
|
unreachable
|
|
bb4:
|
|
ret i64 200
|
|
bb5:
|
|
ret i64 10
|
|
}
|
|
|
|
; propagate value both to bb1 and bb2.
|
|
define i64 @test2(i64 %x) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i64 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i64 0, i64 10
|
|
; CHECK-NEXT: ret i64 [[SWITCH_SELECT]]
|
|
;
|
|
entry:
|
|
switch i64 %x, label %bb3 [
|
|
i64 1, label %bb1
|
|
i64 2, label %bb2
|
|
]
|
|
bb1:
|
|
%0 = icmp eq i64 %x, 100
|
|
br i1 %0, label %bb4, label %return
|
|
return:
|
|
ret i64 0
|
|
bb2:
|
|
%1 = icmp eq i64 %x, 101
|
|
br i1 %1, label %bb4, label %bb5
|
|
bb3:
|
|
unreachable
|
|
bb4:
|
|
ret i64 200
|
|
bb5:
|
|
ret i64 10
|
|
}
|
|
|
|
define i64 @test3(i64 %x) {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND]], i64 10, i64 0
|
|
; CHECK-NEXT: ret i64 [[SPEC_SELECT]]
|
|
;
|
|
entry:
|
|
switch i64 %x, label %bb1 [
|
|
i64 1, label %bb2
|
|
]
|
|
bb1:
|
|
ret i64 0
|
|
bb2:
|
|
%0 = icmp eq i64 %x, 100
|
|
br i1 %0, label %bb4, label %bb5
|
|
bb4:
|
|
ret i64 200
|
|
bb5:
|
|
ret i64 10
|
|
}
|
|
|
|
; bb2 has two predecessors with case value 1 and 2.
|
|
define i64 @test_fail1(i64 %x) {
|
|
; CHECK-LABEL: @test_fail1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[SWITCH:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i64 0, i64 10
|
|
; CHECK-NEXT: ret i64 [[SPEC_SELECT]]
|
|
;
|
|
entry:
|
|
switch i64 %x, label %bb3 [
|
|
i64 0, label %bb1
|
|
i64 1, label %bb2
|
|
i64 2, label %bb2
|
|
]
|
|
bb1:
|
|
ret i64 0
|
|
bb2:
|
|
%0 = icmp eq i64 %x, 100
|
|
br i1 %0, label %bb4, label %bb5
|
|
bb3:
|
|
unreachable
|
|
bb4:
|
|
ret i64 200
|
|
bb5:
|
|
ret i64 10
|
|
}
|
|
|
|
; return block has two predecessors.
|
|
define i64 @test_fail2(i64 %x) {
|
|
; CHECK-LABEL: @test_fail2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i64 2, i64 1
|
|
; CHECK-NEXT: ret i64 [[SWITCH_SELECT]]
|
|
;
|
|
entry:
|
|
switch i64 %x, label %bb2 [
|
|
i64 0, label %bb1
|
|
i64 1, label %return
|
|
]
|
|
bb1:
|
|
br label %return
|
|
return:
|
|
%retval.0 = phi i64 [ %x, %entry ], [ 2, %bb1 ]
|
|
ret i64 %retval.0
|
|
bb2:
|
|
unreachable
|
|
}
|