1090 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=armeb-unknown | FileCheck %s3; RUN: llc < %s -mtriple=armv6eb-unknown | FileCheck %s --check-prefix=CHECK-ARMv64; RUN: llc < %s -mtriple=thumbv6meb-none-eabi | FileCheck %s --check-prefix=CHECK-THUMBv65; RUN: llc < %s -mtriple=thumbv6meb-none-eabi | FileCheck %s --check-prefix=CHECK-THUMBv76 7; ptr p; // p is 4 byte aligned8; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]9define i32 @load_i32_by_i8_big_endian(ptr %arg) {10; CHECK-LABEL: load_i32_by_i8_big_endian:11; CHECK: @ %bb.0:12; CHECK-NEXT: ldr r0, [r0]13; CHECK-NEXT: mov pc, lr14;15; CHECK-ARMv6-LABEL: load_i32_by_i8_big_endian:16; CHECK-ARMv6: @ %bb.0:17; CHECK-ARMv6-NEXT: ldr r0, [r0]18; CHECK-ARMv6-NEXT: bx lr19;20; CHECK-THUMBv6-LABEL: load_i32_by_i8_big_endian:21; CHECK-THUMBv6: @ %bb.0:22; CHECK-THUMBv6-NEXT: ldr r0, [r0]23; CHECK-THUMBv6-NEXT: bx lr24;25; CHECK-THUMBv7-LABEL: load_i32_by_i8_big_endian:26; CHECK-THUMBv7: @ %bb.0:27; CHECK-THUMBv7-NEXT: ldr r0, [r0]28; CHECK-THUMBv7-NEXT: bx lr29 30 %tmp1 = load i8, ptr %arg, align 431 %tmp2 = zext i8 %tmp1 to i3232 %tmp3 = shl nuw nsw i32 %tmp2, 2433 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 134 %tmp5 = load i8, ptr %tmp4, align 135 %tmp6 = zext i8 %tmp5 to i3236 %tmp7 = shl nuw nsw i32 %tmp6, 1637 %tmp8 = or i32 %tmp7, %tmp338 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 239 %tmp10 = load i8, ptr %tmp9, align 140 %tmp11 = zext i8 %tmp10 to i3241 %tmp12 = shl nuw nsw i32 %tmp11, 842 %tmp13 = or i32 %tmp8, %tmp1243 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 344 %tmp15 = load i8, ptr %tmp14, align 145 %tmp16 = zext i8 %tmp15 to i3246 %tmp17 = or i32 %tmp13, %tmp1647 ret i32 %tmp1748}49 50; ptr p; // p is 4 byte aligned51; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)52define i32 @load_i32_by_i8_bswap(ptr %arg) {53; BSWAP is not supported by 32 bit target54; CHECK-LABEL: load_i32_by_i8_bswap:55; CHECK: @ %bb.0:56; CHECK-NEXT: mov r1, #25557; CHECK-NEXT: ldr r0, [r0]58; CHECK-NEXT: orr r1, r1, #1671168059; CHECK-NEXT: and r2, r0, r160; CHECK-NEXT: and r0, r1, r0, ror #2461; CHECK-NEXT: orr r0, r0, r2, ror #862; CHECK-NEXT: mov pc, lr63;64; CHECK-ARMv6-LABEL: load_i32_by_i8_bswap:65; CHECK-ARMv6: @ %bb.0:66; CHECK-ARMv6-NEXT: ldr r0, [r0]67; CHECK-ARMv6-NEXT: rev r0, r068; CHECK-ARMv6-NEXT: bx lr69;70; CHECK-THUMBv6-LABEL: load_i32_by_i8_bswap:71; CHECK-THUMBv6: @ %bb.0:72; CHECK-THUMBv6-NEXT: ldr r0, [r0]73; CHECK-THUMBv6-NEXT: rev r0, r074; CHECK-THUMBv6-NEXT: bx lr75;76; CHECK-THUMBv7-LABEL: load_i32_by_i8_bswap:77; CHECK-THUMBv7: @ %bb.0:78; CHECK-THUMBv7-NEXT: ldr r0, [r0]79; CHECK-THUMBv7-NEXT: rev r0, r080; CHECK-THUMBv7-NEXT: bx lr81 82 %tmp2 = load i8, ptr %arg, align 483 %tmp3 = zext i8 %tmp2 to i3284 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 185 %tmp5 = load i8, ptr %tmp4, align 186 %tmp6 = zext i8 %tmp5 to i3287 %tmp7 = shl nuw nsw i32 %tmp6, 888 %tmp8 = or i32 %tmp7, %tmp389 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 290 %tmp10 = load i8, ptr %tmp9, align 191 %tmp11 = zext i8 %tmp10 to i3292 %tmp12 = shl nuw nsw i32 %tmp11, 1693 %tmp13 = or i32 %tmp8, %tmp1294 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 395 %tmp15 = load i8, ptr %tmp14, align 196 %tmp16 = zext i8 %tmp15 to i3297 %tmp17 = shl nuw nsw i32 %tmp16, 2498 %tmp18 = or i32 %tmp13, %tmp1799 ret i32 %tmp18100}101 102; ptr p; // p is 4 byte aligned103; ((i32) (((i16) p[0] << 8) | (i16) p[1]) << 16) | (i32) (((i16) p[3] << 8) | (i16) p[4])104define i32 @load_i32_by_i16_by_i8_big_endian(ptr %arg) {105; CHECK-LABEL: load_i32_by_i16_by_i8_big_endian:106; CHECK: @ %bb.0:107; CHECK-NEXT: ldr r0, [r0]108; CHECK-NEXT: mov pc, lr109;110; CHECK-ARMv6-LABEL: load_i32_by_i16_by_i8_big_endian:111; CHECK-ARMv6: @ %bb.0:112; CHECK-ARMv6-NEXT: ldr r0, [r0]113; CHECK-ARMv6-NEXT: bx lr114;115; CHECK-THUMBv6-LABEL: load_i32_by_i16_by_i8_big_endian:116; CHECK-THUMBv6: @ %bb.0:117; CHECK-THUMBv6-NEXT: ldr r0, [r0]118; CHECK-THUMBv6-NEXT: bx lr119;120; CHECK-THUMBv7-LABEL: load_i32_by_i16_by_i8_big_endian:121; CHECK-THUMBv7: @ %bb.0:122; CHECK-THUMBv7-NEXT: ldr r0, [r0]123; CHECK-THUMBv7-NEXT: bx lr124 125 %tmp1 = load i8, ptr %arg, align 4126 %tmp2 = zext i8 %tmp1 to i16127 %tmp3 = getelementptr inbounds i8, ptr %arg, i32 1128 %tmp4 = load i8, ptr %tmp3, align 1129 %tmp5 = zext i8 %tmp4 to i16130 %tmp6 = shl nuw nsw i16 %tmp2, 8131 %tmp7 = or i16 %tmp6, %tmp5132 %tmp8 = getelementptr inbounds i8, ptr %arg, i32 2133 %tmp9 = load i8, ptr %tmp8, align 1134 %tmp10 = zext i8 %tmp9 to i16135 %tmp11 = getelementptr inbounds i8, ptr %arg, i32 3136 %tmp12 = load i8, ptr %tmp11, align 1137 %tmp13 = zext i8 %tmp12 to i16138 %tmp14 = shl nuw nsw i16 %tmp10, 8139 %tmp15 = or i16 %tmp14, %tmp13140 %tmp16 = zext i16 %tmp7 to i32141 %tmp17 = zext i16 %tmp15 to i32142 %tmp18 = shl nuw nsw i32 %tmp16, 16143 %tmp19 = or i32 %tmp18, %tmp17144 ret i32 %tmp19145}146 147; ptr p; // p is 4 byte aligned148; ((i32) p[0] << 16) | (i32) p[1]149define i32 @load_i32_by_i16(ptr %arg) {150; CHECK-LABEL: load_i32_by_i16:151; CHECK: @ %bb.0:152; CHECK-NEXT: ldr r0, [r0]153; CHECK-NEXT: mov pc, lr154;155; CHECK-ARMv6-LABEL: load_i32_by_i16:156; CHECK-ARMv6: @ %bb.0:157; CHECK-ARMv6-NEXT: ldr r0, [r0]158; CHECK-ARMv6-NEXT: bx lr159;160; CHECK-THUMBv6-LABEL: load_i32_by_i16:161; CHECK-THUMBv6: @ %bb.0:162; CHECK-THUMBv6-NEXT: ldr r0, [r0]163; CHECK-THUMBv6-NEXT: bx lr164;165; CHECK-THUMBv7-LABEL: load_i32_by_i16:166; CHECK-THUMBv7: @ %bb.0:167; CHECK-THUMBv7-NEXT: ldr r0, [r0]168; CHECK-THUMBv7-NEXT: bx lr169 170 %tmp1 = load i16, ptr %arg, align 4171 %tmp2 = zext i16 %tmp1 to i32172 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1173 %tmp4 = load i16, ptr %tmp3, align 1174 %tmp5 = zext i16 %tmp4 to i32175 %tmp6 = shl nuw nsw i32 %tmp2, 16176 %tmp7 = or i32 %tmp6, %tmp5177 ret i32 %tmp7178}179 180; ptr p_16; // p_16 is 4 byte aligned181; ptr p_8 = (ptr) p_16;182; (i32) (p_16[0] << 16) | ((i32) p[2] << 8) | (i32) p[3]183define i32 @load_i32_by_i16_i8(ptr %arg) {184; CHECK-LABEL: load_i32_by_i16_i8:185; CHECK: @ %bb.0:186; CHECK-NEXT: ldr r0, [r0]187; CHECK-NEXT: mov pc, lr188;189; CHECK-ARMv6-LABEL: load_i32_by_i16_i8:190; CHECK-ARMv6: @ %bb.0:191; CHECK-ARMv6-NEXT: ldr r0, [r0]192; CHECK-ARMv6-NEXT: bx lr193;194; CHECK-THUMBv6-LABEL: load_i32_by_i16_i8:195; CHECK-THUMBv6: @ %bb.0:196; CHECK-THUMBv6-NEXT: ldr r0, [r0]197; CHECK-THUMBv6-NEXT: bx lr198;199; CHECK-THUMBv7-LABEL: load_i32_by_i16_i8:200; CHECK-THUMBv7: @ %bb.0:201; CHECK-THUMBv7-NEXT: ldr r0, [r0]202; CHECK-THUMBv7-NEXT: bx lr203 204 %tmp2 = load i16, ptr %arg, align 4205 %tmp3 = zext i16 %tmp2 to i32206 %tmp4 = shl nuw nsw i32 %tmp3, 16207 %tmp5 = getelementptr inbounds i8, ptr %arg, i32 2208 %tmp6 = load i8, ptr %tmp5, align 1209 %tmp7 = zext i8 %tmp6 to i32210 %tmp8 = shl nuw nsw i32 %tmp7, 8211 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3212 %tmp10 = load i8, ptr %tmp9, align 1213 %tmp11 = zext i8 %tmp10 to i32214 %tmp12 = or i32 %tmp8, %tmp11215 %tmp13 = or i32 %tmp12, %tmp4216 ret i32 %tmp13217}218 219; ptr p; // p is 8 byte aligned220; (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)221define i64 @load_i64_by_i8_bswap(ptr %arg) {222; CHECK-LABEL: load_i64_by_i8_bswap:223; CHECK: @ %bb.0:224; CHECK-NEXT: mov r2, #255225; CHECK-NEXT: ldr r1, [r0]226; CHECK-NEXT: ldr r0, [r0, #4]227; CHECK-NEXT: orr r2, r2, #16711680228; CHECK-NEXT: and r3, r0, r2229; CHECK-NEXT: and r0, r2, r0, ror #24230; CHECK-NEXT: orr r0, r0, r3, ror #8231; CHECK-NEXT: and r3, r1, r2232; CHECK-NEXT: and r1, r2, r1, ror #24233; CHECK-NEXT: orr r1, r1, r3, ror #8234; CHECK-NEXT: mov pc, lr235;236; CHECK-ARMv6-LABEL: load_i64_by_i8_bswap:237; CHECK-ARMv6: @ %bb.0:238; CHECK-ARMv6-NEXT: ldrd r2, r3, [r0]239; CHECK-ARMv6-NEXT: rev r0, r3240; CHECK-ARMv6-NEXT: rev r1, r2241; CHECK-ARMv6-NEXT: bx lr242;243; CHECK-THUMBv6-LABEL: load_i64_by_i8_bswap:244; CHECK-THUMBv6: @ %bb.0:245; CHECK-THUMBv6-NEXT: ldr r1, [r0]246; CHECK-THUMBv6-NEXT: ldr r0, [r0, #4]247; CHECK-THUMBv6-NEXT: rev r0, r0248; CHECK-THUMBv6-NEXT: rev r1, r1249; CHECK-THUMBv6-NEXT: bx lr250;251; CHECK-THUMBv7-LABEL: load_i64_by_i8_bswap:252; CHECK-THUMBv7: @ %bb.0:253; CHECK-THUMBv7-NEXT: ldr r1, [r0]254; CHECK-THUMBv7-NEXT: ldr r0, [r0, #4]255; CHECK-THUMBv7-NEXT: rev r0, r0256; CHECK-THUMBv7-NEXT: rev r1, r1257; CHECK-THUMBv7-NEXT: bx lr258 259 %tmp1 = load i8, ptr %arg, align 8260 %tmp2 = zext i8 %tmp1 to i64261 %tmp3 = getelementptr inbounds i8, ptr %arg, i64 1262 %tmp4 = load i8, ptr %tmp3, align 1263 %tmp5 = zext i8 %tmp4 to i64264 %tmp6 = shl nuw nsw i64 %tmp5, 8265 %tmp7 = or i64 %tmp6, %tmp2266 %tmp8 = getelementptr inbounds i8, ptr %arg, i64 2267 %tmp9 = load i8, ptr %tmp8, align 1268 %tmp10 = zext i8 %tmp9 to i64269 %tmp11 = shl nuw nsw i64 %tmp10, 16270 %tmp12 = or i64 %tmp7, %tmp11271 %tmp13 = getelementptr inbounds i8, ptr %arg, i64 3272 %tmp14 = load i8, ptr %tmp13, align 1273 %tmp15 = zext i8 %tmp14 to i64274 %tmp16 = shl nuw nsw i64 %tmp15, 24275 %tmp17 = or i64 %tmp12, %tmp16276 %tmp18 = getelementptr inbounds i8, ptr %arg, i64 4277 %tmp19 = load i8, ptr %tmp18, align 1278 %tmp20 = zext i8 %tmp19 to i64279 %tmp21 = shl nuw nsw i64 %tmp20, 32280 %tmp22 = or i64 %tmp17, %tmp21281 %tmp23 = getelementptr inbounds i8, ptr %arg, i64 5282 %tmp24 = load i8, ptr %tmp23, align 1283 %tmp25 = zext i8 %tmp24 to i64284 %tmp26 = shl nuw nsw i64 %tmp25, 40285 %tmp27 = or i64 %tmp22, %tmp26286 %tmp28 = getelementptr inbounds i8, ptr %arg, i64 6287 %tmp29 = load i8, ptr %tmp28, align 1288 %tmp30 = zext i8 %tmp29 to i64289 %tmp31 = shl nuw nsw i64 %tmp30, 48290 %tmp32 = or i64 %tmp27, %tmp31291 %tmp33 = getelementptr inbounds i8, ptr %arg, i64 7292 %tmp34 = load i8, ptr %tmp33, align 1293 %tmp35 = zext i8 %tmp34 to i64294 %tmp36 = shl nuw i64 %tmp35, 56295 %tmp37 = or i64 %tmp32, %tmp36296 ret i64 %tmp37297}298 299; ptr p; // p is 8 byte aligned300; ((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]301define i64 @load_i64_by_i8(ptr %arg) {302; CHECK-LABEL: load_i64_by_i8:303; CHECK: @ %bb.0:304; CHECK-NEXT: ldr r2, [r0]305; CHECK-NEXT: ldr r1, [r0, #4]306; CHECK-NEXT: mov r0, r2307; CHECK-NEXT: mov pc, lr308;309; CHECK-ARMv6-LABEL: load_i64_by_i8:310; CHECK-ARMv6: @ %bb.0:311; CHECK-ARMv6-NEXT: ldrd r0, r1, [r0]312; CHECK-ARMv6-NEXT: bx lr313;314; CHECK-THUMBv6-LABEL: load_i64_by_i8:315; CHECK-THUMBv6: @ %bb.0:316; CHECK-THUMBv6-NEXT: ldr r2, [r0]317; CHECK-THUMBv6-NEXT: ldr r1, [r0, #4]318; CHECK-THUMBv6-NEXT: mov r0, r2319; CHECK-THUMBv6-NEXT: bx lr320;321; CHECK-THUMBv7-LABEL: load_i64_by_i8:322; CHECK-THUMBv7: @ %bb.0:323; CHECK-THUMBv7-NEXT: ldr r2, [r0]324; CHECK-THUMBv7-NEXT: ldr r1, [r0, #4]325; CHECK-THUMBv7-NEXT: mov r0, r2326; CHECK-THUMBv7-NEXT: bx lr327 328 %tmp1 = load i8, ptr %arg, align 8329 %tmp2 = zext i8 %tmp1 to i64330 %tmp3 = shl nuw i64 %tmp2, 56331 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1332 %tmp5 = load i8, ptr %tmp4, align 1333 %tmp6 = zext i8 %tmp5 to i64334 %tmp7 = shl nuw nsw i64 %tmp6, 48335 %tmp8 = or i64 %tmp7, %tmp3336 %tmp9 = getelementptr inbounds i8, ptr %arg, i64 2337 %tmp10 = load i8, ptr %tmp9, align 1338 %tmp11 = zext i8 %tmp10 to i64339 %tmp12 = shl nuw nsw i64 %tmp11, 40340 %tmp13 = or i64 %tmp8, %tmp12341 %tmp14 = getelementptr inbounds i8, ptr %arg, i64 3342 %tmp15 = load i8, ptr %tmp14, align 1343 %tmp16 = zext i8 %tmp15 to i64344 %tmp17 = shl nuw nsw i64 %tmp16, 32345 %tmp18 = or i64 %tmp13, %tmp17346 %tmp19 = getelementptr inbounds i8, ptr %arg, i64 4347 %tmp20 = load i8, ptr %tmp19, align 1348 %tmp21 = zext i8 %tmp20 to i64349 %tmp22 = shl nuw nsw i64 %tmp21, 24350 %tmp23 = or i64 %tmp18, %tmp22351 %tmp24 = getelementptr inbounds i8, ptr %arg, i64 5352 %tmp25 = load i8, ptr %tmp24, align 1353 %tmp26 = zext i8 %tmp25 to i64354 %tmp27 = shl nuw nsw i64 %tmp26, 16355 %tmp28 = or i64 %tmp23, %tmp27356 %tmp29 = getelementptr inbounds i8, ptr %arg, i64 6357 %tmp30 = load i8, ptr %tmp29, align 1358 %tmp31 = zext i8 %tmp30 to i64359 %tmp32 = shl nuw nsw i64 %tmp31, 8360 %tmp33 = or i64 %tmp28, %tmp32361 %tmp34 = getelementptr inbounds i8, ptr %arg, i64 7362 %tmp35 = load i8, ptr %tmp34, align 1363 %tmp36 = zext i8 %tmp35 to i64364 %tmp37 = or i64 %tmp33, %tmp36365 ret i64 %tmp37366}367 368; ptr p; // p[1] is 4 byte aligned369; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24)370define i32 @load_i32_by_i8_nonzero_offset(ptr %arg) {371; CHECK-LABEL: load_i32_by_i8_nonzero_offset:372; CHECK: @ %bb.0:373; CHECK-NEXT: mov r1, #255374; CHECK-NEXT: ldr r0, [r0, #1]375; CHECK-NEXT: orr r1, r1, #16711680376; CHECK-NEXT: and r2, r0, r1377; CHECK-NEXT: and r0, r1, r0, ror #24378; CHECK-NEXT: orr r0, r0, r2, ror #8379; CHECK-NEXT: mov pc, lr380;381; CHECK-ARMv6-LABEL: load_i32_by_i8_nonzero_offset:382; CHECK-ARMv6: @ %bb.0:383; CHECK-ARMv6-NEXT: ldr r0, [r0, #1]384; CHECK-ARMv6-NEXT: rev r0, r0385; CHECK-ARMv6-NEXT: bx lr386;387; CHECK-THUMBv6-LABEL: load_i32_by_i8_nonzero_offset:388; CHECK-THUMBv6: @ %bb.0:389; CHECK-THUMBv6-NEXT: movs r1, #1390; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]391; CHECK-THUMBv6-NEXT: rev r0, r0392; CHECK-THUMBv6-NEXT: bx lr393;394; CHECK-THUMBv7-LABEL: load_i32_by_i8_nonzero_offset:395; CHECK-THUMBv7: @ %bb.0:396; CHECK-THUMBv7-NEXT: movs r1, #1397; CHECK-THUMBv7-NEXT: ldr r0, [r0, r1]398; CHECK-THUMBv7-NEXT: rev r0, r0399; CHECK-THUMBv7-NEXT: bx lr400 401 402 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1403 %tmp2 = load i8, ptr %tmp1, align 4404 %tmp3 = zext i8 %tmp2 to i32405 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2406 %tmp5 = load i8, ptr %tmp4, align 1407 %tmp6 = zext i8 %tmp5 to i32408 %tmp7 = shl nuw nsw i32 %tmp6, 8409 %tmp8 = or i32 %tmp7, %tmp3410 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3411 %tmp10 = load i8, ptr %tmp9, align 1412 %tmp11 = zext i8 %tmp10 to i32413 %tmp12 = shl nuw nsw i32 %tmp11, 16414 %tmp13 = or i32 %tmp8, %tmp12415 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 4416 %tmp15 = load i8, ptr %tmp14, align 1417 %tmp16 = zext i8 %tmp15 to i32418 %tmp17 = shl nuw nsw i32 %tmp16, 24419 %tmp18 = or i32 %tmp13, %tmp17420 ret i32 %tmp18421}422 423; ptr p; // p[-4] is 4 byte aligned424; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24)425define i32 @load_i32_by_i8_neg_offset(ptr %arg) {426; CHECK-LABEL: load_i32_by_i8_neg_offset:427; CHECK: @ %bb.0:428; CHECK-NEXT: mov r1, #255429; CHECK-NEXT: ldr r0, [r0, #-4]430; CHECK-NEXT: orr r1, r1, #16711680431; CHECK-NEXT: and r2, r0, r1432; CHECK-NEXT: and r0, r1, r0, ror #24433; CHECK-NEXT: orr r0, r0, r2, ror #8434; CHECK-NEXT: mov pc, lr435;436; CHECK-ARMv6-LABEL: load_i32_by_i8_neg_offset:437; CHECK-ARMv6: @ %bb.0:438; CHECK-ARMv6-NEXT: ldr r0, [r0, #-4]439; CHECK-ARMv6-NEXT: rev r0, r0440; CHECK-ARMv6-NEXT: bx lr441;442; CHECK-THUMBv6-LABEL: load_i32_by_i8_neg_offset:443; CHECK-THUMBv6: @ %bb.0:444; CHECK-THUMBv6-NEXT: subs r0, r0, #4445; CHECK-THUMBv6-NEXT: ldr r0, [r0]446; CHECK-THUMBv6-NEXT: rev r0, r0447; CHECK-THUMBv6-NEXT: bx lr448;449; CHECK-THUMBv7-LABEL: load_i32_by_i8_neg_offset:450; CHECK-THUMBv7: @ %bb.0:451; CHECK-THUMBv7-NEXT: subs r0, r0, #4452; CHECK-THUMBv7-NEXT: ldr r0, [r0]453; CHECK-THUMBv7-NEXT: rev r0, r0454; CHECK-THUMBv7-NEXT: bx lr455 456 457 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -4458 %tmp2 = load i8, ptr %tmp1, align 4459 %tmp3 = zext i8 %tmp2 to i32460 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -3461 %tmp5 = load i8, ptr %tmp4, align 1462 %tmp6 = zext i8 %tmp5 to i32463 %tmp7 = shl nuw nsw i32 %tmp6, 8464 %tmp8 = or i32 %tmp7, %tmp3465 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -2466 %tmp10 = load i8, ptr %tmp9, align 1467 %tmp11 = zext i8 %tmp10 to i32468 %tmp12 = shl nuw nsw i32 %tmp11, 16469 %tmp13 = or i32 %tmp8, %tmp12470 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -1471 %tmp15 = load i8, ptr %tmp14, align 1472 %tmp16 = zext i8 %tmp15 to i32473 %tmp17 = shl nuw nsw i32 %tmp16, 24474 %tmp18 = or i32 %tmp13, %tmp17475 ret i32 %tmp18476}477 478; ptr p; // p[1] is 4 byte aligned479; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24)480define i32 @load_i32_by_i8_nonzero_offset_bswap(ptr %arg) {481; CHECK-LABEL: load_i32_by_i8_nonzero_offset_bswap:482; CHECK: @ %bb.0:483; CHECK-NEXT: ldr r0, [r0, #1]484; CHECK-NEXT: mov pc, lr485;486; CHECK-ARMv6-LABEL: load_i32_by_i8_nonzero_offset_bswap:487; CHECK-ARMv6: @ %bb.0:488; CHECK-ARMv6-NEXT: ldr r0, [r0, #1]489; CHECK-ARMv6-NEXT: bx lr490;491; CHECK-THUMBv6-LABEL: load_i32_by_i8_nonzero_offset_bswap:492; CHECK-THUMBv6: @ %bb.0:493; CHECK-THUMBv6-NEXT: movs r1, #1494; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]495; CHECK-THUMBv6-NEXT: bx lr496;497; CHECK-THUMBv7-LABEL: load_i32_by_i8_nonzero_offset_bswap:498; CHECK-THUMBv7: @ %bb.0:499; CHECK-THUMBv7-NEXT: movs r1, #1500; CHECK-THUMBv7-NEXT: ldr r0, [r0, r1]501; CHECK-THUMBv7-NEXT: bx lr502 503 504 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 4505 %tmp2 = load i8, ptr %tmp1, align 1506 %tmp3 = zext i8 %tmp2 to i32507 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 3508 %tmp5 = load i8, ptr %tmp4, align 1509 %tmp6 = zext i8 %tmp5 to i32510 %tmp7 = shl nuw nsw i32 %tmp6, 8511 %tmp8 = or i32 %tmp7, %tmp3512 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2513 %tmp10 = load i8, ptr %tmp9, align 1514 %tmp11 = zext i8 %tmp10 to i32515 %tmp12 = shl nuw nsw i32 %tmp11, 16516 %tmp13 = or i32 %tmp8, %tmp12517 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 1518 %tmp15 = load i8, ptr %tmp14, align 4519 %tmp16 = zext i8 %tmp15 to i32520 %tmp17 = shl nuw nsw i32 %tmp16, 24521 %tmp18 = or i32 %tmp13, %tmp17522 ret i32 %tmp18523}524 525; ptr p; // p[-4] is 4 byte aligned526; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24)527define i32 @load_i32_by_i8_neg_offset_bswap(ptr %arg) {528; CHECK-LABEL: load_i32_by_i8_neg_offset_bswap:529; CHECK: @ %bb.0:530; CHECK-NEXT: ldr r0, [r0, #-4]531; CHECK-NEXT: mov pc, lr532;533; CHECK-ARMv6-LABEL: load_i32_by_i8_neg_offset_bswap:534; CHECK-ARMv6: @ %bb.0:535; CHECK-ARMv6-NEXT: ldr r0, [r0, #-4]536; CHECK-ARMv6-NEXT: bx lr537;538; CHECK-THUMBv6-LABEL: load_i32_by_i8_neg_offset_bswap:539; CHECK-THUMBv6: @ %bb.0:540; CHECK-THUMBv6-NEXT: subs r0, r0, #4541; CHECK-THUMBv6-NEXT: ldr r0, [r0]542; CHECK-THUMBv6-NEXT: bx lr543;544; CHECK-THUMBv7-LABEL: load_i32_by_i8_neg_offset_bswap:545; CHECK-THUMBv7: @ %bb.0:546; CHECK-THUMBv7-NEXT: subs r0, r0, #4547; CHECK-THUMBv7-NEXT: ldr r0, [r0]548; CHECK-THUMBv7-NEXT: bx lr549 550 551 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -1552 %tmp2 = load i8, ptr %tmp1, align 1553 %tmp3 = zext i8 %tmp2 to i32554 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -2555 %tmp5 = load i8, ptr %tmp4, align 1556 %tmp6 = zext i8 %tmp5 to i32557 %tmp7 = shl nuw nsw i32 %tmp6, 8558 %tmp8 = or i32 %tmp7, %tmp3559 %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -3560 %tmp10 = load i8, ptr %tmp9, align 1561 %tmp11 = zext i8 %tmp10 to i32562 %tmp12 = shl nuw nsw i32 %tmp11, 16563 %tmp13 = or i32 %tmp8, %tmp12564 %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -4565 %tmp15 = load i8, ptr %tmp14, align 4566 %tmp16 = zext i8 %tmp15 to i32567 %tmp17 = shl nuw nsw i32 %tmp16, 24568 %tmp18 = or i32 %tmp13, %tmp17569 ret i32 %tmp18570}571 572declare i16 @llvm.bswap.i16(i16)573 574; ptr p; // p is 4 byte aligned575; (i32) bswap(p[0]) | (i32) bswap(p[1] << 16)576define i32 @load_i32_by_bswap_i16(ptr %arg) {577; CHECK-LABEL: load_i32_by_bswap_i16:578; CHECK: @ %bb.0:579; CHECK-NEXT: mov r1, #255580; CHECK-NEXT: ldr r0, [r0]581; CHECK-NEXT: orr r1, r1, #16711680582; CHECK-NEXT: and r2, r0, r1583; CHECK-NEXT: and r0, r1, r0, ror #24584; CHECK-NEXT: orr r0, r0, r2, ror #8585; CHECK-NEXT: mov pc, lr586;587; CHECK-ARMv6-LABEL: load_i32_by_bswap_i16:588; CHECK-ARMv6: @ %bb.0:589; CHECK-ARMv6-NEXT: ldr r0, [r0]590; CHECK-ARMv6-NEXT: rev r0, r0591; CHECK-ARMv6-NEXT: bx lr592;593; CHECK-THUMBv6-LABEL: load_i32_by_bswap_i16:594; CHECK-THUMBv6: @ %bb.0:595; CHECK-THUMBv6-NEXT: ldr r0, [r0]596; CHECK-THUMBv6-NEXT: rev r0, r0597; CHECK-THUMBv6-NEXT: bx lr598;599; CHECK-THUMBv7-LABEL: load_i32_by_bswap_i16:600; CHECK-THUMBv7: @ %bb.0:601; CHECK-THUMBv7-NEXT: ldr r0, [r0]602; CHECK-THUMBv7-NEXT: rev r0, r0603; CHECK-THUMBv7-NEXT: bx lr604 605 606 %tmp1 = load i16, ptr %arg, align 4607 %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1)608 %tmp2 = zext i16 %tmp11 to i32609 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1610 %tmp4 = load i16, ptr %tmp3, align 1611 %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4)612 %tmp5 = zext i16 %tmp41 to i32613 %tmp6 = shl nuw nsw i32 %tmp5, 16614 %tmp7 = or i32 %tmp6, %tmp2615 ret i32 %tmp7616}617 618; ptr p; // p is 4 byte aligned619; (i32) p[1] | (sext(p[0] << 16) to i32)620define i32 @load_i32_by_sext_i16(ptr %arg) {621; CHECK-LABEL: load_i32_by_sext_i16:622; CHECK: @ %bb.0:623; CHECK-NEXT: ldr r0, [r0]624; CHECK-NEXT: mov pc, lr625;626; CHECK-ARMv6-LABEL: load_i32_by_sext_i16:627; CHECK-ARMv6: @ %bb.0:628; CHECK-ARMv6-NEXT: ldr r0, [r0]629; CHECK-ARMv6-NEXT: bx lr630;631; CHECK-THUMBv6-LABEL: load_i32_by_sext_i16:632; CHECK-THUMBv6: @ %bb.0:633; CHECK-THUMBv6-NEXT: ldr r0, [r0]634; CHECK-THUMBv6-NEXT: bx lr635;636; CHECK-THUMBv7-LABEL: load_i32_by_sext_i16:637; CHECK-THUMBv7: @ %bb.0:638; CHECK-THUMBv7-NEXT: ldr r0, [r0]639; CHECK-THUMBv7-NEXT: bx lr640 %tmp1 = load i16, ptr %arg, align 4641 %tmp2 = sext i16 %tmp1 to i32642 %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1643 %tmp4 = load i16, ptr %tmp3, align 1644 %tmp5 = zext i16 %tmp4 to i32645 %tmp6 = shl nuw nsw i32 %tmp2, 16646 %tmp7 = or i32 %tmp6, %tmp5647 ret i32 %tmp7648}649 650; ptr arg; i32 i;651; p = arg + 12;652; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24)653define i32 @load_i32_by_i8_base_offset_index(ptr %arg, i32 %i) {654; CHECK-LABEL: load_i32_by_i8_base_offset_index:655; CHECK: @ %bb.0:656; CHECK-NEXT: add r0, r0, r1657; CHECK-NEXT: mov r1, #255658; CHECK-NEXT: orr r1, r1, #16711680659; CHECK-NEXT: ldr r0, [r0, #12]660; CHECK-NEXT: and r2, r0, r1661; CHECK-NEXT: and r0, r1, r0, ror #24662; CHECK-NEXT: orr r0, r0, r2, ror #8663; CHECK-NEXT: mov pc, lr664;665; CHECK-ARMv6-LABEL: load_i32_by_i8_base_offset_index:666; CHECK-ARMv6: @ %bb.0:667; CHECK-ARMv6-NEXT: add r0, r0, r1668; CHECK-ARMv6-NEXT: ldr r0, [r0, #12]669; CHECK-ARMv6-NEXT: rev r0, r0670; CHECK-ARMv6-NEXT: bx lr671;672; CHECK-THUMBv6-LABEL: load_i32_by_i8_base_offset_index:673; CHECK-THUMBv6: @ %bb.0:674; CHECK-THUMBv6-NEXT: adds r0, r0, r1675; CHECK-THUMBv6-NEXT: ldr r0, [r0, #12]676; CHECK-THUMBv6-NEXT: rev r0, r0677; CHECK-THUMBv6-NEXT: bx lr678;679; CHECK-THUMBv7-LABEL: load_i32_by_i8_base_offset_index:680; CHECK-THUMBv7: @ %bb.0:681; CHECK-THUMBv7-NEXT: adds r0, r0, r1682; CHECK-THUMBv7-NEXT: ldr r0, [r0, #12]683; CHECK-THUMBv7-NEXT: rev r0, r0684; CHECK-THUMBv7-NEXT: bx lr685 %tmp = add nuw nsw i32 %i, 3686 %tmp2 = add nuw nsw i32 %i, 2687 %tmp3 = add nuw nsw i32 %i, 1688 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12689 %tmp5 = zext i32 %i to i64690 %tmp6 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp5691 %tmp7 = load i8, ptr %tmp6, align 4692 %tmp8 = zext i8 %tmp7 to i32693 %tmp9 = zext i32 %tmp3 to i64694 %tmp10 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp9695 %tmp11 = load i8, ptr %tmp10, align 1696 %tmp12 = zext i8 %tmp11 to i32697 %tmp13 = shl nuw nsw i32 %tmp12, 8698 %tmp14 = or i32 %tmp13, %tmp8699 %tmp15 = zext i32 %tmp2 to i64700 %tmp16 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp15701 %tmp17 = load i8, ptr %tmp16, align 1702 %tmp18 = zext i8 %tmp17 to i32703 %tmp19 = shl nuw nsw i32 %tmp18, 16704 %tmp20 = or i32 %tmp14, %tmp19705 %tmp21 = zext i32 %tmp to i64706 %tmp22 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp21707 %tmp23 = load i8, ptr %tmp22, align 1708 %tmp24 = zext i8 %tmp23 to i32709 %tmp25 = shl nuw i32 %tmp24, 24710 %tmp26 = or i32 %tmp20, %tmp25711 ret i32 %tmp26712}713 714; ptr arg; i32 i;715; p = arg + 12;716; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24)717define i32 @load_i32_by_i8_base_offset_index_2(ptr %arg, i32 %i) {718; CHECK-LABEL: load_i32_by_i8_base_offset_index_2:719; CHECK: @ %bb.0:720; CHECK-NEXT: add r0, r1, r0721; CHECK-NEXT: mov r1, #255722; CHECK-NEXT: orr r1, r1, #16711680723; CHECK-NEXT: ldr r0, [r0, #13]724; CHECK-NEXT: and r2, r0, r1725; CHECK-NEXT: and r0, r1, r0, ror #24726; CHECK-NEXT: orr r0, r0, r2, ror #8727; CHECK-NEXT: mov pc, lr728;729; CHECK-ARMv6-LABEL: load_i32_by_i8_base_offset_index_2:730; CHECK-ARMv6: @ %bb.0:731; CHECK-ARMv6-NEXT: add r0, r1, r0732; CHECK-ARMv6-NEXT: ldr r0, [r0, #13]733; CHECK-ARMv6-NEXT: rev r0, r0734; CHECK-ARMv6-NEXT: bx lr735;736; CHECK-THUMBv6-LABEL: load_i32_by_i8_base_offset_index_2:737; CHECK-THUMBv6: @ %bb.0:738; CHECK-THUMBv6-NEXT: adds r0, r1, r0739; CHECK-THUMBv6-NEXT: movs r1, #13740; CHECK-THUMBv6-NEXT: ldr r0, [r0, r1]741; CHECK-THUMBv6-NEXT: rev r0, r0742; CHECK-THUMBv6-NEXT: bx lr743;744; CHECK-THUMBv7-LABEL: load_i32_by_i8_base_offset_index_2:745; CHECK-THUMBv7: @ %bb.0:746; CHECK-THUMBv7-NEXT: adds r0, r1, r0747; CHECK-THUMBv7-NEXT: movs r1, #13748; CHECK-THUMBv7-NEXT: ldr r0, [r0, r1]749; CHECK-THUMBv7-NEXT: rev r0, r0750; CHECK-THUMBv7-NEXT: bx lr751 752 %tmp = add nuw nsw i32 %i, 4753 %tmp2 = add nuw nsw i32 %i, 3754 %tmp3 = add nuw nsw i32 %i, 2755 %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12756 %tmp5 = add nuw nsw i32 %i, 1757 %tmp27 = zext i32 %tmp5 to i64758 %tmp28 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp27759 %tmp29 = load i8, ptr %tmp28, align 4760 %tmp30 = zext i8 %tmp29 to i32761 %tmp31 = zext i32 %tmp3 to i64762 %tmp32 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp31763 %tmp33 = load i8, ptr %tmp32, align 1764 %tmp34 = zext i8 %tmp33 to i32765 %tmp35 = shl nuw nsw i32 %tmp34, 8766 %tmp36 = or i32 %tmp35, %tmp30767 %tmp37 = zext i32 %tmp2 to i64768 %tmp38 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp37769 %tmp39 = load i8, ptr %tmp38, align 1770 %tmp40 = zext i8 %tmp39 to i32771 %tmp41 = shl nuw nsw i32 %tmp40, 16772 %tmp42 = or i32 %tmp36, %tmp41773 %tmp43 = zext i32 %tmp to i64774 %tmp44 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp43775 %tmp45 = load i8, ptr %tmp44, align 1776 %tmp46 = zext i8 %tmp45 to i32777 %tmp47 = shl nuw i32 %tmp46, 24778 %tmp48 = or i32 %tmp42, %tmp47779 ret i32 %tmp48780}781 782; ptr p; // p is 2 byte aligned783; (i32) p[0] | ((i32) p[1] << 8)784define i32 @zext_load_i32_by_i8(ptr %arg) {785; CHECK-LABEL: zext_load_i32_by_i8:786; CHECK: @ %bb.0:787; CHECK-NEXT: ldrb r1, [r0]788; CHECK-NEXT: ldrb r0, [r0, #1]789; CHECK-NEXT: orr r0, r1, r0, lsl #8790; CHECK-NEXT: mov pc, lr791;792; CHECK-ARMv6-LABEL: zext_load_i32_by_i8:793; CHECK-ARMv6: @ %bb.0:794; CHECK-ARMv6-NEXT: ldrh r0, [r0]795; CHECK-ARMv6-NEXT: rev16 r0, r0796; CHECK-ARMv6-NEXT: bx lr797;798; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8:799; CHECK-THUMBv6: @ %bb.0:800; CHECK-THUMBv6-NEXT: ldrh r0, [r0]801; CHECK-THUMBv6-NEXT: rev16 r0, r0802; CHECK-THUMBv6-NEXT: bx lr803;804; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8:805; CHECK-THUMBv7: @ %bb.0:806; CHECK-THUMBv7-NEXT: ldrh r0, [r0]807; CHECK-THUMBv7-NEXT: rev16 r0, r0808; CHECK-THUMBv7-NEXT: bx lr809 810 %tmp2 = load i8, ptr %arg, align 2811 %tmp3 = zext i8 %tmp2 to i32812 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1813 %tmp5 = load i8, ptr %tmp4, align 1814 %tmp6 = zext i8 %tmp5 to i32815 %tmp7 = shl nuw nsw i32 %tmp6, 8816 %tmp8 = or i32 %tmp7, %tmp3817 ret i32 %tmp8818}819 820; ptr p; // p is 2 byte aligned821; ((i32) p[0] << 8) | ((i32) p[1] << 16)822define i32 @zext_load_i32_by_i8_shl_8(ptr %arg) {823; CHECK-LABEL: zext_load_i32_by_i8_shl_8:824; CHECK: @ %bb.0:825; CHECK-NEXT: ldrb r1, [r0]826; CHECK-NEXT: ldrb r0, [r0, #1]827; CHECK-NEXT: lsl r0, r0, #16828; CHECK-NEXT: orr r0, r0, r1, lsl #8829; CHECK-NEXT: mov pc, lr830;831; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_shl_8:832; CHECK-ARMv6: @ %bb.0:833; CHECK-ARMv6-NEXT: ldrb r1, [r0]834; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]835; CHECK-ARMv6-NEXT: lsl r0, r0, #16836; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #8837; CHECK-ARMv6-NEXT: bx lr838;839; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_shl_8:840; CHECK-THUMBv6: @ %bb.0:841; CHECK-THUMBv6-NEXT: ldrb r1, [r0]842; CHECK-THUMBv6-NEXT: lsls r1, r1, #8843; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #1]844; CHECK-THUMBv6-NEXT: lsls r0, r0, #16845; CHECK-THUMBv6-NEXT: adds r0, r0, r1846; CHECK-THUMBv6-NEXT: bx lr847;848; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_shl_8:849; CHECK-THUMBv7: @ %bb.0:850; CHECK-THUMBv7-NEXT: ldrb r1, [r0]851; CHECK-THUMBv7-NEXT: lsls r1, r1, #8852; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]853; CHECK-THUMBv7-NEXT: lsls r0, r0, #16854; CHECK-THUMBv7-NEXT: adds r0, r0, r1855; CHECK-THUMBv7-NEXT: bx lr856 857 %tmp2 = load i8, ptr %arg, align 2858 %tmp3 = zext i8 %tmp2 to i32859 %tmp30 = shl nuw nsw i32 %tmp3, 8860 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1861 %tmp5 = load i8, ptr %tmp4, align 1862 %tmp6 = zext i8 %tmp5 to i32863 %tmp7 = shl nuw nsw i32 %tmp6, 16864 %tmp8 = or i32 %tmp7, %tmp30865 ret i32 %tmp8866}867 868; ptr p; // p is 2 byte aligned869; ((i32) p[0] << 16) | ((i32) p[1] << 24)870define i32 @zext_load_i32_by_i8_shl_16(ptr %arg) {871; CHECK-LABEL: zext_load_i32_by_i8_shl_16:872; CHECK: @ %bb.0:873; CHECK-NEXT: ldrb r1, [r0]874; CHECK-NEXT: ldrb r0, [r0, #1]875; CHECK-NEXT: lsl r0, r0, #24876; CHECK-NEXT: orr r0, r0, r1, lsl #16877; CHECK-NEXT: mov pc, lr878;879; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_shl_16:880; CHECK-ARMv6: @ %bb.0:881; CHECK-ARMv6-NEXT: ldrb r1, [r0]882; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]883; CHECK-ARMv6-NEXT: lsl r0, r0, #24884; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #16885; CHECK-ARMv6-NEXT: bx lr886;887; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_shl_16:888; CHECK-THUMBv6: @ %bb.0:889; CHECK-THUMBv6-NEXT: ldrb r1, [r0]890; CHECK-THUMBv6-NEXT: lsls r1, r1, #16891; CHECK-THUMBv6-NEXT: ldrb r0, [r0, #1]892; CHECK-THUMBv6-NEXT: lsls r0, r0, #24893; CHECK-THUMBv6-NEXT: adds r0, r0, r1894; CHECK-THUMBv6-NEXT: bx lr895;896; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_shl_16:897; CHECK-THUMBv7: @ %bb.0:898; CHECK-THUMBv7-NEXT: ldrb r1, [r0]899; CHECK-THUMBv7-NEXT: lsls r1, r1, #16900; CHECK-THUMBv7-NEXT: ldrb r0, [r0, #1]901; CHECK-THUMBv7-NEXT: lsls r0, r0, #24902; CHECK-THUMBv7-NEXT: adds r0, r0, r1903; CHECK-THUMBv7-NEXT: bx lr904 905 %tmp2 = load i8, ptr %arg, align 2906 %tmp3 = zext i8 %tmp2 to i32907 %tmp30 = shl nuw nsw i32 %tmp3, 16908 %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1909 %tmp5 = load i8, ptr %tmp4, align 1910 %tmp6 = zext i8 %tmp5 to i32911 %tmp7 = shl nuw nsw i32 %tmp6, 24912 %tmp8 = or i32 %tmp7, %tmp30913 ret i32 %tmp8914}915 916; ptr p; // p is 2 byte aligned917; (i32) p[1] | ((i32) p[0] << 8)918define i32 @zext_load_i32_by_i8_bswap(ptr %arg) {919; CHECK-LABEL: zext_load_i32_by_i8_bswap:920; CHECK: @ %bb.0:921; CHECK-NEXT: ldrh r0, [r0]922; CHECK-NEXT: mov pc, lr923;924; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap:925; CHECK-ARMv6: @ %bb.0:926; CHECK-ARMv6-NEXT: ldrh r0, [r0]927; CHECK-ARMv6-NEXT: bx lr928;929; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap:930; CHECK-THUMBv6: @ %bb.0:931; CHECK-THUMBv6-NEXT: ldrh r0, [r0]932; CHECK-THUMBv6-NEXT: bx lr933;934; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap:935; CHECK-THUMBv7: @ %bb.0:936; CHECK-THUMBv7-NEXT: ldrh r0, [r0]937; CHECK-THUMBv7-NEXT: bx lr938 939 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1940 %tmp2 = load i8, ptr %tmp1, align 1941 %tmp3 = zext i8 %tmp2 to i32942 %tmp5 = load i8, ptr %arg, align 2943 %tmp6 = zext i8 %tmp5 to i32944 %tmp7 = shl nuw nsw i32 %tmp6, 8945 %tmp8 = or i32 %tmp7, %tmp3946 ret i32 %tmp8947}948 949; ptr p; // p is 2 byte aligned950; ((i32) p[1] << 8) | ((i32) p[0] << 16)951define i32 @zext_load_i32_by_i8_bswap_shl_8(ptr %arg) {952; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8:953; CHECK: @ %bb.0:954; CHECK-NEXT: ldrb r1, [r0]955; CHECK-NEXT: ldrb r0, [r0, #1]956; CHECK-NEXT: lsl r1, r1, #16957; CHECK-NEXT: orr r0, r1, r0, lsl #8958; CHECK-NEXT: mov pc, lr959;960; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap_shl_8:961; CHECK-ARMv6: @ %bb.0:962; CHECK-ARMv6-NEXT: ldrb r1, [r0]963; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]964; CHECK-ARMv6-NEXT: lsl r1, r1, #16965; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #8966; CHECK-ARMv6-NEXT: bx lr967;968; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap_shl_8:969; CHECK-THUMBv6: @ %bb.0:970; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #1]971; CHECK-THUMBv6-NEXT: lsls r1, r1, #8972; CHECK-THUMBv6-NEXT: ldrb r0, [r0]973; CHECK-THUMBv6-NEXT: lsls r0, r0, #16974; CHECK-THUMBv6-NEXT: adds r0, r0, r1975; CHECK-THUMBv6-NEXT: bx lr976;977; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap_shl_8:978; CHECK-THUMBv7: @ %bb.0:979; CHECK-THUMBv7-NEXT: ldrb r1, [r0, #1]980; CHECK-THUMBv7-NEXT: lsls r1, r1, #8981; CHECK-THUMBv7-NEXT: ldrb r0, [r0]982; CHECK-THUMBv7-NEXT: lsls r0, r0, #16983; CHECK-THUMBv7-NEXT: adds r0, r0, r1984; CHECK-THUMBv7-NEXT: bx lr985 986 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1987 %tmp2 = load i8, ptr %tmp1, align 1988 %tmp3 = zext i8 %tmp2 to i32989 %tmp30 = shl nuw nsw i32 %tmp3, 8990 %tmp5 = load i8, ptr %arg, align 2991 %tmp6 = zext i8 %tmp5 to i32992 %tmp7 = shl nuw nsw i32 %tmp6, 16993 %tmp8 = or i32 %tmp7, %tmp30994 ret i32 %tmp8995}996 997; ptr p; // p is 2 byte aligned998; ((i32) p[1] << 16) | ((i32) p[0] << 24)999define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {1000; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16:1001; CHECK: @ %bb.0:1002; CHECK-NEXT: ldrb r1, [r0]1003; CHECK-NEXT: ldrb r0, [r0, #1]1004; CHECK-NEXT: lsl r1, r1, #241005; CHECK-NEXT: orr r0, r1, r0, lsl #161006; CHECK-NEXT: mov pc, lr1007;1008; CHECK-ARMv6-LABEL: zext_load_i32_by_i8_bswap_shl_16:1009; CHECK-ARMv6: @ %bb.0:1010; CHECK-ARMv6-NEXT: ldrb r1, [r0]1011; CHECK-ARMv6-NEXT: ldrb r0, [r0, #1]1012; CHECK-ARMv6-NEXT: lsl r1, r1, #241013; CHECK-ARMv6-NEXT: orr r0, r1, r0, lsl #161014; CHECK-ARMv6-NEXT: bx lr1015;1016; CHECK-THUMBv6-LABEL: zext_load_i32_by_i8_bswap_shl_16:1017; CHECK-THUMBv6: @ %bb.0:1018; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #1]1019; CHECK-THUMBv6-NEXT: lsls r1, r1, #161020; CHECK-THUMBv6-NEXT: ldrb r0, [r0]1021; CHECK-THUMBv6-NEXT: lsls r0, r0, #241022; CHECK-THUMBv6-NEXT: adds r0, r0, r11023; CHECK-THUMBv6-NEXT: bx lr1024;1025; CHECK-THUMBv7-LABEL: zext_load_i32_by_i8_bswap_shl_16:1026; CHECK-THUMBv7: @ %bb.0:1027; CHECK-THUMBv7-NEXT: ldrb r1, [r0, #1]1028; CHECK-THUMBv7-NEXT: lsls r1, r1, #161029; CHECK-THUMBv7-NEXT: ldrb r0, [r0]1030; CHECK-THUMBv7-NEXT: lsls r0, r0, #241031; CHECK-THUMBv7-NEXT: adds r0, r0, r11032; CHECK-THUMBv7-NEXT: bx lr1033 1034 %tmp1 = getelementptr inbounds i8, ptr %arg, i32 11035 %tmp2 = load i8, ptr %tmp1, align 11036 %tmp3 = zext i8 %tmp2 to i321037 %tmp30 = shl nuw nsw i32 %tmp3, 161038 %tmp5 = load i8, ptr %arg, align 21039 %tmp6 = zext i8 %tmp5 to i321040 %tmp7 = shl nuw nsw i32 %tmp6, 241041 %tmp8 = or i32 %tmp7, %tmp301042 ret i32 %tmp81043}1044 1045; ptr p;1046; ptr p1.i16 = (ptr) p;1047; (p1.i16[0] << 8) | ((i16) p[2])1048;1049; This is essentialy a i16 load from p[1], but we don't fold the pattern now1050; because in the original DAG we don't have p[1] address available1051define i16 @load_i16_from_nonzero_offset(ptr %p) {1052; CHECK-LABEL: load_i16_from_nonzero_offset:1053; CHECK: @ %bb.0:1054; CHECK-NEXT: ldrh r1, [r0]1055; CHECK-NEXT: ldrb r0, [r0, #2]1056; CHECK-NEXT: orr r0, r0, r1, lsl #81057; CHECK-NEXT: mov pc, lr1058;1059; CHECK-ARMv6-LABEL: load_i16_from_nonzero_offset:1060; CHECK-ARMv6: @ %bb.0:1061; CHECK-ARMv6-NEXT: ldrh r1, [r0]1062; CHECK-ARMv6-NEXT: ldrb r0, [r0, #2]1063; CHECK-ARMv6-NEXT: orr r0, r0, r1, lsl #81064; CHECK-ARMv6-NEXT: bx lr1065;1066; CHECK-THUMBv6-LABEL: load_i16_from_nonzero_offset:1067; CHECK-THUMBv6: @ %bb.0:1068; CHECK-THUMBv6-NEXT: ldrb r1, [r0, #2]1069; CHECK-THUMBv6-NEXT: ldrh r0, [r0]1070; CHECK-THUMBv6-NEXT: lsls r0, r0, #81071; CHECK-THUMBv6-NEXT: adds r0, r0, r11072; CHECK-THUMBv6-NEXT: bx lr1073;1074; CHECK-THUMBv7-LABEL: load_i16_from_nonzero_offset:1075; CHECK-THUMBv7: @ %bb.0:1076; CHECK-THUMBv7-NEXT: ldrb r1, [r0, #2]1077; CHECK-THUMBv7-NEXT: ldrh r0, [r0]1078; CHECK-THUMBv7-NEXT: lsls r0, r0, #81079; CHECK-THUMBv7-NEXT: adds r0, r0, r11080; CHECK-THUMBv7-NEXT: bx lr1081 1082 %p2.i8 = getelementptr i8, ptr %p, i64 21083 %v1 = load i16, ptr %p1084 %v2.i8 = load i8, ptr %p2.i81085 %v2 = zext i8 %v2.i8 to i161086 %v1.shl = shl i16 %v1, 81087 %res = or i16 %v1.shl, %v21088 ret i16 %res1089}1090