565 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=aarch64_be-unknown | FileCheck %s3 4; ptr p; // p is 4 byte aligned5; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]6define i32 @load_i32_by_i8_big_endian(ptr %arg) {7; CHECK-LABEL: load_i32_by_i8_big_endian:8; CHECK: // %bb.0:9; CHECK-NEXT: ldr w0, [x0]10; CHECK-NEXT: ret11 %tmp1 = load i8, ptr %arg, align 412 %tmp2 = zext i8 %tmp1 to i3213 %tmp3 = shl nuw nsw i32 %tmp2, 2414 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 115 %tmp5 = load i8, ptr %tmp4, align 116 %tmp6 = zext i8 %tmp5 to i3217 %tmp7 = shl nuw nsw i32 %tmp6, 1618 %tmp8 = or i32 %tmp7, %tmp319 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 220 %tmp10 = load i8, ptr %tmp9, align 121 %tmp11 = zext i8 %tmp10 to i3222 %tmp12 = shl nuw nsw i32 %tmp11, 823 %tmp13 = or i32 %tmp8, %tmp1224 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 325 %tmp15 = load i8, ptr %tmp14, align 126 %tmp16 = zext i8 %tmp15 to i3227 %tmp17 = or i32 %tmp13, %tmp1628 ret i32 %tmp1729}30 31; ptr p; // p is 4 byte aligned32; ((i32) (((i16) p[0] << 8) | (i16) p[1]) << 16) | (i32) (((i16) p[3] << 8) | (i16) p[4])33define i32 @load_i32_by_i16_by_i8_big_endian(ptr %arg) {34; CHECK-LABEL: load_i32_by_i16_by_i8_big_endian:35; CHECK: // %bb.0:36; CHECK-NEXT: ldr w0, [x0]37; CHECK-NEXT: ret38 %tmp1 = load i8, ptr %arg, align 439 %tmp2 = zext i8 %tmp1 to i1640 %tmp3 = getelementptr inbounds i8, ptr %arg, i32 141 %tmp4 = load i8, ptr %tmp3, align 142 %tmp5 = zext i8 %tmp4 to i1643 %tmp6 = shl nuw nsw i16 %tmp2, 844 %tmp7 = or i16 %tmp6, %tmp545 %tmp8 = getelementptr inbounds i8, ptr %arg, i32 246 %tmp9 = load i8, ptr %tmp8, align 147 %tmp10 = zext i8 %tmp9 to i1648 %tmp11 = getelementptr inbounds i8, ptr %arg, i32 349 %tmp12 = load i8, ptr %tmp11, align 150 %tmp13 = zext i8 %tmp12 to i1651 %tmp14 = shl nuw nsw i16 %tmp10, 852 %tmp15 = or i16 %tmp14, %tmp1353 %tmp16 = zext i16 %tmp7 to i3254 %tmp17 = zext i16 %tmp15 to i3255 %tmp18 = shl nuw nsw i32 %tmp16, 1656 %tmp19 = or i32 %tmp18, %tmp1757 ret i32 %tmp1958}59 60; ptr p; // p is 4 byte aligned61; ((i32) p[0] << 16) | (i32) p[1]62define i32 @load_i32_by_i16(ptr %arg) {63; CHECK-LABEL: load_i32_by_i16:64; CHECK: // %bb.0:65; CHECK-NEXT: ldr w0, [x0]66; CHECK-NEXT: ret67 %tmp1 = load i16, ptr %arg, align 468 %tmp2 = zext i16 %tmp1 to i3269 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 170 %tmp4 = load i16, ptr %tmp3, align 171 %tmp5 = zext i16 %tmp4 to i3272 %tmp6 = shl nuw nsw i32 %tmp2, 1673 %tmp7 = or i32 %tmp6, %tmp574 ret i32 %tmp775}76 77; ptr p_16; // p_16 is 4 byte aligned78; ptr p_8 = (ptr) p_16;79; (i32) (p_16[0] << 16) | ((i32) p[2] << 8) | (i32) p[3]80define i32 @load_i32_by_i16_i8(ptr %arg) {81; CHECK-LABEL: load_i32_by_i16_i8:82; CHECK: // %bb.0:83; CHECK-NEXT: ldr w0, [x0]84; CHECK-NEXT: ret85 %tmp2 = load i16, ptr %arg, align 486 %tmp3 = zext i16 %tmp2 to i3287 %tmp4 = shl nuw nsw i32 %tmp3, 1688 %tmp5 = getelementptr inbounds i8, ptr %arg, i32 289 %tmp6 = load i8, ptr %tmp5, align 190 %tmp7 = zext i8 %tmp6 to i3291 %tmp8 = shl nuw nsw i32 %tmp7, 892 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 393 %tmp10 = load i8, ptr %tmp9, align 194 %tmp11 = zext i8 %tmp10 to i3295 %tmp12 = or i32 %tmp8, %tmp1196 %tmp13 = or i32 %tmp12, %tmp497 ret i32 %tmp1398}99 100; ptr p; // p is 8 byte aligned101; (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)102define i64 @load_i64_by_i8_bswap(ptr %arg) {103; CHECK-LABEL: load_i64_by_i8_bswap:104; CHECK: // %bb.0:105; CHECK-NEXT: ldr x8, [x0]106; CHECK-NEXT: rev x0, x8107; CHECK-NEXT: ret108 %tmp1 = load i8, ptr %arg, align 8109 %tmp2 = zext i8 %tmp1 to i64110 %tmp3 = getelementptr inbounds i8, ptr %arg, i64 1111 %tmp4 = load i8, ptr %tmp3, align 1112 %tmp5 = zext i8 %tmp4 to i64113 %tmp6 = shl nuw nsw i64 %tmp5, 8114 %tmp7 = or i64 %tmp6, %tmp2115 %tmp8 = getelementptr inbounds i8, ptr %arg, i64 2116 %tmp9 = load i8, ptr %tmp8, align 1117 %tmp10 = zext i8 %tmp9 to i64118 %tmp11 = shl nuw nsw i64 %tmp10, 16119 %tmp12 = or i64 %tmp7, %tmp11120 %tmp13 = getelementptr inbounds i8, ptr %arg, i64 3121 %tmp14 = load i8, ptr %tmp13, align 1122 %tmp15 = zext i8 %tmp14 to i64123 %tmp16 = shl nuw nsw i64 %tmp15, 24124 %tmp17 = or i64 %tmp12, %tmp16125 %tmp18 = getelementptr inbounds i8, ptr %arg, i64 4126 %tmp19 = load i8, ptr %tmp18, align 1127 %tmp20 = zext i8 %tmp19 to i64128 %tmp21 = shl nuw nsw i64 %tmp20, 32129 %tmp22 = or i64 %tmp17, %tmp21130 %tmp23 = getelementptr inbounds i8, ptr %arg, i64 5131 %tmp24 = load i8, ptr %tmp23, align 1132 %tmp25 = zext i8 %tmp24 to i64133 %tmp26 = shl nuw nsw i64 %tmp25, 40134 %tmp27 = or i64 %tmp22, %tmp26135 %tmp28 = getelementptr inbounds i8, ptr %arg, i64 6136 %tmp29 = load i8, ptr %tmp28, align 1137 %tmp30 = zext i8 %tmp29 to i64138 %tmp31 = shl nuw nsw i64 %tmp30, 48139 %tmp32 = or i64 %tmp27, %tmp31140 %tmp33 = getelementptr inbounds i8, ptr %arg, i64 7141 %tmp34 = load i8, ptr %tmp33, align 1142 %tmp35 = zext i8 %tmp34 to i64143 %tmp36 = shl nuw i64 %tmp35, 56144 %tmp37 = or i64 %tmp32, %tmp36145 ret i64 %tmp37146}147 148; ptr p; // p is 8 byte aligned149; ((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]150define i64 @load_i64_by_i8(ptr %arg) {151; CHECK-LABEL: load_i64_by_i8:152; CHECK: // %bb.0:153; CHECK-NEXT: ldr x0, [x0]154; CHECK-NEXT: ret155 %tmp1 = load i8, ptr %arg, align 8156 %tmp2 = zext i8 %tmp1 to i64157 %tmp3 = shl nuw i64 %tmp2, 56158 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1159 %tmp5 = load i8, ptr %tmp4, align 1160 %tmp6 = zext i8 %tmp5 to i64161 %tmp7 = shl nuw nsw i64 %tmp6, 48162 %tmp8 = or i64 %tmp7, %tmp3163 %tmp9 = getelementptr inbounds i8, ptr %arg, i64 2164 %tmp10 = load i8, ptr %tmp9, align 1165 %tmp11 = zext i8 %tmp10 to i64166 %tmp12 = shl nuw nsw i64 %tmp11, 40167 %tmp13 = or i64 %tmp8, %tmp12168 %tmp14 = getelementptr inbounds i8, ptr %arg, i64 3169 %tmp15 = load i8, ptr %tmp14, align 1170 %tmp16 = zext i8 %tmp15 to i64171 %tmp17 = shl nuw nsw i64 %tmp16, 32172 %tmp18 = or i64 %tmp13, %tmp17173 %tmp19 = getelementptr inbounds i8, ptr %arg, i64 4174 %tmp20 = load i8, ptr %tmp19, align 1175 %tmp21 = zext i8 %tmp20 to i64176 %tmp22 = shl nuw nsw i64 %tmp21, 24177 %tmp23 = or i64 %tmp18, %tmp22178 %tmp24 = getelementptr inbounds i8, ptr %arg, i64 5179 %tmp25 = load i8, ptr %tmp24, align 1180 %tmp26 = zext i8 %tmp25 to i64181 %tmp27 = shl nuw nsw i64 %tmp26, 16182 %tmp28 = or i64 %tmp23, %tmp27183 %tmp29 = getelementptr inbounds i8, ptr %arg, i64 6184 %tmp30 = load i8, ptr %tmp29, align 1185 %tmp31 = zext i8 %tmp30 to i64186 %tmp32 = shl nuw nsw i64 %tmp31, 8187 %tmp33 = or i64 %tmp28, %tmp32188 %tmp34 = getelementptr inbounds i8, ptr %arg, i64 7189 %tmp35 = load i8, ptr %tmp34, align 1190 %tmp36 = zext i8 %tmp35 to i64191 %tmp37 = or i64 %tmp33, %tmp36192 ret i64 %tmp37193}194 195; ptr p; // p[1] is 4 byte aligned196; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24)197define i32 @load_i32_by_i8_nonzero_offset(ptr %arg) {198; CHECK-LABEL: load_i32_by_i8_nonzero_offset:199; CHECK: // %bb.0:200; CHECK-NEXT: ldur w8, [x0, #1]201; CHECK-NEXT: rev w0, w8202; CHECK-NEXT: ret203 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1204 %tmp2 = load i8, ptr %tmp1, align 4205 %tmp3 = zext i8 %tmp2 to i32206 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2207 %tmp5 = load i8, ptr %tmp4, align 1208 %tmp6 = zext i8 %tmp5 to i32209 %tmp7 = shl nuw nsw i32 %tmp6, 8210 %tmp8 = or i32 %tmp7, %tmp3211 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3212 %tmp10 = load i8, ptr %tmp9, align 1213 %tmp11 = zext i8 %tmp10 to i32214 %tmp12 = shl nuw nsw i32 %tmp11, 16215 %tmp13 = or i32 %tmp8, %tmp12216 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 4217 %tmp15 = load i8, ptr %tmp14, align 1218 %tmp16 = zext i8 %tmp15 to i32219 %tmp17 = shl nuw nsw i32 %tmp16, 24220 %tmp18 = or i32 %tmp13, %tmp17221 ret i32 %tmp18222}223 224; ptr p; // p[-4] is 4 byte aligned225; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24)226define i32 @load_i32_by_i8_neg_offset(ptr %arg) {227; CHECK-LABEL: load_i32_by_i8_neg_offset:228; CHECK: // %bb.0:229; CHECK-NEXT: ldur w8, [x0, #-4]230; CHECK-NEXT: rev w0, w8231; CHECK-NEXT: ret232 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -4233 %tmp2 = load i8, ptr %tmp1, align 4234 %tmp3 = zext i8 %tmp2 to i32235 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -3236 %tmp5 = load i8, ptr %tmp4, align 1237 %tmp6 = zext i8 %tmp5 to i32238 %tmp7 = shl nuw nsw i32 %tmp6, 8239 %tmp8 = or i32 %tmp7, %tmp3240 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -2241 %tmp10 = load i8, ptr %tmp9, align 1242 %tmp11 = zext i8 %tmp10 to i32243 %tmp12 = shl nuw nsw i32 %tmp11, 16244 %tmp13 = or i32 %tmp8, %tmp12245 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -1246 %tmp15 = load i8, ptr %tmp14, align 1247 %tmp16 = zext i8 %tmp15 to i32248 %tmp17 = shl nuw nsw i32 %tmp16, 24249 %tmp18 = or i32 %tmp13, %tmp17250 ret i32 %tmp18251}252 253; ptr p; // p[1] is 4 byte aligned254; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24)255define i32 @load_i32_by_i8_nonzero_offset_bswap(ptr %arg) {256; CHECK-LABEL: load_i32_by_i8_nonzero_offset_bswap:257; CHECK: // %bb.0:258; CHECK-NEXT: ldur w0, [x0, #1]259; CHECK-NEXT: ret260 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 4261 %tmp2 = load i8, ptr %tmp1, align 1262 %tmp3 = zext i8 %tmp2 to i32263 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 3264 %tmp5 = load i8, ptr %tmp4, align 1265 %tmp6 = zext i8 %tmp5 to i32266 %tmp7 = shl nuw nsw i32 %tmp6, 8267 %tmp8 = or i32 %tmp7, %tmp3268 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2269 %tmp10 = load i8, ptr %tmp9, align 1270 %tmp11 = zext i8 %tmp10 to i32271 %tmp12 = shl nuw nsw i32 %tmp11, 16272 %tmp13 = or i32 %tmp8, %tmp12273 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 1274 %tmp15 = load i8, ptr %tmp14, align 4275 %tmp16 = zext i8 %tmp15 to i32276 %tmp17 = shl nuw nsw i32 %tmp16, 24277 %tmp18 = or i32 %tmp13, %tmp17278 ret i32 %tmp18279}280 281; ptr p; // p[-4] is 4 byte aligned282; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24)283define i32 @load_i32_by_i8_neg_offset_bswap(ptr %arg) {284; CHECK-LABEL: load_i32_by_i8_neg_offset_bswap:285; CHECK: // %bb.0:286; CHECK-NEXT: ldur w0, [x0, #-4]287; CHECK-NEXT: ret288 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -1289 %tmp2 = load i8, ptr %tmp1, align 1290 %tmp3 = zext i8 %tmp2 to i32291 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -2292 %tmp5 = load i8, ptr %tmp4, align 1293 %tmp6 = zext i8 %tmp5 to i32294 %tmp7 = shl nuw nsw i32 %tmp6, 8295 %tmp8 = or i32 %tmp7, %tmp3296 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -3297 %tmp10 = load i8, ptr %tmp9, align 1298 %tmp11 = zext i8 %tmp10 to i32299 %tmp12 = shl nuw nsw i32 %tmp11, 16300 %tmp13 = or i32 %tmp8, %tmp12301 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -4302 %tmp15 = load i8, ptr %tmp14, align 4303 %tmp16 = zext i8 %tmp15 to i32304 %tmp17 = shl nuw nsw i32 %tmp16, 24305 %tmp18 = or i32 %tmp13, %tmp17306 ret i32 %tmp18307}308 309declare i16 @llvm.bswap.i16(i16)310 311; ptr p; // p is 4 byte aligned312; (i32) bswap(p[0]) | (i32) bswap(p[1] << 16)313define i32 @load_i32_by_bswap_i16(ptr %arg) {314; CHECK-LABEL: load_i32_by_bswap_i16:315; CHECK: // %bb.0:316; CHECK-NEXT: ldr w8, [x0]317; CHECK-NEXT: rev w0, w8318; CHECK-NEXT: ret319 %tmp1 = load i16, ptr %arg, align 4320 %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1)321 %tmp2 = zext i16 %tmp11 to i32322 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1323 %tmp4 = load i16, ptr %tmp3, align 1324 %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4)325 %tmp5 = zext i16 %tmp41 to i32326 %tmp6 = shl nuw nsw i32 %tmp5, 16327 %tmp7 = or i32 %tmp6, %tmp2328 ret i32 %tmp7329}330 331; ptr p; // p is 4 byte aligned332; (i32) p[1] | (sext(p[0] << 16) to i32)333define i32 @load_i32_by_sext_i16(ptr %arg) {334; CHECK-LABEL: load_i32_by_sext_i16:335; CHECK: // %bb.0:336; CHECK-NEXT: ldr w0, [x0]337; CHECK-NEXT: ret338 %tmp1 = load i16, ptr %arg, align 4339 %tmp2 = sext i16 %tmp1 to i32340 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1341 %tmp4 = load i16, ptr %tmp3, align 1342 %tmp5 = zext i16 %tmp4 to i32343 %tmp6 = shl nuw nsw i32 %tmp2, 16344 %tmp7 = or i32 %tmp6, %tmp5345 ret i32 %tmp7346}347 348; ptr arg; i32 i;349; p = arg + 12;350; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24)351define i32 @load_i32_by_i8_base_offset_index(ptr %arg, i32 %i) {352; CHECK-LABEL: load_i32_by_i8_base_offset_index:353; CHECK: // %bb.0:354; CHECK-NEXT: add x8, x0, w1, uxtw355; CHECK-NEXT: ldr w8, [x8, #12]356; CHECK-NEXT: rev w0, w8357; CHECK-NEXT: ret358 %tmp = add nuw nsw i32 %i, 3359 %tmp2 = add nuw nsw i32 %i, 2360 %tmp3 = add nuw nsw i32 %i, 1361 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12362 %tmp5 = zext i32 %i to i64363 %tmp6 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp5364 %tmp7 = load i8, ptr %tmp6, align 4365 %tmp8 = zext i8 %tmp7 to i32366 %tmp9 = zext i32 %tmp3 to i64367 %tmp10 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp9368 %tmp11 = load i8, ptr %tmp10, align 1369 %tmp12 = zext i8 %tmp11 to i32370 %tmp13 = shl nuw nsw i32 %tmp12, 8371 %tmp14 = or i32 %tmp13, %tmp8372 %tmp15 = zext i32 %tmp2 to i64373 %tmp16 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp15374 %tmp17 = load i8, ptr %tmp16, align 1375 %tmp18 = zext i8 %tmp17 to i32376 %tmp19 = shl nuw nsw i32 %tmp18, 16377 %tmp20 = or i32 %tmp14, %tmp19378 %tmp21 = zext i32 %tmp to i64379 %tmp22 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp21380 %tmp23 = load i8, ptr %tmp22, align 1381 %tmp24 = zext i8 %tmp23 to i32382 %tmp25 = shl nuw i32 %tmp24, 24383 %tmp26 = or i32 %tmp20, %tmp25384 ret i32 %tmp26385}386 387; ptr arg; i32 i;388; p = arg + 12;389; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24)390define i32 @load_i32_by_i8_base_offset_index_2(ptr %arg, i32 %i) {391; CHECK-LABEL: load_i32_by_i8_base_offset_index_2:392; CHECK: // %bb.0:393; CHECK-NEXT: add x8, x0, w1, uxtw394; CHECK-NEXT: ldur w8, [x8, #13]395; CHECK-NEXT: rev w0, w8396; CHECK-NEXT: ret397 %tmp = add nuw nsw i32 %i, 4398 %tmp2 = add nuw nsw i32 %i, 3399 %tmp3 = add nuw nsw i32 %i, 2400 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12401 %tmp5 = add nuw nsw i32 %i, 1402 %tmp27 = zext i32 %tmp5 to i64403 %tmp28 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp27404 %tmp29 = load i8, ptr %tmp28, align 4405 %tmp30 = zext i8 %tmp29 to i32406 %tmp31 = zext i32 %tmp3 to i64407 %tmp32 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp31408 %tmp33 = load i8, ptr %tmp32, align 1409 %tmp34 = zext i8 %tmp33 to i32410 %tmp35 = shl nuw nsw i32 %tmp34, 8411 %tmp36 = or i32 %tmp35, %tmp30412 %tmp37 = zext i32 %tmp2 to i64413 %tmp38 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp37414 %tmp39 = load i8, ptr %tmp38, align 1415 %tmp40 = zext i8 %tmp39 to i32416 %tmp41 = shl nuw nsw i32 %tmp40, 16417 %tmp42 = or i32 %tmp36, %tmp41418 %tmp43 = zext i32 %tmp to i64419 %tmp44 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp43420 %tmp45 = load i8, ptr %tmp44, align 1421 %tmp46 = zext i8 %tmp45 to i32422 %tmp47 = shl nuw i32 %tmp46, 24423 %tmp48 = or i32 %tmp42, %tmp47424 ret i32 %tmp48425}426; ptr p; // p is 2 byte aligned427; (i32) p[0] | ((i32) p[1] << 8)428define i32 @zext_load_i32_by_i8(ptr %arg) {429; CHECK-LABEL: zext_load_i32_by_i8:430; CHECK: // %bb.0:431; CHECK-NEXT: ldrh w8, [x0]432; CHECK-NEXT: rev16 w0, w8433; CHECK-NEXT: ret434 %tmp2 = load i8, ptr %arg, align 2435 %tmp3 = zext i8 %tmp2 to i32436 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1437 %tmp5 = load i8, ptr %tmp4, align 1438 %tmp6 = zext i8 %tmp5 to i32439 %tmp7 = shl nuw nsw i32 %tmp6, 8440 %tmp8 = or i32 %tmp7, %tmp3441 ret i32 %tmp8442}443 444; ptr p; // p is 2 byte aligned445; ((i32) p[0] << 8) | ((i32) p[1] << 16)446define i32 @zext_load_i32_by_i8_shl_8(ptr %arg) {447; CHECK-LABEL: zext_load_i32_by_i8_shl_8:448; CHECK: // %bb.0:449; CHECK-NEXT: ldrb w8, [x0]450; CHECK-NEXT: ldrb w9, [x0, #1]451; CHECK-NEXT: lsl w8, w8, #8452; CHECK-NEXT: orr w0, w8, w9, lsl #16453; CHECK-NEXT: ret454 %tmp2 = load i8, ptr %arg, align 2455 %tmp3 = zext i8 %tmp2 to i32456 %tmp30 = shl nuw nsw i32 %tmp3, 8457 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1458 %tmp5 = load i8, ptr %tmp4, align 1459 %tmp6 = zext i8 %tmp5 to i32460 %tmp7 = shl nuw nsw i32 %tmp6, 16461 %tmp8 = or i32 %tmp7, %tmp30462 ret i32 %tmp8463}464 465; ptr p; // p is 2 byte aligned466; ((i32) p[0] << 16) | ((i32) p[1] << 24)467define i32 @zext_load_i32_by_i8_shl_16(ptr %arg) {468; CHECK-LABEL: zext_load_i32_by_i8_shl_16:469; CHECK: // %bb.0:470; CHECK-NEXT: ldrb w8, [x0]471; CHECK-NEXT: ldrb w9, [x0, #1]472; CHECK-NEXT: lsl w8, w8, #16473; CHECK-NEXT: orr w0, w8, w9, lsl #24474; CHECK-NEXT: ret475 %tmp2 = load i8, ptr %arg, align 2476 %tmp3 = zext i8 %tmp2 to i32477 %tmp30 = shl nuw nsw i32 %tmp3, 16478 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1479 %tmp5 = load i8, ptr %tmp4, align 1480 %tmp6 = zext i8 %tmp5 to i32481 %tmp7 = shl nuw nsw i32 %tmp6, 24482 %tmp8 = or i32 %tmp7, %tmp30483 ret i32 %tmp8484}485; ptr p; // p is 2 byte aligned486; (i32) p[1] | ((i32) p[0] << 8)487define i32 @zext_load_i32_by_i8_bswap(ptr %arg) {488; CHECK-LABEL: zext_load_i32_by_i8_bswap:489; CHECK: // %bb.0:490; CHECK-NEXT: ldrh w0, [x0]491; CHECK-NEXT: ret492 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1493 %tmp2 = load i8, ptr %tmp1, align 1494 %tmp3 = zext i8 %tmp2 to i32495 %tmp5 = load i8, ptr %arg, align 2496 %tmp6 = zext i8 %tmp5 to i32497 %tmp7 = shl nuw nsw i32 %tmp6, 8498 %tmp8 = or i32 %tmp7, %tmp3499 ret i32 %tmp8500}501 502; ptr p; // p is 2 byte aligned503; ((i32) p[1] << 8) | ((i32) p[0] << 16)504define i32 @zext_load_i32_by_i8_bswap_shl_8(ptr %arg) {505; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8:506; CHECK: // %bb.0:507; CHECK-NEXT: ldrb w8, [x0, #1]508; CHECK-NEXT: ldrb w9, [x0]509; CHECK-NEXT: lsl w8, w8, #8510; CHECK-NEXT: orr w0, w8, w9, lsl #16511; CHECK-NEXT: ret512 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1513 %tmp2 = load i8, ptr %tmp1, align 1514 %tmp3 = zext i8 %tmp2 to i32515 %tmp30 = shl nuw nsw i32 %tmp3, 8516 %tmp5 = load i8, ptr %arg, align 2517 %tmp6 = zext i8 %tmp5 to i32518 %tmp7 = shl nuw nsw i32 %tmp6, 16519 %tmp8 = or i32 %tmp7, %tmp30520 ret i32 %tmp8521}522 523; ptr p; // p is 2 byte aligned524; ((i32) p[1] << 16) | ((i32) p[0] << 24)525define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {526; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16:527; CHECK: // %bb.0:528; CHECK-NEXT: ldrb w8, [x0, #1]529; CHECK-NEXT: ldrb w9, [x0]530; CHECK-NEXT: lsl w8, w8, #16531; CHECK-NEXT: orr w0, w8, w9, lsl #24532; CHECK-NEXT: ret533 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1534 %tmp2 = load i8, ptr %tmp1, align 1535 %tmp3 = zext i8 %tmp2 to i32536 %tmp30 = shl nuw nsw i32 %tmp3, 16537 %tmp5 = load i8, ptr %arg, align 2538 %tmp6 = zext i8 %tmp5 to i32539 %tmp7 = shl nuw nsw i32 %tmp6, 24540 %tmp8 = or i32 %tmp7, %tmp30541 ret i32 %tmp8542}543 544; ptr p;545; ptr p1.i16 = (ptr) p;546; (p1.i16[0] << 8) | ((i16) p[2])547;548; This is essentialy a i16 load from p[1], but we don't fold the pattern now549; because in the original DAG we don't have p[1] address available550define i16 @load_i16_from_nonzero_offset(ptr %p) {551; CHECK-LABEL: load_i16_from_nonzero_offset:552; CHECK: // %bb.0:553; CHECK-NEXT: ldrh w8, [x0]554; CHECK-NEXT: ldrb w9, [x0, #2]555; CHECK-NEXT: orr w0, w9, w8, lsl #8556; CHECK-NEXT: ret557 %p2.i8 = getelementptr i8, ptr %p, i64 2558 %v1 = load i16, ptr %p559 %v2.i8 = load i8, ptr %p2.i8560 %v2 = zext i8 %v2.i8 to i16561 %v1.shl = shl i16 %v1, 8562 %res = or i16 %v1.shl, %v2563 ret i16 %res564}565