1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
; RUN: opt -instcombine -value-tracking-dom-conditions=1 -S < %s | FileCheck %s
target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
define i1 @test_cmp_ult(i64 %A) {
; CHECK-LABEL: @test_cmp_ult
entry:
%cmp = icmp ult i64 %A, 64
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i1 false
%cmp2 = icmp ugt i64 %A, 64
ret i1 %cmp2
untaken:
ret i1 true
}
define i1 @test_cmp_ule(i64 %A) {
; CHECK-LABEL: @test_cmp_ule
entry:
%cmp = icmp ule i64 %A, 64
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i1 false
%cmp2 = icmp ugt i64 %A, 128
ret i1 %cmp2
untaken:
ret i1 true
}
define i1 @test_cmp_sgt(i32 %A) {
; CHECK-LABEL: @test_cmp_sgt
entry:
%cmp = icmp sgt i32 %A, 10
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i1 true
%cmp2 = icmp sgt i32 %A, -1
ret i1 %cmp2
untaken:
ret i1 true
}
define i64 @test_add_zero_bits(i64 %A) {
; CHECK-LABEL: @test_add_zero_bits
entry:
%cmp = icmp eq i64 %A, 2
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: ret i64 3
%add = add i64 %A, 1
ret i64 %add
untaken:
ret i64 %A
}
define i64 @test_add_nsw(i64 %A) {
; CHECK-LABEL: @test_add_nsw
entry:
%cmp = icmp ult i64 %A, 20
br i1 %cmp, label %taken, label %untaken
taken:
; CHECK-LABEL: taken:
; CHECK-NEXT: %add = add nuw nsw i64 %A, 1
; CHECK-NEXT: ret i64 %add
%add = add i64 %A, 1
ret i64 %add
untaken:
ret i64 %A
}
; After sinking the instructions into the if block, check that we
; can simplify some of them using dominating conditions.
define i32 @test_add_zero_bits_sink(i32 %x) nounwind ssp {
; CHECK-LABEL: @test_add_zero_bits_sink(
; CHECK-NOT: sdiv i32
entry:
%a = add nsw i32 %x, 16
%b = sdiv i32 %a, %x
%cmp = icmp ult i32 %x, 7
br i1 %cmp, label %bb1, label %bb2
bb1:
; CHECK-LABEL: bb1:
; CHECK-NEXT: or i32 %x, 16
; CHECK-NEXT: udiv i32
ret i32 %b
bb2:
ret i32 %x
}
; A condition in the same block gives no information
define i32 @test_neg1(i32 %x) nounwind ssp {
; CHECK-LABEL: @test_neg1
; CHECK: add
; CHECK: sdiv
; CHECK: icmp
; CHECK: select
entry:
%a = add nsw i32 %x, 16
%b = sdiv i32 %a, %x
%cmp = icmp ult i32 %x, 7
%ret = select i1 %cmp, i32 %a, i32 %b
ret i32 %ret
}
; A non-dominating edge gives no information
define i32 @test_neg2(i32 %x) {
; CHECK-LABEL: @test_neg2
entry:
%cmp = icmp ult i32 %x, 7
br i1 %cmp, label %bb1, label %merge
bb1:
br label %merge
merge:
; CHECK-LABEL: merge:
; CHECK: icmp
; CHECK: select
%cmp2 = icmp ult i32 %x, 7
%ret = select i1 %cmp2, i32 %x, i32 0
ret i32 %ret
}
; A unconditional branch expressed as a condition one gives no
; information (and shouldn't trip any asserts.)
define i32 @test_neg3(i32 %x) {
; CHECK-LABEL: @test_neg3
entry:
%cmp = icmp ult i32 %x, 7
br i1 %cmp, label %merge, label %merge
merge:
; CHECK-LABEL: merge:
; CHECK: icmp
; CHECK: select
%cmp2 = icmp ult i32 %x, 7
%ret = select i1 %cmp2, i32 %x, i32 0
ret i32 %ret
}
declare i32 @bar()
|