|
2 | 2 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
3 | 3 |
|
4 | 4 | declare void @use(i8)
|
| 5 | +declare void @use32(i32) |
5 | 6 |
|
6 | 7 | declare i8 @llvm.umin.i8(i8, i8)
|
7 | 8 | declare i8 @llvm.umax.i8(i8, i8)
|
@@ -1025,3 +1026,257 @@ define i8 @udiv_shl_no_overflow(i8 %x, i8 %y) {
|
1025 | 1026 | %mul = udiv i8 %x, %min
|
1026 | 1027 | ret i8 %mul
|
1027 | 1028 | }
|
| 1029 | + |
| 1030 | +; (X<<Y) / (X<<Z) -> 1 << Y >> Z |
| 1031 | + |
| 1032 | +define i32 @sdiv_shl_pair_const(i32 %a) { |
| 1033 | +; CHECK-LABEL: @sdiv_shl_pair_const( |
| 1034 | +; CHECK-NEXT: entry: |
| 1035 | +; CHECK-NEXT: ret i32 2 |
| 1036 | +; |
| 1037 | +entry: |
| 1038 | + %lhs = shl nsw i32 %a, 2 |
| 1039 | + %rhs = shl nsw i32 %a, 1 |
| 1040 | + %div = sdiv i32 %lhs, %rhs |
| 1041 | + ret i32 %div |
| 1042 | +} |
| 1043 | + |
| 1044 | +define i32 @udiv_shl_pair_const(i32 %a) { |
| 1045 | +; CHECK-LABEL: @udiv_shl_pair_const( |
| 1046 | +; CHECK-NEXT: entry: |
| 1047 | +; CHECK-NEXT: ret i32 2 |
| 1048 | +; |
| 1049 | +entry: |
| 1050 | + %lhs = shl nuw i32 %a, 2 |
| 1051 | + %rhs = shl nuw i32 %a, 1 |
| 1052 | + %div = udiv i32 %lhs, %rhs |
| 1053 | + ret i32 %div |
| 1054 | +} |
| 1055 | + |
| 1056 | +define i32 @sdiv_shl_pair1(i32 %a, i32 %x, i32 %y) { |
| 1057 | +; CHECK-LABEL: @sdiv_shl_pair1( |
| 1058 | +; CHECK-NEXT: entry: |
| 1059 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] |
| 1060 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1061 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1062 | +; |
| 1063 | +entry: |
| 1064 | + %lhs = shl nsw i32 %a, %x |
| 1065 | + %rhs = shl nuw nsw i32 %a, %y |
| 1066 | + %div = sdiv i32 %lhs, %rhs |
| 1067 | + ret i32 %div |
| 1068 | +} |
| 1069 | + |
| 1070 | +define i32 @sdiv_shl_pair2(i32 %a, i32 %x, i32 %y) { |
| 1071 | +; CHECK-LABEL: @sdiv_shl_pair2( |
| 1072 | +; CHECK-NEXT: entry: |
| 1073 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] |
| 1074 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1075 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1076 | +; |
| 1077 | +entry: |
| 1078 | + %lhs = shl nuw nsw i32 %a, %x |
| 1079 | + %rhs = shl nsw i32 %a, %y |
| 1080 | + %div = sdiv i32 %lhs, %rhs |
| 1081 | + ret i32 %div |
| 1082 | +} |
| 1083 | + |
| 1084 | +define i32 @sdiv_shl_pair3(i32 %a, i32 %x, i32 %y) { |
| 1085 | +; CHECK-LABEL: @sdiv_shl_pair3( |
| 1086 | +; CHECK-NEXT: entry: |
| 1087 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]] |
| 1088 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1089 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1090 | +; |
| 1091 | +entry: |
| 1092 | + %lhs = shl nsw i32 %a, %x |
| 1093 | + %rhs = shl nsw i32 %a, %y |
| 1094 | + %div = sdiv i32 %lhs, %rhs |
| 1095 | + ret i32 %div |
| 1096 | +} |
| 1097 | + |
| 1098 | +define i32 @sdiv_shl_no_pair_fail(i32 %a, i32 %b, i32 %x, i32 %y) { |
| 1099 | +; CHECK-LABEL: @sdiv_shl_no_pair_fail( |
| 1100 | +; CHECK-NEXT: entry: |
| 1101 | +; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] |
| 1102 | +; CHECK-NEXT: [[RHS:%.*]] = shl nuw i32 [[B:%.*]], [[Y:%.*]] |
| 1103 | +; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]] |
| 1104 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1105 | +; |
| 1106 | +entry: |
| 1107 | + %lhs = shl nuw nsw i32 %a, %x |
| 1108 | + %rhs = shl nuw i32 %b, %y |
| 1109 | + %div = sdiv i32 %lhs, %rhs |
| 1110 | + ret i32 %div |
| 1111 | +} |
| 1112 | + |
| 1113 | +define i32 @udiv_shl_pair1(i32 %a, i32 %x, i32 %y) { |
| 1114 | +; CHECK-LABEL: @udiv_shl_pair1( |
| 1115 | +; CHECK-NEXT: entry: |
| 1116 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]] |
| 1117 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1118 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1119 | +; |
| 1120 | +entry: |
| 1121 | + %lhs = shl nuw i32 %a, %x |
| 1122 | + %rhs = shl nuw i32 %a, %y |
| 1123 | + %div = udiv i32 %lhs, %rhs |
| 1124 | + ret i32 %div |
| 1125 | +} |
| 1126 | + |
| 1127 | +define i32 @udiv_shl_pair2(i32 %a, i32 %x, i32 %y) { |
| 1128 | +; CHECK-LABEL: @udiv_shl_pair2( |
| 1129 | +; CHECK-NEXT: entry: |
| 1130 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] |
| 1131 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1132 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1133 | +; |
| 1134 | +entry: |
| 1135 | + %lhs = shl nuw nsw i32 %a, %x |
| 1136 | + %rhs = shl nuw i32 %a, %y |
| 1137 | + %div = udiv i32 %lhs, %rhs |
| 1138 | + ret i32 %div |
| 1139 | +} |
| 1140 | + |
| 1141 | +define i32 @udiv_shl_pair3(i32 %a, i32 %x, i32 %y) { |
| 1142 | +; CHECK-LABEL: @udiv_shl_pair3( |
| 1143 | +; CHECK-NEXT: entry: |
| 1144 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]] |
| 1145 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1146 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1147 | +; |
| 1148 | +entry: |
| 1149 | + %lhs = shl nuw i32 %a, %x |
| 1150 | + %rhs = shl nuw nsw i32 %a, %y |
| 1151 | + %div = udiv i32 %lhs, %rhs |
| 1152 | + ret i32 %div |
| 1153 | +} |
| 1154 | + |
| 1155 | +define i32 @sdiv_shl_pair_overflow_fail1(i32 %a, i32 %x, i32 %y) { |
| 1156 | +; CHECK-LABEL: @sdiv_shl_pair_overflow_fail1( |
| 1157 | +; CHECK-NEXT: entry: |
| 1158 | +; CHECK-NEXT: [[LHS:%.*]] = shl i32 [[A:%.*]], [[X:%.*]] |
| 1159 | +; CHECK-NEXT: [[RHS:%.*]] = shl nsw i32 [[A]], [[Y:%.*]] |
| 1160 | +; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]] |
| 1161 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1162 | +; |
| 1163 | +entry: |
| 1164 | + %lhs = shl i32 %a, %x |
| 1165 | + %rhs = shl nsw i32 %a, %y |
| 1166 | + %div = sdiv i32 %lhs, %rhs |
| 1167 | + ret i32 %div |
| 1168 | +} |
| 1169 | + |
| 1170 | +define i32 @sdiv_shl_pair_overflow_fail2(i32 %a, i32 %x, i32 %y) { |
| 1171 | +; CHECK-LABEL: @sdiv_shl_pair_overflow_fail2( |
| 1172 | +; CHECK-NEXT: entry: |
| 1173 | +; CHECK-NEXT: [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]] |
| 1174 | +; CHECK-NEXT: [[RHS:%.*]] = shl nuw i32 [[A]], [[Y:%.*]] |
| 1175 | +; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]] |
| 1176 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1177 | +; |
| 1178 | +entry: |
| 1179 | + %lhs = shl nsw i32 %a, %x |
| 1180 | + %rhs = shl nuw i32 %a, %y |
| 1181 | + %div = sdiv i32 %lhs, %rhs |
| 1182 | + ret i32 %div |
| 1183 | +} |
| 1184 | + |
| 1185 | +define i32 @udiv_shl_pair_overflow_fail1(i32 %a, i32 %x, i32 %y) { |
| 1186 | +; CHECK-LABEL: @udiv_shl_pair_overflow_fail1( |
| 1187 | +; CHECK-NEXT: entry: |
| 1188 | +; CHECK-NEXT: [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]] |
| 1189 | +; CHECK-NEXT: [[RHS:%.*]] = shl nuw i32 [[A]], [[Y:%.*]] |
| 1190 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]] |
| 1191 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1192 | +; |
| 1193 | +entry: |
| 1194 | + %lhs = shl nsw i32 %a, %x |
| 1195 | + %rhs = shl nuw i32 %a, %y |
| 1196 | + %div = udiv i32 %lhs, %rhs |
| 1197 | + ret i32 %div |
| 1198 | +} |
| 1199 | + |
| 1200 | +define i32 @udiv_shl_pair_overflow_fail2(i32 %a, i32 %x, i32 %y) { |
| 1201 | +; CHECK-LABEL: @udiv_shl_pair_overflow_fail2( |
| 1202 | +; CHECK-NEXT: entry: |
| 1203 | +; CHECK-NEXT: [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]] |
| 1204 | +; CHECK-NEXT: [[RHS:%.*]] = shl i32 [[A]], [[Y:%.*]] |
| 1205 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]] |
| 1206 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1207 | +; |
| 1208 | +entry: |
| 1209 | + %lhs = shl nsw i32 %a, %x |
| 1210 | + %rhs = shl i32 %a, %y |
| 1211 | + %div = udiv i32 %lhs, %rhs |
| 1212 | + ret i32 %div |
| 1213 | +} |
| 1214 | + |
| 1215 | +define i32 @udiv_shl_pair_overflow_fail3(i32 %a, i32 %x, i32 %y) { |
| 1216 | +; CHECK-LABEL: @udiv_shl_pair_overflow_fail3( |
| 1217 | +; CHECK-NEXT: entry: |
| 1218 | +; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] |
| 1219 | +; CHECK-NEXT: [[RHS:%.*]] = shl i32 [[A]], [[Y:%.*]] |
| 1220 | +; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]] |
| 1221 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1222 | +; |
| 1223 | +entry: |
| 1224 | + %lhs = shl nuw nsw i32 %a, %x |
| 1225 | + %rhs = shl i32 %a, %y |
| 1226 | + %div = udiv i32 %lhs, %rhs |
| 1227 | + ret i32 %div |
| 1228 | +} |
| 1229 | + |
| 1230 | +define i32 @sdiv_shl_pair_multiuse1(i32 %a, i32 %x, i32 %y) { |
| 1231 | +; CHECK-LABEL: @sdiv_shl_pair_multiuse1( |
| 1232 | +; CHECK-NEXT: entry: |
| 1233 | +; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] |
| 1234 | +; CHECK-NEXT: call void @use32(i32 [[LHS]]) |
| 1235 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X]] |
| 1236 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]] |
| 1237 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1238 | +; |
| 1239 | +entry: |
| 1240 | + %lhs = shl nuw nsw i32 %a, %x |
| 1241 | + call void @use32(i32 %lhs) |
| 1242 | + %rhs = shl nsw i32 %a, %y |
| 1243 | + %div = sdiv i32 %lhs, %rhs |
| 1244 | + ret i32 %div |
| 1245 | +} |
| 1246 | + |
| 1247 | +define i32 @sdiv_shl_pair_multiuse2(i32 %a, i32 %x, i32 %y) { |
| 1248 | +; CHECK-LABEL: @sdiv_shl_pair_multiuse2( |
| 1249 | +; CHECK-NEXT: entry: |
| 1250 | +; CHECK-NEXT: [[RHS:%.*]] = shl nsw i32 [[A:%.*]], [[Y:%.*]] |
| 1251 | +; CHECK-NEXT: call void @use32(i32 [[RHS]]) |
| 1252 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]] |
| 1253 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y]] |
| 1254 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1255 | +; |
| 1256 | +entry: |
| 1257 | + %lhs = shl nuw nsw i32 %a, %x |
| 1258 | + %rhs = shl nsw i32 %a, %y |
| 1259 | + call void @use32(i32 %rhs) |
| 1260 | + %div = sdiv i32 %lhs, %rhs |
| 1261 | + ret i32 %div |
| 1262 | +} |
| 1263 | + |
| 1264 | +define i32 @sdiv_shl_pair_multiuse3(i32 %a, i32 %x, i32 %y) { |
| 1265 | +; CHECK-LABEL: @sdiv_shl_pair_multiuse3( |
| 1266 | +; CHECK-NEXT: entry: |
| 1267 | +; CHECK-NEXT: [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]] |
| 1268 | +; CHECK-NEXT: [[RHS:%.*]] = shl nsw i32 [[A]], [[Y:%.*]] |
| 1269 | +; CHECK-NEXT: call void @use32(i32 [[LHS]]) |
| 1270 | +; CHECK-NEXT: call void @use32(i32 [[RHS]]) |
| 1271 | +; CHECK-NEXT: [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X]] |
| 1272 | +; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y]] |
| 1273 | +; CHECK-NEXT: ret i32 [[DIV]] |
| 1274 | +; |
| 1275 | +entry: |
| 1276 | + %lhs = shl nuw nsw i32 %a, %x |
| 1277 | + %rhs = shl nsw i32 %a, %y |
| 1278 | + call void @use32(i32 %lhs) |
| 1279 | + call void @use32(i32 %rhs) |
| 1280 | + %div = sdiv i32 %lhs, %rhs |
| 1281 | + ret i32 %div |
| 1282 | +} |
0 commit comments