@@ -90,3 +90,109 @@ define <2 x i1> @icmp_ugt_16x2(<2 x i32>) {
90
90
%d = icmp ugt <2 x i32 > %c , <i32 1048575 , i32 1048575 >
91
91
ret <2 x i1 > %d
92
92
}
93
+
94
+ define i1 @fold_icmp_shl_nuw_c1 (i32 %x ) {
95
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c1(
96
+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 61440
97
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
98
+ ; CHECK-NEXT: ret i1 [[CMP]]
99
+ ;
100
+ %lshr = lshr i32 %x , 12
101
+ %and = and i32 %lshr , 15
102
+ %shl = shl nuw i32 2 , %and
103
+ %cmp = icmp ult i32 %shl , 4
104
+ ret i1 %cmp
105
+ }
106
+
107
+ define i1 @fold_icmp_shl_nuw_c2 (i32 %x ) {
108
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2(
109
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 2
110
+ ; CHECK-NEXT: ret i1 [[CMP]]
111
+ ;
112
+ %shl = shl nuw i32 16 , %x
113
+ %cmp = icmp ult i32 %shl , 64
114
+ ret i1 %cmp
115
+ }
116
+
117
+ define i1 @fold_icmp_shl_nuw_c2_non_pow2 (i32 %x ) {
118
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2_non_pow2(
119
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 2
120
+ ; CHECK-NEXT: ret i1 [[CMP]]
121
+ ;
122
+ %shl = shl nuw i32 48 , %x
123
+ %cmp = icmp ult i32 %shl , 192
124
+ ret i1 %cmp
125
+ }
126
+
127
+ define i1 @fold_icmp_shl_nuw_c2_div_non_pow2 (i32 %x ) {
128
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2_div_non_pow2(
129
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 5
130
+ ; CHECK-NEXT: ret i1 [[CMP]]
131
+ ;
132
+ %shl = shl nuw i32 2 , %x
133
+ %cmp = icmp ult i32 %shl , 60
134
+ ret i1 %cmp
135
+ }
136
+
137
+ define i1 @fold_icmp_shl_nuw_c3 (i32 %x ) {
138
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c3(
139
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 1
140
+ ; CHECK-NEXT: ret i1 [[CMP]]
141
+ ;
142
+ %shl = shl nuw i32 48 , %x
143
+ %cmp = icmp uge i32 %shl , 144
144
+ ret i1 %cmp
145
+ }
146
+
147
+ define i1 @fold_icmp_shl_nuw_c2_indivisible (i32 %x ) {
148
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2_indivisible(
149
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 2
150
+ ; CHECK-NEXT: ret i1 [[CMP]]
151
+ ;
152
+ %shl = shl nuw i32 16 , %x
153
+ %cmp = icmp ult i32 %shl , 63
154
+ ret i1 %cmp
155
+ }
156
+
157
+ ; Negative tests
158
+
159
+ define i1 @fold_icmp_shl_c2_without_nuw (i32 %x ) {
160
+ ; CHECK-LABEL: @fold_icmp_shl_c2_without_nuw(
161
+ ; CHECK-NEXT: [[SHL:%.*]] = shl i32 16, [[X:%.*]]
162
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[SHL]], 64
163
+ ; CHECK-NEXT: ret i1 [[CMP]]
164
+ ;
165
+ %shl = shl i32 16 , %x
166
+ %cmp = icmp ult i32 %shl , 64
167
+ ret i1 %cmp
168
+ }
169
+
170
+ ; Make sure this trivial case is folded by InstSimplify.
171
+ define i1 @fold_icmp_shl_nuw_c2_precondition1 (i32 %x ) {
172
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2_precondition1(
173
+ ; CHECK-NEXT: ret i1 true
174
+ ;
175
+ %shl = shl nuw i32 0 , %x
176
+ %cmp = icmp ult i32 %shl , 63
177
+ ret i1 %cmp
178
+ }
179
+
180
+ ; Make sure this trivial case is folded by InstSimplify.
181
+ define i1 @fold_icmp_shl_nuw_c2_precondition2 (i32 %x ) {
182
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2_precondition2(
183
+ ; CHECK-NEXT: ret i1 false
184
+ ;
185
+ %shl = shl nuw i32 127 , %x
186
+ %cmp = icmp ult i32 %shl , 63
187
+ ret i1 %cmp
188
+ }
189
+
190
+ ; Make sure we don't crash on this case.
191
+ define i1 @fold_icmp_shl_nuw_c2_precondition3 (i32 %x ) {
192
+ ; CHECK-LABEL: @fold_icmp_shl_nuw_c2_precondition3(
193
+ ; CHECK-NEXT: ret i1 false
194
+ ;
195
+ %shl = shl nuw i32 1 , %x
196
+ %cmp = icmp ult i32 %shl , 1
197
+ ret i1 %cmp
198
+ }
0 commit comments