forked from OSchip/llvm-project
842 lines
23 KiB
LLVM
842 lines
23 KiB
LLVM
; 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, i8* %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, i8* %p0, i64 1
|
|
store i8 %t0, i8* %p0, align 1
|
|
store i8 %t1, i8* %p1, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @le_i16_to_i8_order(i16 %x, i8* %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, i8* %p0, i64 1
|
|
store i8 %t1, i8* %p1, align 1
|
|
store i8 %t0, i8* %p0, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @be_i16_to_i8_offset(i16 %x, i8* %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, i8* %p0, i64 11
|
|
%p12 = getelementptr inbounds i8, i8* %p0, i64 12
|
|
store i8 %t0, i8* %p12, align 1
|
|
store i8 %t1, i8* %p11, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @be_i16_to_i8_order(i16 %x, i8* %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, i8* %p0, i64 1
|
|
store i8 %t1, i8* %p0, align 1
|
|
store i8 %t0, i8* %p1, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @le_i32_to_i8(i32 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
store i8 %t0, i8* %p0, align 1
|
|
store i8 %t1, i8* %p1, align 1
|
|
store i8 %t2, i8* %p2, align 1
|
|
store i8 %t3, i8* %p3, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @le_i32_to_i8_order(i32 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
store i8 %t3, i8* %p3, align 1
|
|
store i8 %t1, i8* %p1, align 1
|
|
store i8 %t0, i8* %p0, align 1
|
|
store i8 %t2, i8* %p2, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @be_i32_to_i8(i32 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
store i8 %t0, i8* %p3, align 1
|
|
store i8 %t1, i8* %p2, align 1
|
|
store i8 %t2, i8* %p1, align 1
|
|
store i8 %t3, i8* %p0, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @be_i32_to_i8_order(i32 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
store i8 %t3, i8* %p0, align 1
|
|
store i8 %t2, i8* %p1, align 1
|
|
store i8 %t0, i8* %p3, align 1
|
|
store i8 %t1, i8* %p2, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @le_i32_to_i16(i32 %x, i16* %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, i16* %p0, i64 1
|
|
store i16 %t0, i16* %p0, align 2
|
|
store i16 %t1, i16* %p1, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @le_i32_to_i16_order(i32 %x, i16* %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, i16* %p0, i64 1
|
|
store i16 %t1, i16* %p1, align 2
|
|
store i16 %t0, i16* %p0, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @be_i32_to_i16(i32 %x, i16* %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, i16* %p0, i64 1
|
|
store i16 %t0, i16* %p1, align 2
|
|
store i16 %t1, i16* %p0, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @be_i32_to_i16_order(i32 %x, i16* %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, i16* %p0, i64 1
|
|
store i16 %t1, i16* %p0, align 2
|
|
store i16 %t0, i16* %p1, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @le_i64_to_i8(i64 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
%p4 = getelementptr inbounds i8, i8* %p0, i64 4
|
|
%p5 = getelementptr inbounds i8, i8* %p0, i64 5
|
|
%p6 = getelementptr inbounds i8, i8* %p0, i64 6
|
|
%p7 = getelementptr inbounds i8, i8* %p0, i64 7
|
|
store i8 %t0, i8* %p0, align 1
|
|
store i8 %t1, i8* %p1, align 1
|
|
store i8 %t2, i8* %p2, align 1
|
|
store i8 %t3, i8* %p3, align 1
|
|
store i8 %t4, i8* %p4, align 1
|
|
store i8 %t5, i8* %p5, align 1
|
|
store i8 %t6, i8* %p6, align 1
|
|
store i8 %t7, i8* %p7, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @le_i64_to_i8_order(i64 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
%p4 = getelementptr inbounds i8, i8* %p0, i64 4
|
|
%p5 = getelementptr inbounds i8, i8* %p0, i64 5
|
|
%p6 = getelementptr inbounds i8, i8* %p0, i64 6
|
|
%p7 = getelementptr inbounds i8, i8* %p0, i64 7
|
|
store i8 %t5, i8* %p5, align 1
|
|
store i8 %t0, i8* %p0, align 1
|
|
store i8 %t3, i8* %p3, align 1
|
|
store i8 %t7, i8* %p7, align 1
|
|
store i8 %t1, i8* %p1, align 1
|
|
store i8 %t6, i8* %p6, align 1
|
|
store i8 %t2, i8* %p2, align 1
|
|
store i8 %t4, i8* %p4, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @be_i64_to_i8(i64 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
%p4 = getelementptr inbounds i8, i8* %p0, i64 4
|
|
%p5 = getelementptr inbounds i8, i8* %p0, i64 5
|
|
%p6 = getelementptr inbounds i8, i8* %p0, i64 6
|
|
%p7 = getelementptr inbounds i8, i8* %p0, i64 7
|
|
store i8 %t0, i8* %p7, align 1
|
|
store i8 %t1, i8* %p6, align 1
|
|
store i8 %t2, i8* %p5, align 1
|
|
store i8 %t3, i8* %p4, align 1
|
|
store i8 %t4, i8* %p3, align 1
|
|
store i8 %t5, i8* %p2, align 1
|
|
store i8 %t6, i8* %p1, align 1
|
|
store i8 %t7, i8* %p0, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @be_i64_to_i8_order(i64 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
%p4 = getelementptr inbounds i8, i8* %p0, i64 4
|
|
%p5 = getelementptr inbounds i8, i8* %p0, i64 5
|
|
%p6 = getelementptr inbounds i8, i8* %p0, i64 6
|
|
%p7 = getelementptr inbounds i8, i8* %p0, i64 7
|
|
store i8 %t7, i8* %p0, align 1
|
|
store i8 %t6, i8* %p1, align 1
|
|
store i8 %t5, i8* %p2, align 1
|
|
store i8 %t4, i8* %p3, align 1
|
|
store i8 %t3, i8* %p4, align 1
|
|
store i8 %t2, i8* %p5, align 1
|
|
store i8 %t1, i8* %p6, align 1
|
|
store i8 %t0, i8* %p7, align 1
|
|
ret void
|
|
}
|
|
|
|
define void @le_i64_to_i16(i64 %x, i16* %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, i16* %p0, i64 1
|
|
%p2 = getelementptr inbounds i16, i16* %p0, i64 2
|
|
%p3 = getelementptr inbounds i16, i16* %p0, i64 3
|
|
store i16 %t0, i16* %p0, align 2
|
|
store i16 %t1, i16* %p1, align 2
|
|
store i16 %t2, i16* %p2, align 2
|
|
store i16 %t3, i16* %p3, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @le_i64_to_i16_order(i64 %x, i16* %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, #32
|
|
; BE-NEXT: lsr x10, x0, #48
|
|
; BE-NEXT: strh w0, [x1]
|
|
; BE-NEXT: strh w8, [x1, #2]
|
|
; BE-NEXT: strh w10, [x1, #6]
|
|
; BE-NEXT: strh w9, [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, i16* %p0, i64 1
|
|
%p2 = getelementptr inbounds i16, i16* %p0, i64 2
|
|
%p3 = getelementptr inbounds i16, i16* %p0, i64 3
|
|
store i16 %t1, i16* %p1, align 2
|
|
store i16 %t3, i16* %p3, align 2
|
|
store i16 %t0, i16* %p0, align 2
|
|
store i16 %t2, i16* %p2, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @be_i64_to_i16(i64 %x, i16* %p0) {
|
|
; LE-LABEL: be_i64_to_i16:
|
|
; LE: // %bb.0:
|
|
; LE-NEXT: lsr x8, x0, #32
|
|
; LE-NEXT: lsr x9, x0, #48
|
|
; LE-NEXT: ror w10, w0, #16
|
|
; LE-NEXT: str w10, [x1, #4]
|
|
; LE-NEXT: strh w8, [x1, #2]
|
|
; LE-NEXT: strh w9, [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, i16* %p0, i64 1
|
|
%p2 = getelementptr inbounds i16, i16* %p0, i64 2
|
|
%p3 = getelementptr inbounds i16, i16* %p0, i64 3
|
|
store i16 %t0, i16* %p3, align 2
|
|
store i16 %t1, i16* %p2, align 2
|
|
store i16 %t2, i16* %p1, align 2
|
|
store i16 %t3, i16* %p0, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @be_i64_to_i16_order(i64 %x, i16* %p0) {
|
|
; LE-LABEL: be_i64_to_i16_order:
|
|
; LE: // %bb.0:
|
|
; LE-NEXT: lsr x8, x0, #16
|
|
; LE-NEXT: lsr x9, x0, #32
|
|
; LE-NEXT: lsr x10, x0, #48
|
|
; LE-NEXT: strh w0, [x1, #6]
|
|
; LE-NEXT: strh w10, [x1]
|
|
; LE-NEXT: strh w9, [x1, #2]
|
|
; LE-NEXT: strh w8, [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, i16* %p0, i64 1
|
|
%p2 = getelementptr inbounds i16, i16* %p0, i64 2
|
|
%p3 = getelementptr inbounds i16, i16* %p0, i64 3
|
|
store i16 %t0, i16* %p3, align 2
|
|
store i16 %t3, i16* %p0, align 2
|
|
store i16 %t2, i16* %p1, align 2
|
|
store i16 %t1, i16* %p2, align 2
|
|
ret void
|
|
}
|
|
|
|
define void @le_i64_to_i32(i64 %x, i32* %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, i32* %p0, i64 1
|
|
store i32 %t0, i32* %p0, align 4
|
|
store i32 %t1, i32* %p1, align 4
|
|
ret void
|
|
}
|
|
|
|
define void @le_i64_to_i32_order(i64 %x, i32* %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, i32* %p0, i64 1
|
|
store i32 %t1, i32* %p1, align 4
|
|
store i32 %t0, i32* %p0, align 4
|
|
ret void
|
|
}
|
|
|
|
define void @be_i64_to_i32(i64 %x, i32* %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, i32* %p0, i64 1
|
|
store i32 %t0, i32* %p1, align 4
|
|
store i32 %t1, i32* %p0, align 4
|
|
ret void
|
|
}
|
|
|
|
define void @be_i64_to_i32_order(i64 %x, i32* %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, i32* %p0, i64 1
|
|
store i32 %t1, i32* %p0, align 4
|
|
store i32 %t0, i32* %p1, align 4
|
|
ret void
|
|
}
|
|
|
|
; Negative test - not consecutive addresses
|
|
|
|
define void @i64_to_i32_wrong_addr(i64 %x, i32* %p0) {
|
|
; CHECK-LABEL: i64_to_i32_wrong_addr:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: lsr x8, x0, #32
|
|
; CHECK-NEXT: str w8, [x1, #12]
|
|
; CHECK-NEXT: str w0, [x1]
|
|
; CHECK-NEXT: ret
|
|
%sh1 = lshr i64 %x, 32
|
|
%t0 = trunc i64 %x to i32
|
|
%t1 = trunc i64 %sh1 to i32
|
|
%p3 = getelementptr inbounds i32, i32* %p0, i64 3
|
|
store i32 %t1, i32* %p3, align 4
|
|
store i32 %t0, i32* %p0, align 4
|
|
ret void
|
|
}
|
|
|
|
; Negative test - addresses don't line up with shift amounts
|
|
|
|
define void @i64_to_i16_wrong_order(i64 %x, i16* %p0) {
|
|
; CHECK-LABEL: i64_to_i16_wrong_order:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: lsr x8, x0, #16
|
|
; CHECK-NEXT: lsr x9, x0, #32
|
|
; CHECK-NEXT: lsr x10, x0, #48
|
|
; CHECK-NEXT: strh w10, [x1, #6]
|
|
; CHECK-NEXT: strh w8, [x1, #4]
|
|
; CHECK-NEXT: strh w9, [x1, #2]
|
|
; CHECK-NEXT: strh w0, [x1]
|
|
; 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, i16* %p0, i64 1
|
|
%p2 = getelementptr inbounds i16, i16* %p0, i64 2
|
|
%p3 = getelementptr inbounds i16, i16* %p0, i64 3
|
|
store i16 %t3, i16* %p3, align 2
|
|
store i16 %t1, i16* %p2, align 2
|
|
store i16 %t2, i16* %p1, align 2
|
|
store i16 %t0, i16* %p0, align 2
|
|
ret void
|
|
}
|
|
|
|
; Negative test - no store of 't1'
|
|
|
|
define void @i32_to_i8_incomplete(i32 %x, i8* %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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
store i8 %t0, i8* %p0, align 1
|
|
store i8 %t2, i8* %p2, align 1
|
|
store i8 %t3, i8* %p3, align 1
|
|
ret void
|
|
}
|
|
|
|
; Negative test - no store of 't3'
|
|
|
|
define void @i64_to_i8_incomplete(i64 %x, i8* %p0) {
|
|
; CHECK-LABEL: i64_to_i8_incomplete:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: lsr x8, x0, #8
|
|
; CHECK-NEXT: lsr x9, x0, #16
|
|
; CHECK-NEXT: lsr x10, x0, #32
|
|
; CHECK-NEXT: lsr x11, x0, #40
|
|
; CHECK-NEXT: lsr x12, x0, #48
|
|
; CHECK-NEXT: lsr x13, x0, #56
|
|
; CHECK-NEXT: strb w13, [x1]
|
|
; CHECK-NEXT: strb w12, [x1, #1]
|
|
; CHECK-NEXT: strb w11, [x1, #2]
|
|
; CHECK-NEXT: strb w10, [x1, #3]
|
|
; CHECK-NEXT: strb w9, [x1, #5]
|
|
; CHECK-NEXT: strb w8, [x1, #6]
|
|
; CHECK-NEXT: strb w0, [x1, #7]
|
|
; 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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
%p4 = getelementptr inbounds i8, i8* %p0, i64 4
|
|
%p5 = getelementptr inbounds i8, i8* %p0, i64 5
|
|
%p6 = getelementptr inbounds i8, i8* %p0, i64 6
|
|
%p7 = getelementptr inbounds i8, i8* %p0, i64 7
|
|
store i8 %t7, i8* %p0, align 1
|
|
store i8 %t6, i8* %p1, align 1
|
|
store i8 %t5, i8* %p2, align 1
|
|
store i8 %t4, i8* %p3, align 1
|
|
store i8 %t2, i8* %p5, align 1
|
|
store i8 %t1, i8* %p6, align 1
|
|
store i8 %t0, i8* %p7, align 1
|
|
ret void
|
|
}
|
|
|
|
; Negative test - not consecutive addresses
|
|
|
|
define void @i32_to_i16_wrong_addr(i32 %x, i16* %p0) {
|
|
; CHECK-LABEL: i32_to_i16_wrong_addr:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: lsr w8, w0, #16
|
|
; CHECK-NEXT: strh w8, [x1, #4]
|
|
; CHECK-NEXT: strh w0, [x1]
|
|
; CHECK-NEXT: ret
|
|
%sh1 = lshr i32 %x, 16
|
|
%t0 = trunc i32 %x to i16
|
|
%t1 = trunc i32 %sh1 to i16
|
|
%p2 = getelementptr inbounds i16, i16* %p0, i64 2
|
|
store i16 %t1, i16* %p2, align 2
|
|
store i16 %t0, i16* %p0, align 2
|
|
ret void
|
|
}
|
|
|
|
; Negative test - addresses don't line up with shift amounts
|
|
|
|
define void @i32_to_i8_wrong_order(i32 %x, i8* %p0) {
|
|
; CHECK-LABEL: i32_to_i8_wrong_order:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: lsr w8, w0, #8
|
|
; CHECK-NEXT: lsr w9, w0, #16
|
|
; CHECK-NEXT: lsr w10, w0, #24
|
|
; CHECK-NEXT: strb w0, [x1, #3]
|
|
; CHECK-NEXT: strb w10, [x1, #1]
|
|
; CHECK-NEXT: strb w9, [x1]
|
|
; CHECK-NEXT: strb w8, [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, i8* %p0, i64 1
|
|
%p2 = getelementptr inbounds i8, i8* %p0, i64 2
|
|
%p3 = getelementptr inbounds i8, i8* %p0, i64 3
|
|
store i8 %t3, i8* %p1, align 1
|
|
store i8 %t2, i8* %p0, align 1
|
|
store i8 %t0, i8* %p3, align 1
|
|
store i8 %t1, i8* %p2, align 1
|
|
ret void
|
|
}
|