2011-03-15 10:23:35 +08:00
|
|
|
; RUN: opt < %s -simplifycfg -S | FileCheck %s
|
2004-10-18 12:06:41 +08:00
|
|
|
|
2008-03-18 11:45:45 +08:00
|
|
|
define void @test1(i1 %C, i1* %BP) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test1(
|
2011-03-15 10:23:35 +08:00
|
|
|
; CHECK: entry:
|
|
|
|
; CHECK-NEXT: ret void
|
|
|
|
entry:
|
2008-03-18 11:45:45 +08:00
|
|
|
br i1 %C, label %T, label %F
|
2011-03-15 10:23:35 +08:00
|
|
|
T:
|
2008-03-18 11:45:45 +08:00
|
|
|
store i1 %C, i1* %BP
|
|
|
|
unreachable
|
2011-03-15 10:23:35 +08:00
|
|
|
F:
|
2008-03-18 11:45:45 +08:00
|
|
|
ret void
|
2004-10-18 12:06:41 +08:00
|
|
|
}
|
|
|
|
|
2008-03-18 11:45:45 +08:00
|
|
|
define void @test2() {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test2(
|
2011-03-15 10:23:35 +08:00
|
|
|
; CHECK: entry:
|
|
|
|
; CHECK-NEXT: call void @test2()
|
|
|
|
; CHECK-NEXT: ret void
|
|
|
|
entry:
|
2008-03-18 11:45:45 +08:00
|
|
|
invoke void @test2( )
|
|
|
|
to label %N unwind label %U
|
2011-03-15 10:23:35 +08:00
|
|
|
U:
|
2008-03-18 11:45:45 +08:00
|
|
|
unreachable
|
2011-03-15 10:23:35 +08:00
|
|
|
N:
|
2008-03-18 11:45:45 +08:00
|
|
|
ret void
|
2004-10-18 12:06:41 +08:00
|
|
|
}
|
|
|
|
|
2008-03-18 11:45:45 +08:00
|
|
|
define i32 @test3(i32 %v) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test3(
|
2011-03-15 10:23:35 +08:00
|
|
|
; CHECK: entry:
|
|
|
|
; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2
|
|
|
|
; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1
|
|
|
|
; CHECK-NEXT: ret
|
|
|
|
entry:
|
2008-03-18 11:45:45 +08:00
|
|
|
switch i32 %v, label %default [
|
|
|
|
i32 1, label %U
|
|
|
|
i32 2, label %T
|
|
|
|
]
|
2011-03-15 10:23:35 +08:00
|
|
|
default:
|
2008-03-18 11:45:45 +08:00
|
|
|
ret i32 1
|
2011-03-15 10:23:35 +08:00
|
|
|
U:
|
2008-03-18 11:45:45 +08:00
|
|
|
unreachable
|
2011-03-15 10:23:35 +08:00
|
|
|
T:
|
2008-03-18 11:45:45 +08:00
|
|
|
ret i32 2
|
2004-10-18 12:06:41 +08:00
|
|
|
}
|
2008-03-18 11:45:45 +08:00
|
|
|
|
SimplifyCFG: Don't convert phis into selects if we could remove undef behavior
instead
We used to transform this:
define void @test6(i1 %cond, i8* %ptr) {
entry:
br i1 %cond, label %bb1, label %bb2
bb1:
br label %bb2
bb2:
%ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
store i8 2, i8* %ptr.2, align 8
ret void
}
into this:
define void @test6(i1 %cond, i8* %ptr) {
%ptr.2 = select i1 %cond, i8* null, i8* %ptr
store i8 2, i8* %ptr.2, align 8
ret void
}
because the simplifycfg transformation into selects would happen to happen
before the simplifycfg transformation that removes unreachable control flow
(We have 'unreachable control flow' due to the store to null which is undefined
behavior).
The existing transformation that removes unreachable control flow in simplifycfg
is:
/// If BB has an incoming value that will always trigger undefined behavior
/// (eg. null pointer dereference), remove the branch leading here.
static bool removeUndefIntroducingPredecessor(BasicBlock *BB)
Now we generate:
define void @test6(i1 %cond, i8* %ptr) {
store i8 2, i8* %ptr.2, align 8
ret void
}
I did not see any impact on the test-suite + externals.
rdar://18596215
llvm-svn: 219462
2014-10-10 09:27:02 +08:00
|
|
|
|
|
|
|
;; We can either convert the following control-flow to a select or remove the
|
|
|
|
;; unreachable control flow because of the undef store of null. Make sure we do
|
|
|
|
;; the latter.
|
|
|
|
|
|
|
|
define void @test5(i1 %cond, i8* %ptr) {
|
|
|
|
|
|
|
|
; CHECK-LABEL: test5
|
|
|
|
; CHECK: entry:
|
|
|
|
; CHECK-NOT: select
|
|
|
|
; CHECK: store i8 2, i8* %ptr
|
|
|
|
; CHECK: ret
|
|
|
|
|
|
|
|
entry:
|
|
|
|
br i1 %cond, label %bb1, label %bb3
|
|
|
|
|
|
|
|
bb3:
|
|
|
|
br label %bb2
|
|
|
|
|
|
|
|
bb1:
|
|
|
|
br label %bb2
|
|
|
|
|
|
|
|
bb2:
|
|
|
|
%ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ]
|
|
|
|
store i8 2, i8* %ptr.2, align 8
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
; CHECK-LABEL: test6
|
|
|
|
; CHECK: entry:
|
|
|
|
; CHECK-NOT: select
|
|
|
|
; CHECK: store i8 2, i8* %ptr
|
|
|
|
; CHECK: ret
|
|
|
|
|
|
|
|
define void @test6(i1 %cond, i8* %ptr) {
|
|
|
|
entry:
|
|
|
|
br i1 %cond, label %bb1, label %bb2
|
|
|
|
|
|
|
|
bb1:
|
|
|
|
br label %bb2
|
|
|
|
|
|
|
|
bb2:
|
|
|
|
%ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
|
|
|
|
store i8 2, i8* %ptr.2, align 8
|
|
|
|
ret void
|
|
|
|
}
|