895 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=arm64-unknown | FileCheck %s3 4; ptr p; // p is 1 byte aligned5; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)6define i32 @load_i32_by_i8_unaligned(ptr %arg) {7; CHECK-LABEL: load_i32_by_i8_unaligned:8; CHECK: // %bb.0:9; CHECK-NEXT: ldr w0, [x0]10; CHECK-NEXT: ret11 %tmp2 = load i8, ptr %arg, align 112 %tmp3 = zext i8 %tmp2 to i3213 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 114 %tmp5 = load i8, ptr %tmp4, align 115 %tmp6 = zext i8 %tmp5 to i3216 %tmp7 = shl nuw nsw i32 %tmp6, 817 %tmp8 = or i32 %tmp7, %tmp318 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 219 %tmp10 = load i8, ptr %tmp9, align 120 %tmp11 = zext i8 %tmp10 to i3221 %tmp12 = shl nuw nsw i32 %tmp11, 1622 %tmp13 = or i32 %tmp8, %tmp1223 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 324 %tmp15 = load i8, ptr %tmp14, align 125 %tmp16 = zext i8 %tmp15 to i3226 %tmp17 = shl nuw nsw i32 %tmp16, 2427 %tmp18 = or i32 %tmp13, %tmp1728 ret i32 %tmp1829}30 31; ptr p; // p is 4 byte aligned32; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)33define i32 @load_i32_by_i8_aligned(ptr %arg) {34; CHECK-LABEL: load_i32_by_i8_aligned:35; CHECK: // %bb.0:36; CHECK-NEXT: ldr w0, [x0]37; CHECK-NEXT: ret38 %tmp2 = load i8, ptr %arg, align 439 %tmp3 = zext i8 %tmp2 to i3240 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 141 %tmp5 = load i8, ptr %tmp4, align 142 %tmp6 = zext i8 %tmp5 to i3243 %tmp7 = shl nuw nsw i32 %tmp6, 844 %tmp8 = or i32 %tmp7, %tmp345 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 246 %tmp10 = load i8, ptr %tmp9, align 147 %tmp11 = zext i8 %tmp10 to i3248 %tmp12 = shl nuw nsw i32 %tmp11, 1649 %tmp13 = or i32 %tmp8, %tmp1250 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 351 %tmp15 = load i8, ptr %tmp14, align 152 %tmp16 = zext i8 %tmp15 to i3253 %tmp17 = shl nuw nsw i32 %tmp16, 2454 %tmp18 = or i32 %tmp13, %tmp1755 ret i32 %tmp1856}57 58; ptr p; // p is 4 byte aligned59; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]60define i32 @load_i32_by_i8_bswap(ptr %arg) {61; CHECK-LABEL: load_i32_by_i8_bswap:62; CHECK: // %bb.0:63; CHECK-NEXT: ldr w8, [x0]64; CHECK-NEXT: rev w0, w865; CHECK-NEXT: ret66 %tmp1 = load i8, ptr %arg, align 467 %tmp2 = zext i8 %tmp1 to i3268 %tmp3 = shl nuw nsw i32 %tmp2, 2469 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 170 %tmp5 = load i8, ptr %tmp4, align 171 %tmp6 = zext i8 %tmp5 to i3272 %tmp7 = shl nuw nsw i32 %tmp6, 1673 %tmp8 = or i32 %tmp7, %tmp374 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 275 %tmp10 = load i8, ptr %tmp9, align 176 %tmp11 = zext i8 %tmp10 to i3277 %tmp12 = shl nuw nsw i32 %tmp11, 878 %tmp13 = or i32 %tmp8, %tmp1279 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 380 %tmp15 = load i8, ptr %tmp14, align 181 %tmp16 = zext i8 %tmp15 to i3282 %tmp17 = or i32 %tmp13, %tmp1683 ret i32 %tmp1784}85 86; ptr p; // p is 8 byte aligned87; (i64) p[0] | ((i64) p[1] << 8) | ((i64) p[2] << 16) | ((i64) p[3] << 24) | ((i64) p[4] << 32) | ((i64) p[5] << 40) | ((i64) p[6] << 48) | ((i64) p[7] << 56)88define i64 @load_i64_by_i8(ptr %arg) {89; CHECK-LABEL: load_i64_by_i8:90; CHECK: // %bb.0:91; CHECK-NEXT: ldr x0, [x0]92; CHECK-NEXT: ret93 %tmp1 = load i8, ptr %arg, align 894 %tmp2 = zext i8 %tmp1 to i6495 %tmp3 = getelementptr inbounds i8, ptr %arg, i64 196 %tmp4 = load i8, ptr %tmp3, align 197 %tmp5 = zext i8 %tmp4 to i6498 %tmp6 = shl nuw nsw i64 %tmp5, 899 %tmp7 = or i64 %tmp6, %tmp2100 %tmp8 = getelementptr inbounds i8, ptr %arg, i64 2101 %tmp9 = load i8, ptr %tmp8, align 1102 %tmp10 = zext i8 %tmp9 to i64103 %tmp11 = shl nuw nsw i64 %tmp10, 16104 %tmp12 = or i64 %tmp7, %tmp11105 %tmp13 = getelementptr inbounds i8, ptr %arg, i64 3106 %tmp14 = load i8, ptr %tmp13, align 1107 %tmp15 = zext i8 %tmp14 to i64108 %tmp16 = shl nuw nsw i64 %tmp15, 24109 %tmp17 = or i64 %tmp12, %tmp16110 %tmp18 = getelementptr inbounds i8, ptr %arg, i64 4111 %tmp19 = load i8, ptr %tmp18, align 1112 %tmp20 = zext i8 %tmp19 to i64113 %tmp21 = shl nuw nsw i64 %tmp20, 32114 %tmp22 = or i64 %tmp17, %tmp21115 %tmp23 = getelementptr inbounds i8, ptr %arg, i64 5116 %tmp24 = load i8, ptr %tmp23, align 1117 %tmp25 = zext i8 %tmp24 to i64118 %tmp26 = shl nuw nsw i64 %tmp25, 40119 %tmp27 = or i64 %tmp22, %tmp26120 %tmp28 = getelementptr inbounds i8, ptr %arg, i64 6121 %tmp29 = load i8, ptr %tmp28, align 1122 %tmp30 = zext i8 %tmp29 to i64123 %tmp31 = shl nuw nsw i64 %tmp30, 48124 %tmp32 = or i64 %tmp27, %tmp31125 %tmp33 = getelementptr inbounds i8, ptr %arg, i64 7126 %tmp34 = load i8, ptr %tmp33, align 1127 %tmp35 = zext i8 %tmp34 to i64128 %tmp36 = shl nuw i64 %tmp35, 56129 %tmp37 = or i64 %tmp32, %tmp36130 ret i64 %tmp37131}132 133; ptr p; // p is 8 byte aligned134; ((i64) p[0] << 56) | ((i64) p[1] << 48) | ((i64) p[2] << 40) | ((i64) p[3] << 32) | ((i64) p[4] << 24) | ((i64) p[5] << 16) | ((i64) p[6] << 8) | (i64) p[7]135define i64 @load_i64_by_i8_bswap(ptr %arg) {136; CHECK-LABEL: load_i64_by_i8_bswap:137; CHECK: // %bb.0:138; CHECK-NEXT: ldr x8, [x0]139; CHECK-NEXT: rev x0, x8140; CHECK-NEXT: ret141 %tmp1 = load i8, ptr %arg, align 8142 %tmp2 = zext i8 %tmp1 to i64143 %tmp3 = shl nuw i64 %tmp2, 56144 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1145 %tmp5 = load i8, ptr %tmp4, align 1146 %tmp6 = zext i8 %tmp5 to i64147 %tmp7 = shl nuw nsw i64 %tmp6, 48148 %tmp8 = or i64 %tmp7, %tmp3149 %tmp9 = getelementptr inbounds i8, ptr %arg, i64 2150 %tmp10 = load i8, ptr %tmp9, align 1151 %tmp11 = zext i8 %tmp10 to i64152 %tmp12 = shl nuw nsw i64 %tmp11, 40153 %tmp13 = or i64 %tmp8, %tmp12154 %tmp14 = getelementptr inbounds i8, ptr %arg, i64 3155 %tmp15 = load i8, ptr %tmp14, align 1156 %tmp16 = zext i8 %tmp15 to i64157 %tmp17 = shl nuw nsw i64 %tmp16, 32158 %tmp18 = or i64 %tmp13, %tmp17159 %tmp19 = getelementptr inbounds i8, ptr %arg, i64 4160 %tmp20 = load i8, ptr %tmp19, align 1161 %tmp21 = zext i8 %tmp20 to i64162 %tmp22 = shl nuw nsw i64 %tmp21, 24163 %tmp23 = or i64 %tmp18, %tmp22164 %tmp24 = getelementptr inbounds i8, ptr %arg, i64 5165 %tmp25 = load i8, ptr %tmp24, align 1166 %tmp26 = zext i8 %tmp25 to i64167 %tmp27 = shl nuw nsw i64 %tmp26, 16168 %tmp28 = or i64 %tmp23, %tmp27169 %tmp29 = getelementptr inbounds i8, ptr %arg, i64 6170 %tmp30 = load i8, ptr %tmp29, align 1171 %tmp31 = zext i8 %tmp30 to i64172 %tmp32 = shl nuw nsw i64 %tmp31, 8173 %tmp33 = or i64 %tmp28, %tmp32174 %tmp34 = getelementptr inbounds i8, ptr %arg, i64 7175 %tmp35 = load i8, ptr %tmp34, align 1176 %tmp36 = zext i8 %tmp35 to i64177 %tmp37 = or i64 %tmp33, %tmp36178 ret i64 %tmp37179}180 181; ptr p; // p[1] is 4 byte aligned182; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24)183define i32 @load_i32_by_i8_nonzero_offset(ptr %arg) {184; CHECK-LABEL: load_i32_by_i8_nonzero_offset:185; CHECK: // %bb.0:186; CHECK-NEXT: ldur w0, [x0, #1]187; CHECK-NEXT: ret188 189 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1190 %tmp2 = load i8, ptr %tmp1, align 4191 %tmp3 = zext i8 %tmp2 to i32192 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2193 %tmp5 = load i8, ptr %tmp4, align 1194 %tmp6 = zext i8 %tmp5 to i32195 %tmp7 = shl nuw nsw i32 %tmp6, 8196 %tmp8 = or i32 %tmp7, %tmp3197 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3198 %tmp10 = load i8, ptr %tmp9, align 1199 %tmp11 = zext i8 %tmp10 to i32200 %tmp12 = shl nuw nsw i32 %tmp11, 16201 %tmp13 = or i32 %tmp8, %tmp12202 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 4203 %tmp15 = load i8, ptr %tmp14, align 1204 %tmp16 = zext i8 %tmp15 to i32205 %tmp17 = shl nuw nsw i32 %tmp16, 24206 %tmp18 = or i32 %tmp13, %tmp17207 ret i32 %tmp18208}209 210; ptr p; // p[-4] is 4 byte aligned211; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24)212define i32 @load_i32_by_i8_neg_offset(ptr %arg) {213; CHECK-LABEL: load_i32_by_i8_neg_offset:214; CHECK: // %bb.0:215; CHECK-NEXT: ldur w0, [x0, #-4]216; CHECK-NEXT: ret217 218 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -4219 %tmp2 = load i8, ptr %tmp1, align 4220 %tmp3 = zext i8 %tmp2 to i32221 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -3222 %tmp5 = load i8, ptr %tmp4, align 1223 %tmp6 = zext i8 %tmp5 to i32224 %tmp7 = shl nuw nsw i32 %tmp6, 8225 %tmp8 = or i32 %tmp7, %tmp3226 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -2227 %tmp10 = load i8, ptr %tmp9, align 1228 %tmp11 = zext i8 %tmp10 to i32229 %tmp12 = shl nuw nsw i32 %tmp11, 16230 %tmp13 = or i32 %tmp8, %tmp12231 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -1232 %tmp15 = load i8, ptr %tmp14, align 1233 %tmp16 = zext i8 %tmp15 to i32234 %tmp17 = shl nuw nsw i32 %tmp16, 24235 %tmp18 = or i32 %tmp13, %tmp17236 ret i32 %tmp18237}238 239; ptr p; // p[1] is 4 byte aligned240; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24)241define i32 @load_i32_by_i8_nonzero_offset_bswap(ptr %arg) {242; CHECK-LABEL: load_i32_by_i8_nonzero_offset_bswap:243; CHECK: // %bb.0:244; CHECK-NEXT: ldur w8, [x0, #1]245; CHECK-NEXT: rev w0, w8246; CHECK-NEXT: ret247 248 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 4249 %tmp2 = load i8, ptr %tmp1, align 1250 %tmp3 = zext i8 %tmp2 to i32251 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 3252 %tmp5 = load i8, ptr %tmp4, align 1253 %tmp6 = zext i8 %tmp5 to i32254 %tmp7 = shl nuw nsw i32 %tmp6, 8255 %tmp8 = or i32 %tmp7, %tmp3256 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2257 %tmp10 = load i8, ptr %tmp9, align 1258 %tmp11 = zext i8 %tmp10 to i32259 %tmp12 = shl nuw nsw i32 %tmp11, 16260 %tmp13 = or i32 %tmp8, %tmp12261 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 1262 %tmp15 = load i8, ptr %tmp14, align 4263 %tmp16 = zext i8 %tmp15 to i32264 %tmp17 = shl nuw nsw i32 %tmp16, 24265 %tmp18 = or i32 %tmp13, %tmp17266 ret i32 %tmp18267}268 269; ptr p; // p[-4] is 4 byte aligned270; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24)271define i32 @load_i32_by_i8_neg_offset_bswap(ptr %arg) {272; CHECK-LABEL: load_i32_by_i8_neg_offset_bswap:273; CHECK: // %bb.0:274; CHECK-NEXT: ldur w8, [x0, #-4]275; CHECK-NEXT: rev w0, w8276; CHECK-NEXT: ret277 278 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -1279 %tmp2 = load i8, ptr %tmp1, align 1280 %tmp3 = zext i8 %tmp2 to i32281 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -2282 %tmp5 = load i8, ptr %tmp4, align 1283 %tmp6 = zext i8 %tmp5 to i32284 %tmp7 = shl nuw nsw i32 %tmp6, 8285 %tmp8 = or i32 %tmp7, %tmp3286 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -3287 %tmp10 = load i8, ptr %tmp9, align 1288 %tmp11 = zext i8 %tmp10 to i32289 %tmp12 = shl nuw nsw i32 %tmp11, 16290 %tmp13 = or i32 %tmp8, %tmp12291 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -4292 %tmp15 = load i8, ptr %tmp14, align 4293 %tmp16 = zext i8 %tmp15 to i32294 %tmp17 = shl nuw nsw i32 %tmp16, 24295 %tmp18 = or i32 %tmp13, %tmp17296 ret i32 %tmp18297}298 299declare i16 @llvm.bswap.i16(i16)300 301; ptr p; // p is 4 byte aligned302; (i32) bswap(p[1]) | (i32) bswap(p[0] << 16)303define i32 @load_i32_by_bswap_i16(ptr %arg) {304; CHECK-LABEL: load_i32_by_bswap_i16:305; CHECK: // %bb.0:306; CHECK-NEXT: ldr w8, [x0]307; CHECK-NEXT: rev w0, w8308; CHECK-NEXT: ret309 310 %tmp1 = load i16, ptr %arg, align 4311 %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1)312 %tmp2 = zext i16 %tmp11 to i32313 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1314 %tmp4 = load i16, ptr %tmp3, align 1315 %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4)316 %tmp5 = zext i16 %tmp41 to i32317 %tmp6 = shl nuw nsw i32 %tmp2, 16318 %tmp7 = or i32 %tmp6, %tmp5319 ret i32 %tmp7320}321 322; ptr p; // p is 4 byte aligned323; (i32) p[0] | (sext(p[1] << 16) to i32)324define i32 @load_i32_by_sext_i16(ptr %arg) {325; CHECK-LABEL: load_i32_by_sext_i16:326; CHECK: // %bb.0:327; CHECK-NEXT: ldr w0, [x0]328; CHECK-NEXT: ret329 %tmp1 = load i16, ptr %arg, align 4330 %tmp2 = zext i16 %tmp1 to i32331 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1332 %tmp4 = load i16, ptr %tmp3, align 1333 %tmp5 = sext i16 %tmp4 to i32334 %tmp6 = shl nuw nsw i32 %tmp5, 16335 %tmp7 = or i32 %tmp6, %tmp2336 ret i32 %tmp7337}338 339; ptr arg; i32 i;340; p = arg + 12;341; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24)342define i32 @load_i32_by_i8_base_offset_index(ptr %arg, i32 %i) {343; CHECK-LABEL: load_i32_by_i8_base_offset_index:344; CHECK: // %bb.0:345; CHECK-NEXT: add x8, x0, w1, uxtw346; CHECK-NEXT: ldr w0, [x8, #12]347; CHECK-NEXT: ret348 %tmp = add nuw nsw i32 %i, 3349 %tmp2 = add nuw nsw i32 %i, 2350 %tmp3 = add nuw nsw i32 %i, 1351 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12352 %tmp5 = zext i32 %i to i64353 %tmp6 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp5354 %tmp7 = load i8, ptr %tmp6, align 4355 %tmp8 = zext i8 %tmp7 to i32356 %tmp9 = zext i32 %tmp3 to i64357 %tmp10 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp9358 %tmp11 = load i8, ptr %tmp10, align 1359 %tmp12 = zext i8 %tmp11 to i32360 %tmp13 = shl nuw nsw i32 %tmp12, 8361 %tmp14 = or i32 %tmp13, %tmp8362 %tmp15 = zext i32 %tmp2 to i64363 %tmp16 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp15364 %tmp17 = load i8, ptr %tmp16, align 1365 %tmp18 = zext i8 %tmp17 to i32366 %tmp19 = shl nuw nsw i32 %tmp18, 16367 %tmp20 = or i32 %tmp14, %tmp19368 %tmp21 = zext i32 %tmp to i64369 %tmp22 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp21370 %tmp23 = load i8, ptr %tmp22, align 1371 %tmp24 = zext i8 %tmp23 to i32372 %tmp25 = shl nuw i32 %tmp24, 24373 %tmp26 = or i32 %tmp20, %tmp25374 ret i32 %tmp26375}376 377; ptr arg; i32 i;378; p = arg + 12;379; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24)380define i32 @load_i32_by_i8_base_offset_index_2(ptr %arg, i32 %i) {381; CHECK-LABEL: load_i32_by_i8_base_offset_index_2:382; CHECK: // %bb.0:383; CHECK-NEXT: add x8, x0, w1, uxtw384; CHECK-NEXT: ldur w0, [x8, #13]385; CHECK-NEXT: ret386 %tmp = add nuw nsw i32 %i, 4387 %tmp2 = add nuw nsw i32 %i, 3388 %tmp3 = add nuw nsw i32 %i, 2389 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12390 %tmp5 = add nuw nsw i32 %i, 1391 %tmp27 = zext i32 %tmp5 to i64392 %tmp28 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp27393 %tmp29 = load i8, ptr %tmp28, align 4394 %tmp30 = zext i8 %tmp29 to i32395 %tmp31 = zext i32 %tmp3 to i64396 %tmp32 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp31397 %tmp33 = load i8, ptr %tmp32, align 1398 %tmp34 = zext i8 %tmp33 to i32399 %tmp35 = shl nuw nsw i32 %tmp34, 8400 %tmp36 = or i32 %tmp35, %tmp30401 %tmp37 = zext i32 %tmp2 to i64402 %tmp38 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp37403 %tmp39 = load i8, ptr %tmp38, align 1404 %tmp40 = zext i8 %tmp39 to i32405 %tmp41 = shl nuw nsw i32 %tmp40, 16406 %tmp42 = or i32 %tmp36, %tmp41407 %tmp43 = zext i32 %tmp to i64408 %tmp44 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp43409 %tmp45 = load i8, ptr %tmp44, align 1410 %tmp46 = zext i8 %tmp45 to i32411 %tmp47 = shl nuw i32 %tmp46, 24412 %tmp48 = or i32 %tmp42, %tmp47413 ret i32 %tmp48414}415 416; ptr p; // p is 2 byte aligned417; (i32) p[0] | ((i32) p[1] << 8)418define i32 @zext_load_i32_by_i8(ptr %arg) {419; CHECK-LABEL: zext_load_i32_by_i8:420; CHECK: // %bb.0:421; CHECK-NEXT: ldrh w0, [x0]422; CHECK-NEXT: ret423 424 %tmp2 = load i8, ptr %arg, align 2425 %tmp3 = zext i8 %tmp2 to i32426 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1427 %tmp5 = load i8, ptr %tmp4, align 1428 %tmp6 = zext i8 %tmp5 to i32429 %tmp7 = shl nuw nsw i32 %tmp6, 8430 %tmp8 = or i32 %tmp7, %tmp3431 ret i32 %tmp8432}433 434; ptr p; // p is 2 byte aligned435; ((i32) p[0] << 8) | ((i32) p[1] << 16)436define i32 @zext_load_i32_by_i8_shl_8(ptr %arg) {437; CHECK-LABEL: zext_load_i32_by_i8_shl_8:438; CHECK: // %bb.0:439; CHECK-NEXT: ldrb w8, [x0]440; CHECK-NEXT: ldrb w9, [x0, #1]441; CHECK-NEXT: lsl w8, w8, #8442; CHECK-NEXT: orr w0, w8, w9, lsl #16443; CHECK-NEXT: ret444 445 %tmp2 = load i8, ptr %arg, align 2446 %tmp3 = zext i8 %tmp2 to i32447 %tmp30 = shl nuw nsw i32 %tmp3, 8448 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1449 %tmp5 = load i8, ptr %tmp4, align 1450 %tmp6 = zext i8 %tmp5 to i32451 %tmp7 = shl nuw nsw i32 %tmp6, 16452 %tmp8 = or i32 %tmp7, %tmp30453 ret i32 %tmp8454}455 456; ptr p; // p is 2 byte aligned457; ((i32) p[0] << 16) | ((i32) p[1] << 24)458define i32 @zext_load_i32_by_i8_shl_16(ptr %arg) {459; CHECK-LABEL: zext_load_i32_by_i8_shl_16:460; CHECK: // %bb.0:461; CHECK-NEXT: ldrb w8, [x0]462; CHECK-NEXT: ldrb w9, [x0, #1]463; CHECK-NEXT: lsl w8, w8, #16464; CHECK-NEXT: orr w0, w8, w9, lsl #24465; CHECK-NEXT: ret466 467 %tmp2 = load i8, ptr %arg, align 2468 %tmp3 = zext i8 %tmp2 to i32469 %tmp30 = shl nuw nsw i32 %tmp3, 16470 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1471 %tmp5 = load i8, ptr %tmp4, align 1472 %tmp6 = zext i8 %tmp5 to i32473 %tmp7 = shl nuw nsw i32 %tmp6, 24474 %tmp8 = or i32 %tmp7, %tmp30475 ret i32 %tmp8476}477; ptr p; // p is 2 byte aligned478; (i32) p[1] | ((i32) p[0] << 8)479define i32 @zext_load_i32_by_i8_bswap(ptr %arg) {480; CHECK-LABEL: zext_load_i32_by_i8_bswap:481; CHECK: // %bb.0:482; CHECK-NEXT: ldrh w8, [x0]483; CHECK-NEXT: rev16 w0, w8484; CHECK-NEXT: ret485 486 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1487 %tmp2 = load i8, ptr %tmp1, align 1488 %tmp3 = zext i8 %tmp2 to i32489 %tmp5 = load i8, ptr %arg, align 2490 %tmp6 = zext i8 %tmp5 to i32491 %tmp7 = shl nuw nsw i32 %tmp6, 8492 %tmp8 = or i32 %tmp7, %tmp3493 ret i32 %tmp8494}495 496; ptr p; // p is 2 byte aligned497; ((i32) p[1] << 8) | ((i32) p[0] << 16)498define i32 @zext_load_i32_by_i8_bswap_shl_8(ptr %arg) {499; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8:500; CHECK: // %bb.0:501; CHECK-NEXT: ldrb w8, [x0, #1]502; CHECK-NEXT: ldrb w9, [x0]503; CHECK-NEXT: lsl w8, w8, #8504; CHECK-NEXT: orr w0, w8, w9, lsl #16505; CHECK-NEXT: ret506 507 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1508 %tmp2 = load i8, ptr %tmp1, align 1509 %tmp3 = zext i8 %tmp2 to i32510 %tmp30 = shl nuw nsw i32 %tmp3, 8511 %tmp5 = load i8, ptr %arg, align 2512 %tmp6 = zext i8 %tmp5 to i32513 %tmp7 = shl nuw nsw i32 %tmp6, 16514 %tmp8 = or i32 %tmp7, %tmp30515 ret i32 %tmp8516}517 518; ptr p; // p is 2 byte aligned519; ((i32) p[1] << 16) | ((i32) p[0] << 24)520define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {521; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16:522; CHECK: // %bb.0:523; CHECK-NEXT: ldrb w8, [x0, #1]524; CHECK-NEXT: ldrb w9, [x0]525; CHECK-NEXT: lsl w8, w8, #16526; CHECK-NEXT: orr w0, w8, w9, lsl #24527; CHECK-NEXT: ret528 529 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1530 %tmp2 = load i8, ptr %tmp1, align 1531 %tmp3 = zext i8 %tmp2 to i32532 %tmp30 = shl nuw nsw i32 %tmp3, 16533 %tmp5 = load i8, ptr %arg, align 2534 %tmp6 = zext i8 %tmp5 to i32535 %tmp7 = shl nuw nsw i32 %tmp6, 24536 %tmp8 = or i32 %tmp7, %tmp30537 ret i32 %tmp8538}539 540; x1 = x0541define void @short_vector_to_i32(ptr %in, ptr %out, ptr %p) {542; CHECK-LABEL: short_vector_to_i32:543; CHECK: // %bb.0:544; CHECK-NEXT: ldr w8, [x0]545; CHECK-NEXT: str w8, [x1]546; CHECK-NEXT: ret547 %ld = load <4 x i8>, ptr %in, align 4548 549 %e1 = extractelement <4 x i8> %ld, i32 0550 %e2 = extractelement <4 x i8> %ld, i32 1551 %e3 = extractelement <4 x i8> %ld, i32 2552 %e4 = extractelement <4 x i8> %ld, i32 3553 554 %z0 = zext i8 %e1 to i32555 %z1 = zext i8 %e2 to i32556 %z2 = zext i8 %e3 to i32557 %z3 = zext i8 %e4 to i32558 559 %s1 = shl nuw nsw i32 %z1, 8560 %s2 = shl nuw nsw i32 %z2, 16561 %s3 = shl nuw i32 %z3, 24562 563 %i1 = or i32 %s1, %z0564 %i2 = or i32 %i1, %s2565 %i3 = or i32 %i2, %s3566 567 store i32 %i3, ptr %out568 ret void569}570 571define void @short_vector_to_i32_unused_low_i8(ptr %in, ptr %out, ptr %p) {572; CHECK-LABEL: short_vector_to_i32_unused_low_i8:573; CHECK: // %bb.0:574; CHECK-NEXT: ldr s0, [x0]575; CHECK-NEXT: ushll v0.8h, v0.8b, #0576; CHECK-NEXT: umov w8, v0.h[2]577; CHECK-NEXT: umov w9, v0.h[1]578; CHECK-NEXT: umov w10, v0.h[3]579; CHECK-NEXT: lsl w8, w8, #16580; CHECK-NEXT: bfi w8, w9, #8, #8581; CHECK-NEXT: orr w8, w8, w10, lsl #24582; CHECK-NEXT: str w8, [x1]583; CHECK-NEXT: ret584 %ld = load <4 x i8>, ptr %in, align 4585 586 %e2 = extractelement <4 x i8> %ld, i32 1587 %e3 = extractelement <4 x i8> %ld, i32 2588 %e4 = extractelement <4 x i8> %ld, i32 3589 590 %z1 = zext i8 %e2 to i32591 %z2 = zext i8 %e3 to i32592 %z3 = zext i8 %e4 to i32593 594 %s1 = shl nuw nsw i32 %z1, 8595 %s2 = shl nuw nsw i32 %z2, 16596 %s3 = shl nuw i32 %z3, 24597 598 %i2 = or i32 %s1, %s2599 %i3 = or i32 %i2, %s3600 601 store i32 %i3, ptr %out602 ret void603}604 605define void @short_vector_to_i32_unused_high_i8(ptr %in, ptr %out, ptr %p) {606; CHECK-LABEL: short_vector_to_i32_unused_high_i8:607; CHECK: // %bb.0:608; CHECK-NEXT: ldr s0, [x0]609; CHECK-NEXT: ldrh w9, [x0]610; CHECK-NEXT: ushll v0.8h, v0.8b, #0611; CHECK-NEXT: umov w8, v0.h[2]612; CHECK-NEXT: orr w8, w9, w8, lsl #16613; CHECK-NEXT: str w8, [x1]614; CHECK-NEXT: ret615 %ld = load <4 x i8>, ptr %in, align 4616 617 %e1 = extractelement <4 x i8> %ld, i32 0618 %e2 = extractelement <4 x i8> %ld, i32 1619 %e3 = extractelement <4 x i8> %ld, i32 2620 621 %z0 = zext i8 %e1 to i32622 %z1 = zext i8 %e2 to i32623 %z2 = zext i8 %e3 to i32624 625 %s1 = shl nuw nsw i32 %z1, 8626 %s2 = shl nuw nsw i32 %z2, 16627 628 %i1 = or i32 %s1, %z0629 %i2 = or i32 %i1, %s2630 631 store i32 %i2, ptr %out632 ret void633}634 635define void @short_vector_to_i32_unused_low_i16(ptr %in, ptr %out, ptr %p) {636; CHECK-LABEL: short_vector_to_i32_unused_low_i16:637; CHECK: // %bb.0:638; CHECK-NEXT: ldr s0, [x0]639; CHECK-NEXT: ushll v0.8h, v0.8b, #0640; CHECK-NEXT: umov w8, v0.h[3]641; CHECK-NEXT: umov w9, v0.h[2]642; CHECK-NEXT: lsl w8, w8, #24643; CHECK-NEXT: orr w8, w8, w9, lsl #16644; CHECK-NEXT: str w8, [x1]645; CHECK-NEXT: ret646 %ld = load <4 x i8>, ptr %in, align 4647 648 %e3 = extractelement <4 x i8> %ld, i32 2649 %e4 = extractelement <4 x i8> %ld, i32 3650 651 %z2 = zext i8 %e3 to i32652 %z3 = zext i8 %e4 to i32653 654 %s2 = shl nuw nsw i32 %z2, 16655 %s3 = shl nuw i32 %z3, 24656 657 %i3 = or i32 %s2, %s3658 659 store i32 %i3, ptr %out660 ret void661}662 663; x1 = x0[0:1]664define void @short_vector_to_i32_unused_high_i16(ptr %in, ptr %out, ptr %p) {665; CHECK-LABEL: short_vector_to_i32_unused_high_i16:666; CHECK: // %bb.0:667; CHECK-NEXT: ldrh w8, [x0]668; CHECK-NEXT: str w8, [x1]669; CHECK-NEXT: ret670 %ld = load <4 x i8>, ptr %in, align 4671 672 %e1 = extractelement <4 x i8> %ld, i32 0673 %e2 = extractelement <4 x i8> %ld, i32 1674 675 %z0 = zext i8 %e1 to i32676 %z1 = zext i8 %e2 to i32677 678 %s1 = shl nuw nsw i32 %z1, 8679 680 %i1 = or i32 %s1, %z0681 682 store i32 %i1, ptr %out683 ret void684}685 686; x1 = x0687define void @short_vector_to_i64(ptr %in, ptr %out, ptr %p) {688; CHECK-LABEL: short_vector_to_i64:689; CHECK: // %bb.0:690; CHECK-NEXT: ldr w8, [x0]691; CHECK-NEXT: str x8, [x1]692; CHECK-NEXT: ret693 %ld = load <4 x i8>, ptr %in, align 4694 695 %e1 = extractelement <4 x i8> %ld, i32 0696 %e2 = extractelement <4 x i8> %ld, i32 1697 %e3 = extractelement <4 x i8> %ld, i32 2698 %e4 = extractelement <4 x i8> %ld, i32 3699 700 %z0 = zext i8 %e1 to i64701 %z1 = zext i8 %e2 to i64702 %z2 = zext i8 %e3 to i64703 %z3 = zext i8 %e4 to i64704 705 %s1 = shl nuw nsw i64 %z1, 8706 %s2 = shl nuw nsw i64 %z2, 16707 %s3 = shl nuw i64 %z3, 24708 709 %i1 = or i64 %s1, %z0710 %i2 = or i64 %i1, %s2711 %i3 = or i64 %i2, %s3712 713 store i64 %i3, ptr %out714 ret void715}716 717; x1 = x0718define void @scalable_vector_to_i32(ptr %in, ptr %out, ptr %p) #0 {719; CHECK-LABEL: scalable_vector_to_i32:720; CHECK: // %bb.0:721; CHECK-NEXT: ldr w8, [x0]722; CHECK-NEXT: str w8, [x1]723; CHECK-NEXT: ret724 %ld = load <vscale x 4 x i8>, ptr %in, align 4725 726 %e1 = extractelement <vscale x 4 x i8> %ld, i32 0727 %e2 = extractelement <vscale x 4 x i8> %ld, i32 1728 %e3 = extractelement <vscale x 4 x i8> %ld, i32 2729 %e4 = extractelement <vscale x 4 x i8> %ld, i32 3730 731 %z0 = zext i8 %e1 to i32732 %z1 = zext i8 %e2 to i32733 %z2 = zext i8 %e3 to i32734 %z3 = zext i8 %e4 to i32735 736 %s1 = shl nuw nsw i32 %z1, 8737 %s2 = shl nuw nsw i32 %z2, 16738 %s3 = shl nuw i32 %z3, 24739 740 %i1 = or i32 %s1, %z0741 %i2 = or i32 %i1, %s2742 %i3 = or i32 %i2, %s3743 744 store i32 %i3, ptr %out745 ret void746}747 748define void @scalable_vector_to_i32_unused_low_i8(ptr %in, ptr %out, ptr %p) #0 {749; CHECK-LABEL: scalable_vector_to_i32_unused_low_i8:750; CHECK: // %bb.0:751; CHECK-NEXT: ptrue p0.s752; CHECK-NEXT: ld1b { z0.s }, p0/z, [x0]753; CHECK-NEXT: mov w8, v0.s[1]754; CHECK-NEXT: mov w9, v0.s[2]755; CHECK-NEXT: mov w10, v0.s[3]756; CHECK-NEXT: lsl w8, w8, #8757; CHECK-NEXT: orr w8, w8, w9, lsl #16758; CHECK-NEXT: orr w8, w8, w10, lsl #24759; CHECK-NEXT: str w8, [x1]760; CHECK-NEXT: ret761 %ld = load <vscale x 4 x i8>, ptr %in, align 4762 763 %e2 = extractelement <vscale x 4 x i8> %ld, i32 1764 %e3 = extractelement <vscale x 4 x i8> %ld, i32 2765 %e4 = extractelement <vscale x 4 x i8> %ld, i32 3766 767 %z1 = zext i8 %e2 to i32768 %z2 = zext i8 %e3 to i32769 %z3 = zext i8 %e4 to i32770 771 %s1 = shl nuw nsw i32 %z1, 8772 %s2 = shl nuw nsw i32 %z2, 16773 %s3 = shl nuw i32 %z3, 24774 775 %i2 = or i32 %s1, %s2776 %i3 = or i32 %i2, %s3777 778 store i32 %i3, ptr %out779 ret void780}781 782define void @scalable_vector_to_i32_unused_high_i8(ptr %in, ptr %out, ptr %p) #0 {783; CHECK-LABEL: scalable_vector_to_i32_unused_high_i8:784; CHECK: // %bb.0:785; CHECK-NEXT: ptrue p0.s786; CHECK-NEXT: ldrh w9, [x0]787; CHECK-NEXT: ld1b { z0.s }, p0/z, [x0]788; CHECK-NEXT: mov w8, v0.s[2]789; CHECK-NEXT: orr w8, w9, w8, lsl #16790; CHECK-NEXT: str w8, [x1]791; CHECK-NEXT: ret792 %ld = load <vscale x 4 x i8>, ptr %in, align 4793 794 %e1 = extractelement <vscale x 4 x i8> %ld, i32 0795 %e2 = extractelement <vscale x 4 x i8> %ld, i32 1796 %e3 = extractelement <vscale x 4 x i8> %ld, i32 2797 798 %z0 = zext i8 %e1 to i32799 %z1 = zext i8 %e2 to i32800 %z2 = zext i8 %e3 to i32801 802 %s1 = shl nuw nsw i32 %z1, 8803 %s2 = shl nuw nsw i32 %z2, 16804 805 %i1 = or i32 %s1, %z0806 %i2 = or i32 %i1, %s2807 808 store i32 %i2, ptr %out809 ret void810}811 812define void @scalable_vector_to_i32_unused_low_i16(ptr %in, ptr %out, ptr %p) #0 {813; CHECK-LABEL: scalable_vector_to_i32_unused_low_i16:814; CHECK: // %bb.0:815; CHECK-NEXT: ptrue p0.s816; CHECK-NEXT: ld1b { z0.s }, p0/z, [x0]817; CHECK-NEXT: mov w8, v0.s[2]818; CHECK-NEXT: mov w9, v0.s[3]819; CHECK-NEXT: lsl w8, w8, #16820; CHECK-NEXT: orr w8, w8, w9, lsl #24821; CHECK-NEXT: str w8, [x1]822; CHECK-NEXT: ret823 %ld = load <vscale x 4 x i8>, ptr %in, align 4824 825 %e3 = extractelement <vscale x 4 x i8> %ld, i32 2826 %e4 = extractelement <vscale x 4 x i8> %ld, i32 3827 828 %z2 = zext i8 %e3 to i32829 %z3 = zext i8 %e4 to i32830 831 %s2 = shl nuw nsw i32 %z2, 16832 %s3 = shl nuw i32 %z3, 24833 834 %i3 = or i32 %s2, %s3835 836 store i32 %i3, ptr %out837 ret void838}839 840; x1 = x0[0:1]841define void @scalable_vector_to_i32_unused_high_i16(ptr %in, ptr %out, ptr %p) #0 {842; CHECK-LABEL: scalable_vector_to_i32_unused_high_i16:843; CHECK: // %bb.0:844; CHECK-NEXT: ldrh w8, [x0]845; CHECK-NEXT: str w8, [x1]846; CHECK-NEXT: ret847 %ld = load <vscale x 4 x i8>, ptr %in, align 4848 849 %e1 = extractelement <vscale x 4 x i8> %ld, i32 0850 %e2 = extractelement <vscale x 4 x i8> %ld, i32 1851 852 %z0 = zext i8 %e1 to i32853 %z1 = zext i8 %e2 to i32854 855 %s1 = shl nuw nsw i32 %z1, 8856 857 %i1 = or i32 %s1, %z0858 859 store i32 %i1, ptr %out860 ret void861}862 863; x1 = x0864define void @scalable_vector_to_i64(ptr %in, ptr %out, ptr %p) #0 {865; CHECK-LABEL: scalable_vector_to_i64:866; CHECK: // %bb.0:867; CHECK-NEXT: ldr w8, [x0]868; CHECK-NEXT: str x8, [x1]869; CHECK-NEXT: ret870 %ld = load <vscale x 4 x i8>, ptr %in, align 4871 872 %e1 = extractelement <vscale x 4 x i8> %ld, i32 0873 %e2 = extractelement <vscale x 4 x i8> %ld, i32 1874 %e3 = extractelement <vscale x 4 x i8> %ld, i32 2875 %e4 = extractelement <vscale x 4 x i8> %ld, i32 3876 877 %z0 = zext i8 %e1 to i64878 %z1 = zext i8 %e2 to i64879 %z2 = zext i8 %e3 to i64880 %z3 = zext i8 %e4 to i64881 882 %s1 = shl nuw nsw i64 %z1, 8883 %s2 = shl nuw nsw i64 %z2, 16884 %s3 = shl nuw i64 %z3, 24885 886 %i1 = or i64 %s1, %z0887 %i2 = or i64 %i1, %s2888 %i3 = or i64 %i2, %s3889 890 store i64 %i3, ptr %out891 ret void892}893 894attributes #0 = { "target-features"="+sve" }895