@@ -1214,3 +1214,75 @@ define i31 @fshr_neg_amount_non_power_two(i31 %x, i31 %y) {
1214
1214
%r = call i31 @llvm.fshr.i31 (i31 %x , i31 %x , i31 %n )
1215
1215
ret i31 %r
1216
1216
}
1217
+
1218
+ define i32 @rot_const_consecutive (i32 %x ) {
1219
+ ; CHECK-LABEL: @rot_const_consecutive(
1220
+ ; CHECK-NEXT: [[R2:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 8)
1221
+ ; CHECK-NEXT: ret i32 [[R2]]
1222
+ ;
1223
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 13 )
1224
+ %r2 = call i32 @llvm.fshl.i32 (i32 %r , i32 %r , i32 27 )
1225
+ ret i32 %r2
1226
+ }
1227
+
1228
+ define i32 @rot_const_consecutive_multi_use (i32 %x ) {
1229
+ ; CHECK-LABEL: @rot_const_consecutive_multi_use(
1230
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 7)
1231
+ ; CHECK-NEXT: [[R3:%.*]] = call i32 @llvm.fshl.i32(i32 [[X]], i32 [[X]], i32 11)
1232
+ ; CHECK-NEXT: [[R2:%.*]] = and i32 [[R]], [[R3]]
1233
+ ; CHECK-NEXT: ret i32 [[R2]]
1234
+ ;
1235
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 7 )
1236
+ %r2 = call i32 @llvm.fshl.i32 (i32 %r , i32 %r , i32 4 )
1237
+ %and = and i32 %r , %r2
1238
+ ret i32 %and
1239
+ }
1240
+
1241
+ define i32 @rot_const_consecutive_cancel_out (i32 %x ) {
1242
+ ; CHECK-LABEL: @rot_const_consecutive_cancel_out(
1243
+ ; CHECK-NEXT: ret i32 [[X:%.*]]
1244
+ ;
1245
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 7 )
1246
+ %r2 = call i32 @llvm.fshl.i32 (i32 %r , i32 %r , i32 25 )
1247
+ ret i32 %r2
1248
+ }
1249
+
1250
+ ;; negative test, consecutive rotates only fold if shift amounts are const
1251
+
1252
+ define i32 @rot_nonconst_shift (i32 %x , i32 %amt ) {
1253
+ ; CHECK-LABEL: @rot_nonconst_shift(
1254
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 7)
1255
+ ; CHECK-NEXT: [[R2:%.*]] = call i32 @llvm.fshl.i32(i32 [[R]], i32 [[R]], i32 [[AMT:%.*]])
1256
+ ; CHECK-NEXT: ret i32 [[R2]]
1257
+ ;
1258
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 7 )
1259
+ %r2 = call i32 @llvm.fshl.i32 (i32 %r , i32 %r , i32 %amt )
1260
+ ret i32 %r2
1261
+ }
1262
+
1263
+ ;; negative test, 1st funnel shift isn't a rotate.
1264
+
1265
+ define i32 @fsh_rot (i32 %x , i32 %y ) {
1266
+ ; CHECK-LABEL: @fsh_rot(
1267
+ ; CHECK-NEXT: [[FSH:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[Y:%.*]], i32 7)
1268
+ ; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.fshl.i32(i32 [[FSH]], i32 [[FSH]], i32 4)
1269
+ ; CHECK-NEXT: ret i32 [[R]]
1270
+ ;
1271
+ %fsh = call i32 @llvm.fshl.i32 (i32 %x , i32 %y , i32 7 )
1272
+ %r = call i32 @llvm.fshl.i32 (i32 %fsh , i32 %fsh , i32 4 )
1273
+ ret i32 %r
1274
+ }
1275
+
1276
+ ;; negative test, 2nd funnel shift isn't a rotate.
1277
+
1278
+ define i32 @rot_fsh (i32 %x , i32 %y ) {
1279
+ ; CHECK-LABEL: @rot_fsh(
1280
+ ; CHECK-NEXT: [[Y:%.*]] = call i32 @llvm.fshl.i32(i32 [[X:%.*]], i32 [[X]], i32 7)
1281
+ ; CHECK-NEXT: [[R2:%.*]] = call i32 @llvm.fshl.i32(i32 [[Y]], i32 [[R:%.*]], i32 4)
1282
+ ; CHECK-NEXT: ret i32 [[R2]]
1283
+ ;
1284
+ %r = call i32 @llvm.fshl.i32 (i32 %x , i32 %x , i32 7 )
1285
+ %r2 = call i32 @llvm.fshl.i32 (i32 %r , i32 %y , i32 4 )
1286
+ ret i32 %r2
1287
+ }
1288
+
0 commit comments