| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc -mtriple=aarch64 < %s | FileCheck %s --check-prefix=AARCH64 |
| |
| define i16 @test_bitextract_var(b32 %src, i32 %off) { |
| ; AARCH64-LABEL: test_bitextract_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: lsr w0, w0, w1 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i16, b32 %src, i32 %off |
| ret i16 %result |
| } |
| |
| define i16 @test_bitextract_const(b32 %src) { |
| ; AARCH64-LABEL: test_bitextract_const: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: lsr w0, w0, #8 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i16, b32 %src, i32 8 |
| ret i16 %result |
| } |
| |
| define i8 @test_bitextract_narrow(b64 %src) { |
| ; AARCH64-LABEL: test_bitextract_narrow: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: // kill: def $w0 killed $w0 killed $x0 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i8, b64 %src, i32 0 |
| ret i8 %result |
| } |
| |
| define i1 @test_bitextract_b1(b1 %src) { |
| ; AARCH64-LABEL: test_bitextract_b1: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: and w0, w0, #0x1 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i1, b1 %src, i32 0 |
| ret i1 %result |
| } |
| |
| define i8 @test_bitextract_b37(b37 %src, i32 %off) { |
| ; AARCH64-LABEL: test_bitextract_b37: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: and x8, x0, #0x1fffffffff |
| ; AARCH64-NEXT: // kill: def $w1 killed $w1 def $x1 |
| ; AARCH64-NEXT: lsr x0, x8, x1 |
| ; AARCH64-NEXT: // kill: def $w0 killed $w0 killed $x0 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i8, b37 %src, i32 %off |
| ret i8 %result |
| } |
| |
| define i8 @test_bitextract_b37_const(b37 %src) { |
| ; AARCH64-LABEL: test_bitextract_b37_const: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: ubfx x0, x0, #20, #17 |
| ; AARCH64-NEXT: // kill: def $w0 killed $w0 killed $x0 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i8, b37 %src, i32 20 |
| ret i8 %result |
| } |
| |
| define i16 @test_bitextract_b87(b87 %src, i32 %off) { |
| ; AARCH64-LABEL: test_bitextract_b87: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: and x8, x1, #0x7fffff |
| ; AARCH64-NEXT: mov w10, w2 |
| ; AARCH64-NEXT: mvn w11, w2 |
| ; AARCH64-NEXT: lsl x9, x8, #1 |
| ; AARCH64-NEXT: lsr x12, x0, x10 |
| ; AARCH64-NEXT: lsr x8, x8, x10 |
| ; AARCH64-NEXT: tst x10, #0x40 |
| ; AARCH64-NEXT: lsl x9, x9, x11 |
| ; AARCH64-NEXT: orr x9, x9, x12 |
| ; AARCH64-NEXT: csel x0, x8, x9, ne |
| ; AARCH64-NEXT: // kill: def $w0 killed $w0 killed $x0 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i16, b87 %src, i32 %off |
| ret i16 %result |
| } |
| |
| |
| define i32 @test_bitextract_b128(b128 %src, i32 %off) { |
| ; AARCH64-LABEL: test_bitextract_b128: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: lsl x8, x1, #1 |
| ; AARCH64-NEXT: mov w9, w2 |
| ; AARCH64-NEXT: mvn w10, w2 |
| ; AARCH64-NEXT: lsr x11, x0, x9 |
| ; AARCH64-NEXT: tst x9, #0x40 |
| ; AARCH64-NEXT: lsl x8, x8, x10 |
| ; AARCH64-NEXT: lsr x10, x1, x9 |
| ; AARCH64-NEXT: orr x8, x8, x11 |
| ; AARCH64-NEXT: csel x0, x10, x8, ne |
| ; AARCH64-NEXT: // kill: def $w0 killed $w0 killed $x0 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i32, b128 %src, i32 %off |
| ret i32 %result |
| } |
| |
| define i32 @test_bitextract_b231(b231 %src, i32 %off) { |
| ; AARCH64-LABEL: test_bitextract_b231: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: stp x0, x1, [sp, #-64]! |
| ; AARCH64-NEXT: .cfi_def_cfa_offset 64 |
| ; AARCH64-NEXT: movi v0.2d, #0000000000000000 |
| ; AARCH64-NEXT: mov w8, w4 |
| ; AARCH64-NEXT: and x10, x3, #0x7fffffffff |
| ; AARCH64-NEXT: lsr x9, x8, #3 |
| ; AARCH64-NEXT: mov x11, sp |
| ; AARCH64-NEXT: stp x2, x10, [sp, #16] |
| ; AARCH64-NEXT: and x9, x9, #0x18 |
| ; AARCH64-NEXT: stp q0, q0, [sp, #32] |
| ; AARCH64-NEXT: add x9, x11, x9 |
| ; AARCH64-NEXT: mvn w11, w4 |
| ; AARCH64-NEXT: ldp x9, x10, [x9] |
| ; AARCH64-NEXT: lsl x10, x10, #1 |
| ; AARCH64-NEXT: lsr x8, x9, x8 |
| ; AARCH64-NEXT: lsl x10, x10, x11 |
| ; AARCH64-NEXT: orr w0, w10, w8 |
| ; AARCH64-NEXT: add sp, sp, #64 |
| ; AARCH64-NEXT: ret |
| %result = bitextract i32, b231 %src, i32 %off |
| ret i32 %result |
| } |
| |
| |
| |
| ; Bitinsert |
| define b32 @test_bitinsert_var(b32 %base, i16 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #65535 // =0xffff |
| ; AARCH64-NEXT: and w9, w1, #0xffff |
| ; AARCH64-NEXT: lsl w8, w8, w2 |
| ; AARCH64-NEXT: lsl w9, w9, w2 |
| ; AARCH64-NEXT: bic w8, w0, w8 |
| ; AARCH64-NEXT: orr w0, w8, w9 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b32 %base, i16 %val, i32 %off |
| ret b32 %result |
| } |
| |
| define b1 @test_bitinsert_b1(b1 %base, i1 %val) { |
| ; AARCH64-LABEL: test_bitinsert_b1: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: and w0, w1, #0x1 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b1 %base, i1 %val, i32 0 |
| ret b1 %result |
| } |
| |
| define b37 @test_bitinsert_b37_var(b37 %base, i8 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b37_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #255 // =0xff |
| ; AARCH64-NEXT: // kill: def $w2 killed $w2 def $x2 |
| ; AARCH64-NEXT: // kill: def $w1 killed $w1 def $x1 |
| ; AARCH64-NEXT: and x9, x1, #0xff |
| ; AARCH64-NEXT: lsl x8, x8, x2 |
| ; AARCH64-NEXT: lsl x9, x9, x2 |
| ; AARCH64-NEXT: eor x8, x8, #0x1fffffffff |
| ; AARCH64-NEXT: and x8, x0, x8 |
| ; AARCH64-NEXT: orr x0, x8, x9 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b37 %base, i8 %val, i32 %off |
| ret b37 %result |
| } |
| |
| define b87 @test_bitinsert_b87_var(b87 %base, i16 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b87_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mvn w8, w3 |
| ; AARCH64-NEXT: mov w10, w3 |
| ; AARCH64-NEXT: mov w11, #32767 // =0x7fff |
| ; AARCH64-NEXT: mov w12, #65535 // =0xffff |
| ; AARCH64-NEXT: // kill: def $w2 killed $w2 def $x2 |
| ; AARCH64-NEXT: ubfx x9, x2, #1, #15 |
| ; AARCH64-NEXT: lsr x11, x11, x8 |
| ; AARCH64-NEXT: lsl x12, x12, x10 |
| ; AARCH64-NEXT: and x13, x2, #0xffff |
| ; AARCH64-NEXT: tst x10, #0x40 |
| ; AARCH64-NEXT: lsr x8, x9, x8 |
| ; AARCH64-NEXT: lsl x9, x13, x10 |
| ; AARCH64-NEXT: csel x10, x12, x11, ne |
| ; AARCH64-NEXT: csel x11, xzr, x12, ne |
| ; AARCH64-NEXT: eor x10, x10, #0x7fffff |
| ; AARCH64-NEXT: csel x8, x9, x8, ne |
| ; AARCH64-NEXT: csel x9, xzr, x9, ne |
| ; AARCH64-NEXT: and x10, x1, x10 |
| ; AARCH64-NEXT: bic x11, x0, x11 |
| ; AARCH64-NEXT: orr x0, x11, x9 |
| ; AARCH64-NEXT: orr x1, x10, x8 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b87 %base, i16 %val, i32 %off |
| ret b87 %result |
| } |
| |
| define b128 @test_bitinsert_b128_var(b128 %base, i32 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b128_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, w2 |
| ; AARCH64-NEXT: mov w9, #2147483647 // =0x7fffffff |
| ; AARCH64-NEXT: mvn w10, w3 |
| ; AARCH64-NEXT: lsr x11, x8, #1 |
| ; AARCH64-NEXT: mov w12, #-1 // =0xffffffff |
| ; AARCH64-NEXT: mov w13, w3 |
| ; AARCH64-NEXT: lsr x9, x9, x10 |
| ; AARCH64-NEXT: lsl x8, x8, x13 |
| ; AARCH64-NEXT: tst x13, #0x40 |
| ; AARCH64-NEXT: lsr x10, x11, x10 |
| ; AARCH64-NEXT: lsl x11, x12, x13 |
| ; AARCH64-NEXT: csel x9, x11, x9, ne |
| ; AARCH64-NEXT: csel x11, xzr, x11, ne |
| ; AARCH64-NEXT: csel x10, x8, x10, ne |
| ; AARCH64-NEXT: bic x9, x1, x9 |
| ; AARCH64-NEXT: csel x8, xzr, x8, ne |
| ; AARCH64-NEXT: bic x11, x0, x11 |
| ; AARCH64-NEXT: orr x0, x11, x8 |
| ; AARCH64-NEXT: orr x1, x9, x10 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b128 %base, i32 %val, i32 %off |
| ret b128 %result |
| } |
| |
| define b231 @test_bitinsert_b231_var(b231 %base, i32 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b231_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: sub sp, sp, #128 |
| ; AARCH64-NEXT: .cfi_def_cfa_offset 128 |
| ; AARCH64-NEXT: mov w8, w4 |
| ; AARCH64-NEXT: movi v0.2d, #0000000000000000 |
| ; AARCH64-NEXT: mov x9, sp |
| ; AARCH64-NEXT: str x8, [sp, #32] |
| ; AARCH64-NEXT: mov w8, w5 |
| ; AARCH64-NEXT: add x12, sp, #64 |
| ; AARCH64-NEXT: lsr x10, x8, #3 |
| ; AARCH64-NEXT: mov w11, #-1 // =0xffffffff |
| ; AARCH64-NEXT: add x9, x9, #32 |
| ; AARCH64-NEXT: add x12, x12, #32 |
| ; AARCH64-NEXT: str xzr, [sp, #56] |
| ; AARCH64-NEXT: and x15, x8, #0x3f |
| ; AARCH64-NEXT: and x10, x10, #0x18 |
| ; AARCH64-NEXT: stur q0, [sp, #40] |
| ; AARCH64-NEXT: eor x15, x15, #0x3f |
| ; AARCH64-NEXT: stp q0, q0, [sp] |
| ; AARCH64-NEXT: sub x9, x9, x10 |
| ; AARCH64-NEXT: sub x10, x12, x10 |
| ; AARCH64-NEXT: str xzr, [sp, #120] |
| ; AARCH64-NEXT: stur q0, [sp, #104] |
| ; AARCH64-NEXT: stp q0, q0, [sp, #64] |
| ; AARCH64-NEXT: str x11, [sp, #96] |
| ; AARCH64-NEXT: ldp x12, x16, [x10] |
| ; AARCH64-NEXT: ldp x11, x13, [x9] |
| ; AARCH64-NEXT: lsr x17, x12, #1 |
| ; AARCH64-NEXT: lsl x4, x16, x8 |
| ; AARCH64-NEXT: lsr x16, x16, #1 |
| ; AARCH64-NEXT: lsr x14, x11, #1 |
| ; AARCH64-NEXT: lsl x18, x13, x8 |
| ; AARCH64-NEXT: lsr x13, x13, #1 |
| ; AARCH64-NEXT: lsr x17, x17, x15 |
| ; AARCH64-NEXT: lsl x12, x12, x8 |
| ; AARCH64-NEXT: lsr x14, x14, x15 |
| ; AARCH64-NEXT: orr x17, x4, x17 |
| ; AARCH64-NEXT: ldp x4, x10, [x10, #16] |
| ; AARCH64-NEXT: orr x14, x18, x14 |
| ; AARCH64-NEXT: mvn w18, w5 |
| ; AARCH64-NEXT: bic x17, x1, x17 |
| ; AARCH64-NEXT: ldp x5, x9, [x9, #16] |
| ; AARCH64-NEXT: lsr x13, x13, x18 |
| ; AARCH64-NEXT: lsr x1, x4, #1 |
| ; AARCH64-NEXT: lsr x16, x16, x18 |
| ; AARCH64-NEXT: lsl x18, x4, x8 |
| ; AARCH64-NEXT: lsl x10, x10, x8 |
| ; AARCH64-NEXT: bic x12, x0, x12 |
| ; AARCH64-NEXT: lsr x4, x5, #1 |
| ; AARCH64-NEXT: lsr x1, x1, x15 |
| ; AARCH64-NEXT: lsl x6, x5, x8 |
| ; AARCH64-NEXT: lsl x9, x9, x8 |
| ; AARCH64-NEXT: orr x16, x18, x16 |
| ; AARCH64-NEXT: lsl x8, x11, x8 |
| ; AARCH64-NEXT: lsr x15, x4, x15 |
| ; AARCH64-NEXT: orr x10, x10, x1 |
| ; AARCH64-NEXT: orr x13, x6, x13 |
| ; AARCH64-NEXT: eor x10, x10, #0x7fffffffff |
| ; AARCH64-NEXT: bic x11, x2, x16 |
| ; AARCH64-NEXT: orr x0, x12, x8 |
| ; AARCH64-NEXT: orr x9, x9, x15 |
| ; AARCH64-NEXT: and x10, x3, x10 |
| ; AARCH64-NEXT: orr x1, x17, x14 |
| ; AARCH64-NEXT: orr x2, x11, x13 |
| ; AARCH64-NEXT: orr x3, x10, x9 |
| ; AARCH64-NEXT: add sp, sp, #128 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_b1_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: and w0, w1, #0x1 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b1 %base, i1 %val, i32 %off |
| ret b1 %result |
| } |
| |
| define b8 @test_bitinsert_b8_var(b8 %base, i4 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b8_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #15 // =0xf |
| ; AARCH64-NEXT: and w9, w1, #0xf |
| ; AARCH64-NEXT: lsl w8, w8, w2 |
| ; AARCH64-NEXT: lsl w9, w9, w2 |
| ; AARCH64-NEXT: bic w8, w0, w8 |
| ; AARCH64-NEXT: orr w0, w8, w9 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b8 %base, i4 %val, i32 %off |
| ret b8 %result |
| } |
| |
| define b8 @test_bitinsert_b8_const(b8 %base, i4 %val) { |
| ; AARCH64-LABEL: test_bitinsert_b8_const: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi w0, w1, #3, #4 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b8 %base, i4 %val, i32 3 |
| ret b8 %result |
| } |
| |
| define b21 @test_bitinsert_b21_var(b21 %base, i6 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b21_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #63 // =0x3f |
| ; AARCH64-NEXT: and w9, w1, #0x3f |
| ; AARCH64-NEXT: lsl w8, w8, w2 |
| ; AARCH64-NEXT: lsl w9, w9, w2 |
| ; AARCH64-NEXT: eor w8, w8, #0x1fffff |
| ; AARCH64-NEXT: and w8, w0, w8 |
| ; AARCH64-NEXT: orr w0, w8, w9 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b21 %base, i6 %val, i32 %off |
| ret b21 %result |
| } |
| |
| define b21 @test_bitinsert_b21_const(b21 %base, i6 %val) { |
| ; AARCH64-LABEL: test_bitinsert_b21_const: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: and w8, w0, #0x1fffff |
| ; AARCH64-NEXT: and w0, w8, #0xfff03fff |
| ; AARCH64-NEXT: bfi w0, w1, #14, #6 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b21 %base, i6 %val, i32 14 |
| ret b21 %result |
| } |
| |
| define b123 @test_bitinsert_b123_var(b123 %base, i32 %val, i32 %off) { |
| ; AARCH64-LABEL: test_bitinsert_b123_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, w3 |
| ; AARCH64-NEXT: mov w9, w2 |
| ; AARCH64-NEXT: mov w10, #2147483647 // =0x7fffffff |
| ; AARCH64-NEXT: mvn w11, w3 |
| ; AARCH64-NEXT: mov w13, #-1 // =0xffffffff |
| ; AARCH64-NEXT: lsr x12, x9, #1 |
| ; AARCH64-NEXT: lsr x10, x10, x11 |
| ; AARCH64-NEXT: lsl x13, x13, x8 |
| ; AARCH64-NEXT: tst x8, #0x40 |
| ; AARCH64-NEXT: lsl x9, x9, x8 |
| ; AARCH64-NEXT: lsr x8, x12, x11 |
| ; AARCH64-NEXT: csel x10, x13, x10, ne |
| ; AARCH64-NEXT: csel x11, xzr, x13, ne |
| ; AARCH64-NEXT: eor x10, x10, #0x7ffffffffffffff |
| ; AARCH64-NEXT: csel x8, x9, x8, ne |
| ; AARCH64-NEXT: csel x9, xzr, x9, ne |
| ; AARCH64-NEXT: and x10, x1, x10 |
| ; AARCH64-NEXT: bic x11, x0, x11 |
| ; AARCH64-NEXT: orr x0, x11, x9 |
| ; AARCH64-NEXT: orr x1, x10, x8 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b123 %base, i32 %val, i32 %off |
| ret b123 %result |
| } |
| |
| define b123 @test_bitinsert_b123_crossword(b123 %base, i32 %val) { |
| ; AARCH64-LABEL: test_bitinsert_b123_crossword: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, w2 |
| ; AARCH64-NEXT: and x9, x1, #0x7fffffff0000000 |
| ; AARCH64-NEXT: bfi x0, x8, #60, #4 |
| ; AARCH64-NEXT: orr x1, x9, x8, lsr #4 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b123 %base, i32 %val, i32 60 |
| ret b123 %result |
| } |
| |
| |
| define b123 @test_bitinsert_val_b123_full(b123 %base, b123 %val) { |
| ; AARCH64-LABEL: test_bitinsert_val_b123_full: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov x1, x3 |
| ; AARCH64-NEXT: mov x0, x2 |
| ; AARCH64-NEXT: ret |
| %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 |
| ; AARCH64-LABEL: test_bitinsert_val_b8_full: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w0, w1 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b8_into_b32_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #255 // =0xff |
| ; AARCH64-NEXT: and w9, w1, #0xff |
| ; AARCH64-NEXT: lsl w8, w8, w2 |
| ; AARCH64-NEXT: lsl w9, w9, w2 |
| ; AARCH64-NEXT: bic w8, w0, w8 |
| ; AARCH64-NEXT: orr w0, w8, w9 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b8_into_b32_const_mid: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi w0, w1, #12, #8 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b8_into_b64_const_top: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: // kill: def $w1 killed $w1 def $x1 |
| ; AARCH64-NEXT: bfi x0, x1, #56, #8 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b1_into_b8: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #1 // =0x1 |
| ; AARCH64-NEXT: and w9, w1, #0x1 |
| ; AARCH64-NEXT: lsl w8, w8, w2 |
| ; AARCH64-NEXT: lsl w9, w9, w2 |
| ; AARCH64-NEXT: bic w8, w0, w8 |
| ; AARCH64-NEXT: orr w0, w8, w9 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b1_into_b32_const_top: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi w0, w1, #31, #1 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b32 %base, b1 %val, i32 31 |
| ret b32 %result |
| } |
| |
| define b21 @test_bitinsert_val_b21_full(b21 %base, b21 %val) { |
| ; AARCH64-LABEL: test_bitinsert_val_b21_full: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w0, w1 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b21_into_b32_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #2097151 // =0x1fffff |
| ; AARCH64-NEXT: and w9, w1, #0x1fffff |
| ; AARCH64-NEXT: lsl w8, w8, w2 |
| ; AARCH64-NEXT: lsl w9, w9, w2 |
| ; AARCH64-NEXT: bic w8, w0, w8 |
| ; AARCH64-NEXT: orr w0, w8, w9 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b21_into_b32_const_top: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi w0, w1, #11, #21 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b21_into_b64_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov w8, #2097151 // =0x1fffff |
| ; AARCH64-NEXT: // kill: def $w2 killed $w2 def $x2 |
| ; AARCH64-NEXT: // kill: def $w1 killed $w1 def $x1 |
| ; AARCH64-NEXT: and x9, x1, #0x1fffff |
| ; AARCH64-NEXT: lsl x8, x8, x2 |
| ; AARCH64-NEXT: lsl x9, x9, x2 |
| ; AARCH64-NEXT: bic x8, x0, x8 |
| ; AARCH64-NEXT: orr x0, x8, x9 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b123_into_b128_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: lsr x9, x2, #1 |
| ; AARCH64-NEXT: mvn w8, w4 |
| ; AARCH64-NEXT: mov w11, w4 |
| ; AARCH64-NEXT: mov x12, #9223372036854775807 // =0x7fffffffffffffff |
| ; AARCH64-NEXT: mov x13, #576460752303423487 // =0x7ffffffffffffff |
| ; AARCH64-NEXT: and x10, x3, #0x7ffffffffffffff |
| ; AARCH64-NEXT: lsr x9, x9, x8 |
| ; AARCH64-NEXT: lsr x8, x12, x8 |
| ; AARCH64-NEXT: lsl x12, x13, x11 |
| ; AARCH64-NEXT: mov x13, #-1 // =0xffffffffffffffff |
| ; AARCH64-NEXT: lsl x10, x10, x11 |
| ; AARCH64-NEXT: lsl x14, x2, x11 |
| ; AARCH64-NEXT: lsl x13, x13, x11 |
| ; AARCH64-NEXT: tst x11, #0x40 |
| ; AARCH64-NEXT: orr x8, x12, x8 |
| ; AARCH64-NEXT: orr x9, x10, x9 |
| ; AARCH64-NEXT: csel x11, xzr, x14, ne |
| ; AARCH64-NEXT: csel x8, x13, x8, ne |
| ; AARCH64-NEXT: csel x10, xzr, x13, ne |
| ; AARCH64-NEXT: csel x9, x14, x9, ne |
| ; AARCH64-NEXT: bic x8, x1, x8 |
| ; AARCH64-NEXT: bic x10, x0, x10 |
| ; AARCH64-NEXT: orr x0, x10, x11 |
| ; AARCH64-NEXT: orr x1, x8, x9 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b123_into_b128_const_top: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi x0, x2, #5, #59 |
| ; AARCH64-NEXT: extr x1, x3, x2, #59 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b123_into_b231_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: sub sp, sp, #128 |
| ; AARCH64-NEXT: .cfi_def_cfa_offset 128 |
| ; AARCH64-NEXT: and x8, x5, #0x7ffffffffffffff |
| ; AARCH64-NEXT: movi v0.2d, #0000000000000000 |
| ; AARCH64-NEXT: mov x9, #576460752303423487 // =0x7ffffffffffffff |
| ; AARCH64-NEXT: stp x4, x8, [sp, #32] |
| ; AARCH64-NEXT: mov x10, #-1 // =0xffffffffffffffff |
| ; AARCH64-NEXT: mov w8, w6 |
| ; AARCH64-NEXT: stp x10, x9, [sp, #96] |
| ; AARCH64-NEXT: lsr x9, x8, #3 |
| ; AARCH64-NEXT: mov x11, sp |
| ; AARCH64-NEXT: add x10, sp, #64 |
| ; AARCH64-NEXT: add x11, x11, #32 |
| ; AARCH64-NEXT: and x15, x8, #0x3f |
| ; AARCH64-NEXT: and x9, x9, #0x18 |
| ; AARCH64-NEXT: add x10, x10, #32 |
| ; AARCH64-NEXT: stp q0, q0, [sp] |
| ; AARCH64-NEXT: stp q0, q0, [sp, #48] |
| ; AARCH64-NEXT: sub x11, x11, x9 |
| ; AARCH64-NEXT: sub x9, x10, x9 |
| ; AARCH64-NEXT: str q0, [sp, #112] |
| ; AARCH64-NEXT: eor x15, x15, #0x3f |
| ; AARCH64-NEXT: str q0, [sp, #80] |
| ; AARCH64-NEXT: ldp x10, x16, [x9] |
| ; AARCH64-NEXT: ldp x12, x13, [x11] |
| ; AARCH64-NEXT: ldp x5, x11, [x11, #16] |
| ; AARCH64-NEXT: lsr x17, x10, #1 |
| ; AARCH64-NEXT: lsl x4, x16, x8 |
| ; AARCH64-NEXT: lsr x16, x16, #1 |
| ; AARCH64-NEXT: lsr x14, x12, #1 |
| ; AARCH64-NEXT: lsl x18, x13, x8 |
| ; AARCH64-NEXT: lsr x13, x13, #1 |
| ; AARCH64-NEXT: lsr x17, x17, x15 |
| ; AARCH64-NEXT: lsl x11, x11, x8 |
| ; AARCH64-NEXT: lsl x10, x10, x8 |
| ; AARCH64-NEXT: lsr x14, x14, x15 |
| ; AARCH64-NEXT: orr x17, x4, x17 |
| ; AARCH64-NEXT: ldp x4, x9, [x9, #16] |
| ; AARCH64-NEXT: bic x17, x1, x17 |
| ; AARCH64-NEXT: orr x14, x18, x14 |
| ; AARCH64-NEXT: mvn w18, w6 |
| ; AARCH64-NEXT: lsr x13, x13, x18 |
| ; AARCH64-NEXT: lsr x16, x16, x18 |
| ; AARCH64-NEXT: lsl x6, x5, x8 |
| ; AARCH64-NEXT: lsr x1, x4, #1 |
| ; AARCH64-NEXT: lsl x18, x4, x8 |
| ; AARCH64-NEXT: lsr x4, x5, #1 |
| ; AARCH64-NEXT: lsl x9, x9, x8 |
| ; AARCH64-NEXT: lsl x8, x12, x8 |
| ; AARCH64-NEXT: orr x13, x6, x13 |
| ; AARCH64-NEXT: lsr x1, x1, x15 |
| ; AARCH64-NEXT: lsr x15, x4, x15 |
| ; AARCH64-NEXT: orr x16, x18, x16 |
| ; AARCH64-NEXT: bic x12, x2, x16 |
| ; AARCH64-NEXT: bic x10, x0, x10 |
| ; AARCH64-NEXT: orr x9, x9, x1 |
| ; AARCH64-NEXT: orr x11, x11, x15 |
| ; AARCH64-NEXT: orr x0, x10, x8 |
| ; AARCH64-NEXT: eor x9, x9, #0x7fffffffff |
| ; AARCH64-NEXT: orr x1, x17, x14 |
| ; AARCH64-NEXT: orr x2, x12, x13 |
| ; AARCH64-NEXT: and x9, x3, x9 |
| ; AARCH64-NEXT: orr x3, x9, x11 |
| ; AARCH64-NEXT: add sp, sp, #128 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_val_b123_into_b231_const_wordcross: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: extr x1, x5, x4, #4 |
| ; AARCH64-NEXT: bfi x0, x4, #60, #4 |
| ; AARCH64-NEXT: bfxil x2, x5, #4, #55 |
| ; AARCH64-NEXT: and x3, x3, #0x7fffffffff |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_ptr_var: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov x8, #-1 // =0xffffffffffffffff |
| ; AARCH64-NEXT: // kill: def $w2 killed $w2 def $x2 |
| ; AARCH64-NEXT: lsl x9, x1, x2 |
| ; AARCH64-NEXT: lsl x8, x8, x2 |
| ; AARCH64-NEXT: bic x8, x0, x8 |
| ; AARCH64-NEXT: orr x0, x8, x9 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b64 %base, ptr %val, i32 %off |
| ret b64 %result |
| } |
| |
| define b128 @test_bitinsert_ptr_const(b128 %base, ptr %val) { |
| ; AARCH64-LABEL: test_bitinsert_ptr_const: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi x0, x2, #32, #32 |
| ; AARCH64-NEXT: bfxil x1, x2, #32, #32 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_ptr_addrspace1: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: mov x8, #-1 // =0xffffffffffffffff |
| ; AARCH64-NEXT: // kill: def $w2 killed $w2 def $x2 |
| ; AARCH64-NEXT: lsl x9, x1, x2 |
| ; AARCH64-NEXT: lsl x8, x8, x2 |
| ; AARCH64-NEXT: bic x8, x0, x8 |
| ; AARCH64-NEXT: orr x0, x8, x9 |
| ; AARCH64-NEXT: ret |
| %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) { |
| ; AARCH64-LABEL: test_bitinsert_ptr_addrspace3_const: |
| ; AARCH64: // %bb.0: |
| ; AARCH64-NEXT: bfi x0, x2, #16, #48 |
| ; AARCH64-NEXT: bfxil x1, x2, #48, #16 |
| ; AARCH64-NEXT: ret |
| %result = bitinsert b128 %base, ptr addrspace(3) %val, i32 16 |
| ret b128 %result |
| } |