| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s | |
| define i16 @test_bitextract_var(b32 %src, i32 %off) { | |
| ; CHECK-LABEL: test_bitextract_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %ecx | |
| ; CHECK-NEXT: movl %edi, %eax | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shrl %cl, %eax | |
| ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i16, b32 %src, i32 %off | |
| ret i16 %result | |
| } | |
| define i16 @test_bitextract_const(b32 %src) { | |
| ; CHECK-LABEL: test_bitextract_const: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edi, %eax | |
| ; CHECK-NEXT: shrl $8, %eax | |
| ; CHECK-NEXT: # kill: def $ax killed $ax killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i16, b32 %src, i32 8 | |
| ret i16 %result | |
| } | |
| define i8 @test_bitextract_narrow(b64 %src) { | |
| ; CHECK-LABEL: test_bitextract_narrow: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $rax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i8, b64 %src, i32 0 | |
| ret i8 %result | |
| } | |
| define i1 @test_bitextract_b1(b1 %src) { | |
| ; CHECK-LABEL: test_bitextract_b1: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edi, %eax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i1, b1 %src, i32 0 | |
| ret i1 %result | |
| } | |
| define i8 @test_bitextract_b37(b37 %src, i32 %off) { | |
| ; CHECK-LABEL: test_bitextract_b37: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %ecx | |
| ; CHECK-NEXT: movabsq $137438953471, %rax # imm = 0x1FFFFFFFFF | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shrq %cl, %rax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $rax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i8, b37 %src, i32 %off | |
| ret i8 %result | |
| } | |
| define i8 @test_bitextract_b37_const(b37 %src) { | |
| ; CHECK-LABEL: test_bitextract_b37_const: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: shrl $20, %eax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $rax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i8, b37 %src, i32 20 | |
| ret i8 %result | |
| } | |
| define i16 @test_bitextract_b87(b87 %src, i32 %off) { | |
| ; CHECK-LABEL: test_bitextract_b87: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: movq %rsi, %rax | |
| ; CHECK-NEXT: andl $8388607, %eax # imm = 0x7FFFFF | |
| ; CHECK-NEXT: shrdq %cl, %rax, %rdi | |
| ; CHECK-NEXT: shrq %cl, %rax | |
| ; CHECK-NEXT: testb $64, %cl | |
| ; CHECK-NEXT: cmoveq %rdi, %rax | |
| ; CHECK-NEXT: # kill: def $ax killed $ax killed $rax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i16, b87 %src, i32 %off | |
| ret i16 %result | |
| } | |
| define i32 @test_bitextract_b128(b128 %src, i32 %off) { | |
| ; CHECK-LABEL: test_bitextract_b128: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: movq %rsi, %rax | |
| ; CHECK-NEXT: shrdq %cl, %rsi, %rdi | |
| ; CHECK-NEXT: shrq %cl, %rax | |
| ; CHECK-NEXT: testb $64, %cl | |
| ; CHECK-NEXT: cmoveq %rdi, %rax | |
| ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i32, b128 %src, i32 %off | |
| ret i32 %result | |
| } | |
| define i32 @test_bitextract_b231(b231 %src, i32 %off) { | |
| ; CHECK-LABEL: test_bitextract_b231: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movabsq $549755813887, %rax # imm = 0x7FFFFFFFFF | |
| ; CHECK-NEXT: andq %rcx, %rax | |
| ; CHECK-NEXT: xorps %xmm0, %xmm0 | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq %rdx, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq %rsi, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq %rdi, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq %rax, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movl %r8d, %eax | |
| ; CHECK-NEXT: shrb $6, %al | |
| ; CHECK-NEXT: movzbl %al, %eax | |
| ; CHECK-NEXT: movq -72(%rsp,%rax,8), %rdx | |
| ; CHECK-NEXT: movl %r8d, %ecx | |
| ; CHECK-NEXT: shrq %cl, %rdx | |
| ; CHECK-NEXT: movl -64(%rsp,%rax,8), %eax | |
| ; CHECK-NEXT: addl %eax, %eax | |
| ; CHECK-NEXT: andb $63, %r8b | |
| ; CHECK-NEXT: notb %r8b | |
| ; CHECK-NEXT: movl %r8d, %ecx | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: orl %edx, %eax | |
| ; CHECK-NEXT: # kill: def $eax killed $eax killed $rax | |
| ; CHECK-NEXT: retq | |
| %result = bitextract i32, b231 %src, i32 %off | |
| ret i32 %result | |
| } | |
| ; Bitinsert | |
| define b32 @test_bitinsert_var(b32 %base, i16 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: movzwl %si, %edx | |
| ; CHECK-NEXT: shll %cl, %edx | |
| ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shll %cl, %eax | |
| ; CHECK-NEXT: notl %eax | |
| ; CHECK-NEXT: andl %edi, %eax | |
| ; CHECK-NEXT: orl %edx, %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b32 %base, i16 %val, i32 %off | |
| ret b32 %result | |
| } | |
| define b1 @test_bitinsert_b1(b1 %base, i1 %val) { | |
| ; CHECK-LABEL: test_bitinsert_b1: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %eax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b1 %base, i1 %val, i32 0 | |
| ret b1 %result | |
| } | |
| define b37 @test_bitinsert_b37_var(b37 %base, i8 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b37_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: movzbl %sil, %edx | |
| ; CHECK-NEXT: shlq %cl, %rdx | |
| ; CHECK-NEXT: movl $255, %esi | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shlq %cl, %rsi | |
| ; CHECK-NEXT: movabsq $137438953471, %rax # imm = 0x1FFFFFFFFF | |
| ; CHECK-NEXT: xorq %rsi, %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %rdx, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b37 %base, i8 %val, i32 %off | |
| ret b37 %result | |
| } | |
| define b87 @test_bitinsert_b87_var(b87 %base, i16 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b87_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %r8d | |
| ; CHECK-NEXT: xorl %r9d, %r9d | |
| ; CHECK-NEXT: movl $65535, %eax # imm = 0xFFFF | |
| ; CHECK-NEXT: xorl %edx, %edx | |
| ; CHECK-NEXT: shldq %cl, %rax, %rdx | |
| ; CHECK-NEXT: movzwl %r8w, %r8d | |
| ; CHECK-NEXT: xorl %r10d, %r10d | |
| ; CHECK-NEXT: shldq %cl, %r8, %r10 | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: shlq %cl, %r8 | |
| ; CHECK-NEXT: testb $64, %cl | |
| ; CHECK-NEXT: cmovneq %r8, %r10 | |
| ; CHECK-NEXT: cmovneq %rax, %rdx | |
| ; CHECK-NEXT: cmovneq %r9, %r8 | |
| ; CHECK-NEXT: cmovneq %r9, %rax | |
| ; CHECK-NEXT: xorq $8388607, %rdx # imm = 0x7FFFFF | |
| ; CHECK-NEXT: andq %rsi, %rdx | |
| ; CHECK-NEXT: orq %r10, %rdx | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %r8, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b87 %base, i16 %val, i32 %off | |
| ret b87 %result | |
| } | |
| define b128 @test_bitinsert_b128_var(b128 %base, i32 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b128_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %r8d | |
| ; CHECK-NEXT: xorl %r9d, %r9d | |
| ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF | |
| ; CHECK-NEXT: xorl %edx, %edx | |
| ; CHECK-NEXT: shldq %cl, %rax, %rdx | |
| ; CHECK-NEXT: movl %r8d, %r8d | |
| ; CHECK-NEXT: xorl %r10d, %r10d | |
| ; CHECK-NEXT: shldq %cl, %r8, %r10 | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: shlq %cl, %r8 | |
| ; CHECK-NEXT: testb $64, %cl | |
| ; CHECK-NEXT: cmovneq %r8, %r10 | |
| ; CHECK-NEXT: cmovneq %rax, %rdx | |
| ; CHECK-NEXT: notq %rdx | |
| ; CHECK-NEXT: cmovneq %r9, %r8 | |
| ; CHECK-NEXT: cmovneq %r9, %rax | |
| ; CHECK-NEXT: andq %rsi, %rdx | |
| ; CHECK-NEXT: orq %r10, %rdx | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %r8, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b128 %base, i32 %val, i32 %off | |
| ret b128 %result | |
| } | |
| define b231 @test_bitinsert_b231_var(b231 %base, i32 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b231_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: pushq %r15 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 16 | |
| ; CHECK-NEXT: pushq %r14 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 24 | |
| ; CHECK-NEXT: pushq %rbx | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-NEXT: .cfi_offset %rbx, -32 | |
| ; CHECK-NEXT: .cfi_offset %r14, -24 | |
| ; CHECK-NEXT: .cfi_offset %r15, -16 | |
| ; CHECK-NEXT: movq %rcx, %r10 | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: movzbl {{[0-9]+}}(%rsp), %ecx | |
| ; CHECK-NEXT: xorps %xmm0, %xmm0 | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movl %r9d, %edi | |
| ; CHECK-NEXT: movq %rdi, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movl $4294967295, %edi # imm = 0xFFFFFFFF | |
| ; CHECK-NEXT: movq %rdi, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq $0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movl %ecx, %edi | |
| ; CHECK-NEXT: shrb $3, %dil | |
| ; CHECK-NEXT: andb $24, %dil | |
| ; CHECK-NEXT: negb %dil | |
| ; CHECK-NEXT: movsbq %dil, %r11 | |
| ; CHECK-NEXT: movq -16(%rsp,%r11), %r14 | |
| ; CHECK-NEXT: movq -8(%rsp,%r11), %rbx | |
| ; CHECK-NEXT: shldq %cl, %r14, %rbx | |
| ; CHECK-NEXT: movq $0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq -80(%rsp,%r11), %r9 | |
| ; CHECK-NEXT: movq -72(%rsp,%r11), %rdi | |
| ; CHECK-NEXT: shldq %cl, %r9, %rdi | |
| ; CHECK-NEXT: notq %rdi | |
| ; CHECK-NEXT: andq %r8, %rdi | |
| ; CHECK-NEXT: orq %rbx, %rdi | |
| ; CHECK-NEXT: movq -32(%rsp,%r11), %rbx | |
| ; CHECK-NEXT: movq -24(%rsp,%r11), %r8 | |
| ; CHECK-NEXT: shldq %cl, %r8, %r14 | |
| ; CHECK-NEXT: movq -96(%rsp,%r11), %r15 | |
| ; CHECK-NEXT: movq -88(%rsp,%r11), %r11 | |
| ; CHECK-NEXT: shldq %cl, %r11, %r9 | |
| ; CHECK-NEXT: notq %r9 | |
| ; CHECK-NEXT: andq %r10, %r9 | |
| ; CHECK-NEXT: orq %r14, %r9 | |
| ; CHECK-NEXT: movq %rbx, %r10 | |
| ; CHECK-NEXT: shlq %cl, %r10 | |
| ; CHECK-NEXT: movq %r15, %r14 | |
| ; CHECK-NEXT: shlq %cl, %r14 | |
| ; CHECK-NEXT: notq %r14 | |
| ; CHECK-NEXT: andq %rsi, %r14 | |
| ; CHECK-NEXT: orq %r10, %r14 | |
| ; CHECK-NEXT: shldq %cl, %rbx, %r8 | |
| ; CHECK-NEXT: shldq %cl, %r15, %r11 | |
| ; CHECK-NEXT: notq %r11 | |
| ; CHECK-NEXT: andq %rdx, %r11 | |
| ; CHECK-NEXT: orq %r8, %r11 | |
| ; CHECK-NEXT: movq %r9, 16(%rax) | |
| ; CHECK-NEXT: movq %r11, 8(%rax) | |
| ; CHECK-NEXT: movq %r14, (%rax) | |
| ; CHECK-NEXT: movl %edi, 24(%rax) | |
| ; CHECK-NEXT: shrq $32, %rdi | |
| ; CHECK-NEXT: andl $127, %edi | |
| ; CHECK-NEXT: movb %dil, 28(%rax) | |
| ; CHECK-NEXT: popq %rbx | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 24 | |
| ; CHECK-NEXT: popq %r14 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 16 | |
| ; CHECK-NEXT: popq %r15 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 8 | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b231 %base, i32 %val, i32 %off | |
| ret b231 %result | |
| } | |
| ; different inserted value widths | |
| define b1 @test_bitinsert_b1_var(b1 %base, i1 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b1_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %eax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b1 %base, i1 %val, i32 %off | |
| ret b1 %result | |
| } | |
| define b8 @test_bitinsert_b8_var(b8 %base, i4 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b8_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: andb $15, %sil | |
| ; CHECK-NEXT: shlb %cl, %sil | |
| ; CHECK-NEXT: movb $15, %al | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shlb %cl, %al | |
| ; CHECK-NEXT: notb %al | |
| ; CHECK-NEXT: andb %dil, %al | |
| ; CHECK-NEXT: orb %sil, %al | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b8 %base, i4 %val, i32 %off | |
| ret b8 %result | |
| } | |
| define b8 @test_bitinsert_b8_const(b8 %base, i4 %val) { | |
| ; CHECK-LABEL: test_bitinsert_b8_const: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi | |
| ; CHECK-NEXT: andb $-121, %dil | |
| ; CHECK-NEXT: andb $15, %sil | |
| ; CHECK-NEXT: leal (,%rsi,8), %eax | |
| ; CHECK-NEXT: orb %dil, %al | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b8 %base, i4 %val, i32 3 | |
| ret b8 %result | |
| } | |
| define b21 @test_bitinsert_b21_var(b21 %base, i6 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b21_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: andl $63, %esi | |
| ; CHECK-NEXT: shll %cl, %esi | |
| ; CHECK-NEXT: movl $63, %eax | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shll %cl, %eax | |
| ; CHECK-NEXT: xorl $2097151, %eax # imm = 0x1FFFFF | |
| ; CHECK-NEXT: andl %edi, %eax | |
| ; CHECK-NEXT: orl %esi, %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b21 %base, i6 %val, i32 %off | |
| ret b21 %result | |
| } | |
| define b21 @test_bitinsert_b21_const(b21 %base, i6 %val) { | |
| ; CHECK-LABEL: test_bitinsert_b21_const: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi | |
| ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi | |
| ; CHECK-NEXT: andl $1064959, %edi # imm = 0x103FFF | |
| ; CHECK-NEXT: andl $63, %esi | |
| ; CHECK-NEXT: shll $14, %esi | |
| ; CHECK-NEXT: leal (%rsi,%rdi), %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b21 %base, i6 %val, i32 14 | |
| ret b21 %result | |
| } | |
| define b123 @test_bitinsert_b123_var(b123 %base, i32 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_b123_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: xorl %r9d, %r9d | |
| ; CHECK-NEXT: movl $4294967295, %eax # imm = 0xFFFFFFFF | |
| ; CHECK-NEXT: xorl %r10d, %r10d | |
| ; CHECK-NEXT: shldq %cl, %rax, %r10 | |
| ; CHECK-NEXT: movl %edx, %r8d | |
| ; CHECK-NEXT: xorl %r11d, %r11d | |
| ; CHECK-NEXT: shldq %cl, %r8, %r11 | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: shlq %cl, %r8 | |
| ; CHECK-NEXT: testb $64, %cl | |
| ; CHECK-NEXT: cmovneq %r8, %r11 | |
| ; CHECK-NEXT: cmovneq %rax, %r10 | |
| ; CHECK-NEXT: cmovneq %r9, %r8 | |
| ; CHECK-NEXT: cmovneq %r9, %rax | |
| ; CHECK-NEXT: movabsq $576460752303423487, %rdx # imm = 0x7FFFFFFFFFFFFFF | |
| ; CHECK-NEXT: xorq %r10, %rdx | |
| ; CHECK-NEXT: andq %rsi, %rdx | |
| ; CHECK-NEXT: orq %r11, %rdx | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %r8, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b123 %base, i32 %val, i32 %off | |
| ret b123 %result | |
| } | |
| define b123 @test_bitinsert_b123_crossword(b123 %base, i32 %val) { | |
| ; CHECK-LABEL: test_bitinsert_b123_crossword: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: # kill: def $edx killed $edx def $rdx | |
| ; CHECK-NEXT: movabsq $1152921504606846975, %rcx # imm = 0xFFFFFFFFFFFFFFF | |
| ; CHECK-NEXT: andq %rdi, %rcx | |
| ; CHECK-NEXT: movq %rdx, %rax | |
| ; CHECK-NEXT: shlq $60, %rax | |
| ; CHECK-NEXT: orq %rcx, %rax | |
| ; CHECK-NEXT: movabsq $576460752034988032, %rcx # imm = 0x7FFFFFFF0000000 | |
| ; CHECK-NEXT: andq %rsi, %rcx | |
| ; CHECK-NEXT: shrl $4, %edx | |
| ; CHECK-NEXT: orq %rcx, %rdx | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b123 %base, i32 %val, i32 60 | |
| ret b123 %result | |
| } | |
| define b123 @test_bitinsert_val_b123_full(b123 %base, b123 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b123_full: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdx, %rax | |
| ; CHECK-NEXT: movq %rcx, %rdx | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b123 %base, b123 %val, i32 0 | |
| ret b123 %result | |
| } | |
| define b8 @test_bitinsert_val_b8_full(b8 %base, b8 %val) { | |
| ; container == value width: full overwrite | |
| ; CHECK-LABEL: test_bitinsert_val_b8_full: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %eax | |
| ; CHECK-NEXT: # kill: def $al killed $al killed $eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b8 %base, b8 %val, i32 0 | |
| ret b8 %result | |
| } | |
| define b32 @test_bitinsert_val_b8_into_b32_var(b32 %base, b8 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_val_b8_into_b32_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: movzbl %sil, %edx | |
| ; CHECK-NEXT: shll %cl, %edx | |
| ; CHECK-NEXT: movl $255, %eax | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shll %cl, %eax | |
| ; CHECK-NEXT: notl %eax | |
| ; CHECK-NEXT: andl %edi, %eax | |
| ; CHECK-NEXT: orl %edx, %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b32 %base, b8 %val, i32 %off | |
| ret b32 %result | |
| } | |
| define b32 @test_bitinsert_val_b8_into_b32_const_mid(b32 %base, b8 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b8_into_b32_const_mid: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: andl $-1044481, %edi # imm = 0xFFF00FFF | |
| ; CHECK-NEXT: movzbl %sil, %eax | |
| ; CHECK-NEXT: shll $12, %eax | |
| ; CHECK-NEXT: orl %edi, %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b32 %base, b8 %val, i32 12 | |
| ret b32 %result | |
| } | |
| define b64 @test_bitinsert_val_b8_into_b64_const_top(b64 %base, b8 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b8_into_b64_const_top: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi | |
| ; CHECK-NEXT: movabsq $72057594037927935, %rax # imm = 0xFFFFFFFFFFFFFF | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: shlq $56, %rsi | |
| ; CHECK-NEXT: orq %rsi, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b64 %base, b8 %val, i32 56 | |
| ret b64 %result | |
| } | |
| define b8 @test_bitinsert_val_b1_into_b8(b8 %base, b1 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_val_b1_into_b8: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: andb $1, %sil | |
| ; CHECK-NEXT: shlb %cl, %sil | |
| ; CHECK-NEXT: movb $-2, %al | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: rolb %cl, %al | |
| ; CHECK-NEXT: andb %dil, %al | |
| ; CHECK-NEXT: orb %sil, %al | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b8 %base, b1 %val, i32 %off | |
| ret b8 %result | |
| } | |
| define b32 @test_bitinsert_val_b1_into_b32_const_top(b32 %base, b1 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b1_into_b32_const_top: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi | |
| ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi | |
| ; CHECK-NEXT: shll $31, %esi | |
| ; CHECK-NEXT: andl $2147483647, %edi # imm = 0x7FFFFFFF | |
| ; CHECK-NEXT: leal (%rdi,%rsi), %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b32 %base, b1 %val, i32 31 | |
| ret b32 %result | |
| } | |
| define b21 @test_bitinsert_val_b21_full(b21 %base, b21 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b21_full: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %esi, %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b21 %base, b21 %val, i32 0 | |
| ret b21 %result | |
| } | |
| define b32 @test_bitinsert_val_b21_into_b32_var(b32 %base, b21 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_val_b21_into_b32_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: andl $2097151, %esi # imm = 0x1FFFFF | |
| ; CHECK-NEXT: shll %cl, %esi | |
| ; CHECK-NEXT: movl $2097151, %eax # imm = 0x1FFFFF | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shll %cl, %eax | |
| ; CHECK-NEXT: notl %eax | |
| ; CHECK-NEXT: andl %edi, %eax | |
| ; CHECK-NEXT: orl %esi, %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b32 %base, b21 %val, i32 %off | |
| ret b32 %result | |
| } | |
| define b32 @test_bitinsert_val_b21_into_b32_const_top(b32 %base, b21 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b21_into_b32_const_top: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi | |
| ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi | |
| ; CHECK-NEXT: shll $11, %esi | |
| ; CHECK-NEXT: andl $2047, %edi # imm = 0x7FF | |
| ; CHECK-NEXT: leal (%rdi,%rsi), %eax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b32 %base, b21 %val, i32 11 | |
| ret b32 %result | |
| } | |
| define b64 @test_bitinsert_val_b21_into_b64_var(b64 %base, b21 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_val_b21_into_b64_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi | |
| ; CHECK-NEXT: andl $2097151, %esi # imm = 0x1FFFFF | |
| ; CHECK-NEXT: shlq %cl, %rsi | |
| ; CHECK-NEXT: movl $2097151, %eax # imm = 0x1FFFFF | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %rsi, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b64 %base, b21 %val, i32 %off | |
| ret b64 %result | |
| } | |
| define b128 @test_bitinsert_val_b123_into_b128_var(b128 %base, b123 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_val_b123_into_b128_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %r8d, %r10d | |
| ; CHECK-NEXT: movq %rcx, %r8 | |
| ; CHECK-NEXT: movq $-1, %rax | |
| ; CHECK-NEXT: movabsq $576460752303423487, %r9 # imm = 0x7FFFFFFFFFFFFFF | |
| ; CHECK-NEXT: andq %r9, %r8 | |
| ; CHECK-NEXT: movl %r10d, %ecx | |
| ; CHECK-NEXT: shldq %cl, %rax, %r9 | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: shldq %cl, %rdx, %r8 | |
| ; CHECK-NEXT: shlq %cl, %rdx | |
| ; CHECK-NEXT: xorl %ecx, %ecx | |
| ; CHECK-NEXT: testb $64, %r10b | |
| ; CHECK-NEXT: cmovneq %rdx, %r8 | |
| ; CHECK-NEXT: cmovneq %rax, %r9 | |
| ; CHECK-NEXT: notq %r9 | |
| ; CHECK-NEXT: cmovneq %rcx, %rdx | |
| ; CHECK-NEXT: cmovneq %rcx, %rax | |
| ; CHECK-NEXT: andq %rsi, %r9 | |
| ; CHECK-NEXT: orq %r8, %r9 | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %rdx, %rax | |
| ; CHECK-NEXT: movq %r9, %rdx | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b128 %base, b123 %val, i32 %off | |
| ret b128 %result | |
| } | |
| define b128 @test_bitinsert_val_b123_into_b128_const_top(b128 %base, b123 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b123_into_b128_const_top: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: shldq $5, %rdx, %rcx | |
| ; CHECK-NEXT: shlq $5, %rdx | |
| ; CHECK-NEXT: andl $31, %edi | |
| ; CHECK-NEXT: leaq (%rdi,%rdx), %rax | |
| ; CHECK-NEXT: movq %rcx, %rdx | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b128 %base, b123 %val, i32 5 | |
| ret b128 %result | |
| } | |
| define b231 @test_bitinsert_val_b123_into_b231_var(b231 %base, b123 %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_val_b123_into_b231_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: pushq %r15 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 16 | |
| ; CHECK-NEXT: pushq %r14 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 24 | |
| ; CHECK-NEXT: pushq %rbx | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 32 | |
| ; CHECK-NEXT: .cfi_offset %rbx, -32 | |
| ; CHECK-NEXT: .cfi_offset %r14, -24 | |
| ; CHECK-NEXT: .cfi_offset %r15, -16 | |
| ; CHECK-NEXT: movq %rcx, %r10 | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: movzbl {{[0-9]+}}(%rsp), %ecx | |
| ; CHECK-NEXT: xorps %xmm0, %xmm0 | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq %r9, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movabsq $576460752303423487, %rdi # imm = 0x7FFFFFFFFFFFFFF | |
| ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %r9 | |
| ; CHECK-NEXT: andq %rdi, %r9 | |
| ; CHECK-NEXT: movq %r9, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq %rdi, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movl %ecx, %edi | |
| ; CHECK-NEXT: shrb $3, %dil | |
| ; CHECK-NEXT: andb $24, %dil | |
| ; CHECK-NEXT: negb %dil | |
| ; CHECK-NEXT: movsbq %dil, %r11 | |
| ; CHECK-NEXT: movq -16(%rsp,%r11), %r14 | |
| ; CHECK-NEXT: movq -8(%rsp,%r11), %rbx | |
| ; CHECK-NEXT: shldq %cl, %r14, %rbx | |
| ; CHECK-NEXT: movq $-1, -{{[0-9]+}}(%rsp) | |
| ; CHECK-NEXT: movq -80(%rsp,%r11), %r9 | |
| ; CHECK-NEXT: movq -72(%rsp,%r11), %rdi | |
| ; CHECK-NEXT: shldq %cl, %r9, %rdi | |
| ; CHECK-NEXT: notq %rdi | |
| ; CHECK-NEXT: andq %r8, %rdi | |
| ; CHECK-NEXT: orq %rbx, %rdi | |
| ; CHECK-NEXT: movq -32(%rsp,%r11), %rbx | |
| ; CHECK-NEXT: movq -24(%rsp,%r11), %r8 | |
| ; CHECK-NEXT: shldq %cl, %r8, %r14 | |
| ; CHECK-NEXT: movq -96(%rsp,%r11), %r15 | |
| ; CHECK-NEXT: movq -88(%rsp,%r11), %r11 | |
| ; CHECK-NEXT: shldq %cl, %r11, %r9 | |
| ; CHECK-NEXT: notq %r9 | |
| ; CHECK-NEXT: andq %r10, %r9 | |
| ; CHECK-NEXT: orq %r14, %r9 | |
| ; CHECK-NEXT: movq %rbx, %r10 | |
| ; CHECK-NEXT: shlq %cl, %r10 | |
| ; CHECK-NEXT: movq %r15, %r14 | |
| ; CHECK-NEXT: shlq %cl, %r14 | |
| ; CHECK-NEXT: notq %r14 | |
| ; CHECK-NEXT: andq %rsi, %r14 | |
| ; CHECK-NEXT: orq %r10, %r14 | |
| ; CHECK-NEXT: shldq %cl, %rbx, %r8 | |
| ; CHECK-NEXT: shldq %cl, %r15, %r11 | |
| ; CHECK-NEXT: notq %r11 | |
| ; CHECK-NEXT: andq %rdx, %r11 | |
| ; CHECK-NEXT: orq %r8, %r11 | |
| ; CHECK-NEXT: movq %r9, 16(%rax) | |
| ; CHECK-NEXT: movq %r11, 8(%rax) | |
| ; CHECK-NEXT: movq %r14, (%rax) | |
| ; CHECK-NEXT: movl %edi, 24(%rax) | |
| ; CHECK-NEXT: shrq $32, %rdi | |
| ; CHECK-NEXT: andl $127, %edi | |
| ; CHECK-NEXT: movb %dil, 28(%rax) | |
| ; CHECK-NEXT: popq %rbx | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 24 | |
| ; CHECK-NEXT: popq %r14 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 16 | |
| ; CHECK-NEXT: popq %r15 | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 8 | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b231 %base, b123 %val, i32 %off | |
| ret b231 %result | |
| } | |
| define b231 @test_bitinsert_val_b123_into_b231_const_wordcross(b231 %base, b123 %val) { | |
| ; CHECK-LABEL: test_bitinsert_val_b123_into_b231_const_wordcross: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdi, %rax | |
| ; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rdx | |
| ; CHECK-NEXT: movabsq $-36028797018963968, %rdi # imm = 0xFF80000000000000 | |
| ; CHECK-NEXT: andq %rcx, %rdi | |
| ; CHECK-NEXT: movabsq $576460752303423472, %rcx # imm = 0x7FFFFFFFFFFFFF0 | |
| ; CHECK-NEXT: andq %rdx, %rcx | |
| ; CHECK-NEXT: shrq $4, %rcx | |
| ; CHECK-NEXT: orq %rdi, %rcx | |
| ; CHECK-NEXT: movabsq $1152921504606846975, %rdi # imm = 0xFFFFFFFFFFFFFFF | |
| ; CHECK-NEXT: andq %rsi, %rdi | |
| ; CHECK-NEXT: shldq $60, %r9, %rdx | |
| ; CHECK-NEXT: shlq $60, %r9 | |
| ; CHECK-NEXT: orq %rdi, %r9 | |
| ; CHECK-NEXT: movl %r8d, 24(%rax) | |
| ; CHECK-NEXT: movq %rcx, 16(%rax) | |
| ; CHECK-NEXT: movq %rdx, 8(%rax) | |
| ; CHECK-NEXT: movq %r9, (%rax) | |
| ; CHECK-NEXT: shrq $32, %r8 | |
| ; CHECK-NEXT: andl $127, %r8d | |
| ; CHECK-NEXT: movb %r8b, 28(%rax) | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b231 %base, b123 %val, i32 60 | |
| ret b231 %result | |
| } | |
| ; pointer values | |
| define b64 @test_bitinsert_ptr_var(b64 %base, ptr %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_ptr_var: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: shlq %cl, %rsi | |
| ; CHECK-NEXT: movq $-1, %rax | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %rsi, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b64 %base, ptr %val, i32 %off | |
| ret b64 %result | |
| } | |
| define b128 @test_bitinsert_ptr_const(b128 %base, ptr %val) { | |
| ; CHECK-LABEL: test_bitinsert_ptr_const: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movabsq $-4294967296, %rax # imm = 0xFFFFFFFF00000000 | |
| ; CHECK-NEXT: andq %rsi, %rax | |
| ; CHECK-NEXT: movq %rdx, %rcx | |
| ; CHECK-NEXT: shrq $32, %rcx | |
| ; CHECK-NEXT: orq %rax, %rcx | |
| ; CHECK-NEXT: shlq $32, %rdx | |
| ; CHECK-NEXT: movl %edi, %eax | |
| ; CHECK-NEXT: orq %rdx, %rax | |
| ; CHECK-NEXT: movq %rcx, %rdx | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b128 %base, ptr %val, i32 32 | |
| ret b128 %result | |
| } | |
| ; pointers in non-default address spaces | |
| define b64 @test_bitinsert_ptr_addrspace1(b64 %base, ptr addrspace(1) %val, i32 %off) { | |
| ; CHECK-LABEL: test_bitinsert_ptr_addrspace1: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movl %edx, %ecx | |
| ; CHECK-NEXT: shlq %cl, %rsi | |
| ; CHECK-NEXT: movq $-1, %rax | |
| ; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx | |
| ; CHECK-NEXT: shlq %cl, %rax | |
| ; CHECK-NEXT: notq %rax | |
| ; CHECK-NEXT: andq %rdi, %rax | |
| ; CHECK-NEXT: orq %rsi, %rax | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b64 %base, ptr addrspace(1) %val, i32 %off | |
| ret b64 %result | |
| } | |
| define b128 @test_bitinsert_ptr_addrspace3_const(b128 %base, ptr addrspace(3) %val) { | |
| ; CHECK-LABEL: test_bitinsert_ptr_addrspace3_const: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: movq %rdx, %rcx | |
| ; CHECK-NEXT: shrq $48, %rcx | |
| ; CHECK-NEXT: andq $-65536, %rsi # imm = 0xFFFF0000 | |
| ; CHECK-NEXT: orq %rsi, %rcx | |
| ; CHECK-NEXT: shlq $16, %rdx | |
| ; CHECK-NEXT: movzwl %di, %eax | |
| ; CHECK-NEXT: orq %rdx, %rax | |
| ; CHECK-NEXT: movq %rcx, %rdx | |
| ; CHECK-NEXT: retq | |
| %result = bitinsert b128 %base, ptr addrspace(3) %val, i32 16 | |
| ret b128 %result | |
| } |