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
153
154
155
156
157
158
159
160
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=instcombine -S < %s | FileCheck %s
declare void @escape(i16 %add)
declare void @escape2(<2 x i16> %add)
define void @numsignbits_shl_zext(i8 %x) {
; CHECK-LABEL: define void @numsignbits_shl_zext(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
; CHECK-NEXT: [[NSB4:%.*]] = shl i16 [[ZEXT]], 10
; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB4]], 15360
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB4]], 7168
; CHECK-NEXT: call void @escape(i16 [[ADD13]])
; CHECK-NEXT: [[ADD12:%.*]] = and i16 [[NSB4]], 3072
; CHECK-NEXT: call void @escape(i16 [[ADD12]])
; CHECK-NEXT: [[AND11:%.*]] = and i16 [[NSB4]], 2048
; CHECK-NEXT: [[ADD11:%.*]] = add nsw i16 [[AND11]], [[NSB4]]
; CHECK-NEXT: call void @escape(i16 [[ADD11]])
; CHECK-NEXT: ret void
;
%ashr = ashr i8 %x, 5
%zext = zext i8 %ashr to i16
%nsb4 = shl i16 %zext, 10
; Validate ComputeNumSignBits using this simplification:
; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
; 4 sign bits: Goal is to fold away the add for bits 12-14.
%and14 = and i16 %nsb4, 16384
%add14 = add i16 %and14, %nsb4
call void @escape(i16 %add14)
%and13 = and i16 %nsb4, 8192
%add13 = add i16 %and13, %nsb4
call void @escape(i16 %add13)
%and12 = and i16 %nsb4, 4096
%add12 = add i16 %and12, %nsb4
call void @escape(i16 %add12)
%and11 = and i16 %nsb4, 2048
%add11 = add i16 %and11, %nsb4
call void @escape(i16 %add11)
ret void
}
define void @numsignbits_shl_zext_shift_amounr_matches_extend(i8 %x) {
; CHECK-LABEL: define void @numsignbits_shl_zext_shift_amounr_matches_extend(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 2
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
; CHECK-NEXT: [[NSB3:%.*]] = shl nuw i16 [[ZEXT]], 8
; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB3]], 16128
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB3]], 7936
; CHECK-NEXT: call void @escape(i16 [[ADD13]])
; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB3]], 4096
; CHECK-NEXT: [[ADD12:%.*]] = add nsw i16 [[AND12]], [[NSB3]]
; CHECK-NEXT: call void @escape(i16 [[ADD12]])
; CHECK-NEXT: ret void
;
%ashr = ashr i8 %x, 2
%zext = zext i8 %ashr to i16
%nsb3 = shl i16 %zext, 8
; Validate ComputeNumSignBits using this simplification:
; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
; 3 sign bits: Goal is to fold away the add for bits 13-14.
%and14 = and i16 %nsb3, 16384
%add14 = add i16 %and14, %nsb3
call void @escape(i16 %add14)
%and13 = and i16 %nsb3, 8192
%add13 = add i16 %and13, %nsb3
call void @escape(i16 %add13)
%and12 = and i16 %nsb3, 4096
%add12 = add i16 %and12, %nsb3
call void @escape(i16 %add12)
ret void
}
define void @numsignbits_shl_zext_extended_bits_remains(i8 %x) {
; CHECK-LABEL: define void @numsignbits_shl_zext_extended_bits_remains(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
; CHECK-NEXT: [[NSB1:%.*]] = shl nuw nsw i16 [[ZEXT]], 7
; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB1]], 16384
; CHECK-NEXT: [[ADD14:%.*]] = add nuw i16 [[AND14]], [[NSB1]]
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
; CHECK-NEXT: ret void
;
%ashr = ashr i8 %x, 5
%zext = zext i8 %ashr to i16
%nsb1 = shl i16 %zext, 7
; Validate ComputeNumSignBits using this simplification:
; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
; 1 sign bit: The add can't be folded away here.
%and14 = and i16 %nsb1, 16384
%add14 = add i16 %and14, %nsb1
call void @escape(i16 %add14)
ret void
}
define void @numsignbits_shl_zext_all_bits_shifted_out(i8 %x) {
; CHECK-LABEL: define void @numsignbits_shl_zext_all_bits_shifted_out(
; CHECK-SAME: i8 [[X:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = lshr i8 [[X]], 5
; CHECK-NEXT: [[ZEXT:%.*]] = zext nneg i8 [[ASHR]] to i16
; CHECK-NEXT: [[NSB1:%.*]] = shl i16 [[ZEXT]], 14
; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB1]], 16384
; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB1]]
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
; CHECK-NEXT: ret void
;
%ashr = ashr i8 %x, 5
%zext = zext i8 %ashr to i16
%nsb1 = shl i16 %zext, 14
; Validate ComputeNumSignBits using this simplification:
; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
; 1 sign bit: The add can't be folded away here.
%and14 = and i16 %nsb1, 16384
%add14 = add i16 %and14, %nsb1
call void @escape(i16 %add14)
ret void
}
define void @numsignbits_shl_zext_vector(<2 x i8> %x) {
; CHECK-LABEL: define void @numsignbits_shl_zext_vector(
; CHECK-SAME: <2 x i8> [[X:%.*]]) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i8> [[X]], splat (i8 5)
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[ASHR]] to <2 x i16>
; CHECK-NEXT: [[NSB4:%.*]] = shl <2 x i16> [[ZEXT]], splat (i16 10)
; CHECK-NEXT: [[ADD14:%.*]] = and <2 x i16> [[NSB4]], splat (i16 15360)
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD14]])
; CHECK-NEXT: [[ADD13:%.*]] = and <2 x i16> [[NSB4]], splat (i16 7168)
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD13]])
; CHECK-NEXT: [[ADD12:%.*]] = and <2 x i16> [[NSB4]], splat (i16 3072)
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD12]])
; CHECK-NEXT: [[AND11:%.*]] = and <2 x i16> [[NSB4]], splat (i16 2048)
; CHECK-NEXT: [[ADD11:%.*]] = add nsw <2 x i16> [[AND11]], [[NSB4]]
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD11]])
; CHECK-NEXT: ret void
;
%ashr = ashr <2 x i8> %x, <i8 5, i8 5>
%zext = zext <2 x i8> %ashr to <2 x i16>
%nsb4 = shl <2 x i16> %zext, <i16 10, i16 10>
; Validate ComputeNumSignBits using this simplification:
; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit
; 4 sign bits: Goal is to fold away the add for bits 12-14.
%and14 = and <2 x i16> %nsb4, <i16 16384, i16 16384>
%add14 = add <2 x i16> %and14, %nsb4
call void @escape2(<2 x i16> %add14)
%and13 = and <2 x i16> %nsb4, <i16 8192, i16 8192>
%add13 = add <2 x i16> %and13, %nsb4
call void @escape2(<2 x i16> %add13)
%and12 = and <2 x i16> %nsb4, <i16 4096, i16 4096>
%add12 = add <2 x i16> %and12, %nsb4
call void @escape2(<2 x i16> %add12)
%and11 = and <2 x i16> %nsb4, <i16 2048, i16 2048>
%add11 = add <2 x i16> %and11, %nsb4
call void @escape2(<2 x i16> %add11)
ret void
}
|