1
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
1
2
; RUN: opt < %s -instcombine -S | FileCheck %s
2
3
3
4
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
@@ -11,9 +12,9 @@ declare i64 @llabs(i64)
11
12
12
13
define i32 @test_abs (i32 %x ) {
13
14
; CHECK-LABEL: @test_abs(
14
- ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 %x , -1
15
- ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, %x
16
- ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i32 %x , i32 [[NEG]]
15
+ ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i32 [[X:%.*]] , -1
16
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[X]]
17
+ ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i32 [[X]] , i32 [[NEG]]
17
18
; CHECK-NEXT: ret i32 [[TMP1]]
18
19
;
19
20
%ret = call i32 @abs (i32 %x )
@@ -22,9 +23,9 @@ define i32 @test_abs(i32 %x) {
22
23
23
24
define i64 @test_labs (i64 %x ) {
24
25
; CHECK-LABEL: @test_labs(
25
- ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 %x , -1
26
- ; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, %x
27
- ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i64 %x , i64 [[NEG]]
26
+ ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[X:%.*]] , -1
27
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[X]]
28
+ ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i64 [[X]] , i64 [[NEG]]
28
29
; CHECK-NEXT: ret i64 [[TMP1]]
29
30
;
30
31
%ret = call i64 @labs (i64 %x )
@@ -33,24 +34,140 @@ define i64 @test_labs(i64 %x) {
33
34
34
35
define i64 @test_llabs (i64 %x ) {
35
36
; CHECK-LABEL: @test_llabs(
36
- ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 %x , -1
37
- ; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, %x
38
- ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i64 %x , i64 [[NEG]]
37
+ ; CHECK-NEXT: [[ISPOS:%.*]] = icmp sgt i64 [[X:%.*]] , -1
38
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i64 0, [[X]]
39
+ ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISPOS]], i64 [[X]] , i64 [[NEG]]
39
40
; CHECK-NEXT: ret i64 [[TMP1]]
40
41
;
41
42
%ret = call i64 @llabs (i64 %x )
42
43
ret i64 %ret
43
44
}
44
45
46
+ ; FIXME: We should have a canonical form of abs to make CSE easier.
47
+
48
+ define i8 @abs_canonical_1 (i8 %x ) {
49
+ ; CHECK-LABEL: @abs_canonical_1(
50
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 0
51
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]]
52
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
53
+ ; CHECK-NEXT: ret i8 [[ABS]]
54
+ ;
55
+ %cmp = icmp sgt i8 %x , 0
56
+ %neg = sub i8 0 , %x
57
+ %abs = select i1 %cmp , i8 %x , i8 %neg
58
+ ret i8 %abs
59
+ }
60
+
61
+ ; FIXME: Vectors should work too.
62
+
63
+ define <2 x i8 > @abs_canonical_2 (<2 x i8 > %x ) {
64
+ ; CHECK-LABEL: @abs_canonical_2(
65
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
66
+ ; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
67
+ ; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> [[NEG]]
68
+ ; CHECK-NEXT: ret <2 x i8> [[ABS]]
69
+ ;
70
+ %cmp = icmp sgt <2 x i8 > %x , <i8 -1 , i8 -1 >
71
+ %neg = sub <2 x i8 > zeroinitializer , %x
72
+ %abs = select <2 x i1 > %cmp , <2 x i8 > %x , <2 x i8 > %neg
73
+ ret <2 x i8 > %abs
74
+ }
75
+
76
+ ; NSW should not change.
77
+
78
+ define i8 @abs_canonical_3 (i8 %x ) {
79
+ ; CHECK-LABEL: @abs_canonical_3(
80
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
81
+ ; CHECK-NEXT: [[NEG:%.*]] = sub nsw i8 0, [[X]]
82
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
83
+ ; CHECK-NEXT: ret i8 [[ABS]]
84
+ ;
85
+ %cmp = icmp slt i8 %x , 0
86
+ %neg = sub nsw i8 0 , %x
87
+ %abs = select i1 %cmp , i8 %neg , i8 %x
88
+ ret i8 %abs
89
+ }
90
+
91
+ define i8 @abs_canonical_4 (i8 %x ) {
92
+ ; CHECK-LABEL: @abs_canonical_4(
93
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 1
94
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]]
95
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
96
+ ; CHECK-NEXT: ret i8 [[ABS]]
97
+ ;
98
+ %cmp = icmp slt i8 %x , 1
99
+ %neg = sub i8 0 , %x
100
+ %abs = select i1 %cmp , i8 %neg , i8 %x
101
+ ret i8 %abs
102
+ }
103
+
104
+ ; FIXME: We should have a canonical form of nabs to make CSE easier.
105
+
106
+ define i8 @nabs_canonical_1 (i8 %x ) {
107
+ ; CHECK-LABEL: @nabs_canonical_1(
108
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 0
109
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]]
110
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEG]], i8 [[X]]
111
+ ; CHECK-NEXT: ret i8 [[ABS]]
112
+ ;
113
+ %cmp = icmp sgt i8 %x , 0
114
+ %neg = sub i8 0 , %x
115
+ %abs = select i1 %cmp , i8 %neg , i8 %x
116
+ ret i8 %abs
117
+ }
118
+
119
+ ; FIXME: Vectors should work too.
120
+
121
+ define <2 x i8 > @nabs_canonical_2 (<2 x i8 > %x ) {
122
+ ; CHECK-LABEL: @nabs_canonical_2(
123
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1>
124
+ ; CHECK-NEXT: [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
125
+ ; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[NEG]], <2 x i8> [[X]]
126
+ ; CHECK-NEXT: ret <2 x i8> [[ABS]]
127
+ ;
128
+ %cmp = icmp sgt <2 x i8 > %x , <i8 -1 , i8 -1 >
129
+ %neg = sub <2 x i8 > zeroinitializer , %x
130
+ %abs = select <2 x i1 > %cmp , <2 x i8 > %neg , <2 x i8 > %x
131
+ ret <2 x i8 > %abs
132
+ }
133
+
134
+ ; NSW should not change.
135
+
136
+ define i8 @nabs_canonical_3 (i8 %x ) {
137
+ ; CHECK-LABEL: @nabs_canonical_3(
138
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
139
+ ; CHECK-NEXT: [[NEG:%.*]] = sub nsw i8 0, [[X]]
140
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
141
+ ; CHECK-NEXT: ret i8 [[ABS]]
142
+ ;
143
+ %cmp = icmp slt i8 %x , 0
144
+ %neg = sub nsw i8 0 , %x
145
+ %abs = select i1 %cmp , i8 %x , i8 %neg
146
+ ret i8 %abs
147
+ }
148
+
149
+ define i8 @nabs_canonical_4 (i8 %x ) {
150
+ ; CHECK-LABEL: @nabs_canonical_4(
151
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 1
152
+ ; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[X]]
153
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEG]]
154
+ ; CHECK-NEXT: ret i8 [[ABS]]
155
+ ;
156
+ %cmp = icmp slt i8 %x , 1
157
+ %neg = sub i8 0 , %x
158
+ %abs = select i1 %cmp , i8 %x , i8 %neg
159
+ ret i8 %abs
160
+ }
161
+
45
162
; The following 5 tests use a shift+add+xor to implement abs():
46
163
; B = ashr i8 A, 7 -- smear the sign bit.
47
164
; xor (add A, B), B -- add -1 and flip bits if negative
48
165
49
166
define i8 @shifty_abs_commute0 (i8 %x ) {
50
167
; CHECK-LABEL: @shifty_abs_commute0(
51
- ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 %x , 0
52
- ; CHECK-NEXT: [[TMP2:%.*]] = sub i8 0, %x
53
- ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 %x
168
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]] , 0
169
+ ; CHECK-NEXT: [[TMP2:%.*]] = sub i8 0, [[X]]
170
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
54
171
; CHECK-NEXT: ret i8 [[ABS]]
55
172
;
56
173
%signbit = ashr i8 %x , 7
@@ -61,9 +178,9 @@ define i8 @shifty_abs_commute0(i8 %x) {
61
178
62
179
define i8 @shifty_abs_commute0_nsw (i8 %x ) {
63
180
; CHECK-LABEL: @shifty_abs_commute0_nsw(
64
- ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 %x , 0
65
- ; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i8 0, %x
66
- ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 %x
181
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[X:%.*]] , 0
182
+ ; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i8 0, [[X]]
183
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[X]]
67
184
; CHECK-NEXT: ret i8 [[ABS]]
68
185
;
69
186
%signbit = ashr i8 %x , 7
@@ -77,8 +194,8 @@ define i8 @shifty_abs_commute0_nsw(i8 %x) {
77
194
; have produced all 1s. We partially optimize this.
78
195
define i8 @shifty_abs_commute0_nuw (i8 %x ) {
79
196
; CHECK-LABEL: @shifty_abs_commute0_nuw(
80
- ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 %x , 0
81
- ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 %x , i8 0
197
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[X:%.*]] , 0
198
+ ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 [[X]] , i8 0
82
199
; CHECK-NEXT: ret i8 [[ABS]]
83
200
;
84
201
%signbit = ashr i8 %x , 7
@@ -89,9 +206,9 @@ define i8 @shifty_abs_commute0_nuw(i8 %x) {
89
206
90
207
define <2 x i8 > @shifty_abs_commute1 (<2 x i8 > %x ) {
91
208
; CHECK-LABEL: @shifty_abs_commute1(
92
- ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i8> %x , zeroinitializer
93
- ; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, %x
94
- ; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> %x
209
+ ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i8> [[X:%.*]] , zeroinitializer
210
+ ; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
211
+ ; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> [[X]]
95
212
; CHECK-NEXT: ret <2 x i8> [[ABS]]
96
213
;
97
214
%signbit = ashr <2 x i8 > %x , <i8 7 , i8 7 >
@@ -102,7 +219,7 @@ define <2 x i8> @shifty_abs_commute1(<2 x i8> %x) {
102
219
103
220
define <2 x i8 > @shifty_abs_commute2 (<2 x i8 > %x ) {
104
221
; CHECK-LABEL: @shifty_abs_commute2(
105
- ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> %x , <i8 3, i8 3>
222
+ ; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[X:%.*]] , <i8 3, i8 3>
106
223
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i8> [[Y]], zeroinitializer
107
224
; CHECK-NEXT: [[TMP2:%.*]] = sub <2 x i8> zeroinitializer, [[Y]]
108
225
; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[TMP2]], <2 x i8> [[Y]]
@@ -117,7 +234,7 @@ define <2 x i8> @shifty_abs_commute2(<2 x i8> %x) {
117
234
118
235
define i8 @shifty_abs_commute3 (i8 %x ) {
119
236
; CHECK-LABEL: @shifty_abs_commute3(
120
- ; CHECK-NEXT: [[Y:%.*]] = mul i8 %x , 3
237
+ ; CHECK-NEXT: [[Y:%.*]] = mul i8 [[X:%.*]] , 3
121
238
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y]], 0
122
239
; CHECK-NEXT: [[TMP2:%.*]] = sub i8 0, [[Y]]
123
240
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 [[Y]]
@@ -136,8 +253,8 @@ declare void @extra_use(i8)
136
253
137
254
define i8 @shifty_abs_too_many_uses (i8 %x ) {
138
255
; CHECK-LABEL: @shifty_abs_too_many_uses(
139
- ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 %x , 7
140
- ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SIGNBIT]], %x
256
+ ; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]] , 7
257
+ ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[SIGNBIT]], [[X]]
141
258
; CHECK-NEXT: [[ABS:%.*]] = xor i8 [[ADD]], [[SIGNBIT]]
142
259
; CHECK-NEXT: call void @extra_use(i8 [[SIGNBIT]])
143
260
; CHECK-NEXT: ret i8 [[ABS]]
0 commit comments