brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.2 KiB · f21c075 Raw
1317 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=CHECK --check-prefix=BSWAP3; RUN: llc < %s -mtriple=i686-unknown -mattr=+movbe | FileCheck %s --check-prefix=CHECK --check-prefix=MOVBE4; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=CHECK64 --check-prefix=BSWAP645; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+movbe | FileCheck %s --check-prefix=CHECK64 --check-prefix=MOVBE646 7; ptr p;8; (i32) p[0] | ((i32) p[1] << 8) | ((i32) p[2] << 16) | ((i32) p[3] << 24)9define i32 @load_i32_by_i8(ptr %arg) {10; CHECK-LABEL: load_i32_by_i8:11; CHECK:       # %bb.0:12; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax13; CHECK-NEXT:    movl (%eax), %eax14; CHECK-NEXT:    retl15;16; CHECK64-LABEL: load_i32_by_i8:17; CHECK64:       # %bb.0:18; CHECK64-NEXT:    movl (%rdi), %eax19; CHECK64-NEXT:    retq20  %tmp1 = load i8, ptr %arg, align 121  %tmp2 = zext i8 %tmp1 to i3222  %tmp3 = getelementptr inbounds i8, ptr %arg, i32 123  %tmp4 = load i8, ptr %tmp3, align 124  %tmp5 = zext i8 %tmp4 to i3225  %tmp6 = shl nuw nsw i32 %tmp5, 826  %tmp7 = or i32 %tmp6, %tmp227  %tmp8 = getelementptr inbounds i8, ptr %arg, i32 228  %tmp9 = load i8, ptr %tmp8, align 129  %tmp10 = zext i8 %tmp9 to i3230  %tmp11 = shl nuw nsw i32 %tmp10, 1631  %tmp12 = or i32 %tmp7, %tmp1132  %tmp13 = getelementptr inbounds i8, ptr %arg, i32 333  %tmp14 = load i8, ptr %tmp13, align 134  %tmp15 = zext i8 %tmp14 to i3235  %tmp16 = shl nuw nsw i32 %tmp15, 2436  %tmp17 = or i32 %tmp12, %tmp1637  ret i32 %tmp1738}39 40; ptr p;41; ((i32) p[0] << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]42define i32 @load_i32_by_i8_bswap(ptr %arg) {43; BSWAP-LABEL: load_i32_by_i8_bswap:44; BSWAP:       # %bb.0:45; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax46; BSWAP-NEXT:    movl (%eax), %eax47; BSWAP-NEXT:    bswapl %eax48; BSWAP-NEXT:    retl49;50; MOVBE-LABEL: load_i32_by_i8_bswap:51; MOVBE:       # %bb.0:52; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax53; MOVBE-NEXT:    movbel (%eax), %eax54; MOVBE-NEXT:    retl55;56; BSWAP64-LABEL: load_i32_by_i8_bswap:57; BSWAP64:       # %bb.0:58; BSWAP64-NEXT:    movl (%rdi), %eax59; BSWAP64-NEXT:    bswapl %eax60; BSWAP64-NEXT:    retq61;62; MOVBE64-LABEL: load_i32_by_i8_bswap:63; MOVBE64:       # %bb.0:64; MOVBE64-NEXT:    movbel (%rdi), %eax65; MOVBE64-NEXT:    retq66  %tmp1 = load i8, ptr %arg, align 167  %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;87; (i32) p[0] | ((i32) p[1] << 16)88define i32 @load_i32_by_i16(ptr %arg) {89; CHECK-LABEL: load_i32_by_i16:90; CHECK:       # %bb.0:91; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax92; CHECK-NEXT:    movl (%eax), %eax93; CHECK-NEXT:    retl94;95; CHECK64-LABEL: load_i32_by_i16:96; CHECK64:       # %bb.0:97; CHECK64-NEXT:    movl (%rdi), %eax98; CHECK64-NEXT:    retq99  %tmp1 = load i16, ptr %arg, align 1100  %tmp2 = zext i16 %tmp1 to i32101  %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1102  %tmp4 = load i16, ptr %tmp3, align 1103  %tmp5 = zext i16 %tmp4 to i32104  %tmp6 = shl nuw nsw i32 %tmp5, 16105  %tmp7 = or i32 %tmp6, %tmp2106  ret i32 %tmp7107}108 109; ptr p_16;110; ptr p_8 = (ptr) p_16;111; (i32) p_16[0] | ((i32) p[2] << 16) | ((i32) p[3] << 24)112define i32 @load_i32_by_i16_i8(ptr %arg) {113; CHECK-LABEL: load_i32_by_i16_i8:114; CHECK:       # %bb.0:115; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax116; CHECK-NEXT:    movl (%eax), %eax117; CHECK-NEXT:    retl118;119; CHECK64-LABEL: load_i32_by_i16_i8:120; CHECK64:       # %bb.0:121; CHECK64-NEXT:    movl (%rdi), %eax122; CHECK64-NEXT:    retq123  %tmp2 = load i16, ptr %arg, align 1124  %tmp3 = zext i16 %tmp2 to i32125  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2126  %tmp5 = load i8, ptr %tmp4, align 1127  %tmp6 = zext i8 %tmp5 to i32128  %tmp7 = shl nuw nsw i32 %tmp6, 16129  %tmp8 = getelementptr inbounds i8, ptr %arg, i32 3130  %tmp9 = load i8, ptr %tmp8, align 1131  %tmp10 = zext i8 %tmp9 to i32132  %tmp11 = shl nuw nsw i32 %tmp10, 24133  %tmp12 = or i32 %tmp7, %tmp11134  %tmp13 = or i32 %tmp12, %tmp3135  ret i32 %tmp13136}137 138 139; ptr p;140; (i32) ((i16) p[0] | ((i16) p[1] << 8)) | (((i32) ((i16) p[3] | ((i16) p[4] << 8)) << 16)141define i32 @load_i32_by_i16_by_i8(ptr %arg) {142; CHECK-LABEL: load_i32_by_i16_by_i8:143; CHECK:       # %bb.0:144; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax145; CHECK-NEXT:    movl (%eax), %eax146; CHECK-NEXT:    retl147;148; CHECK64-LABEL: load_i32_by_i16_by_i8:149; CHECK64:       # %bb.0:150; CHECK64-NEXT:    movl (%rdi), %eax151; CHECK64-NEXT:    retq152  %tmp1 = load i8, ptr %arg, align 1153  %tmp2 = zext i8 %tmp1 to i16154  %tmp3 = getelementptr inbounds i8, ptr %arg, i32 1155  %tmp4 = load i8, ptr %tmp3, align 1156  %tmp5 = zext i8 %tmp4 to i16157  %tmp6 = shl nuw nsw i16 %tmp5, 8158  %tmp7 = or i16 %tmp6, %tmp2159  %tmp8 = getelementptr inbounds i8, ptr %arg, i32 2160  %tmp9 = load i8, ptr %tmp8, align 1161  %tmp10 = zext i8 %tmp9 to i16162  %tmp11 = getelementptr inbounds i8, ptr %arg, i32 3163  %tmp12 = load i8, ptr %tmp11, align 1164  %tmp13 = zext i8 %tmp12 to i16165  %tmp14 = shl nuw nsw i16 %tmp13, 8166  %tmp15 = or i16 %tmp14, %tmp10167  %tmp16 = zext i16 %tmp7 to i32168  %tmp17 = zext i16 %tmp15 to i32169  %tmp18 = shl nuw nsw i32 %tmp17, 16170  %tmp19 = or i32 %tmp18, %tmp16171  ret i32 %tmp19172}173 174; ptr p;175; ((i32) (((i16) p[0] << 8) | (i16) p[1]) << 16) | (i32) (((i16) p[3] << 8) | (i16) p[4])176define i32 @load_i32_by_i16_by_i8_bswap(ptr %arg) {177; BSWAP-LABEL: load_i32_by_i16_by_i8_bswap:178; BSWAP:       # %bb.0:179; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax180; BSWAP-NEXT:    movl (%eax), %eax181; BSWAP-NEXT:    bswapl %eax182; BSWAP-NEXT:    retl183;184; MOVBE-LABEL: load_i32_by_i16_by_i8_bswap:185; MOVBE:       # %bb.0:186; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax187; MOVBE-NEXT:    movbel (%eax), %eax188; MOVBE-NEXT:    retl189;190; BSWAP64-LABEL: load_i32_by_i16_by_i8_bswap:191; BSWAP64:       # %bb.0:192; BSWAP64-NEXT:    movl (%rdi), %eax193; BSWAP64-NEXT:    bswapl %eax194; BSWAP64-NEXT:    retq195;196; MOVBE64-LABEL: load_i32_by_i16_by_i8_bswap:197; MOVBE64:       # %bb.0:198; MOVBE64-NEXT:    movbel (%rdi), %eax199; MOVBE64-NEXT:    retq200  %tmp1 = load i8, ptr %arg, align 1201  %tmp2 = zext i8 %tmp1 to i16202  %tmp3 = getelementptr inbounds i8, ptr %arg, i32 1203  %tmp4 = load i8, ptr %tmp3, align 1204  %tmp5 = zext i8 %tmp4 to i16205  %tmp6 = shl nuw nsw i16 %tmp2, 8206  %tmp7 = or i16 %tmp6, %tmp5207  %tmp8 = getelementptr inbounds i8, ptr %arg, i32 2208  %tmp9 = load i8, ptr %tmp8, align 1209  %tmp10 = zext i8 %tmp9 to i16210  %tmp11 = getelementptr inbounds i8, ptr %arg, i32 3211  %tmp12 = load i8, ptr %tmp11, align 1212  %tmp13 = zext i8 %tmp12 to i16213  %tmp14 = shl nuw nsw i16 %tmp10, 8214  %tmp15 = or i16 %tmp14, %tmp13215  %tmp16 = zext i16 %tmp7 to i32216  %tmp17 = zext i16 %tmp15 to i32217  %tmp18 = shl nuw nsw i32 %tmp16, 16218  %tmp19 = or i32 %tmp18, %tmp17219  ret i32 %tmp19220}221 222; ptr p;223; (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)224define i64 @load_i64_by_i8(ptr %arg) {225; CHECK-LABEL: load_i64_by_i8:226; CHECK:       # %bb.0:227; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx228; CHECK-NEXT:    movl (%ecx), %eax229; CHECK-NEXT:    movl 4(%ecx), %edx230; CHECK-NEXT:    retl231;232; CHECK64-LABEL: load_i64_by_i8:233; CHECK64:       # %bb.0:234; CHECK64-NEXT:    movq (%rdi), %rax235; CHECK64-NEXT:    retq236  %tmp1 = load i8, ptr %arg, align 1237  %tmp2 = zext i8 %tmp1 to i64238  %tmp3 = getelementptr inbounds i8, ptr %arg, i64 1239  %tmp4 = load i8, ptr %tmp3, align 1240  %tmp5 = zext i8 %tmp4 to i64241  %tmp6 = shl nuw nsw i64 %tmp5, 8242  %tmp7 = or i64 %tmp6, %tmp2243  %tmp8 = getelementptr inbounds i8, ptr %arg, i64 2244  %tmp9 = load i8, ptr %tmp8, align 1245  %tmp10 = zext i8 %tmp9 to i64246  %tmp11 = shl nuw nsw i64 %tmp10, 16247  %tmp12 = or i64 %tmp7, %tmp11248  %tmp13 = getelementptr inbounds i8, ptr %arg, i64 3249  %tmp14 = load i8, ptr %tmp13, align 1250  %tmp15 = zext i8 %tmp14 to i64251  %tmp16 = shl nuw nsw i64 %tmp15, 24252  %tmp17 = or i64 %tmp12, %tmp16253  %tmp18 = getelementptr inbounds i8, ptr %arg, i64 4254  %tmp19 = load i8, ptr %tmp18, align 1255  %tmp20 = zext i8 %tmp19 to i64256  %tmp21 = shl nuw nsw i64 %tmp20, 32257  %tmp22 = or i64 %tmp17, %tmp21258  %tmp23 = getelementptr inbounds i8, ptr %arg, i64 5259  %tmp24 = load i8, ptr %tmp23, align 1260  %tmp25 = zext i8 %tmp24 to i64261  %tmp26 = shl nuw nsw i64 %tmp25, 40262  %tmp27 = or i64 %tmp22, %tmp26263  %tmp28 = getelementptr inbounds i8, ptr %arg, i64 6264  %tmp29 = load i8, ptr %tmp28, align 1265  %tmp30 = zext i8 %tmp29 to i64266  %tmp31 = shl nuw nsw i64 %tmp30, 48267  %tmp32 = or i64 %tmp27, %tmp31268  %tmp33 = getelementptr inbounds i8, ptr %arg, i64 7269  %tmp34 = load i8, ptr %tmp33, align 1270  %tmp35 = zext i8 %tmp34 to i64271  %tmp36 = shl nuw i64 %tmp35, 56272  %tmp37 = or i64 %tmp32, %tmp36273  ret i64 %tmp37274}275 276; ptr p;277; ((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]278define i64 @load_i64_by_i8_bswap(ptr %arg) {279; BSWAP-LABEL: load_i64_by_i8_bswap:280; BSWAP:       # %bb.0:281; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax282; BSWAP-NEXT:    movl (%eax), %edx283; BSWAP-NEXT:    movl 4(%eax), %eax284; BSWAP-NEXT:    bswapl %eax285; BSWAP-NEXT:    bswapl %edx286; BSWAP-NEXT:    retl287;288; MOVBE-LABEL: load_i64_by_i8_bswap:289; MOVBE:       # %bb.0:290; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %ecx291; MOVBE-NEXT:    movbel 4(%ecx), %eax292; MOVBE-NEXT:    movbel (%ecx), %edx293; MOVBE-NEXT:    retl294;295; BSWAP64-LABEL: load_i64_by_i8_bswap:296; BSWAP64:       # %bb.0:297; BSWAP64-NEXT:    movq (%rdi), %rax298; BSWAP64-NEXT:    bswapq %rax299; BSWAP64-NEXT:    retq300;301; MOVBE64-LABEL: load_i64_by_i8_bswap:302; MOVBE64:       # %bb.0:303; MOVBE64-NEXT:    movbeq (%rdi), %rax304; MOVBE64-NEXT:    retq305  %tmp1 = load i8, ptr %arg, align 1306  %tmp2 = zext i8 %tmp1 to i64307  %tmp3 = shl nuw i64 %tmp2, 56308  %tmp4 = getelementptr inbounds i8, ptr %arg, i64 1309  %tmp5 = load i8, ptr %tmp4, align 1310  %tmp6 = zext i8 %tmp5 to i64311  %tmp7 = shl nuw nsw i64 %tmp6, 48312  %tmp8 = or i64 %tmp7, %tmp3313  %tmp9 = getelementptr inbounds i8, ptr %arg, i64 2314  %tmp10 = load i8, ptr %tmp9, align 1315  %tmp11 = zext i8 %tmp10 to i64316  %tmp12 = shl nuw nsw i64 %tmp11, 40317  %tmp13 = or i64 %tmp8, %tmp12318  %tmp14 = getelementptr inbounds i8, ptr %arg, i64 3319  %tmp15 = load i8, ptr %tmp14, align 1320  %tmp16 = zext i8 %tmp15 to i64321  %tmp17 = shl nuw nsw i64 %tmp16, 32322  %tmp18 = or i64 %tmp13, %tmp17323  %tmp19 = getelementptr inbounds i8, ptr %arg, i64 4324  %tmp20 = load i8, ptr %tmp19, align 1325  %tmp21 = zext i8 %tmp20 to i64326  %tmp22 = shl nuw nsw i64 %tmp21, 24327  %tmp23 = or i64 %tmp18, %tmp22328  %tmp24 = getelementptr inbounds i8, ptr %arg, i64 5329  %tmp25 = load i8, ptr %tmp24, align 1330  %tmp26 = zext i8 %tmp25 to i64331  %tmp27 = shl nuw nsw i64 %tmp26, 16332  %tmp28 = or i64 %tmp23, %tmp27333  %tmp29 = getelementptr inbounds i8, ptr %arg, i64 6334  %tmp30 = load i8, ptr %tmp29, align 1335  %tmp31 = zext i8 %tmp30 to i64336  %tmp32 = shl nuw nsw i64 %tmp31, 8337  %tmp33 = or i64 %tmp28, %tmp32338  %tmp34 = getelementptr inbounds i8, ptr %arg, i64 7339  %tmp35 = load i8, ptr %tmp34, align 1340  %tmp36 = zext i8 %tmp35 to i64341  %tmp37 = or i64 %tmp33, %tmp36342  ret i64 %tmp37343}344 345; Part of the load by bytes pattern is used outside of the pattern346; ptr p;347; i32 x = (i32) p[1]348; res = ((i32) p[0] << 24) | (x << 16) | ((i32) p[2] << 8) | (i32) p[3]349; x | res350define i32 @load_i32_by_i8_bswap_uses(ptr %arg) {351; CHECK-LABEL: load_i32_by_i8_bswap_uses:352; CHECK:       # %bb.0:353; CHECK-NEXT:    pushl %esi354; CHECK-NEXT:    .cfi_def_cfa_offset 8355; CHECK-NEXT:    .cfi_offset %esi, -8356; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax357; CHECK-NEXT:    movzbl (%eax), %ecx358; CHECK-NEXT:    shll $24, %ecx359; CHECK-NEXT:    movzbl 1(%eax), %edx360; CHECK-NEXT:    movl %edx, %esi361; CHECK-NEXT:    shll $16, %esi362; CHECK-NEXT:    orl %ecx, %esi363; CHECK-NEXT:    movzbl 2(%eax), %ecx364; CHECK-NEXT:    shll $8, %ecx365; CHECK-NEXT:    orl %esi, %ecx366; CHECK-NEXT:    movzbl 3(%eax), %eax367; CHECK-NEXT:    orl %ecx, %eax368; CHECK-NEXT:    orl %edx, %eax369; CHECK-NEXT:    popl %esi370; CHECK-NEXT:    .cfi_def_cfa_offset 4371; CHECK-NEXT:    retl372;373; CHECK64-LABEL: load_i32_by_i8_bswap_uses:374; CHECK64:       # %bb.0:375; CHECK64-NEXT:    movzbl (%rdi), %eax376; CHECK64-NEXT:    shll $24, %eax377; CHECK64-NEXT:    movzbl 1(%rdi), %ecx378; CHECK64-NEXT:    movl %ecx, %edx379; CHECK64-NEXT:    shll $16, %edx380; CHECK64-NEXT:    orl %eax, %edx381; CHECK64-NEXT:    movzbl 2(%rdi), %esi382; CHECK64-NEXT:    shll $8, %esi383; CHECK64-NEXT:    orl %edx, %esi384; CHECK64-NEXT:    movzbl 3(%rdi), %eax385; CHECK64-NEXT:    orl %esi, %eax386; CHECK64-NEXT:    orl %ecx, %eax387; CHECK64-NEXT:    retq388  %tmp1 = load i8, ptr %arg, align 1389  %tmp2 = zext i8 %tmp1 to i32390  %tmp3 = shl nuw nsw i32 %tmp2, 24391  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1392  %tmp5 = load i8, ptr %tmp4, align 1393  %tmp6 = zext i8 %tmp5 to i32394  %tmp7 = shl nuw nsw i32 %tmp6, 16395  %tmp8 = or i32 %tmp7, %tmp3396  %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2397  %tmp10 = load i8, ptr %tmp9, align 1398  %tmp11 = zext i8 %tmp10 to i32399  %tmp12 = shl nuw nsw i32 %tmp11, 8400  %tmp13 = or i32 %tmp8, %tmp12401  %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3402  %tmp15 = load i8, ptr %tmp14, align 1403  %tmp16 = zext i8 %tmp15 to i32404  %tmp17 = or i32 %tmp13, %tmp16405  ; Use individual part of the pattern outside of the pattern406  %tmp18 = or i32 %tmp6, %tmp17407  ret i32 %tmp18408}409 410; One of the loads is volatile411; ptr p;412; p0 = volatile *p;413; ((i32) p0 << 24) | ((i32) p[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]414define i32 @load_i32_by_i8_bswap_volatile(ptr %arg) {415; CHECK-LABEL: load_i32_by_i8_bswap_volatile:416; CHECK:       # %bb.0:417; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax418; CHECK-NEXT:    movzbl (%eax), %ecx419; CHECK-NEXT:    shll $24, %ecx420; CHECK-NEXT:    movzbl 1(%eax), %edx421; CHECK-NEXT:    shll $16, %edx422; CHECK-NEXT:    orl %ecx, %edx423; CHECK-NEXT:    movzbl 2(%eax), %ecx424; CHECK-NEXT:    shll $8, %ecx425; CHECK-NEXT:    orl %edx, %ecx426; CHECK-NEXT:    movzbl 3(%eax), %eax427; CHECK-NEXT:    orl %ecx, %eax428; CHECK-NEXT:    retl429;430; CHECK64-LABEL: load_i32_by_i8_bswap_volatile:431; CHECK64:       # %bb.0:432; CHECK64-NEXT:    movzbl (%rdi), %eax433; CHECK64-NEXT:    shll $24, %eax434; CHECK64-NEXT:    movzbl 1(%rdi), %ecx435; CHECK64-NEXT:    shll $16, %ecx436; CHECK64-NEXT:    orl %eax, %ecx437; CHECK64-NEXT:    movzbl 2(%rdi), %edx438; CHECK64-NEXT:    shll $8, %edx439; CHECK64-NEXT:    orl %ecx, %edx440; CHECK64-NEXT:    movzbl 3(%rdi), %eax441; CHECK64-NEXT:    orl %edx, %eax442; CHECK64-NEXT:    retq443  %tmp1 = load volatile i8, ptr %arg, align 1444  %tmp2 = zext i8 %tmp1 to i32445  %tmp3 = shl nuw nsw i32 %tmp2, 24446  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 1447  %tmp5 = load i8, ptr %tmp4, align 1448  %tmp6 = zext i8 %tmp5 to i32449  %tmp7 = shl nuw nsw i32 %tmp6, 16450  %tmp8 = or i32 %tmp7, %tmp3451  %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2452  %tmp10 = load i8, ptr %tmp9, align 1453  %tmp11 = zext i8 %tmp10 to i32454  %tmp12 = shl nuw nsw i32 %tmp11, 8455  %tmp13 = or i32 %tmp8, %tmp12456  %tmp14 = getelementptr inbounds i8, ptr %arg, i32 3457  %tmp15 = load i8, ptr %tmp14, align 1458  %tmp16 = zext i8 %tmp15 to i32459  %tmp17 = or i32 %tmp13, %tmp16460  ret i32 %tmp17461}462 463; There is a store in between individual loads464; ptr p, q;465; res1 = ((i32) p[0] << 24) | ((i32) p[1] << 16)466; *q = 0;467; res2 = ((i32) p[2] << 8) | (i32) p[3]468; res1 | res2469define i32 @load_i32_by_i8_bswap_store_in_between(ptr %arg, ptr %arg1) {470; CHECK-LABEL: load_i32_by_i8_bswap_store_in_between:471; CHECK:       # %bb.0:472; CHECK-NEXT:    pushl %esi473; CHECK-NEXT:    .cfi_def_cfa_offset 8474; CHECK-NEXT:    .cfi_offset %esi, -8475; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx476; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax477; CHECK-NEXT:    movzbl (%eax), %edx478; CHECK-NEXT:    shll $24, %edx479; CHECK-NEXT:    movzbl 1(%eax), %esi480; CHECK-NEXT:    movl $0, (%ecx)481; CHECK-NEXT:    shll $16, %esi482; CHECK-NEXT:    orl %edx, %esi483; CHECK-NEXT:    movzbl 2(%eax), %ecx484; CHECK-NEXT:    shll $8, %ecx485; CHECK-NEXT:    orl %esi, %ecx486; CHECK-NEXT:    movzbl 3(%eax), %eax487; CHECK-NEXT:    orl %ecx, %eax488; CHECK-NEXT:    popl %esi489; CHECK-NEXT:    .cfi_def_cfa_offset 4490; CHECK-NEXT:    retl491;492; CHECK64-LABEL: load_i32_by_i8_bswap_store_in_between:493; CHECK64:       # %bb.0:494; CHECK64-NEXT:    movzbl (%rdi), %eax495; CHECK64-NEXT:    shll $24, %eax496; CHECK64-NEXT:    movzbl 1(%rdi), %ecx497; CHECK64-NEXT:    movl $0, (%rsi)498; CHECK64-NEXT:    shll $16, %ecx499; CHECK64-NEXT:    orl %eax, %ecx500; CHECK64-NEXT:    movzbl 2(%rdi), %edx501; CHECK64-NEXT:    shll $8, %edx502; CHECK64-NEXT:    orl %ecx, %edx503; CHECK64-NEXT:    movzbl 3(%rdi), %eax504; CHECK64-NEXT:    orl %edx, %eax505; CHECK64-NEXT:    retq506  %tmp2 = load i8, ptr %arg, align 1507  %tmp3 = zext i8 %tmp2 to i32508  %tmp4 = shl nuw nsw i32 %tmp3, 24509  %tmp5 = getelementptr inbounds i8, ptr %arg, i32 1510  %tmp6 = load i8, ptr %tmp5, align 1511  ; This store will prevent folding of the pattern512  store i32 0, ptr %arg1513  %tmp7 = zext i8 %tmp6 to i32514  %tmp8 = shl nuw nsw i32 %tmp7, 16515  %tmp9 = or i32 %tmp8, %tmp4516  %tmp10 = getelementptr inbounds i8, ptr %arg, i32 2517  %tmp11 = load i8, ptr %tmp10, align 1518  %tmp12 = zext i8 %tmp11 to i32519  %tmp13 = shl nuw nsw i32 %tmp12, 8520  %tmp14 = or i32 %tmp9, %tmp13521  %tmp15 = getelementptr inbounds i8, ptr %arg, i32 3522  %tmp16 = load i8, ptr %tmp15, align 1523  %tmp17 = zext i8 %tmp16 to i32524  %tmp18 = or i32 %tmp14, %tmp17525  ret i32 %tmp18526}527 528; One of the loads is from an unrelated location529; ptr p, q;530; ((i32) p[0] << 24) | ((i32) q[1] << 16) | ((i32) p[2] << 8) | (i32) p[3]531define i32 @load_i32_by_i8_bswap_unrelated_load(ptr %arg, ptr %arg1) {532; CHECK-LABEL: load_i32_by_i8_bswap_unrelated_load:533; CHECK:       # %bb.0:534; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax535; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx536; CHECK-NEXT:    movzbl (%ecx), %edx537; CHECK-NEXT:    shll $24, %edx538; CHECK-NEXT:    movzbl 1(%eax), %eax539; CHECK-NEXT:    shll $16, %eax540; CHECK-NEXT:    orl %edx, %eax541; CHECK-NEXT:    movzbl 2(%ecx), %edx542; CHECK-NEXT:    shll $8, %edx543; CHECK-NEXT:    orl %eax, %edx544; CHECK-NEXT:    movzbl 3(%ecx), %eax545; CHECK-NEXT:    orl %edx, %eax546; CHECK-NEXT:    retl547;548; CHECK64-LABEL: load_i32_by_i8_bswap_unrelated_load:549; CHECK64:       # %bb.0:550; CHECK64-NEXT:    movzbl (%rdi), %eax551; CHECK64-NEXT:    shll $24, %eax552; CHECK64-NEXT:    movzbl 1(%rsi), %ecx553; CHECK64-NEXT:    shll $16, %ecx554; CHECK64-NEXT:    orl %eax, %ecx555; CHECK64-NEXT:    movzbl 2(%rdi), %edx556; CHECK64-NEXT:    shll $8, %edx557; CHECK64-NEXT:    orl %ecx, %edx558; CHECK64-NEXT:    movzbl 3(%rdi), %eax559; CHECK64-NEXT:    orl %edx, %eax560; CHECK64-NEXT:    retq561  %tmp3 = load i8, ptr %arg, align 1562  %tmp4 = zext i8 %tmp3 to i32563  %tmp5 = shl nuw nsw i32 %tmp4, 24564  ; Load from an unrelated address565  %tmp6 = getelementptr inbounds i8, ptr %arg1, i32 1566  %tmp7 = load i8, ptr %tmp6, align 1567  %tmp8 = zext i8 %tmp7 to i32568  %tmp9 = shl nuw nsw i32 %tmp8, 16569  %tmp10 = or i32 %tmp9, %tmp5570  %tmp11 = getelementptr inbounds i8, ptr %arg, i32 2571  %tmp12 = load i8, ptr %tmp11, align 1572  %tmp13 = zext i8 %tmp12 to i32573  %tmp14 = shl nuw nsw i32 %tmp13, 8574  %tmp15 = or i32 %tmp10, %tmp14575  %tmp16 = getelementptr inbounds i8, ptr %arg, i32 3576  %tmp17 = load i8, ptr %tmp16, align 1577  %tmp18 = zext i8 %tmp17 to i32578  %tmp19 = or i32 %tmp15, %tmp18579  ret i32 %tmp19580}581 582; ptr p;583; (i32) p[1] | ((i32) p[2] << 8) | ((i32) p[3] << 16) | ((i32) p[4] << 24)584define i32 @load_i32_by_i8_nonzero_offset(ptr %arg) {585; CHECK-LABEL: load_i32_by_i8_nonzero_offset:586; CHECK:       # %bb.0:587; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax588; CHECK-NEXT:    movl 1(%eax), %eax589; CHECK-NEXT:    retl590;591; CHECK64-LABEL: load_i32_by_i8_nonzero_offset:592; CHECK64:       # %bb.0:593; CHECK64-NEXT:    movl 1(%rdi), %eax594; CHECK64-NEXT:    retq595  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 1596  %tmp2 = load i8, ptr %tmp1, align 1597  %tmp3 = zext i8 %tmp2 to i32598  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 2599  %tmp5 = load i8, ptr %tmp4, align 1600  %tmp6 = zext i8 %tmp5 to i32601  %tmp7 = shl nuw nsw i32 %tmp6, 8602  %tmp8 = or i32 %tmp7, %tmp3603  %tmp9 = getelementptr inbounds i8, ptr %arg, i32 3604  %tmp10 = load i8, ptr %tmp9, align 1605  %tmp11 = zext i8 %tmp10 to i32606  %tmp12 = shl nuw nsw i32 %tmp11, 16607  %tmp13 = or i32 %tmp8, %tmp12608  %tmp14 = getelementptr inbounds i8, ptr %arg, i32 4609  %tmp15 = load i8, ptr %tmp14, align 1610  %tmp16 = zext i8 %tmp15 to i32611  %tmp17 = shl nuw nsw i32 %tmp16, 24612  %tmp18 = or i32 %tmp13, %tmp17613  ret i32 %tmp18614}615 616; ptr p;617; (i32) p[-4] | ((i32) p[-3] << 8) | ((i32) p[-2] << 16) | ((i32) p[-1] << 24)618define i32 @load_i32_by_i8_neg_offset(ptr %arg) {619; CHECK-LABEL: load_i32_by_i8_neg_offset:620; CHECK:       # %bb.0:621; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax622; CHECK-NEXT:    movl -4(%eax), %eax623; CHECK-NEXT:    retl624;625; CHECK64-LABEL: load_i32_by_i8_neg_offset:626; CHECK64:       # %bb.0:627; CHECK64-NEXT:    movl -4(%rdi), %eax628; CHECK64-NEXT:    retq629  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -4630  %tmp2 = load i8, ptr %tmp1, align 1631  %tmp3 = zext i8 %tmp2 to i32632  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -3633  %tmp5 = load i8, ptr %tmp4, align 1634  %tmp6 = zext i8 %tmp5 to i32635  %tmp7 = shl nuw nsw i32 %tmp6, 8636  %tmp8 = or i32 %tmp7, %tmp3637  %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -2638  %tmp10 = load i8, ptr %tmp9, align 1639  %tmp11 = zext i8 %tmp10 to i32640  %tmp12 = shl nuw nsw i32 %tmp11, 16641  %tmp13 = or i32 %tmp8, %tmp12642  %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -1643  %tmp15 = load i8, ptr %tmp14, align 1644  %tmp16 = zext i8 %tmp15 to i32645  %tmp17 = shl nuw nsw i32 %tmp16, 24646  %tmp18 = or i32 %tmp13, %tmp17647  ret i32 %tmp18648}649 650; ptr p;651; (i32) p[4] | ((i32) p[3] << 8) | ((i32) p[2] << 16) | ((i32) p[1] << 24)652define i32 @load_i32_by_i8_nonzero_offset_bswap(ptr %arg) {653; BSWAP-LABEL: load_i32_by_i8_nonzero_offset_bswap:654; BSWAP:       # %bb.0:655; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax656; BSWAP-NEXT:    movl 1(%eax), %eax657; BSWAP-NEXT:    bswapl %eax658; BSWAP-NEXT:    retl659;660; MOVBE-LABEL: load_i32_by_i8_nonzero_offset_bswap:661; MOVBE:       # %bb.0:662; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax663; MOVBE-NEXT:    movbel 1(%eax), %eax664; MOVBE-NEXT:    retl665;666; BSWAP64-LABEL: load_i32_by_i8_nonzero_offset_bswap:667; BSWAP64:       # %bb.0:668; BSWAP64-NEXT:    movl 1(%rdi), %eax669; BSWAP64-NEXT:    bswapl %eax670; BSWAP64-NEXT:    retq671;672; MOVBE64-LABEL: load_i32_by_i8_nonzero_offset_bswap:673; MOVBE64:       # %bb.0:674; MOVBE64-NEXT:    movbel 1(%rdi), %eax675; MOVBE64-NEXT:    retq676  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 4677  %tmp2 = load i8, ptr %tmp1, align 1678  %tmp3 = zext i8 %tmp2 to i32679  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 3680  %tmp5 = load i8, ptr %tmp4, align 1681  %tmp6 = zext i8 %tmp5 to i32682  %tmp7 = shl nuw nsw i32 %tmp6, 8683  %tmp8 = or i32 %tmp7, %tmp3684  %tmp9 = getelementptr inbounds i8, ptr %arg, i32 2685  %tmp10 = load i8, ptr %tmp9, align 1686  %tmp11 = zext i8 %tmp10 to i32687  %tmp12 = shl nuw nsw i32 %tmp11, 16688  %tmp13 = or i32 %tmp8, %tmp12689  %tmp14 = getelementptr inbounds i8, ptr %arg, i32 1690  %tmp15 = load i8, ptr %tmp14, align 1691  %tmp16 = zext i8 %tmp15 to i32692  %tmp17 = shl nuw nsw i32 %tmp16, 24693  %tmp18 = or i32 %tmp13, %tmp17694  ret i32 %tmp18695}696 697; ptr p;698; (i32) p[-1] | ((i32) p[-2] << 8) | ((i32) p[-3] << 16) | ((i32) p[-4] << 24)699define i32 @load_i32_by_i8_neg_offset_bswap(ptr %arg) {700; BSWAP-LABEL: load_i32_by_i8_neg_offset_bswap:701; BSWAP:       # %bb.0:702; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax703; BSWAP-NEXT:    movl -4(%eax), %eax704; BSWAP-NEXT:    bswapl %eax705; BSWAP-NEXT:    retl706;707; MOVBE-LABEL: load_i32_by_i8_neg_offset_bswap:708; MOVBE:       # %bb.0:709; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax710; MOVBE-NEXT:    movbel -4(%eax), %eax711; MOVBE-NEXT:    retl712;713; BSWAP64-LABEL: load_i32_by_i8_neg_offset_bswap:714; BSWAP64:       # %bb.0:715; BSWAP64-NEXT:    movl -4(%rdi), %eax716; BSWAP64-NEXT:    bswapl %eax717; BSWAP64-NEXT:    retq718;719; MOVBE64-LABEL: load_i32_by_i8_neg_offset_bswap:720; MOVBE64:       # %bb.0:721; MOVBE64-NEXT:    movbel -4(%rdi), %eax722; MOVBE64-NEXT:    retq723  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 -1724  %tmp2 = load i8, ptr %tmp1, align 1725  %tmp3 = zext i8 %tmp2 to i32726  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 -2727  %tmp5 = load i8, ptr %tmp4, align 1728  %tmp6 = zext i8 %tmp5 to i32729  %tmp7 = shl nuw nsw i32 %tmp6, 8730  %tmp8 = or i32 %tmp7, %tmp3731  %tmp9 = getelementptr inbounds i8, ptr %arg, i32 -3732  %tmp10 = load i8, ptr %tmp9, align 1733  %tmp11 = zext i8 %tmp10 to i32734  %tmp12 = shl nuw nsw i32 %tmp11, 16735  %tmp13 = or i32 %tmp8, %tmp12736  %tmp14 = getelementptr inbounds i8, ptr %arg, i32 -4737  %tmp15 = load i8, ptr %tmp14, align 1738  %tmp16 = zext i8 %tmp15 to i32739  %tmp17 = shl nuw nsw i32 %tmp16, 24740  %tmp18 = or i32 %tmp13, %tmp17741  ret i32 %tmp18742}743 744; ptr p; i32 i;745; ((i32) p[i] << 24) | ((i32) p[i + 1] << 16) | ((i32) p[i + 2] << 8) | (i32) p[i + 3]746define i32 @load_i32_by_i8_bswap_base_index_offset(ptr %arg, i32 %arg1) {747; BSWAP-LABEL: load_i32_by_i8_bswap_base_index_offset:748; BSWAP:       # %bb.0:749; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax750; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %ecx751; BSWAP-NEXT:    movl (%ecx,%eax), %eax752; BSWAP-NEXT:    bswapl %eax753; BSWAP-NEXT:    retl754;755; MOVBE-LABEL: load_i32_by_i8_bswap_base_index_offset:756; MOVBE:       # %bb.0:757; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax758; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %ecx759; MOVBE-NEXT:    movbel (%ecx,%eax), %eax760; MOVBE-NEXT:    retl761;762; BSWAP64-LABEL: load_i32_by_i8_bswap_base_index_offset:763; BSWAP64:       # %bb.0:764; BSWAP64-NEXT:    movslq %esi, %rax765; BSWAP64-NEXT:    movl (%rdi,%rax), %eax766; BSWAP64-NEXT:    bswapl %eax767; BSWAP64-NEXT:    retq768;769; MOVBE64-LABEL: load_i32_by_i8_bswap_base_index_offset:770; MOVBE64:       # %bb.0:771; MOVBE64-NEXT:    movslq %esi, %rax772; MOVBE64-NEXT:    movbel (%rdi,%rax), %eax773; MOVBE64-NEXT:    retq774  %tmp2 = getelementptr inbounds i8, ptr %arg, i32 %arg1775  %tmp3 = load i8, ptr %tmp2, align 1776  %tmp4 = zext i8 %tmp3 to i32777  %tmp5 = shl nuw nsw i32 %tmp4, 24778  %tmp6 = add nuw nsw i32 %arg1, 1779  %tmp7 = getelementptr inbounds i8, ptr %arg, i32 %tmp6780  %tmp8 = load i8, ptr %tmp7, align 1781  %tmp9 = zext i8 %tmp8 to i32782  %tmp10 = shl nuw nsw i32 %tmp9, 16783  %tmp11 = or i32 %tmp10, %tmp5784  %tmp12 = add nuw nsw i32 %arg1, 2785  %tmp13 = getelementptr inbounds i8, ptr %arg, i32 %tmp12786  %tmp14 = load i8, ptr %tmp13, align 1787  %tmp15 = zext i8 %tmp14 to i32788  %tmp16 = shl nuw nsw i32 %tmp15, 8789  %tmp17 = or i32 %tmp11, %tmp16790  %tmp18 = add nuw nsw i32 %arg1, 3791  %tmp19 = getelementptr inbounds i8, ptr %arg, i32 %tmp18792  %tmp20 = load i8, ptr %tmp19, align 1793  %tmp21 = zext i8 %tmp20 to i32794  %tmp22 = or i32 %tmp17, %tmp21795  ret i32 %tmp22796}797 798; Verify that we don't crash handling shl i32 %conv57, 32799define void @shift_i32_by_32(ptr %src1, ptr %src2, ptr %dst) {800; CHECK-LABEL: shift_i32_by_32:801; CHECK:       # %bb.0: # %entry802; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax803; CHECK-NEXT:    movl $0, 4(%eax)804; CHECK-NEXT:    movl $0, (%eax)805; CHECK-NEXT:    retl806;807; CHECK64-LABEL: shift_i32_by_32:808; CHECK64:       # %bb.0: # %entry809; CHECK64-NEXT:    movq $0, (%rdx)810; CHECK64-NEXT:    retq811entry:812  %load1 = load i8, ptr %src1, align 1813  %conv46 = zext i8 %load1 to i32814  %shl47 = shl i32 %conv46, 56815  %or55 = or i32 %shl47, 0816  %load2 = load i8, ptr %src2, align 1817  %conv57 = zext i8 %load2 to i32818  %shl58 = shl i32 %conv57, 32819  %or59 = or i32 %or55, %shl58820  %or74 = or i32 %or59, 0821  %conv75 = sext i32 %or74 to i64822  store i64 %conv75, ptr %dst, align 8823  ret void824}825 826declare i16 @llvm.bswap.i16(i16)827 828; ptr p;829; (i32) bswap(p[1]) | (i32) bswap(p[0] << 16)830define i32 @load_i32_by_bswap_i16(ptr %arg) {831; BSWAP-LABEL: load_i32_by_bswap_i16:832; BSWAP:       # %bb.0:833; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax834; BSWAP-NEXT:    movl (%eax), %eax835; BSWAP-NEXT:    bswapl %eax836; BSWAP-NEXT:    retl837;838; MOVBE-LABEL: load_i32_by_bswap_i16:839; MOVBE:       # %bb.0:840; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax841; MOVBE-NEXT:    movbel (%eax), %eax842; MOVBE-NEXT:    retl843;844; BSWAP64-LABEL: load_i32_by_bswap_i16:845; BSWAP64:       # %bb.0:846; BSWAP64-NEXT:    movl (%rdi), %eax847; BSWAP64-NEXT:    bswapl %eax848; BSWAP64-NEXT:    retq849;850; MOVBE64-LABEL: load_i32_by_bswap_i16:851; MOVBE64:       # %bb.0:852; MOVBE64-NEXT:    movbel (%rdi), %eax853; MOVBE64-NEXT:    retq854  %tmp1 = load i16, ptr %arg, align 4855  %tmp11 = call i16 @llvm.bswap.i16(i16 %tmp1)856  %tmp2 = zext i16 %tmp11 to i32857  %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1858  %tmp4 = load i16, ptr %tmp3, align 1859  %tmp41 = call i16 @llvm.bswap.i16(i16 %tmp4)860  %tmp5 = zext i16 %tmp41 to i32861  %tmp6 = shl nuw nsw i32 %tmp2, 16862  %tmp7 = or i32 %tmp6, %tmp5863  ret i32 %tmp7864}865 866; ptr p;867; (i32) p[0] | (sext(p[1] << 16) to i32)868define i32 @load_i32_by_sext_i16(ptr %arg) {869; CHECK-LABEL: load_i32_by_sext_i16:870; CHECK:       # %bb.0:871; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax872; CHECK-NEXT:    movl (%eax), %eax873; CHECK-NEXT:    retl874;875; CHECK64-LABEL: load_i32_by_sext_i16:876; CHECK64:       # %bb.0:877; CHECK64-NEXT:    movl (%rdi), %eax878; CHECK64-NEXT:    retq879  %tmp1 = load i16, ptr %arg, align 1880  %tmp2 = zext i16 %tmp1 to i32881  %tmp3 = getelementptr inbounds i16, ptr %arg, i32 1882  %tmp4 = load i16, ptr %tmp3, align 1883  %tmp5 = sext i16 %tmp4 to i32884  %tmp6 = shl nuw nsw i32 %tmp5, 16885  %tmp7 = or i32 %tmp6, %tmp2886  ret i32 %tmp7887}888 889; ptr arg; i32 i;890; p = arg + 12;891; (i32) p[i] | ((i32) p[i + 1] << 8) | ((i32) p[i + 2] << 16) | ((i32) p[i + 3] << 24)892define i32 @load_i32_by_i8_base_offset_index(ptr %arg, i32 %i) {893; CHECK-LABEL: load_i32_by_i8_base_offset_index:894; CHECK:       # %bb.0:895; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax896; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx897; CHECK-NEXT:    movl 12(%eax,%ecx), %eax898; CHECK-NEXT:    retl899;900; CHECK64-LABEL: load_i32_by_i8_base_offset_index:901; CHECK64:       # %bb.0:902; CHECK64-NEXT:    movl %esi, %eax903; CHECK64-NEXT:    movl 12(%rdi,%rax), %eax904; CHECK64-NEXT:    retq905  %tmp = add nuw nsw i32 %i, 3906  %tmp2 = add nuw nsw i32 %i, 2907  %tmp3 = add nuw nsw i32 %i, 1908  %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12909  %tmp5 = zext i32 %i to i64910  %tmp6 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp5911  %tmp7 = load i8, ptr %tmp6, align 1912  %tmp8 = zext i8 %tmp7 to i32913  %tmp9 = zext i32 %tmp3 to i64914  %tmp10 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp9915  %tmp11 = load i8, ptr %tmp10, align 1916  %tmp12 = zext i8 %tmp11 to i32917  %tmp13 = shl nuw nsw i32 %tmp12, 8918  %tmp14 = or i32 %tmp13, %tmp8919  %tmp15 = zext i32 %tmp2 to i64920  %tmp16 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp15921  %tmp17 = load i8, ptr %tmp16, align 1922  %tmp18 = zext i8 %tmp17 to i32923  %tmp19 = shl nuw nsw i32 %tmp18, 16924  %tmp20 = or i32 %tmp14, %tmp19925  %tmp21 = zext i32 %tmp to i64926  %tmp22 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp21927  %tmp23 = load i8, ptr %tmp22, align 1928  %tmp24 = zext i8 %tmp23 to i32929  %tmp25 = shl nuw i32 %tmp24, 24930  %tmp26 = or i32 %tmp20, %tmp25931  ret i32 %tmp26932}933 934; ptr arg; i32 i;935; p = arg + 12;936; (i32) p[i + 1] | ((i32) p[i + 2] << 8) | ((i32) p[i + 3] << 16) | ((i32) p[i + 4] << 24)937define i32 @load_i32_by_i8_base_offset_index_2(ptr %arg, i32 %i) {938; CHECK-LABEL: load_i32_by_i8_base_offset_index_2:939; CHECK:       # %bb.0:940; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax941; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx942; CHECK-NEXT:    movl 13(%eax,%ecx), %eax943; CHECK-NEXT:    retl944;945; CHECK64-LABEL: load_i32_by_i8_base_offset_index_2:946; CHECK64:       # %bb.0:947; CHECK64-NEXT:    movl %esi, %eax948; CHECK64-NEXT:    movl 13(%rax,%rdi), %eax949; CHECK64-NEXT:    retq950  %tmp = add nuw nsw i32 %i, 4951  %tmp2 = add nuw nsw i32 %i, 3952  %tmp3 = add nuw nsw i32 %i, 2953  %tmp4 = getelementptr inbounds i8, ptr %arg, i64 12954  %tmp5 = add nuw nsw i32 %i, 1955  %tmp27 = zext i32 %tmp5 to i64956  %tmp28 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp27957  %tmp29 = load i8, ptr %tmp28, align 1958  %tmp30 = zext i8 %tmp29 to i32959  %tmp31 = zext i32 %tmp3 to i64960  %tmp32 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp31961  %tmp33 = load i8, ptr %tmp32, align 1962  %tmp34 = zext i8 %tmp33 to i32963  %tmp35 = shl nuw nsw i32 %tmp34, 8964  %tmp36 = or i32 %tmp35, %tmp30965  %tmp37 = zext i32 %tmp2 to i64966  %tmp38 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp37967  %tmp39 = load i8, ptr %tmp38, align 1968  %tmp40 = zext i8 %tmp39 to i32969  %tmp41 = shl nuw nsw i32 %tmp40, 16970  %tmp42 = or i32 %tmp36, %tmp41971  %tmp43 = zext i32 %tmp to i64972  %tmp44 = getelementptr inbounds i8, ptr %tmp4, i64 %tmp43973  %tmp45 = load i8, ptr %tmp44, align 1974  %tmp46 = zext i8 %tmp45 to i32975  %tmp47 = shl nuw i32 %tmp46, 24976  %tmp48 = or i32 %tmp42, %tmp47977  ret i32 %tmp48978}979 980; ptr arg; i32 i;981;982; p0 = arg;983; p1 = arg + i + 1;984; p2 = arg + i + 2;985; p3 = arg + i + 3;986;987; (i32) p0[12] | ((i32) p1[12] << 8) | ((i32) p2[12] << 16) | ((i32) p3[12] << 24)988;989; This test excercises zero and any extend loads as a part of load combine pattern.990; In order to fold the pattern above we need to reassociate the address computation991; first. By the time the address computation is reassociated loads are combined to992; to zext and aext loads.993define i32 @load_i32_by_i8_zaext_loads(ptr %arg, i32 %arg1) {994; CHECK-LABEL: load_i32_by_i8_zaext_loads:995; CHECK:       # %bb.0:996; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax997; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx998; CHECK-NEXT:    movl 12(%eax,%ecx), %eax999; CHECK-NEXT:    retl1000;1001; CHECK64-LABEL: load_i32_by_i8_zaext_loads:1002; CHECK64:       # %bb.0:1003; CHECK64-NEXT:    movl %esi, %eax1004; CHECK64-NEXT:    movl 12(%rdi,%rax), %eax1005; CHECK64-NEXT:    retq1006  %tmp = add nuw nsw i32 %arg1, 31007  %tmp2 = add nuw nsw i32 %arg1, 21008  %tmp3 = add nuw nsw i32 %arg1, 11009  %tmp4 = zext i32 %tmp to i641010  %tmp5 = zext i32 %tmp2 to i641011  %tmp6 = zext i32 %tmp3 to i641012  %tmp24 = getelementptr inbounds i8, ptr %arg, i64 %tmp41013  %tmp30 = getelementptr inbounds i8, ptr %arg, i64 %tmp51014  %tmp31 = getelementptr inbounds i8, ptr %arg, i64 %tmp61015  %tmp32 = getelementptr inbounds i8, ptr %arg, i64 121016  %tmp33 = zext i32 %arg1 to i641017  %tmp34 = getelementptr inbounds i8, ptr %tmp32, i64 %tmp331018  %tmp35 = load i8, ptr %tmp34, align 11019  %tmp36 = zext i8 %tmp35 to i321020  %tmp37 = getelementptr inbounds i8, ptr %tmp31, i64 121021  %tmp38 = load i8, ptr %tmp37, align 11022  %tmp39 = zext i8 %tmp38 to i321023  %tmp40 = shl nuw nsw i32 %tmp39, 81024  %tmp41 = or i32 %tmp40, %tmp361025  %tmp42 = getelementptr inbounds i8, ptr %tmp30, i64 121026  %tmp43 = load i8, ptr %tmp42, align 11027  %tmp44 = zext i8 %tmp43 to i321028  %tmp45 = shl nuw nsw i32 %tmp44, 161029  %tmp46 = or i32 %tmp41, %tmp451030  %tmp47 = getelementptr inbounds i8, ptr %tmp24, i64 121031  %tmp48 = load i8, ptr %tmp47, align 11032  %tmp49 = zext i8 %tmp48 to i321033  %tmp50 = shl nuw i32 %tmp49, 241034  %tmp51 = or i32 %tmp46, %tmp501035  ret i32 %tmp511036}1037 1038; The same as load_i32_by_i8_zaext_loads but the last load is combined to1039; a sext load.1040;1041; ptr arg; i32 i;1042;1043; p0 = arg;1044; p1 = arg + i + 1;1045; p2 = arg + i + 2;1046; p3 = arg + i + 3;1047;1048; (i32) p0[12] | ((i32) p1[12] << 8) | ((i32) p2[12] << 16) | ((i32) p3[12] << 24)1049define i32 @load_i32_by_i8_zsext_loads(ptr %arg, i32 %arg1) {1050; CHECK-LABEL: load_i32_by_i8_zsext_loads:1051; CHECK:       # %bb.0:1052; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax1053; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx1054; CHECK-NEXT:    movl 12(%eax,%ecx), %eax1055; CHECK-NEXT:    retl1056;1057; CHECK64-LABEL: load_i32_by_i8_zsext_loads:1058; CHECK64:       # %bb.0:1059; CHECK64-NEXT:    movl %esi, %eax1060; CHECK64-NEXT:    movl 12(%rdi,%rax), %eax1061; CHECK64-NEXT:    retq1062  %tmp = add nuw nsw i32 %arg1, 31063  %tmp2 = add nuw nsw i32 %arg1, 21064  %tmp3 = add nuw nsw i32 %arg1, 11065  %tmp4 = zext i32 %tmp to i641066  %tmp5 = zext i32 %tmp2 to i641067  %tmp6 = zext i32 %tmp3 to i641068  %tmp24 = getelementptr inbounds i8, ptr %arg, i64 %tmp41069  %tmp30 = getelementptr inbounds i8, ptr %arg, i64 %tmp51070  %tmp31 = getelementptr inbounds i8, ptr %arg, i64 %tmp61071  %tmp32 = getelementptr inbounds i8, ptr %arg, i64 121072  %tmp33 = zext i32 %arg1 to i641073  %tmp34 = getelementptr inbounds i8, ptr %tmp32, i64 %tmp331074  %tmp35 = load i8, ptr %tmp34, align 11075  %tmp36 = zext i8 %tmp35 to i321076  %tmp37 = getelementptr inbounds i8, ptr %tmp31, i64 121077  %tmp38 = load i8, ptr %tmp37, align 11078  %tmp39 = zext i8 %tmp38 to i321079  %tmp40 = shl nuw nsw i32 %tmp39, 81080  %tmp41 = or i32 %tmp40, %tmp361081  %tmp42 = getelementptr inbounds i8, ptr %tmp30, i64 121082  %tmp43 = load i8, ptr %tmp42, align 11083  %tmp44 = zext i8 %tmp43 to i321084  %tmp45 = shl nuw nsw i32 %tmp44, 161085  %tmp46 = or i32 %tmp41, %tmp451086  %tmp47 = getelementptr inbounds i8, ptr %tmp24, i64 121087  %tmp48 = load i8, ptr %tmp47, align 11088  %tmp49 = sext i8 %tmp48 to i161089  %tmp50 = zext i16 %tmp49 to i321090  %tmp51 = shl nuw i32 %tmp50, 241091  %tmp52 = or i32 %tmp46, %tmp511092  ret i32 %tmp521093}1094 1095; ptr p;1096; (i32) p[0] | ((i32) p[1] << 8)1097define i32 @zext_load_i32_by_i8(ptr %arg) {1098; CHECK-LABEL: zext_load_i32_by_i8:1099; CHECK:       # %bb.0:1100; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax1101; CHECK-NEXT:    movzwl (%eax), %eax1102; CHECK-NEXT:    retl1103;1104; CHECK64-LABEL: zext_load_i32_by_i8:1105; CHECK64:       # %bb.0:1106; CHECK64-NEXT:    movzwl (%rdi), %eax1107; CHECK64-NEXT:    retq1108  %tmp2 = load i8, ptr %arg, align 11109  %tmp3 = zext i8 %tmp2 to i321110  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 11111  %tmp5 = load i8, ptr %tmp4, align 11112  %tmp6 = zext i8 %tmp5 to i321113  %tmp7 = shl nuw nsw i32 %tmp6, 81114  %tmp8 = or i32 %tmp7, %tmp31115  ret i32 %tmp81116}1117 1118; ptr p;1119; ((i32) p[0] << 8) | ((i32) p[1] << 16)1120define i32 @zext_load_i32_by_i8_shl_8(ptr %arg) {1121; CHECK-LABEL: zext_load_i32_by_i8_shl_8:1122; CHECK:       # %bb.0:1123; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax1124; CHECK-NEXT:    movzbl (%eax), %ecx1125; CHECK-NEXT:    shll $8, %ecx1126; CHECK-NEXT:    movzbl 1(%eax), %eax1127; CHECK-NEXT:    shll $16, %eax1128; CHECK-NEXT:    orl %ecx, %eax1129; CHECK-NEXT:    retl1130;1131; CHECK64-LABEL: zext_load_i32_by_i8_shl_8:1132; CHECK64:       # %bb.0:1133; CHECK64-NEXT:    movzbl (%rdi), %ecx1134; CHECK64-NEXT:    shll $8, %ecx1135; CHECK64-NEXT:    movzbl 1(%rdi), %eax1136; CHECK64-NEXT:    shll $16, %eax1137; CHECK64-NEXT:    orl %ecx, %eax1138; CHECK64-NEXT:    retq1139  %tmp2 = load i8, ptr %arg, align 11140  %tmp3 = zext i8 %tmp2 to i321141  %tmp30 = shl nuw nsw i32 %tmp3, 81142  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 11143  %tmp5 = load i8, ptr %tmp4, align 11144  %tmp6 = zext i8 %tmp5 to i321145  %tmp7 = shl nuw nsw i32 %tmp6, 161146  %tmp8 = or i32 %tmp7, %tmp301147  ret i32 %tmp81148}1149 1150; ptr p;1151; ((i32) p[0] << 16) | ((i32) p[1] << 24)1152define i32 @zext_load_i32_by_i8_shl_16(ptr %arg) {1153; CHECK-LABEL: zext_load_i32_by_i8_shl_16:1154; CHECK:       # %bb.0:1155; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax1156; CHECK-NEXT:    movzbl (%eax), %ecx1157; CHECK-NEXT:    shll $16, %ecx1158; CHECK-NEXT:    movzbl 1(%eax), %eax1159; CHECK-NEXT:    shll $24, %eax1160; CHECK-NEXT:    orl %ecx, %eax1161; CHECK-NEXT:    retl1162;1163; CHECK64-LABEL: zext_load_i32_by_i8_shl_16:1164; CHECK64:       # %bb.0:1165; CHECK64-NEXT:    movzbl (%rdi), %ecx1166; CHECK64-NEXT:    shll $16, %ecx1167; CHECK64-NEXT:    movzbl 1(%rdi), %eax1168; CHECK64-NEXT:    shll $24, %eax1169; CHECK64-NEXT:    orl %ecx, %eax1170; CHECK64-NEXT:    retq1171  %tmp2 = load i8, ptr %arg, align 11172  %tmp3 = zext i8 %tmp2 to i321173  %tmp30 = shl nuw nsw i32 %tmp3, 161174  %tmp4 = getelementptr inbounds i8, ptr %arg, i32 11175  %tmp5 = load i8, ptr %tmp4, align 11176  %tmp6 = zext i8 %tmp5 to i321177  %tmp7 = shl nuw nsw i32 %tmp6, 241178  %tmp8 = or i32 %tmp7, %tmp301179  ret i32 %tmp81180}1181 1182; ptr p;1183; (i32) p[1] | ((i32) p[0] << 8)1184define i32 @zext_load_i32_by_i8_bswap(ptr %arg) {1185; BSWAP-LABEL: zext_load_i32_by_i8_bswap:1186; BSWAP:       # %bb.0:1187; BSWAP-NEXT:    movl {{[0-9]+}}(%esp), %eax1188; BSWAP-NEXT:    movzwl (%eax), %eax1189; BSWAP-NEXT:    rolw $8, %ax1190; BSWAP-NEXT:    movzwl %ax, %eax1191; BSWAP-NEXT:    retl1192;1193; MOVBE-LABEL: zext_load_i32_by_i8_bswap:1194; MOVBE:       # %bb.0:1195; MOVBE-NEXT:    movl {{[0-9]+}}(%esp), %eax1196; MOVBE-NEXT:    movbew (%eax), %ax1197; MOVBE-NEXT:    movzwl %ax, %eax1198; MOVBE-NEXT:    retl1199;1200; BSWAP64-LABEL: zext_load_i32_by_i8_bswap:1201; BSWAP64:       # %bb.0:1202; BSWAP64-NEXT:    movzwl (%rdi), %eax1203; BSWAP64-NEXT:    rolw $8, %ax1204; BSWAP64-NEXT:    movzwl %ax, %eax1205; BSWAP64-NEXT:    retq1206;1207; MOVBE64-LABEL: zext_load_i32_by_i8_bswap:1208; MOVBE64:       # %bb.0:1209; MOVBE64-NEXT:    movbew (%rdi), %ax1210; MOVBE64-NEXT:    movzwl %ax, %eax1211; MOVBE64-NEXT:    retq1212  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 11213  %tmp2 = load i8, ptr %tmp1, align 11214  %tmp3 = zext i8 %tmp2 to i321215  %tmp5 = load i8, ptr %arg, align 11216  %tmp6 = zext i8 %tmp5 to i321217  %tmp7 = shl nuw nsw i32 %tmp6, 81218  %tmp8 = or i32 %tmp7, %tmp31219  ret i32 %tmp81220}1221 1222; ptr p;1223; ((i32) p[1] << 8) | ((i32) p[0] << 16)1224define i32 @zext_load_i32_by_i8_bswap_shl_8(ptr %arg) {1225; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_8:1226; CHECK:       # %bb.0:1227; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax1228; CHECK-NEXT:    movzbl 1(%eax), %ecx1229; CHECK-NEXT:    shll $8, %ecx1230; CHECK-NEXT:    movzbl (%eax), %eax1231; CHECK-NEXT:    shll $16, %eax1232; CHECK-NEXT:    orl %ecx, %eax1233; CHECK-NEXT:    retl1234;1235; CHECK64-LABEL: zext_load_i32_by_i8_bswap_shl_8:1236; CHECK64:       # %bb.0:1237; CHECK64-NEXT:    movzbl 1(%rdi), %ecx1238; CHECK64-NEXT:    shll $8, %ecx1239; CHECK64-NEXT:    movzbl (%rdi), %eax1240; CHECK64-NEXT:    shll $16, %eax1241; CHECK64-NEXT:    orl %ecx, %eax1242; CHECK64-NEXT:    retq1243  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 11244  %tmp2 = load i8, ptr %tmp1, align 11245  %tmp3 = zext i8 %tmp2 to i321246  %tmp30 = shl nuw nsw i32 %tmp3, 81247  %tmp5 = load i8, ptr %arg, align 11248  %tmp6 = zext i8 %tmp5 to i321249  %tmp7 = shl nuw nsw i32 %tmp6, 161250  %tmp8 = or i32 %tmp7, %tmp301251  ret i32 %tmp81252}1253 1254; ptr p;1255; ((i32) p[1] << 16) | ((i32) p[0] << 24)1256define i32 @zext_load_i32_by_i8_bswap_shl_16(ptr %arg) {1257; CHECK-LABEL: zext_load_i32_by_i8_bswap_shl_16:1258; CHECK:       # %bb.0:1259; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax1260; CHECK-NEXT:    movzbl 1(%eax), %ecx1261; CHECK-NEXT:    shll $16, %ecx1262; CHECK-NEXT:    movzbl (%eax), %eax1263; CHECK-NEXT:    shll $24, %eax1264; CHECK-NEXT:    orl %ecx, %eax1265; CHECK-NEXT:    retl1266;1267; CHECK64-LABEL: zext_load_i32_by_i8_bswap_shl_16:1268; CHECK64:       # %bb.0:1269; CHECK64-NEXT:    movzbl 1(%rdi), %ecx1270; CHECK64-NEXT:    shll $16, %ecx1271; CHECK64-NEXT:    movzbl (%rdi), %eax1272; CHECK64-NEXT:    shll $24, %eax1273; CHECK64-NEXT:    orl %ecx, %eax1274; CHECK64-NEXT:    retq1275  %tmp1 = getelementptr inbounds i8, ptr %arg, i32 11276  %tmp2 = load i8, ptr %tmp1, align 11277  %tmp3 = zext i8 %tmp2 to i321278  %tmp30 = shl nuw nsw i32 %tmp3, 161279  %tmp5 = load i8, ptr %arg, align 11280  %tmp6 = zext i8 %tmp5 to i321281  %tmp7 = shl nuw nsw i32 %tmp6, 241282  %tmp8 = or i32 %tmp7, %tmp301283  ret i32 %tmp81284}1285 1286define i32 @pr80911_vector_load_multiuse(ptr %ptr, ptr %clobber) nounwind {1287; CHECK-LABEL: pr80911_vector_load_multiuse:1288; CHECK:       # %bb.0:1289; CHECK-NEXT:    pushl %esi1290; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx1291; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %edx1292; CHECK-NEXT:    movl (%edx), %esi1293; CHECK-NEXT:    movzwl (%edx), %eax1294; CHECK-NEXT:    movl $0, (%ecx)1295; CHECK-NEXT:    movl %esi, (%edx)1296; CHECK-NEXT:    popl %esi1297; CHECK-NEXT:    retl1298;1299; CHECK64-LABEL: pr80911_vector_load_multiuse:1300; CHECK64:       # %bb.0:1301; CHECK64-NEXT:    movl (%rdi), %ecx1302; CHECK64-NEXT:    movzwl (%rdi), %eax1303; CHECK64-NEXT:    movl $0, (%rsi)1304; CHECK64-NEXT:    movl %ecx, (%rdi)1305; CHECK64-NEXT:    retq1306  %load = load <4 x i8>, ptr %ptr, align 161307  store i32 0, ptr %clobber1308  store <4 x i8> %load, ptr %ptr, align 161309  %e1 = extractelement <4 x i8> %load, i64 11310  %e1.ext = zext i8 %e1 to i321311  %e1.ext.shift = shl nuw nsw i32 %e1.ext, 81312  %e0 = extractelement <4 x i8> %load, i64 01313  %e0.ext = zext i8 %e0 to i321314  %res = or i32 %e1.ext.shift, %e0.ext1315  ret i32 %res1316}1317