164 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-- | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s --check-prefixes=X644 5define i32 @t1(ptr %X, i32 %i) {6; X86-LABEL: t1:7; X86: # %bb.0: # %entry8; X86-NEXT: movl {{[0-9]+}}(%esp), %eax9; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx10; X86-NEXT: movzbl %cl, %ecx11; X86-NEXT: movl (%eax,%ecx,4), %eax12; X86-NEXT: retl13;14; X64-LABEL: t1:15; X64: # %bb.0: # %entry16; X64-NEXT: movzbl %sil, %eax17; X64-NEXT: movl (%rdi,%rax,4), %eax18; X64-NEXT: retq19entry:20 %tmp2 = shl i32 %i, 221 %tmp4 = and i32 %tmp2, 102022 %tmp7 = getelementptr i8, ptr %X, i32 %tmp423 %tmp9 = load i32, ptr %tmp724 ret i32 %tmp925}26 27define i32 @t2(ptr %X, i32 %i) {28; X86-LABEL: t2:29; X86: # %bb.0: # %entry30; X86-NEXT: movl {{[0-9]+}}(%esp), %eax31; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx32; X86-NEXT: movzwl %cx, %ecx33; X86-NEXT: movl (%eax,%ecx,4), %eax34; X86-NEXT: retl35;36; X64-LABEL: t2:37; X64: # %bb.0: # %entry38; X64-NEXT: movzwl %si, %eax39; X64-NEXT: movl (%rdi,%rax,4), %eax40; X64-NEXT: retq41entry:42 %tmp2 = shl i32 %i, 143 %tmp4 = and i32 %tmp2, 13107044 %tmp7 = getelementptr i16, ptr %X, i32 %tmp445 %tmp9 = load i32, ptr %tmp746 ret i32 %tmp947}48 49; This case is tricky. The lshr followed by a gep will produce a lshr followed50; by an and to remove the low bits. This can be simplified by doing the lshr by51; a greater constant and using the addressing mode to scale the result back up.52; To make matters worse, because of the two-phase zext of %i and their reuse in53; the function, the DAG can get confusing trying to re-use both of them and54; prevent easy analysis of the mask in order to match this.55define i32 @t3(ptr %i.ptr, ptr %arr) {56; X86-LABEL: t3:57; X86: # %bb.0: # %entry58; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx59; X86-NEXT: movl {{[0-9]+}}(%esp), %eax60; X86-NEXT: movzwl (%eax), %eax61; X86-NEXT: movl %eax, %edx62; X86-NEXT: shrl $11, %edx63; X86-NEXT: addl (%ecx,%edx,4), %eax64; X86-NEXT: retl65;66; X64-LABEL: t3:67; X64: # %bb.0: # %entry68; X64-NEXT: movzwl (%rdi), %eax69; X64-NEXT: movl %eax, %ecx70; X64-NEXT: shrl $11, %ecx71; X64-NEXT: addl (%rsi,%rcx,4), %eax72; X64-NEXT: retq73entry:74 %i = load i16, ptr %i.ptr75 %i.zext = zext i16 %i to i3276 %index = lshr i32 %i.zext, 1177 %val.ptr = getelementptr inbounds i32, ptr %arr, i32 %index78 %val = load i32, ptr %val.ptr79 %sum = add i32 %val, %i.zext80 ret i32 %sum81}82 83; A version of @t3 that has more zero extends and more re-use of intermediate84; values. This exercise slightly different bits of canonicalization.85define i32 @t4(ptr %i.ptr, ptr %arr) {86; X86-LABEL: t4:87; X86: # %bb.0: # %entry88; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx89; X86-NEXT: movl {{[0-9]+}}(%esp), %eax90; X86-NEXT: movzwl (%eax), %eax91; X86-NEXT: movl %eax, %edx92; X86-NEXT: shrl $11, %edx93; X86-NEXT: addl (%ecx,%edx,4), %eax94; X86-NEXT: addl %edx, %eax95; X86-NEXT: retl96;97; X64-LABEL: t4:98; X64: # %bb.0: # %entry99; X64-NEXT: movzwl (%rdi), %eax100; X64-NEXT: movl %eax, %ecx101; X64-NEXT: shrl $11, %ecx102; X64-NEXT: addl (%rsi,%rcx,4), %eax103; X64-NEXT: addl %ecx, %eax104; X64-NEXT: retq105entry:106 %i = load i16, ptr %i.ptr107 %i.zext = zext i16 %i to i32108 %index = lshr i32 %i.zext, 11109 %index.zext = zext i32 %index to i64110 %val.ptr = getelementptr inbounds i32, ptr %arr, i64 %index.zext111 %val = load i32, ptr %val.ptr112 %sum.1 = add i32 %val, %i.zext113 %sum.2 = add i32 %sum.1, %index114 ret i32 %sum.2115}116 117define i8 @t5(ptr %X, i32 %i) {118; X86-LABEL: t5:119; X86: # %bb.0: # %entry120; X86-NEXT: movl {{[0-9]+}}(%esp), %eax121; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx122; X86-NEXT: andl $-14, %ecx123; X86-NEXT: movzbl (%eax,%ecx,4), %eax124; X86-NEXT: retl125;126; X64-LABEL: t5:127; X64: # %bb.0: # %entry128; X64-NEXT: shll $2, %esi129; X64-NEXT: andl $-56, %esi130; X64-NEXT: movslq %esi, %rax131; X64-NEXT: movzbl (%rdi,%rax), %eax132; X64-NEXT: retq133entry:134 %tmp2 = shl i32 %i, 2135 %tmp4 = and i32 %tmp2, -56136 %tmp7 = getelementptr i8, ptr %X, i32 %tmp4137 %tmp9 = load i8, ptr %tmp7138 ret i8 %tmp9139}140 141define i8 @t6(ptr %X, i32 %i) {142; X86-LABEL: t6:143; X86: # %bb.0: # %entry144; X86-NEXT: movl {{[0-9]+}}(%esp), %eax145; X86-NEXT: movl $-255, %ecx146; X86-NEXT: andl {{[0-9]+}}(%esp), %ecx147; X86-NEXT: movzbl (%eax,%ecx,4), %eax148; X86-NEXT: retl149;150; X64-LABEL: t6:151; X64: # %bb.0: # %entry152; X64-NEXT: shll $2, %esi153; X64-NEXT: andl $-1020, %esi # imm = 0xFC04154; X64-NEXT: movslq %esi, %rax155; X64-NEXT: movzbl (%rdi,%rax), %eax156; X64-NEXT: retq157entry:158 %tmp2 = shl i32 %i, 2159 %tmp4 = and i32 %tmp2, -1020160 %tmp7 = getelementptr i8, ptr %X, i32 %tmp4161 %tmp9 = load i8, ptr %tmp7162 ret i8 %tmp9163}164