237 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=x86-64 | FileCheck %s --check-prefixes=X644; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=X645; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=X646; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=X647 8; Tests showing for the analysis of non-constant shift amounts to improve load address math9 10; Alignment of shift amounts should allow sub-integer loads.11 12define i16 @extractSub64_16(ptr %word, i32 %idx) nounwind {13; X86-LABEL: extractSub64_16:14; X86: # %bb.0:15; X86-NEXT: movl {{[0-9]+}}(%esp), %eax16; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx17; X86-NEXT: andl $48, %ecx18; X86-NEXT: shrl $3, %ecx19; X86-NEXT: movzwl (%eax,%ecx), %eax20; X86-NEXT: retl21;22; X64-LABEL: extractSub64_16:23; X64: # %bb.0:24; X64-NEXT: # kill: def $esi killed $esi def $rsi25; X64-NEXT: andl $48, %esi26; X64-NEXT: shrl $3, %esi27; X64-NEXT: movzwl (%rdi,%rsi), %eax28; X64-NEXT: retq29 %idx_bounds = and i32 %idx, 6330 %idx_align = and i32 %idx_bounds, -1631 %sh = zext nneg i32 %idx_align to i6432 %ld = load i64, ptr %word, align 833 %sub = lshr i64 %ld, %sh34 %res = trunc i64 %sub to i1635 ret i16 %res36}37 38define i16 @extractSub128_16(ptr %word, i32 %idx) nounwind {39; X86-LABEL: extractSub128_16:40; X86: # %bb.0:41; X86-NEXT: movl {{[0-9]+}}(%esp), %eax42; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx43; X86-NEXT: andl $112, %ecx44; X86-NEXT: shrl $3, %ecx45; X86-NEXT: movzwl (%eax,%ecx), %eax46; X86-NEXT: retl47;48; X64-LABEL: extractSub128_16:49; X64: # %bb.0:50; X64-NEXT: # kill: def $esi killed $esi def $rsi51; X64-NEXT: andl $112, %esi52; X64-NEXT: shrl $3, %esi53; X64-NEXT: movzwl (%rdi,%rsi), %eax54; X64-NEXT: retq55 %idx_bounds = and i32 %idx, 12756 %idx_align = and i32 %idx_bounds, -1657 %sh = zext nneg i32 %idx_align to i12858 %ld = load i128, ptr %word, align 859 %sub = lshr i128 %ld, %sh60 %res = trunc i128 %sub to i1661 ret i16 %res62}63 64define i32 @extractSub128_32(ptr %word, i32 %idx) nounwind {65; X86-LABEL: extractSub128_32:66; X86: # %bb.0:67; X86-NEXT: movl {{[0-9]+}}(%esp), %eax68; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx69; X86-NEXT: andl $96, %ecx70; X86-NEXT: shrl $3, %ecx71; X86-NEXT: movl (%eax,%ecx), %eax72; X86-NEXT: retl73;74; X64-LABEL: extractSub128_32:75; X64: # %bb.0:76; X64-NEXT: # kill: def $esi killed $esi def $rsi77; X64-NEXT: andl $96, %esi78; X64-NEXT: shrl $3, %esi79; X64-NEXT: movl (%rdi,%rsi), %eax80; X64-NEXT: retq81 %idx_bounds = and i32 %idx, 12782 %idx_align = and i32 %idx_bounds, -3283 %sh = zext nneg i32 %idx_align to i12884 %ld = load i128, ptr %word, align 885 %sub = lshr i128 %ld, %sh86 %res = trunc i128 %sub to i3287 ret i32 %res88}89 90define i64 @extractSub128_64(ptr %word, i32 %idx) nounwind {91; X86-LABEL: extractSub128_64:92; X86: # %bb.0:93; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx94; X86-NEXT: movl {{[0-9]+}}(%esp), %edx95; X86-NEXT: andl $64, %edx96; X86-NEXT: shrl $3, %edx97; X86-NEXT: movl (%ecx,%edx), %eax98; X86-NEXT: movl 4(%ecx,%edx), %edx99; X86-NEXT: retl100;101; X64-LABEL: extractSub128_64:102; X64: # %bb.0:103; X64-NEXT: # kill: def $esi killed $esi def $rsi104; X64-NEXT: andl $64, %esi105; X64-NEXT: shrl $3, %esi106; X64-NEXT: movq (%rdi,%rsi), %rax107; X64-NEXT: retq108 %idx_bounds = and i32 %idx, 127109 %idx_align = and i32 %idx_bounds, -64110 %sh = zext nneg i32 %idx_align to i128111 %ld = load i128, ptr %word, align 8112 %sub = lshr i128 %ld, %sh113 %res = trunc i128 %sub to i64114 ret i64 %res115}116 117define i8 @extractSub512_8(ptr %word, i32 %idx) nounwind {118; X86-LABEL: extractSub512_8:119; X86: # %bb.0:120; X86-NEXT: movl {{[0-9]+}}(%esp), %eax121; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx122; X86-NEXT: shrl $3, %ecx123; X86-NEXT: andl $63, %ecx124; X86-NEXT: movzbl (%eax,%ecx), %eax125; X86-NEXT: retl126;127; X64-LABEL: extractSub512_8:128; X64: # %bb.0:129; X64-NEXT: # kill: def $esi killed $esi def $rsi130; X64-NEXT: shrl $3, %esi131; X64-NEXT: andl $63, %esi132; X64-NEXT: movzbl (%rdi,%rsi), %eax133; X64-NEXT: retq134 %idx_bounds = and i32 %idx, 511135 %idx_align = and i32 %idx_bounds, -8136 %ld = load i512, ptr %word, align 8137 %sh = zext nneg i32 %idx_align to i512138 %sub = lshr i512 %ld, %sh139 %res = trunc i512 %sub to i8140 ret i8 %res141}142 143define i64 @extractSub512_64(ptr %word, i32 %idx) nounwind {144; X86-LABEL: extractSub512_64:145; X86: # %bb.0:146; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx147; X86-NEXT: movl {{[0-9]+}}(%esp), %edx148; X86-NEXT: shrl $3, %edx149; X86-NEXT: andl $56, %edx150; X86-NEXT: movl (%ecx,%edx), %eax151; X86-NEXT: movl 4(%ecx,%edx), %edx152; X86-NEXT: retl153;154; X64-LABEL: extractSub512_64:155; X64: # %bb.0:156; X64-NEXT: # kill: def $esi killed $esi def $rsi157; X64-NEXT: shrl $3, %esi158; X64-NEXT: andl $56, %esi159; X64-NEXT: movq (%rdi,%rsi), %rax160; X64-NEXT: retq161 %idx_bounds = and i32 %idx, 511162 %idx_align = and i32 %idx_bounds, -64163 %sh = zext nneg i32 %idx_align to i512164 %ld = load i512, ptr %word, align 8165 %sub = lshr i512 %ld, %sh166 %res = trunc i512 %sub to i64167 ret i64 %res168}169 170define i128 @extractSub512_128(ptr %word, i32 %idx) nounwind {171; X86-LABEL: extractSub512_128:172; X86: # %bb.0:173; X86-NEXT: pushl %ebx174; X86-NEXT: pushl %edi175; X86-NEXT: pushl %esi176; X86-NEXT: movl {{[0-9]+}}(%esp), %eax177; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx178; X86-NEXT: movl {{[0-9]+}}(%esp), %edx179; X86-NEXT: shrl $3, %edx180; X86-NEXT: andl $48, %edx181; X86-NEXT: movl (%ecx,%edx), %esi182; X86-NEXT: movl 4(%ecx,%edx), %edi183; X86-NEXT: movl 8(%ecx,%edx), %ebx184; X86-NEXT: movl 12(%ecx,%edx), %ecx185; X86-NEXT: movl %ecx, 12(%eax)186; X86-NEXT: movl %ebx, 8(%eax)187; X86-NEXT: movl %edi, 4(%eax)188; X86-NEXT: movl %esi, (%eax)189; X86-NEXT: popl %esi190; X86-NEXT: popl %edi191; X86-NEXT: popl %ebx192; X86-NEXT: retl $4193;194; X64-LABEL: extractSub512_128:195; X64: # %bb.0:196; X64-NEXT: # kill: def $esi killed $esi def $rsi197; X64-NEXT: shrl $3, %esi198; X64-NEXT: andl $48, %esi199; X64-NEXT: movq (%rdi,%rsi), %rax200; X64-NEXT: movq 8(%rdi,%rsi), %rdx201; X64-NEXT: retq202 %idx_bounds = and i32 %idx, 511203 %idx_align = and i32 %idx_bounds, -128204 %sh = zext nneg i32 %idx_align to i512205 %ld = load i512, ptr %word, align 8206 %sub = lshr i512 %ld, %sh207 %res = trunc i512 %sub to i128208 ret i128 %res209}210 211define i64 @extractSub4096_64(ptr %word, i32 %idx) nounwind {212; X86-LABEL: extractSub4096_64:213; X86: # %bb.0:214; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx215; X86-NEXT: movl $4032, %edx # imm = 0xFC0216; X86-NEXT: andl {{[0-9]+}}(%esp), %edx217; X86-NEXT: shrl $3, %edx218; X86-NEXT: movl (%ecx,%edx), %eax219; X86-NEXT: movl 4(%ecx,%edx), %edx220; X86-NEXT: retl221;222; X64-LABEL: extractSub4096_64:223; X64: # %bb.0:224; X64-NEXT: # kill: def $esi killed $esi def $rsi225; X64-NEXT: andl $4032, %esi # imm = 0xFC0226; X64-NEXT: shrl $3, %esi227; X64-NEXT: movq (%rdi,%rsi), %rax228; X64-NEXT: retq229 %idx_bounds = and i32 %idx, 4095230 %idx_align = and i32 %idx_bounds, -64231 %sh = zext nneg i32 %idx_align to i4096232 %ld = load i4096, ptr %word, align 8233 %sub = lshr i4096 %ld, %sh234 %res = trunc i4096 %sub to i64235 ret i64 %res236}237