1; RUN: opt -S -jump-threading %s | FileCheck %s
2; When simplify a branch based on LVI predicates, we should replace the
3; comparison itself with a constant (when possible) in case it's otherwise used.
4
5define i32 @test(i32* %p) {
6; CHECK-LABEL: @test
7; CHECK: icmp eq
8; CHECK-NEXT: br i1 %cmp, label %exit2, label %exit1
9; CHECK-NOT: icmp ne
10entry:
11  %cmp = icmp eq i32* %p, null
12  br i1 %cmp, label %is_null, label %not_null
13is_null:
14  %cmp2 = icmp ne i32* %p, null
15  br i1 %cmp2, label %exit1, label %exit2
16not_null:
17  %cmp3 = icmp ne i32* %p, null
18  br i1 %cmp3, label %exit1, label %exit2
19exit1:
20  ret i32 0
21exit2:
22  ret i32 1
23}
24
25declare void @use(i1)
26
27; It would not be legal to replace %cmp2 (well, in this case it actually is,
28; but that's a CSE problem, not a LVI/jump threading problem)
29define i32 @test_negative(i32* %p) {
30; CHECK-LABEL: @test
31; CHECK: icmp ne
32; CHECK: icmp eq
33; CHECK-NEXT: br i1 %cmp, label %exit2, label %exit1
34; CHECK-NOT: icmp ne
35entry:
36  %cmp2 = icmp ne i32* %p, null
37  call void @use(i1 %cmp2)
38  %cmp = icmp eq i32* %p, null
39  br i1 %cmp, label %is_null, label %not_null
40is_null:
41  br i1 %cmp2, label %exit1, label %exit2
42not_null:
43  br i1 %cmp2, label %exit1, label %exit2
44exit1:
45  ret i32 0
46exit2:
47  ret i32 1
48}
49
50; In this case, we can remove cmp2 because it's otherwise unused
51define i32 @test2(i32* %p) {
52; CHECK-LABEL: @test
53; CHECK-LABEL: entry:
54; CHECK-NEXT: icmp eq
55; CHECK-NEXT: br i1 %cmp, label %exit2, label %exit1
56; CHECK-NOT: icmp ne
57entry:
58  %cmp2 = icmp ne i32* %p, null
59  %cmp = icmp eq i32* %p, null
60  br i1 %cmp, label %is_null, label %not_null
61is_null:
62  br i1 %cmp2, label %exit1, label %exit2
63not_null:
64  br i1 %cmp2, label %exit1, label %exit2
65exit1:
66  ret i32 0
67exit2:
68  ret i32 1
69}
70