@@ -1214,3 +1214,75 @@ define i31 @fshr_neg_amount_non_power_two(i31 %x, i31 %y) {
12141214 %r = call i31 @llvm.fshr.i31 (i31 %x , i31 %x , i31 %n )
12151215 ret i31 %r
12161216}
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