| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s --check-prefixes=CHECK,LE |
| ; RUN: llc < %s -mtriple=aarch64_be-- | FileCheck %s --check-prefixes=CHECK,BE |
| |
| define void @le_i16_to_i8(i16 %x, ptr %p0) { |
| ; LE-LABEL: le_i16_to_i8: |
| ; LE: // %bb.0: |
| ; LE-NEXT: strh w0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i16_to_i8: |
| ; BE: // %bb.0: |
| ; BE-NEXT: rev w8, w0 |
| ; BE-NEXT: lsr w8, w8, #16 |
| ; BE-NEXT: strh w8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i16 %x, 8 |
| %t0 = trunc i16 %x to i8 |
| %t1 = trunc i16 %sh1 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| store i8 %t0, ptr %p0, align 1 |
| store i8 %t1, ptr %p1, align 1 |
| ret void |
| } |
| |
| define void @le_i16_to_i8_order(i16 %x, ptr %p0) { |
| ; LE-LABEL: le_i16_to_i8_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: strh w0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i16_to_i8_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: rev w8, w0 |
| ; BE-NEXT: lsr w8, w8, #16 |
| ; BE-NEXT: strh w8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i16 %x, 8 |
| %t0 = trunc i16 %x to i8 |
| %t1 = trunc i16 %sh1 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| store i8 %t1, ptr %p1, align 1 |
| store i8 %t0, ptr %p0, align 1 |
| ret void |
| } |
| |
| define void @be_i16_to_i8_offset(i16 %x, ptr %p0) { |
| ; LE-LABEL: be_i16_to_i8_offset: |
| ; LE: // %bb.0: |
| ; LE-NEXT: rev w8, w0 |
| ; LE-NEXT: lsr w8, w8, #16 |
| ; LE-NEXT: sturh w8, [x1, #11] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i16_to_i8_offset: |
| ; BE: // %bb.0: |
| ; BE-NEXT: sturh w0, [x1, #11] |
| ; BE-NEXT: ret |
| %sh1 = lshr i16 %x, 8 |
| %t0 = trunc i16 %x to i8 |
| %t1 = trunc i16 %sh1 to i8 |
| %p11 = getelementptr inbounds i8, ptr %p0, i64 11 |
| %p12 = getelementptr inbounds i8, ptr %p0, i64 12 |
| store i8 %t0, ptr %p12, align 1 |
| store i8 %t1, ptr %p11, align 1 |
| ret void |
| } |
| |
| define void @be_i16_to_i8_order(i16 %x, ptr %p0) { |
| ; LE-LABEL: be_i16_to_i8_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: rev w8, w0 |
| ; LE-NEXT: lsr w8, w8, #16 |
| ; LE-NEXT: strh w8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i16_to_i8_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: strh w0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i16 %x, 8 |
| %t0 = trunc i16 %x to i8 |
| %t1 = trunc i16 %sh1 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| store i8 %t1, ptr %p0, align 1 |
| store i8 %t0, ptr %p1, align 1 |
| ret void |
| } |
| |
| define void @le_i32_to_i8(i32 %x, ptr %p0) { |
| ; LE-LABEL: le_i32_to_i8: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str w0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i32_to_i8: |
| ; BE: // %bb.0: |
| ; BE-NEXT: rev w8, w0 |
| ; BE-NEXT: str w8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 8 |
| %sh2 = lshr i32 %x, 16 |
| %sh3 = lshr i32 %x, 24 |
| %t0 = trunc i32 %x to i8 |
| %t1 = trunc i32 %sh1 to i8 |
| %t2 = trunc i32 %sh2 to i8 |
| %t3 = trunc i32 %sh3 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| store i8 %t0, ptr %p0, align 1 |
| store i8 %t1, ptr %p1, align 1 |
| store i8 %t2, ptr %p2, align 1 |
| store i8 %t3, ptr %p3, align 1 |
| ret void |
| } |
| |
| define void @le_i32_to_i8_order(i32 %x, ptr %p0) { |
| ; LE-LABEL: le_i32_to_i8_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str w0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i32_to_i8_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: rev w8, w0 |
| ; BE-NEXT: str w8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 8 |
| %sh2 = lshr i32 %x, 16 |
| %sh3 = lshr i32 %x, 24 |
| %t0 = trunc i32 %x to i8 |
| %t1 = trunc i32 %sh1 to i8 |
| %t2 = trunc i32 %sh2 to i8 |
| %t3 = trunc i32 %sh3 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| store i8 %t3, ptr %p3, align 1 |
| store i8 %t1, ptr %p1, align 1 |
| store i8 %t0, ptr %p0, align 1 |
| store i8 %t2, ptr %p2, align 1 |
| ret void |
| } |
| |
| define void @be_i32_to_i8(i32 %x, ptr %p0) { |
| ; LE-LABEL: be_i32_to_i8: |
| ; LE: // %bb.0: |
| ; LE-NEXT: rev w8, w0 |
| ; LE-NEXT: str w8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i32_to_i8: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str w0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 8 |
| %sh2 = lshr i32 %x, 16 |
| %sh3 = lshr i32 %x, 24 |
| %t0 = trunc i32 %x to i8 |
| %t1 = trunc i32 %sh1 to i8 |
| %t2 = trunc i32 %sh2 to i8 |
| %t3 = trunc i32 %sh3 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| store i8 %t0, ptr %p3, align 1 |
| store i8 %t1, ptr %p2, align 1 |
| store i8 %t2, ptr %p1, align 1 |
| store i8 %t3, ptr %p0, align 1 |
| ret void |
| } |
| |
| define void @be_i32_to_i8_order(i32 %x, ptr %p0) { |
| ; LE-LABEL: be_i32_to_i8_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: rev w8, w0 |
| ; LE-NEXT: str w8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i32_to_i8_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str w0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 8 |
| %sh2 = lshr i32 %x, 16 |
| %sh3 = lshr i32 %x, 24 |
| %t0 = trunc i32 %x to i8 |
| %t1 = trunc i32 %sh1 to i8 |
| %t2 = trunc i32 %sh2 to i8 |
| %t3 = trunc i32 %sh3 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| store i8 %t3, ptr %p0, align 1 |
| store i8 %t2, ptr %p1, align 1 |
| store i8 %t0, ptr %p3, align 1 |
| store i8 %t1, ptr %p2, align 1 |
| ret void |
| } |
| |
| define void @le_i32_to_i16(i32 %x, ptr %p0) { |
| ; LE-LABEL: le_i32_to_i16: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str w0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i32_to_i16: |
| ; BE: // %bb.0: |
| ; BE-NEXT: ror w8, w0, #16 |
| ; BE-NEXT: str w8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 16 |
| %t0 = trunc i32 %x to i16 |
| %t1 = trunc i32 %sh1 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| store i16 %t0, ptr %p0, align 2 |
| store i16 %t1, ptr %p1, align 2 |
| ret void |
| } |
| |
| define void @le_i32_to_i16_order(i32 %x, ptr %p0) { |
| ; LE-LABEL: le_i32_to_i16_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str w0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i32_to_i16_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: ror w8, w0, #16 |
| ; BE-NEXT: str w8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 16 |
| %t0 = trunc i32 %x to i16 |
| %t1 = trunc i32 %sh1 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| store i16 %t1, ptr %p1, align 2 |
| store i16 %t0, ptr %p0, align 2 |
| ret void |
| } |
| |
| define void @be_i32_to_i16(i32 %x, ptr %p0) { |
| ; LE-LABEL: be_i32_to_i16: |
| ; LE: // %bb.0: |
| ; LE-NEXT: ror w8, w0, #16 |
| ; LE-NEXT: str w8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i32_to_i16: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str w0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 16 |
| %t0 = trunc i32 %x to i16 |
| %t1 = trunc i32 %sh1 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| store i16 %t0, ptr %p1, align 2 |
| store i16 %t1, ptr %p0, align 2 |
| ret void |
| } |
| |
| define void @be_i32_to_i16_order(i32 %x, ptr %p0) { |
| ; LE-LABEL: be_i32_to_i16_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: ror w8, w0, #16 |
| ; LE-NEXT: str w8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i32_to_i16_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str w0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i32 %x, 16 |
| %t0 = trunc i32 %x to i16 |
| %t1 = trunc i32 %sh1 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| store i16 %t1, ptr %p0, align 2 |
| store i16 %t0, ptr %p1, align 2 |
| ret void |
| } |
| |
| define void @le_i64_to_i8(i64 %x, ptr %p0) { |
| ; LE-LABEL: le_i64_to_i8: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str x0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i64_to_i8: |
| ; BE: // %bb.0: |
| ; BE-NEXT: rev x8, x0 |
| ; BE-NEXT: str x8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 8 |
| %sh2 = lshr i64 %x, 16 |
| %sh3 = lshr i64 %x, 24 |
| %sh4 = lshr i64 %x, 32 |
| %sh5 = lshr i64 %x, 40 |
| %sh6 = lshr i64 %x, 48 |
| %sh7 = lshr i64 %x, 56 |
| %t0 = trunc i64 %x to i8 |
| %t1 = trunc i64 %sh1 to i8 |
| %t2 = trunc i64 %sh2 to i8 |
| %t3 = trunc i64 %sh3 to i8 |
| %t4 = trunc i64 %sh4 to i8 |
| %t5 = trunc i64 %sh5 to i8 |
| %t6 = trunc i64 %sh6 to i8 |
| %t7 = trunc i64 %sh7 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| %p4 = getelementptr inbounds i8, ptr %p0, i64 4 |
| %p5 = getelementptr inbounds i8, ptr %p0, i64 5 |
| %p6 = getelementptr inbounds i8, ptr %p0, i64 6 |
| %p7 = getelementptr inbounds i8, ptr %p0, i64 7 |
| store i8 %t0, ptr %p0, align 1 |
| store i8 %t1, ptr %p1, align 1 |
| store i8 %t2, ptr %p2, align 1 |
| store i8 %t3, ptr %p3, align 1 |
| store i8 %t4, ptr %p4, align 1 |
| store i8 %t5, ptr %p5, align 1 |
| store i8 %t6, ptr %p6, align 1 |
| store i8 %t7, ptr %p7, align 1 |
| ret void |
| } |
| |
| define void @le_i64_to_i8_order(i64 %x, ptr %p0) { |
| ; LE-LABEL: le_i64_to_i8_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str x0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i64_to_i8_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: rev x8, x0 |
| ; BE-NEXT: str x8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 8 |
| %sh2 = lshr i64 %x, 16 |
| %sh3 = lshr i64 %x, 24 |
| %sh4 = lshr i64 %x, 32 |
| %sh5 = lshr i64 %x, 40 |
| %sh6 = lshr i64 %x, 48 |
| %sh7 = lshr i64 %x, 56 |
| %t0 = trunc i64 %x to i8 |
| %t1 = trunc i64 %sh1 to i8 |
| %t2 = trunc i64 %sh2 to i8 |
| %t3 = trunc i64 %sh3 to i8 |
| %t4 = trunc i64 %sh4 to i8 |
| %t5 = trunc i64 %sh5 to i8 |
| %t6 = trunc i64 %sh6 to i8 |
| %t7 = trunc i64 %sh7 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| %p4 = getelementptr inbounds i8, ptr %p0, i64 4 |
| %p5 = getelementptr inbounds i8, ptr %p0, i64 5 |
| %p6 = getelementptr inbounds i8, ptr %p0, i64 6 |
| %p7 = getelementptr inbounds i8, ptr %p0, i64 7 |
| store i8 %t5, ptr %p5, align 1 |
| store i8 %t0, ptr %p0, align 1 |
| store i8 %t3, ptr %p3, align 1 |
| store i8 %t7, ptr %p7, align 1 |
| store i8 %t1, ptr %p1, align 1 |
| store i8 %t6, ptr %p6, align 1 |
| store i8 %t2, ptr %p2, align 1 |
| store i8 %t4, ptr %p4, align 1 |
| ret void |
| } |
| |
| define void @be_i64_to_i8(i64 %x, ptr %p0) { |
| ; LE-LABEL: be_i64_to_i8: |
| ; LE: // %bb.0: |
| ; LE-NEXT: rev x8, x0 |
| ; LE-NEXT: str x8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i64_to_i8: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str x0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 8 |
| %sh2 = lshr i64 %x, 16 |
| %sh3 = lshr i64 %x, 24 |
| %sh4 = lshr i64 %x, 32 |
| %sh5 = lshr i64 %x, 40 |
| %sh6 = lshr i64 %x, 48 |
| %sh7 = lshr i64 %x, 56 |
| %t0 = trunc i64 %x to i8 |
| %t1 = trunc i64 %sh1 to i8 |
| %t2 = trunc i64 %sh2 to i8 |
| %t3 = trunc i64 %sh3 to i8 |
| %t4 = trunc i64 %sh4 to i8 |
| %t5 = trunc i64 %sh5 to i8 |
| %t6 = trunc i64 %sh6 to i8 |
| %t7 = trunc i64 %sh7 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| %p4 = getelementptr inbounds i8, ptr %p0, i64 4 |
| %p5 = getelementptr inbounds i8, ptr %p0, i64 5 |
| %p6 = getelementptr inbounds i8, ptr %p0, i64 6 |
| %p7 = getelementptr inbounds i8, ptr %p0, i64 7 |
| store i8 %t0, ptr %p7, align 1 |
| store i8 %t1, ptr %p6, align 1 |
| store i8 %t2, ptr %p5, align 1 |
| store i8 %t3, ptr %p4, align 1 |
| store i8 %t4, ptr %p3, align 1 |
| store i8 %t5, ptr %p2, align 1 |
| store i8 %t6, ptr %p1, align 1 |
| store i8 %t7, ptr %p0, align 1 |
| ret void |
| } |
| |
| define void @be_i64_to_i8_order(i64 %x, ptr %p0) { |
| ; LE-LABEL: be_i64_to_i8_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: rev x8, x0 |
| ; LE-NEXT: str x8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i64_to_i8_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str x0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 8 |
| %sh2 = lshr i64 %x, 16 |
| %sh3 = lshr i64 %x, 24 |
| %sh4 = lshr i64 %x, 32 |
| %sh5 = lshr i64 %x, 40 |
| %sh6 = lshr i64 %x, 48 |
| %sh7 = lshr i64 %x, 56 |
| %t0 = trunc i64 %x to i8 |
| %t1 = trunc i64 %sh1 to i8 |
| %t2 = trunc i64 %sh2 to i8 |
| %t3 = trunc i64 %sh3 to i8 |
| %t4 = trunc i64 %sh4 to i8 |
| %t5 = trunc i64 %sh5 to i8 |
| %t6 = trunc i64 %sh6 to i8 |
| %t7 = trunc i64 %sh7 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| %p4 = getelementptr inbounds i8, ptr %p0, i64 4 |
| %p5 = getelementptr inbounds i8, ptr %p0, i64 5 |
| %p6 = getelementptr inbounds i8, ptr %p0, i64 6 |
| %p7 = getelementptr inbounds i8, ptr %p0, i64 7 |
| store i8 %t7, ptr %p0, align 1 |
| store i8 %t6, ptr %p1, align 1 |
| store i8 %t5, ptr %p2, align 1 |
| store i8 %t4, ptr %p3, align 1 |
| store i8 %t3, ptr %p4, align 1 |
| store i8 %t2, ptr %p5, align 1 |
| store i8 %t1, ptr %p6, align 1 |
| store i8 %t0, ptr %p7, align 1 |
| ret void |
| } |
| |
| define void @le_i64_to_i16(i64 %x, ptr %p0) { |
| ; LE-LABEL: le_i64_to_i16: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str x0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i64_to_i16: |
| ; BE: // %bb.0: |
| ; BE-NEXT: lsr x8, x0, #16 |
| ; BE-NEXT: lsr x9, x0, #32 |
| ; BE-NEXT: lsr x10, x0, #48 |
| ; BE-NEXT: strh w0, [x1] |
| ; BE-NEXT: strh w8, [x1, #2] |
| ; BE-NEXT: strh w9, [x1, #4] |
| ; BE-NEXT: strh w10, [x1, #6] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 16 |
| %sh2 = lshr i64 %x, 32 |
| %sh3 = lshr i64 %x, 48 |
| %t0 = trunc i64 %x to i16 |
| %t1 = trunc i64 %sh1 to i16 |
| %t2 = trunc i64 %sh2 to i16 |
| %t3 = trunc i64 %sh3 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i16, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i16, ptr %p0, i64 3 |
| store i16 %t0, ptr %p0, align 2 |
| store i16 %t1, ptr %p1, align 2 |
| store i16 %t2, ptr %p2, align 2 |
| store i16 %t3, ptr %p3, align 2 |
| ret void |
| } |
| |
| define void @le_i64_to_i16_order(i64 %x, ptr %p0) { |
| ; LE-LABEL: le_i64_to_i16_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str x0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i64_to_i16_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: lsr x8, x0, #16 |
| ; BE-NEXT: lsr x9, x0, #48 |
| ; BE-NEXT: lsr x10, x0, #32 |
| ; BE-NEXT: strh w0, [x1] |
| ; BE-NEXT: strh w8, [x1, #2] |
| ; BE-NEXT: strh w9, [x1, #6] |
| ; BE-NEXT: strh w10, [x1, #4] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 16 |
| %sh2 = lshr i64 %x, 32 |
| %sh3 = lshr i64 %x, 48 |
| %t0 = trunc i64 %x to i16 |
| %t1 = trunc i64 %sh1 to i16 |
| %t2 = trunc i64 %sh2 to i16 |
| %t3 = trunc i64 %sh3 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i16, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i16, ptr %p0, i64 3 |
| store i16 %t1, ptr %p1, align 2 |
| store i16 %t3, ptr %p3, align 2 |
| store i16 %t0, ptr %p0, align 2 |
| store i16 %t2, ptr %p2, align 2 |
| ret void |
| } |
| |
| define void @be_i64_to_i16(i64 %x, ptr %p0) { |
| ; LE-LABEL: be_i64_to_i16: |
| ; LE: // %bb.0: |
| ; LE-NEXT: ror w8, w0, #16 |
| ; LE-NEXT: lsr x9, x0, #32 |
| ; LE-NEXT: lsr x10, x0, #48 |
| ; LE-NEXT: str w8, [x1, #4] |
| ; LE-NEXT: strh w9, [x1, #2] |
| ; LE-NEXT: strh w10, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i64_to_i16: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str x0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 16 |
| %sh2 = lshr i64 %x, 32 |
| %sh3 = lshr i64 %x, 48 |
| %t0 = trunc i64 %x to i16 |
| %t1 = trunc i64 %sh1 to i16 |
| %t2 = trunc i64 %sh2 to i16 |
| %t3 = trunc i64 %sh3 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i16, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i16, ptr %p0, i64 3 |
| store i16 %t0, ptr %p3, align 2 |
| store i16 %t1, ptr %p2, align 2 |
| store i16 %t2, ptr %p1, align 2 |
| store i16 %t3, ptr %p0, align 2 |
| ret void |
| } |
| |
| define void @be_i64_to_i16_order(i64 %x, ptr %p0) { |
| ; LE-LABEL: be_i64_to_i16_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: lsr x8, x0, #48 |
| ; LE-NEXT: lsr x9, x0, #32 |
| ; LE-NEXT: lsr x10, x0, #16 |
| ; LE-NEXT: strh w0, [x1, #6] |
| ; LE-NEXT: strh w8, [x1] |
| ; LE-NEXT: strh w9, [x1, #2] |
| ; LE-NEXT: strh w10, [x1, #4] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i64_to_i16_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str x0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 16 |
| %sh2 = lshr i64 %x, 32 |
| %sh3 = lshr i64 %x, 48 |
| %t0 = trunc i64 %x to i16 |
| %t1 = trunc i64 %sh1 to i16 |
| %t2 = trunc i64 %sh2 to i16 |
| %t3 = trunc i64 %sh3 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i16, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i16, ptr %p0, i64 3 |
| store i16 %t0, ptr %p3, align 2 |
| store i16 %t3, ptr %p0, align 2 |
| store i16 %t2, ptr %p1, align 2 |
| store i16 %t1, ptr %p2, align 2 |
| ret void |
| } |
| |
| define void @le_i64_to_i32(i64 %x, ptr %p0) { |
| ; LE-LABEL: le_i64_to_i32: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str x0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i64_to_i32: |
| ; BE: // %bb.0: |
| ; BE-NEXT: ror x8, x0, #32 |
| ; BE-NEXT: str x8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 32 |
| %t0 = trunc i64 %x to i32 |
| %t1 = trunc i64 %sh1 to i32 |
| %p1 = getelementptr inbounds i32, ptr %p0, i64 1 |
| store i32 %t0, ptr %p0, align 4 |
| store i32 %t1, ptr %p1, align 4 |
| ret void |
| } |
| |
| define void @le_i64_to_i32_order(i64 %x, ptr %p0) { |
| ; LE-LABEL: le_i64_to_i32_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: str x0, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: le_i64_to_i32_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: ror x8, x0, #32 |
| ; BE-NEXT: str x8, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 32 |
| %t0 = trunc i64 %x to i32 |
| %t1 = trunc i64 %sh1 to i32 |
| %p1 = getelementptr inbounds i32, ptr %p0, i64 1 |
| store i32 %t1, ptr %p1, align 4 |
| store i32 %t0, ptr %p0, align 4 |
| ret void |
| } |
| |
| define void @be_i64_to_i32(i64 %x, ptr %p0) { |
| ; LE-LABEL: be_i64_to_i32: |
| ; LE: // %bb.0: |
| ; LE-NEXT: ror x8, x0, #32 |
| ; LE-NEXT: str x8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i64_to_i32: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str x0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 32 |
| %t0 = trunc i64 %x to i32 |
| %t1 = trunc i64 %sh1 to i32 |
| %p1 = getelementptr inbounds i32, ptr %p0, i64 1 |
| store i32 %t0, ptr %p1, align 4 |
| store i32 %t1, ptr %p0, align 4 |
| ret void |
| } |
| |
| define void @be_i64_to_i32_order(i64 %x, ptr %p0) { |
| ; LE-LABEL: be_i64_to_i32_order: |
| ; LE: // %bb.0: |
| ; LE-NEXT: ror x8, x0, #32 |
| ; LE-NEXT: str x8, [x1] |
| ; LE-NEXT: ret |
| ; |
| ; BE-LABEL: be_i64_to_i32_order: |
| ; BE: // %bb.0: |
| ; BE-NEXT: str x0, [x1] |
| ; BE-NEXT: ret |
| %sh1 = lshr i64 %x, 32 |
| %t0 = trunc i64 %x to i32 |
| %t1 = trunc i64 %sh1 to i32 |
| %p1 = getelementptr inbounds i32, ptr %p0, i64 1 |
| store i32 %t1, ptr %p0, align 4 |
| store i32 %t0, ptr %p1, align 4 |
| ret void |
| } |
| |
| ; Negative test - not consecutive addresses |
| |
| define void @i64_to_i32_wrong_addr(i64 %x, ptr %p0) { |
| ; CHECK-LABEL: i64_to_i32_wrong_addr: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: lsr x8, x0, #32 |
| ; CHECK-NEXT: str w0, [x1] |
| ; CHECK-NEXT: str w8, [x1, #12] |
| ; CHECK-NEXT: ret |
| %sh1 = lshr i64 %x, 32 |
| %t0 = trunc i64 %x to i32 |
| %t1 = trunc i64 %sh1 to i32 |
| %p3 = getelementptr inbounds i32, ptr %p0, i64 3 |
| store i32 %t1, ptr %p3, align 4 |
| store i32 %t0, ptr %p0, align 4 |
| ret void |
| } |
| |
| ; Negative test - addresses don't line up with shift amounts |
| |
| define void @i64_to_i16_wrong_order(i64 %x, ptr %p0) { |
| ; CHECK-LABEL: i64_to_i16_wrong_order: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: lsr x8, x0, #48 |
| ; CHECK-NEXT: lsr x9, x0, #16 |
| ; CHECK-NEXT: lsr x10, x0, #32 |
| ; CHECK-NEXT: strh w0, [x1] |
| ; CHECK-NEXT: strh w8, [x1, #6] |
| ; CHECK-NEXT: strh w9, [x1, #4] |
| ; CHECK-NEXT: strh w10, [x1, #2] |
| ; CHECK-NEXT: ret |
| %sh1 = lshr i64 %x, 16 |
| %sh2 = lshr i64 %x, 32 |
| %sh3 = lshr i64 %x, 48 |
| %t0 = trunc i64 %x to i16 |
| %t1 = trunc i64 %sh1 to i16 |
| %t2 = trunc i64 %sh2 to i16 |
| %t3 = trunc i64 %sh3 to i16 |
| %p1 = getelementptr inbounds i16, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i16, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i16, ptr %p0, i64 3 |
| store i16 %t3, ptr %p3, align 2 |
| store i16 %t1, ptr %p2, align 2 |
| store i16 %t2, ptr %p1, align 2 |
| store i16 %t0, ptr %p0, align 2 |
| ret void |
| } |
| |
| ; Negative test - no store of 't1' |
| |
| define void @i32_to_i8_incomplete(i32 %x, ptr %p0) { |
| ; CHECK-LABEL: i32_to_i8_incomplete: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: lsr w8, w0, #16 |
| ; CHECK-NEXT: lsr w9, w0, #24 |
| ; CHECK-NEXT: strb w0, [x1] |
| ; CHECK-NEXT: strb w8, [x1, #2] |
| ; CHECK-NEXT: strb w9, [x1, #3] |
| ; CHECK-NEXT: ret |
| %sh1 = lshr i32 %x, 8 |
| %sh2 = lshr i32 %x, 16 |
| %sh3 = lshr i32 %x, 24 |
| %t0 = trunc i32 %x to i8 |
| %t1 = trunc i32 %sh1 to i8 |
| %t2 = trunc i32 %sh2 to i8 |
| %t3 = trunc i32 %sh3 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| store i8 %t0, ptr %p0, align 1 |
| store i8 %t2, ptr %p2, align 1 |
| store i8 %t3, ptr %p3, align 1 |
| ret void |
| } |
| |
| ; Negative test - no store of 't3' |
| |
| define void @i64_to_i8_incomplete(i64 %x, ptr %p0) { |
| ; CHECK-LABEL: i64_to_i8_incomplete: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: lsr x8, x0, #56 |
| ; CHECK-NEXT: lsr x9, x0, #48 |
| ; CHECK-NEXT: lsr x10, x0, #40 |
| ; CHECK-NEXT: strb w0, [x1, #7] |
| ; CHECK-NEXT: strb w8, [x1] |
| ; CHECK-NEXT: lsr x8, x0, #32 |
| ; CHECK-NEXT: strb w9, [x1, #1] |
| ; CHECK-NEXT: lsr x9, x0, #16 |
| ; CHECK-NEXT: strb w10, [x1, #2] |
| ; CHECK-NEXT: lsr x10, x0, #8 |
| ; CHECK-NEXT: strb w8, [x1, #3] |
| ; CHECK-NEXT: strb w9, [x1, #5] |
| ; CHECK-NEXT: strb w10, [x1, #6] |
| ; CHECK-NEXT: ret |
| %sh1 = lshr i64 %x, 8 |
| %sh2 = lshr i64 %x, 16 |
| %sh3 = lshr i64 %x, 24 |
| %sh4 = lshr i64 %x, 32 |
| %sh5 = lshr i64 %x, 40 |
| %sh6 = lshr i64 %x, 48 |
| %sh7 = lshr i64 %x, 56 |
| %t0 = trunc i64 %x to i8 |
| %t1 = trunc i64 %sh1 to i8 |
| %t2 = trunc i64 %sh2 to i8 |
| %t3 = trunc i64 %sh3 to i8 |
| %t4 = trunc i64 %sh4 to i8 |
| %t5 = trunc i64 %sh5 to i8 |
| %t6 = trunc i64 %sh6 to i8 |
| %t7 = trunc i64 %sh7 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| %p4 = getelementptr inbounds i8, ptr %p0, i64 4 |
| %p5 = getelementptr inbounds i8, ptr %p0, i64 5 |
| %p6 = getelementptr inbounds i8, ptr %p0, i64 6 |
| %p7 = getelementptr inbounds i8, ptr %p0, i64 7 |
| store i8 %t7, ptr %p0, align 1 |
| store i8 %t6, ptr %p1, align 1 |
| store i8 %t5, ptr %p2, align 1 |
| store i8 %t4, ptr %p3, align 1 |
| store i8 %t2, ptr %p5, align 1 |
| store i8 %t1, ptr %p6, align 1 |
| store i8 %t0, ptr %p7, align 1 |
| ret void |
| } |
| |
| ; Negative test - not consecutive addresses |
| |
| define void @i32_to_i16_wrong_addr(i32 %x, ptr %p0) { |
| ; CHECK-LABEL: i32_to_i16_wrong_addr: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: lsr w8, w0, #16 |
| ; CHECK-NEXT: strh w0, [x1] |
| ; CHECK-NEXT: strh w8, [x1, #4] |
| ; CHECK-NEXT: ret |
| %sh1 = lshr i32 %x, 16 |
| %t0 = trunc i32 %x to i16 |
| %t1 = trunc i32 %sh1 to i16 |
| %p2 = getelementptr inbounds i16, ptr %p0, i64 2 |
| store i16 %t1, ptr %p2, align 2 |
| store i16 %t0, ptr %p0, align 2 |
| ret void |
| } |
| |
| ; Negative test - addresses don't line up with shift amounts |
| |
| define void @i32_to_i8_wrong_order(i32 %x, ptr %p0) { |
| ; CHECK-LABEL: i32_to_i8_wrong_order: |
| ; CHECK: // %bb.0: |
| ; CHECK-NEXT: lsr w8, w0, #24 |
| ; CHECK-NEXT: lsr w9, w0, #16 |
| ; CHECK-NEXT: lsr w10, w0, #8 |
| ; CHECK-NEXT: strb w0, [x1, #3] |
| ; CHECK-NEXT: strb w8, [x1, #1] |
| ; CHECK-NEXT: strb w9, [x1] |
| ; CHECK-NEXT: strb w10, [x1, #2] |
| ; CHECK-NEXT: ret |
| %sh1 = lshr i32 %x, 8 |
| %sh2 = lshr i32 %x, 16 |
| %sh3 = lshr i32 %x, 24 |
| %t0 = trunc i32 %x to i8 |
| %t1 = trunc i32 %sh1 to i8 |
| %t2 = trunc i32 %sh2 to i8 |
| %t3 = trunc i32 %sh3 to i8 |
| %p1 = getelementptr inbounds i8, ptr %p0, i64 1 |
| %p2 = getelementptr inbounds i8, ptr %p0, i64 2 |
| %p3 = getelementptr inbounds i8, ptr %p0, i64 3 |
| store i8 %t3, ptr %p1, align 1 |
| store i8 %t2, ptr %p0, align 1 |
| store i8 %t0, ptr %p3, align 1 |
| store i8 %t1, ptr %p2, align 1 |
| ret void |
| } |