@@ -1075,6 +1075,170 @@ entry:
10751075 call void @use (i32 %and )
10761076 %shr = ashr i32 %and , 31
10771077 ret i32 %shr
1078+ define i32 @ashr_shift_mul (i32 noundef %x ) {
1079+ ; CHECK-LABEL: @ashr_shift_mul(
1080+ ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
1081+ ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
1082+ ; CHECK-NEXT: ret i32 [[RES]]
1083+ ;
1084+ %a = ashr exact i32 %x , 3
1085+ %res = mul i32 %a , 9
1086+ ret i32 %res
1087+ }
1088+
1089+ define i32 @ashr_shift_mul_nuw (i32 noundef %x ) {
1090+ ; CHECK-LABEL: @ashr_shift_mul_nuw(
1091+ ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
1092+ ; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], 9
1093+ ; CHECK-NEXT: ret i32 [[RES]]
1094+ ;
1095+ %a = ashr exact i32 %x , 3
1096+ %res = mul nuw i32 %a , 9
1097+ ret i32 %res
1098+ }
1099+
1100+ define i32 @ashr_shift_mul_nsw (i32 noundef %x ) {
1101+ ; CHECK-LABEL: @ashr_shift_mul_nsw(
1102+ ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
1103+ ; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
1104+ ; CHECK-NEXT: ret i32 [[RES]]
1105+ ;
1106+ %a = ashr exact i32 %x , 3
1107+ %res = mul nsw i32 %a , 9
1108+ ret i32 %res
1109+ }
1110+
1111+ define i32 @lshr_shift_mul_nuw (i32 noundef %x ) {
1112+ ; CHECK-LABEL: @lshr_shift_mul_nuw(
1113+ ; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
1114+ ; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], 9
1115+ ; CHECK-NEXT: ret i32 [[RES]]
1116+ ;
1117+ %a = lshr exact i32 %x , 3
1118+ %res = mul nuw i32 %a , 9
1119+ ret i32 %res
1120+ }
1121+
1122+ define i32 @lshr_shift_mul (i32 noundef %x ) {
1123+ ; CHECK-LABEL: @lshr_shift_mul(
1124+ ; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
1125+ ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
1126+ ; CHECK-NEXT: ret i32 [[RES]]
1127+ ;
1128+ %a = lshr exact i32 %x , 3
1129+ %res = mul i32 %a , 9
1130+ ret i32 %res
1131+ }
1132+
1133+ define i32 @lshr_shift_mul_nsw (i32 noundef %x ) {
1134+ ; CHECK-LABEL: @lshr_shift_mul_nsw(
1135+ ; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
1136+ ; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
1137+ ; CHECK-NEXT: ret i32 [[RES]]
1138+ ;
1139+ %a = lshr exact i32 %x , 3
1140+ %res = mul nsw i32 %a , 9
1141+ ret i32 %res
1142+ }
1143+
1144+ ; Negative test
1145+
1146+ define i32 @lshr_no_exact (i32 %x ) {
1147+ ; CHECK-LABEL: @lshr_no_exact(
1148+ ; CHECK-NEXT: [[A:%.*]] = lshr i32 [[X:%.*]], 3
1149+ ; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
1150+ ; CHECK-NEXT: ret i32 [[RES]]
1151+ ;
1152+ %a = lshr i32 %x , 3
1153+ %res = mul nsw i32 %a , 9
1154+ ret i32 %res
1155+ }
1156+
1157+ ; Negative test
1158+
1159+ define i32 @ashr_no_exact (i32 %x ) {
1160+ ; CHECK-LABEL: @ashr_no_exact(
1161+ ; CHECK-NEXT: [[A:%.*]] = ashr i32 [[X:%.*]], 3
1162+ ; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
1163+ ; CHECK-NEXT: ret i32 [[RES]]
1164+ ;
1165+ %a = ashr i32 %x , 3
1166+ %res = mul nsw i32 %a , 9
1167+ ret i32 %res
1168+ }
1169+
1170+ define i32 @lshr_no_undef (i32 %x ) {
1171+ ; CHECK-LABEL: @lshr_no_undef(
1172+ ; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
1173+ ; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
1174+ ; CHECK-NEXT: ret i32 [[RES]]
1175+ ;
1176+ %a = lshr exact i32 %x , 3
1177+ %res = mul nsw i32 %a , 9
1178+ ret i32 %res
1179+ }
1180+
1181+ define i32 @ashr_no_undef (i32 %x ) {
1182+ ; CHECK-LABEL: @ashr_no_undef(
1183+ ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
1184+ ; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
1185+ ; CHECK-NEXT: ret i32 [[RES]]
1186+ ;
1187+ %a = ashr exact i32 %x , 3
1188+ %res = mul nsw i32 %a , 9
1189+ ret i32 %res
1190+ }
1191+
1192+ define i32 @lshr_multiuse (i32 noundef %x ) {
1193+ ; CHECK-LABEL: @lshr_multiuse(
1194+ ; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
1195+ ; CHECK-NEXT: call void @use(i32 [[A]])
1196+ ; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], 9
1197+ ; CHECK-NEXT: ret i32 [[RES]]
1198+ ;
1199+ %a = lshr exact i32 %x , 3
1200+ call void @use (i32 %a )
1201+ %res = mul nsw i32 %a , 9
1202+ ret i32 %res
1203+ }
1204+
1205+ define i32 @lshr_multiuse_no_flags (i32 noundef %x ) {
1206+ ; CHECK-LABEL: @lshr_multiuse_no_flags(
1207+ ; CHECK-NEXT: [[A:%.*]] = lshr exact i32 [[X:%.*]], 3
1208+ ; CHECK-NEXT: call void @use(i32 [[A]])
1209+ ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
1210+ ; CHECK-NEXT: ret i32 [[RES]]
1211+ ;
1212+ %a = lshr exact i32 %x , 3
1213+ call void @use (i32 %a )
1214+ %res = mul i32 %a , 9
1215+ ret i32 %res
1216+ }
1217+
1218+ define i32 @ashr_multiuse_no_flags (i32 noundef %x ) {
1219+ ; CHECK-LABEL: @ashr_multiuse_no_flags(
1220+ ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
1221+ ; CHECK-NEXT: call void @use(i32 [[A]])
1222+ ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A]], 9
1223+ ; CHECK-NEXT: ret i32 [[RES]]
1224+ ;
1225+ %a = ashr exact i32 %x , 3
1226+ call void @use (i32 %a )
1227+ %res = mul i32 %a , 9
1228+ ret i32 %res
1229+ }
1230+
1231+ define i32 @ashr_multiuse (i32 noundef %x ) {
1232+ ; CHECK-LABEL: @ashr_multiuse(
1233+ ; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], 3
1234+ ; CHECK-NEXT: call void @use(i32 [[A]])
1235+ ; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], 9
1236+ ; CHECK-NEXT: ret i32 [[RES]]
1237+ ;
1238+ %a = ashr exact i32 %x , 3
1239+ call void @use (i32 %a )
1240+ %res = mul nsw i32 %a , 9
1241+ ret i32 %res
10781242}
10791243
10801244declare void @use (i32 )
0 commit comments