@@ -6,9 +6,9 @@ declare void @use8(i8)
6
6
7
7
define i6 @trunc_lshr (i8 %x ) {
8
8
; CHECK-LABEL: @trunc_lshr(
9
- ; CHECK-NEXT: [[S :%.*]] = lshr i8 [[X:%.*]], 2
10
- ; CHECK-NEXT: [[T :%.*]] = trunc i8 [[S]] to i6
11
- ; CHECK-NEXT: [[R:%.*]] = and i6 [[T ]], 14
9
+ ; CHECK-NEXT: [[TMP1 :%.*]] = trunc i8 [[X:%.*]] to i6
10
+ ; CHECK-NEXT: [[TMP2 :%.*]] = lshr i6 [[TMP1]], 2
11
+ ; CHECK-NEXT: [[R:%.*]] = and i6 [[TMP2 ]], 14
12
12
; CHECK-NEXT: ret i6 [[R]]
13
13
;
14
14
%s = lshr i8 %x , 2
@@ -17,19 +17,22 @@ define i6 @trunc_lshr(i8 %x) {
17
17
ret i6 %r
18
18
}
19
19
20
+ ; The 'and' is eliminated.
21
+
20
22
define i6 @trunc_lshr_exact_mask (i8 %x ) {
21
23
; CHECK-LABEL: @trunc_lshr_exact_mask(
22
- ; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 2
23
- ; CHECK-NEXT: [[T:%.*]] = trunc i8 [[S]] to i6
24
- ; CHECK-NEXT: [[R:%.*]] = and i6 [[T]], 15
25
- ; CHECK-NEXT: ret i6 [[R]]
24
+ ; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i6
25
+ ; CHECK-NEXT: [[TMP2:%.*]] = lshr i6 [[TMP1]], 2
26
+ ; CHECK-NEXT: ret i6 [[TMP2]]
26
27
;
27
28
%s = lshr i8 %x , 2
28
29
%t = trunc i8 %s to i6
29
30
%r = and i6 %t , 15
30
31
ret i6 %r
31
32
}
32
33
34
+ ; negative test - a high bit of x is in the result
35
+
33
36
define i6 @trunc_lshr_big_mask (i8 %x ) {
34
37
; CHECK-LABEL: @trunc_lshr_big_mask(
35
38
; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 2
@@ -43,6 +46,8 @@ define i6 @trunc_lshr_big_mask(i8 %x) {
43
46
ret i6 %r
44
47
}
45
48
49
+ ; negative test - too many uses
50
+
46
51
define i6 @trunc_lshr_use1 (i8 %x ) {
47
52
; CHECK-LABEL: @trunc_lshr_use1(
48
53
; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 2
@@ -58,6 +63,8 @@ define i6 @trunc_lshr_use1(i8 %x) {
58
63
ret i6 %r
59
64
}
60
65
66
+ ; negative test - too many uses
67
+
61
68
define i6 @trunc_lshr_use2 (i8 %x ) {
62
69
; CHECK-LABEL: @trunc_lshr_use2(
63
70
; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 2
@@ -73,11 +80,13 @@ define i6 @trunc_lshr_use2(i8 %x) {
73
80
ret i6 %r
74
81
}
75
82
83
+ ; Splat vectors are ok.
84
+
76
85
define <2 x i7 > @trunc_lshr_vec_splat (<2 x i16 > %x ) {
77
86
; CHECK-LABEL: @trunc_lshr_vec_splat(
78
- ; CHECK-NEXT: [[S :%.*]] = lshr <2 x i16> [[X:%.*]], <i16 5, i16 5 >
79
- ; CHECK-NEXT: [[T :%.*]] = trunc <2 x i16 > [[S]] to <2 x i7>
80
- ; CHECK-NEXT: [[R:%.*]] = and <2 x i7> [[T ]], <i7 1, i7 1>
87
+ ; CHECK-NEXT: [[TMP1 :%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i7 >
88
+ ; CHECK-NEXT: [[TMP2 :%.*]] = lshr <2 x i7 > [[TMP1]], <i7 5, i7 5 >
89
+ ; CHECK-NEXT: [[R:%.*]] = and <2 x i7> [[TMP2 ]], <i7 1, i7 1>
81
90
; CHECK-NEXT: ret <2 x i7> [[R]]
82
91
;
83
92
%s = lshr <2 x i16 > %x , <i16 5 , i16 5 >
@@ -86,19 +95,22 @@ define <2 x i7> @trunc_lshr_vec_splat(<2 x i16> %x) {
86
95
ret <2 x i7 > %r
87
96
}
88
97
98
+ ; The 'and' is eliminated.
99
+
89
100
define <2 x i7 > @trunc_lshr_vec_splat_exact_mask (<2 x i16 > %x ) {
90
101
; CHECK-LABEL: @trunc_lshr_vec_splat_exact_mask(
91
- ; CHECK-NEXT: [[S:%.*]] = lshr <2 x i16> [[X:%.*]], <i16 6, i16 6>
92
- ; CHECK-NEXT: [[T:%.*]] = trunc <2 x i16> [[S]] to <2 x i7>
93
- ; CHECK-NEXT: [[R:%.*]] = and <2 x i7> [[T]], <i7 1, i7 1>
94
- ; CHECK-NEXT: ret <2 x i7> [[R]]
102
+ ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i7>
103
+ ; CHECK-NEXT: [[TMP2:%.*]] = lshr <2 x i7> [[TMP1]], <i7 6, i7 6>
104
+ ; CHECK-NEXT: ret <2 x i7> [[TMP2]]
95
105
;
96
106
%s = lshr <2 x i16 > %x , <i16 6 , i16 6 >
97
107
%t = trunc <2 x i16 > %s to <2 x i7 >
98
108
%r = and <2 x i7 > %t , <i7 1 , i7 1 >
99
109
ret <2 x i7 > %r
100
110
}
101
111
112
+ ; negative test - the shift is too big for the narrow type
113
+
102
114
define <2 x i7 > @trunc_lshr_big_shift (<2 x i16 > %x ) {
103
115
; CHECK-LABEL: @trunc_lshr_big_shift(
104
116
; CHECK-NEXT: [[S:%.*]] = lshr <2 x i16> [[X:%.*]], <i16 7, i16 7>
@@ -112,11 +124,13 @@ define <2 x i7> @trunc_lshr_big_shift(<2 x i16> %x) {
112
124
ret <2 x i7 > %r
113
125
}
114
126
127
+ ; High bits could also be set rather than cleared.
128
+
115
129
define i6 @or_trunc_lshr (i8 %x ) {
116
130
; CHECK-LABEL: @or_trunc_lshr(
117
- ; CHECK-NEXT: [[S :%.*]] = lshr i8 [[X:%.*]], 1
118
- ; CHECK-NEXT: [[T :%.*]] = trunc i8 [[S]] to i6
119
- ; CHECK-NEXT: [[R:%.*]] = or i6 [[T ]], -32
131
+ ; CHECK-NEXT: [[TMP1 :%.*]] = trunc i8 [[X:%.*]] to i6
132
+ ; CHECK-NEXT: [[TMP2 :%.*]] = lshr i6 [[TMP1]], 1
133
+ ; CHECK-NEXT: [[R:%.*]] = or i6 [[TMP2 ]], -32
120
134
; CHECK-NEXT: ret i6 [[R]]
121
135
;
122
136
%s = lshr i8 %x , 1
@@ -127,9 +141,9 @@ define i6 @or_trunc_lshr(i8 %x) {
127
141
128
142
define i6 @or_trunc_lshr_more (i8 %x ) {
129
143
; CHECK-LABEL: @or_trunc_lshr_more(
130
- ; CHECK-NEXT: [[S :%.*]] = lshr i8 [[X:%.*]], 4
131
- ; CHECK-NEXT: [[T :%.*]] = trunc i8 [[S]] to i6
132
- ; CHECK-NEXT: [[R:%.*]] = or i6 [[T ]], -4
144
+ ; CHECK-NEXT: [[TMP1 :%.*]] = trunc i8 [[X:%.*]] to i6
145
+ ; CHECK-NEXT: [[TMP2 :%.*]] = lshr i6 [[TMP1]], 4
146
+ ; CHECK-NEXT: [[R:%.*]] = or i6 [[TMP2 ]], -4
133
147
; CHECK-NEXT: ret i6 [[R]]
134
148
;
135
149
%s = lshr i8 %x , 4
@@ -138,6 +152,8 @@ define i6 @or_trunc_lshr_more(i8 %x) {
138
152
ret i6 %r
139
153
}
140
154
155
+ ; negative test - need all high bits to be undemanded
156
+
141
157
define i6 @or_trunc_lshr_small_mask (i8 %x ) {
142
158
; CHECK-LABEL: @or_trunc_lshr_small_mask(
143
159
; CHECK-NEXT: [[S:%.*]] = lshr i8 [[X:%.*]], 4
0 commit comments