1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86 3; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64 4 5define i32 @mask_add_sext_i32_i64(ptr %base, i32 %i) { 6; X86-LABEL: mask_add_sext_i32_i64: 7; X86: # %bb.0: 8; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax 9; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 10; X86-NEXT: movl 12(%ecx,%eax,4), %eax 11; X86-NEXT: retl 12; 13; X64-LABEL: mask_add_sext_i32_i64: 14; X64: # %bb.0: 15; X64-NEXT: sarl $24, %esi 16; X64-NEXT: movslq %esi, %rax 17; X64-NEXT: movl 12(%rdi,%rax,4), %eax 18; X64-NEXT: retq 19 %mask = ashr i32 %i, 24 20 %offset = add i32 %mask, 3 21 %sext = sext i32 %offset to i64 22 %gep = getelementptr i32, ptr %base, i64 %sext 23 %ret = load i32, ptr %gep 24 ret i32 %ret 25} 26 27define i32 @mask_add_zext_i32_i64(ptr %base, i32 %i) { 28; X86-LABEL: mask_add_zext_i32_i64: 29; X86: # %bb.0: 30; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 31; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 32; X86-NEXT: andl $15, %ecx 33; X86-NEXT: movl 12(%eax,%ecx,4), %eax 34; X86-NEXT: retl 35; 36; X64-LABEL: mask_add_zext_i32_i64: 37; X64: # %bb.0: 38; X64-NEXT: # kill: def $esi killed $esi def $rsi 39; X64-NEXT: andl $15, %esi 40; X64-NEXT: movl 12(%rdi,%rsi,4), %eax 41; X64-NEXT: retq 42 %mask = and i32 %i, 15 43 %offset = add i32 %mask, 3 44 %zext = zext i32 %offset to i64 45 %gep = getelementptr i32, ptr %base, i64 %zext 46 %ret = load i32, ptr %gep 47 ret i32 %ret 48} 49 50define i32 @mask_offset_scale_zext_i32_i64(ptr %base, i32 %i) { 51; X86-LABEL: mask_offset_scale_zext_i32_i64: 52; X86: # %bb.0: 53; X86-NEXT: movl {{[0-9]+}}(%esp), %eax 54; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 55; X86-NEXT: shll $11, %ecx 56; X86-NEXT: movl 48(%eax,%ecx), %eax 57; X86-NEXT: retl 58; 59; X64-LABEL: mask_offset_scale_zext_i32_i64: 60; X64: # %bb.0: 61; X64-NEXT: # kill: def $esi killed $esi def $rsi 62; X64-NEXT: andl $65280, %esi # imm = 0xFF00 63; X64-NEXT: movl 48(%rdi,%rsi,8), %eax 64; X64-NEXT: retq 65 %mask = and i32 %i, 65280 66 %offset = or i32 %mask, 6 67 %scale = shl i32 %offset, 1 68 %idxprom = zext i32 %scale to i64 69 %arrayidx = getelementptr inbounds i32, ptr %base, i64 %idxprom 70 %load = load i32, ptr %arrayidx, align 4 71 ret i32 %load 72} 73 74; PR97533 - multiple uses of shl node (add + gep) in the same dependency chain. 75define i64 @add_shl_zext(ptr %ptr, i8 %arg) nounwind { 76; X86-LABEL: add_shl_zext: 77; X86: # %bb.0: 78; X86-NEXT: pushl %esi 79; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 80; X86-NEXT: movl {{[0-9]+}}(%esp), %esi 81; X86-NEXT: movl 4(%esi,%ecx,4), %edx 82; X86-NEXT: leal (,%ecx,8), %eax 83; X86-NEXT: addl (%esi,%ecx,4), %eax 84; X86-NEXT: adcl $0, %edx 85; X86-NEXT: popl %esi 86; X86-NEXT: retl 87; 88; X64-LABEL: add_shl_zext: 89; X64: # %bb.0: 90; X64-NEXT: movzbl %sil, %eax 91; X64-NEXT: shll $3, %eax 92; X64-NEXT: addq (%rdi,%rax), %rax 93; X64-NEXT: retq 94 %idx = zext i8 %arg to i64 95 %gep = getelementptr ptr, ptr %ptr, i64 %idx 96 %val = load i64, ptr %gep, align 8 97 %shl = shl i64 %idx, 3 98 %sum = add i64 %val, %shl 99 ret i64 %sum 100} 101