mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-28 22:00:30 +00:00
[ARM] Added testing for D64160. NFC
Adds some extra vsel testing and regenerates long shift and saturation bitop tests. llvm-svn: 365116
This commit is contained in:
parent
0e835405fd
commit
5349edee0f
@ -1,69 +1,102 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE
|
||||
; RUN: llc -mtriple=armeb-eabi %s -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE
|
||||
|
||||
define i64 @f0(i64 %A, i64 %B) {
|
||||
; CHECK-LABEL: f0:
|
||||
; CHECK-LE: lsrs r3, r3, #1
|
||||
; CHECK-LE-NEXT: rrx r2, r2
|
||||
; CHECK-LE-NEXT: subs r0, r0, r2
|
||||
; CHECK-LE-NEXT: sbc r1, r1, r3
|
||||
; CHECK-BE: lsrs r2, r2, #1
|
||||
; CHECK-BE-NEXT: rrx r3, r3
|
||||
; CHECK-BE-NEXT: subs r1, r1, r3
|
||||
; CHECK-BE-NEXT: sbc r0, r0, r2
|
||||
%tmp = bitcast i64 %A to i64
|
||||
%tmp2 = lshr i64 %B, 1
|
||||
%tmp3 = sub i64 %tmp, %tmp2
|
||||
ret i64 %tmp3
|
||||
; CHECK-LE-LABEL: f0:
|
||||
; CHECK-LE: @ %bb.0:
|
||||
; CHECK-LE-NEXT: lsrs r3, r3, #1
|
||||
; CHECK-LE-NEXT: rrx r2, r2
|
||||
; CHECK-LE-NEXT: subs r0, r0, r2
|
||||
; CHECK-LE-NEXT: sbc r1, r1, r3
|
||||
; CHECK-LE-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-BE-LABEL: f0:
|
||||
; CHECK-BE: @ %bb.0:
|
||||
; CHECK-BE-NEXT: lsrs r2, r2, #1
|
||||
; CHECK-BE-NEXT: rrx r3, r3
|
||||
; CHECK-BE-NEXT: subs r1, r1, r3
|
||||
; CHECK-BE-NEXT: sbc r0, r0, r2
|
||||
; CHECK-BE-NEXT: mov pc, lr
|
||||
|
||||
%tmp = bitcast i64 %A to i64
|
||||
%tmp2 = lshr i64 %B, 1
|
||||
%tmp3 = sub i64 %tmp, %tmp2
|
||||
ret i64 %tmp3
|
||||
}
|
||||
|
||||
define i32 @f1(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: f1:
|
||||
; CHECK-LE: lsl{{.*}}r2
|
||||
; CHECK-BE: lsl{{.*}}r3
|
||||
%a = shl i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
; CHECK-LE-LABEL: f1:
|
||||
; CHECK-LE: @ %bb.0:
|
||||
; CHECK-LE-NEXT: sub r1, r2, #32
|
||||
; CHECK-LE-NEXT: lsl r0, r0, r2
|
||||
; CHECK-LE-NEXT: cmp r1, #0
|
||||
; CHECK-LE-NEXT: movge r0, #0
|
||||
; CHECK-LE-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-BE-LABEL: f1:
|
||||
; CHECK-BE: @ %bb.0:
|
||||
; CHECK-BE-NEXT: lsl r0, r1, r3
|
||||
; CHECK-BE-NEXT: sub r1, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r1, #0
|
||||
; CHECK-BE-NEXT: movge r0, #0
|
||||
; CHECK-BE-NEXT: mov pc, lr
|
||||
|
||||
%a = shl i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
define i32 @f2(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: f2:
|
||||
; CHECK-LE: rsb r3, r2, #32
|
||||
; CHECK-LE-NEXT: lsr{{.*}}r2
|
||||
; CHECK-LE-NEXT: sub r2, r2, #32
|
||||
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-LE-NEXT: cmp r2, #0
|
||||
; CHECK-LE-NEXT: asrge r0, r1, r2
|
||||
; CHECK-LE-LABEL: f2:
|
||||
; CHECK-LE: @ %bb.0:
|
||||
; CHECK-LE-NEXT: rsb r3, r2, #32
|
||||
; CHECK-LE-NEXT: lsr r0, r0, r2
|
||||
; CHECK-LE-NEXT: sub r2, r2, #32
|
||||
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-LE-NEXT: cmp r2, #0
|
||||
; CHECK-LE-NEXT: asrge r0, r1, r2
|
||||
; CHECK-LE-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-BE-LABEL: f2:
|
||||
; CHECK-BE: @ %bb.0:
|
||||
; CHECK-BE-NEXT: rsb r2, r3, #32
|
||||
; CHECK-BE-NEXT: lsr r1, r1, r3
|
||||
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
|
||||
; CHECK-BE-NEXT: sub r2, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r2, #0
|
||||
; CHECK-BE-NEXT: asrge r1, r0, r2
|
||||
; CHECK-BE-NEXT: mov r0, r1
|
||||
; CHECK-BE-NEXT: mov pc, lr
|
||||
|
||||
; CHECK-BE: rsb r2, r3, #32
|
||||
; CHECK-BE-NEXT: lsr{{.*}}r3
|
||||
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
|
||||
; CHECK-BE-NEXT: sub r2, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r2, #0
|
||||
; CHECK-BE-NEXT: asrge r1, r0, r2
|
||||
|
||||
%a = ashr i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
%a = ashr i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
define i32 @f3(i64 %x, i64 %y) {
|
||||
; CHECK-LABEL: f3:
|
||||
; CHECK-LE: rsb r3, r2, #32
|
||||
; CHECK-LE-NEXT: lsr{{.*}}r2
|
||||
; CHECK-LE-NEXT: sub r2, r2, #32
|
||||
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-LE-NEXT: cmp r2, #0
|
||||
; CHECK-LE-NEXT: lsrge r0, r1, r2
|
||||
; CHECK-LE-LABEL: f3:
|
||||
; CHECK-LE: @ %bb.0:
|
||||
; CHECK-LE-NEXT: rsb r3, r2, #32
|
||||
; CHECK-LE-NEXT: lsr r0, r0, r2
|
||||
; CHECK-LE-NEXT: sub r2, r2, #32
|
||||
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-LE-NEXT: cmp r2, #0
|
||||
; CHECK-LE-NEXT: lsrge r0, r1, r2
|
||||
; CHECK-LE-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-BE-LABEL: f3:
|
||||
; CHECK-BE: @ %bb.0:
|
||||
; CHECK-BE-NEXT: rsb r2, r3, #32
|
||||
; CHECK-BE-NEXT: lsr r1, r1, r3
|
||||
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
|
||||
; CHECK-BE-NEXT: sub r2, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r2, #0
|
||||
; CHECK-BE-NEXT: lsrge r1, r0, r2
|
||||
; CHECK-BE-NEXT: mov r0, r1
|
||||
; CHECK-BE-NEXT: mov pc, lr
|
||||
|
||||
; CHECK-BE: rsb r2, r3, #32
|
||||
; CHECK-BE-NEXT: lsr{{.*}}r3
|
||||
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
|
||||
; CHECK-BE-NEXT: sub r2, r3, #32
|
||||
; CHECK-BE-NEXT: cmp r2, #0
|
||||
; CHECK-BE-NEXT: lsrge r1, r0, r2
|
||||
|
||||
%a = lshr i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
%a = lshr i64 %x, %y
|
||||
%b = trunc i64 %a to i32
|
||||
ret i32 %b
|
||||
}
|
||||
|
@ -1,22 +1,30 @@
|
||||
; RUN: llc -mtriple=arm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM --check-prefix=CHECK-CMP
|
||||
; RUN: llc -mtriple=thumb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T --check-prefix=CHECK-CMP
|
||||
; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T2 --check-prefix=CHECK-CMP
|
||||
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=arm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM
|
||||
; RUN: llc -mtriple=thumb-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T
|
||||
; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T2
|
||||
|
||||
; Check for clipping against 0 that should result in bic
|
||||
;
|
||||
; Base tests with different bit widths
|
||||
;
|
||||
|
||||
; x < 0 ? 0 : x
|
||||
; 32-bit base test
|
||||
define i32 @sat0_base_32bit(i32 %x) #0 {
|
||||
; CHECK-LABEL: sat0_base_32bit:
|
||||
; CHECK-CMP-NOT: cmp
|
||||
; CHECK-ARM: bic {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T2: bic.w {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T: asrs [[IM:r[0-9]]], {{r[0-9]}}, #31
|
||||
; CHECK-T-NEXT: bics {{r[0-9]}}, [[IM]]
|
||||
; CHECK-ARM-LABEL: sat0_base_32bit:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: bic r0, r0, r0, asr #31
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat0_base_32bit:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: asrs r1, r0, #31
|
||||
; CHECK-T-NEXT: bics r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat0_base_32bit:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: bic.w r0, r0, r0, asr #31
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i32 %x, 0
|
||||
%saturateLow = select i1 %cmpLow, i32 0, i32 %x
|
||||
@ -26,11 +34,32 @@ entry:
|
||||
; x < 0 ? 0 : x
|
||||
; 16-bit base test
|
||||
define i16 @sat0_base_16bit(i16 %x) #0 {
|
||||
; CHECK-LABEL: sat0_base_16bit:
|
||||
; CHECK-CMP: cmp
|
||||
; CHECK-ARM-NOT: bic
|
||||
; CHECK-T2-NOT: bic.w
|
||||
; CHECK-T-NOT: bics
|
||||
; CHECK-ARM-LABEL: sat0_base_16bit:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: lsl r1, r0, #16
|
||||
; CHECK-ARM-NEXT: asr r1, r1, #16
|
||||
; CHECK-ARM-NEXT: cmp r1, #0
|
||||
; CHECK-ARM-NEXT: movlt r0, #0
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat0_base_16bit:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: lsls r1, r0, #16
|
||||
; CHECK-T-NEXT: asrs r1, r1, #16
|
||||
; CHECK-T-NEXT: cmp r1, #0
|
||||
; CHECK-T-NEXT: bge .LBB1_2
|
||||
; CHECK-T-NEXT: @ %bb.1:
|
||||
; CHECK-T-NEXT: movs r0, #0
|
||||
; CHECK-T-NEXT: .LBB1_2: @ %entry
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat0_base_16bit:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: sxth r1, r0
|
||||
; CHECK-T2-NEXT: cmp r1, #0
|
||||
; CHECK-T2-NEXT: it lt
|
||||
; CHECK-T2-NEXT: movlt r0, #0
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i16 %x, 0
|
||||
%saturateLow = select i1 %cmpLow, i16 0, i16 %x
|
||||
@ -40,10 +69,32 @@ entry:
|
||||
; x < 0 ? 0 : x
|
||||
; 8-bit base test
|
||||
define i8 @sat0_base_8bit(i8 %x) #0 {
|
||||
; CHECK-LABEL: sat0_base_8bit:
|
||||
; CHECK-CMP: cmp
|
||||
; CHECK-ARM-NOT: bic
|
||||
; CHECK-T2-NOT: bic.w
|
||||
; CHECK-ARM-LABEL: sat0_base_8bit:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: lsl r1, r0, #24
|
||||
; CHECK-ARM-NEXT: asr r1, r1, #24
|
||||
; CHECK-ARM-NEXT: cmp r1, #0
|
||||
; CHECK-ARM-NEXT: movlt r0, #0
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat0_base_8bit:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: lsls r1, r0, #24
|
||||
; CHECK-T-NEXT: asrs r1, r1, #24
|
||||
; CHECK-T-NEXT: cmp r1, #0
|
||||
; CHECK-T-NEXT: bge .LBB2_2
|
||||
; CHECK-T-NEXT: @ %bb.1:
|
||||
; CHECK-T-NEXT: movs r0, #0
|
||||
; CHECK-T-NEXT: .LBB2_2: @ %entry
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat0_base_8bit:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: sxtb r1, r0
|
||||
; CHECK-T2-NEXT: cmp r1, #0
|
||||
; CHECK-T2-NEXT: it lt
|
||||
; CHECK-T2-NEXT: movlt r0, #0
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i8 %x, 0
|
||||
%saturateLow = select i1 %cmpLow, i8 0, i8 %x
|
||||
@ -54,12 +105,21 @@ entry:
|
||||
|
||||
; x > 0 ? x : 0
|
||||
define i32 @sat0_lower_1(i32 %x) #0 {
|
||||
; CHECK-LABEL: sat0_lower_1:
|
||||
; CHECK-CMP-NOT: cmp
|
||||
; CHECK-ARM: bic {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T2: bic.w {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T: asrs [[IM:r[0-9]]], {{r[0-9]}}, #31
|
||||
; CHECK-T-NEXT: bics {{r[0-9]}}, [[IM]]
|
||||
; CHECK-ARM-LABEL: sat0_lower_1:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: bic r0, r0, r0, asr #31
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat0_lower_1:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: asrs r1, r0, #31
|
||||
; CHECK-T-NEXT: bics r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat0_lower_1:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: bic.w r0, r0, r0, asr #31
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpGt = icmp sgt i32 %x, 0
|
||||
%saturateLow = select i1 %cmpGt, i32 %x, i32 0
|
||||
@ -75,12 +135,21 @@ entry:
|
||||
; x < -1 ? -1 : x
|
||||
; 32-bit base test
|
||||
define i32 @sat1_base_32bit(i32 %x) #0 {
|
||||
; CHECK-LABEL: sat1_base_32bit:
|
||||
; CHECK-CMP-NOT: cmp
|
||||
; CHECK-ARM: orr {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T2: orr.w {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T: asrs [[IM:r[0-9]]], {{r[0-9]}}, #31
|
||||
; CHECK-T-NEXT: orrs {{r[0-9]}}, [[IM]]
|
||||
; CHECK-ARM-LABEL: sat1_base_32bit:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: orr r0, r0, r0, asr #31
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat1_base_32bit:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: asrs r1, r0, #31
|
||||
; CHECK-T-NEXT: orrs r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat1_base_32bit:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: orr.w r0, r0, r0, asr #31
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i32 %x, -1
|
||||
%saturateLow = select i1 %cmpLow, i32 -1, i32 %x
|
||||
@ -90,10 +159,35 @@ entry:
|
||||
; x < -1 ? -1 : x
|
||||
; 16-bit base test
|
||||
define i16 @sat1_base_16bit(i16 %x) #0 {
|
||||
; CHECK-LABEL: sat1_base_16bit:
|
||||
; CHECK-ARM: cmn
|
||||
; CHECK-T2: cmp
|
||||
; CHECK-T: cmp
|
||||
; CHECK-ARM-LABEL: sat1_base_16bit:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: lsl r1, r0, #16
|
||||
; CHECK-ARM-NEXT: asr r1, r1, #16
|
||||
; CHECK-ARM-NEXT: cmn r1, #1
|
||||
; CHECK-ARM-NEXT: mvnlt r0, #0
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat1_base_16bit:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: movs r1, #0
|
||||
; CHECK-T-NEXT: mvns r1, r1
|
||||
; CHECK-T-NEXT: lsls r2, r0, #16
|
||||
; CHECK-T-NEXT: asrs r2, r2, #16
|
||||
; CHECK-T-NEXT: cmp r2, r1
|
||||
; CHECK-T-NEXT: blt .LBB5_2
|
||||
; CHECK-T-NEXT: @ %bb.1: @ %entry
|
||||
; CHECK-T-NEXT: movs r1, r0
|
||||
; CHECK-T-NEXT: .LBB5_2: @ %entry
|
||||
; CHECK-T-NEXT: movs r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat1_base_16bit:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: sxth r1, r0
|
||||
; CHECK-T2-NEXT: cmp.w r1, #-1
|
||||
; CHECK-T2-NEXT: it lt
|
||||
; CHECK-T2-NEXT: movlt.w r0, #-1
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i16 %x, -1
|
||||
%saturateLow = select i1 %cmpLow, i16 -1, i16 %x
|
||||
@ -103,10 +197,35 @@ entry:
|
||||
; x < -1 ? -1 : x
|
||||
; 8-bit base test
|
||||
define i8 @sat1_base_8bit(i8 %x) #0 {
|
||||
; CHECK-LABEL: sat1_base_8bit:
|
||||
; CHECK-ARM: cmn
|
||||
; CHECK-T2: cmp
|
||||
; CHECK-T: cmp
|
||||
; CHECK-ARM-LABEL: sat1_base_8bit:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: lsl r1, r0, #24
|
||||
; CHECK-ARM-NEXT: asr r1, r1, #24
|
||||
; CHECK-ARM-NEXT: cmn r1, #1
|
||||
; CHECK-ARM-NEXT: mvnlt r0, #0
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat1_base_8bit:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: movs r1, #0
|
||||
; CHECK-T-NEXT: mvns r1, r1
|
||||
; CHECK-T-NEXT: lsls r2, r0, #24
|
||||
; CHECK-T-NEXT: asrs r2, r2, #24
|
||||
; CHECK-T-NEXT: cmp r2, r1
|
||||
; CHECK-T-NEXT: blt .LBB6_2
|
||||
; CHECK-T-NEXT: @ %bb.1: @ %entry
|
||||
; CHECK-T-NEXT: movs r1, r0
|
||||
; CHECK-T-NEXT: .LBB6_2: @ %entry
|
||||
; CHECK-T-NEXT: movs r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat1_base_8bit:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: sxtb r1, r0
|
||||
; CHECK-T2-NEXT: cmp.w r1, #-1
|
||||
; CHECK-T2-NEXT: it lt
|
||||
; CHECK-T2-NEXT: movlt.w r0, #-1
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i8 %x, -1
|
||||
%saturateLow = select i1 %cmpLow, i8 -1, i8 %x
|
||||
@ -117,12 +236,21 @@ entry:
|
||||
|
||||
; x > -1 ? x : -1
|
||||
define i32 @sat1_lower_1(i32 %x) #0 {
|
||||
; CHECK-LABEL: sat1_lower_1:
|
||||
; CHECK-ARM: orr {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T2: orr.w {{r[0-9]}}, [[INPUT:r[0-9]]], [[INPUT]], asr #31
|
||||
; CHECK-T: asrs [[IM:r[0-9]]], {{r[0-9]}}, #31
|
||||
; CHECK-T-NEXT: orrs {{r[0-9]}}, [[IM]]
|
||||
; CHECK-CMP-NOT: cmp
|
||||
; CHECK-ARM-LABEL: sat1_lower_1:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: orr r0, r0, r0, asr #31
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: sat1_lower_1:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: asrs r1, r0, #31
|
||||
; CHECK-T-NEXT: orrs r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: sat1_lower_1:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: orr.w r0, r0, r0, asr #31
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpGt = icmp sgt i32 %x, -1
|
||||
%saturateLow = select i1 %cmpGt, i32 %x, i32 -1
|
||||
@ -134,10 +262,30 @@ entry:
|
||||
|
||||
; x < 0 ? 0 : y where x and y does not properly match
|
||||
define i32 @no_sat0_incorrect_variable(i32 %x, i32 %y) #0 {
|
||||
; CHECK-LABEL: no_sat0_incorrect_variable:
|
||||
; CHECK-NOT: bic
|
||||
; CHECK-NOT: asrs
|
||||
; CHECK-CMP: cmp
|
||||
; CHECK-ARM-LABEL: no_sat0_incorrect_variable:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: cmp r0, #0
|
||||
; CHECK-ARM-NEXT: movlt r1, #0
|
||||
; CHECK-ARM-NEXT: mov r0, r1
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: no_sat0_incorrect_variable:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: cmp r0, #0
|
||||
; CHECK-T-NEXT: bge .LBB8_2
|
||||
; CHECK-T-NEXT: @ %bb.1:
|
||||
; CHECK-T-NEXT: movs r1, #0
|
||||
; CHECK-T-NEXT: .LBB8_2: @ %entry
|
||||
; CHECK-T-NEXT: movs r0, r1
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: no_sat0_incorrect_variable:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: cmp r0, #0
|
||||
; CHECK-T2-NEXT: it lt
|
||||
; CHECK-T2-NEXT: movlt r1, #0
|
||||
; CHECK-T2-NEXT: mov r0, r1
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i32 %x, 0
|
||||
%saturateLow = select i1 %cmpLow, i32 0, i32 %y
|
||||
@ -145,11 +293,29 @@ entry:
|
||||
}
|
||||
|
||||
; x < 0 ? -1 : x
|
||||
define i32 @no_sat0_incorrect_constant(i32 %x) #0 {
|
||||
; CHECK-LABEL: no_sat0_incorrect_constant:
|
||||
; CHECK-NOT: bic
|
||||
; CHECK-NOT: asrs
|
||||
; CHECK-CMP: cmp
|
||||
define i32 @no_sat0_incorrect_constant(i32 %x) {
|
||||
; CHECK-ARM-LABEL: no_sat0_incorrect_constant:
|
||||
; CHECK-ARM: @ %bb.0: @ %entry
|
||||
; CHECK-ARM-NEXT: cmp r0, #0
|
||||
; CHECK-ARM-NEXT: mvnlt r0, #0
|
||||
; CHECK-ARM-NEXT: mov pc, lr
|
||||
;
|
||||
; CHECK-T-LABEL: no_sat0_incorrect_constant:
|
||||
; CHECK-T: @ %bb.0: @ %entry
|
||||
; CHECK-T-NEXT: cmp r0, #0
|
||||
; CHECK-T-NEXT: bge .LBB9_2
|
||||
; CHECK-T-NEXT: @ %bb.1:
|
||||
; CHECK-T-NEXT: movs r0, #0
|
||||
; CHECK-T-NEXT: mvns r0, r0
|
||||
; CHECK-T-NEXT: .LBB9_2: @ %entry
|
||||
; CHECK-T-NEXT: bx lr
|
||||
;
|
||||
; CHECK-T2-LABEL: no_sat0_incorrect_constant:
|
||||
; CHECK-T2: @ %bb.0: @ %entry
|
||||
; CHECK-T2-NEXT: cmp r0, #0
|
||||
; CHECK-T2-NEXT: it lt
|
||||
; CHECK-T2-NEXT: movlt.w r0, #-1
|
||||
; CHECK-T2-NEXT: bx lr
|
||||
entry:
|
||||
%cmpLow = icmp slt i32 %x, 0
|
||||
%saturateLow = select i1 %cmpLow, i32 -1, i32 %x
|
||||
|
@ -1,32 +1,26 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=armv6m-eabi %s -o - | FileCheck %s --check-prefix=EXPAND
|
||||
|
||||
define i64 @test_shl(i64 %val, i64 %amt) {
|
||||
; CHECK-LABEL: test_shl:
|
||||
; CHECK: @ %bb.0:
|
||||
; CHECK-NEXT: rsb r3, r2, #32
|
||||
; CHECK-NEXT: lsr r3, r0, r3
|
||||
; CHECK-NEXT: orr r1, r3, r1, lsl r2
|
||||
; CHECK-NEXT: sub r3, r2, #32
|
||||
; CHECK-NEXT: cmp r3, #0
|
||||
; CHECK-NEXT: lslge r1, r0, r3
|
||||
; CHECK-NEXT: lsl r0, r0, r2
|
||||
; CHECK-NEXT: movge r0, #0
|
||||
; CHECK-NEXT: mov pc, lr
|
||||
;
|
||||
; EXPAND-LABEL: test_shl:
|
||||
; First calculate the hi part when the shift amount is small enough that it
|
||||
; contains components from both halves. It'll be returned in r1 so that's a
|
||||
; reasonable place for it to end up.
|
||||
; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
|
||||
; CHECK: lsr [[TMP:.*]], r0, [[REVERSE_SHIFT]]
|
||||
; CHECK: orr r1, [[TMP]], r1, lsl r2
|
||||
|
||||
; Check whether the shift was in fact small (< 32 bits).
|
||||
; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
|
||||
; CHECK: cmp [[EXTRA_SHIFT]], #0
|
||||
|
||||
; If not, the high part of the answer is just the low part shifted by the
|
||||
; excess.
|
||||
; CHECK: lslge r1, r0, [[EXTRA_SHIFT]]
|
||||
|
||||
; The low part is either a direct shift (1st inst) or 0. We can reuse the same
|
||||
; NZCV.
|
||||
; CHECK: lsl r0, r0, r2
|
||||
; CHECK: movge r0, #0
|
||||
|
||||
; EXPAND: push {[[REG:r[0-9]+]], lr}
|
||||
; EXPAND-NEXT: bl __aeabi_llsl
|
||||
; EXPAND-NEXT: pop {[[REG]], pc}
|
||||
; EXPAND: @ %bb.0:
|
||||
; EXPAND-NEXT: .save {r7, lr}
|
||||
; EXPAND-NEXT: push {r7, lr}
|
||||
; EXPAND-NEXT: bl __aeabi_llsl
|
||||
; EXPAND-NEXT: pop {r7, pc}
|
||||
%res = shl i64 %val, %amt
|
||||
ret i64 %res
|
||||
}
|
||||
@ -34,19 +28,23 @@ define i64 @test_shl(i64 %val, i64 %amt) {
|
||||
; Explanation for lshr is pretty much the reverse of shl.
|
||||
define i64 @test_lshr(i64 %val, i64 %amt) {
|
||||
; CHECK-LABEL: test_lshr:
|
||||
; CHECK: @ %bb.0:
|
||||
; CHECK-NEXT: rsb r3, r2, #32
|
||||
; CHECK-NEXT: lsr r0, r0, r2
|
||||
; CHECK-NEXT: orr r0, r0, r1, lsl r3
|
||||
; CHECK-NEXT: sub r3, r2, #32
|
||||
; CHECK-NEXT: cmp r3, #0
|
||||
; CHECK-NEXT: lsrge r0, r1, r3
|
||||
; CHECK-NEXT: lsr r1, r1, r2
|
||||
; CHECK-NEXT: movge r1, #0
|
||||
; CHECK-NEXT: mov pc, lr
|
||||
;
|
||||
; EXPAND-LABEL: test_lshr:
|
||||
; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
|
||||
; CHECK: lsr r0, r0, r2
|
||||
; CHECK: orr r0, r0, r1, lsl [[REVERSE_SHIFT]]
|
||||
; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
|
||||
; CHECK: cmp [[EXTRA_SHIFT]], #0
|
||||
; CHECK: lsrge r0, r1, [[EXTRA_SHIFT]]
|
||||
; CHECK: lsr r1, r1, r2
|
||||
; CHECK: movge r1, #0
|
||||
|
||||
; EXPAND: push {[[REG:r[0-9]+]], lr}
|
||||
; EXPAND-NEXT: bl __aeabi_llsr
|
||||
; EXPAND-NEXT: pop {[[REG]], pc}
|
||||
; EXPAND: @ %bb.0:
|
||||
; EXPAND-NEXT: .save {r7, lr}
|
||||
; EXPAND-NEXT: push {r7, lr}
|
||||
; EXPAND-NEXT: bl __aeabi_llsr
|
||||
; EXPAND-NEXT: pop {r7, pc}
|
||||
%res = lshr i64 %val, %amt
|
||||
ret i64 %res
|
||||
}
|
||||
@ -55,20 +53,24 @@ define i64 @test_lshr(i64 %val, i64 %amt) {
|
||||
; amount is large to get the right sign bit.
|
||||
define i64 @test_ashr(i64 %val, i64 %amt) {
|
||||
; CHECK-LABEL: test_ashr:
|
||||
; CHECK: @ %bb.0:
|
||||
; CHECK-NEXT: sub r12, r2, #32
|
||||
; CHECK-NEXT: asr r3, r1, r2
|
||||
; CHECK-NEXT: lsr r0, r0, r2
|
||||
; CHECK-NEXT: rsb r2, r2, #32
|
||||
; CHECK-NEXT: cmp r12, #0
|
||||
; CHECK-NEXT: orr r0, r0, r1, lsl r2
|
||||
; CHECK-NEXT: asrge r3, r1, #31
|
||||
; CHECK-NEXT: asrge r0, r1, r12
|
||||
; CHECK-NEXT: mov r1, r3
|
||||
; CHECK-NEXT: mov pc, lr
|
||||
;
|
||||
; EXPAND-LABEL: test_ashr:
|
||||
; CHECK: sub [[EXTRA_SHIFT:.*]], r2, #32
|
||||
; CHECK: asr [[HI_TMP:.*]], r1, r2
|
||||
; CHECK: lsr r0, r0, r2
|
||||
; CHECK: rsb [[REVERSE_SHIFT:.*]], r2, #32
|
||||
; CHECK: cmp [[EXTRA_SHIFT]], #0
|
||||
; CHECK: orr r0, r0, r1, lsl [[REVERSE_SHIFT]]
|
||||
; CHECK: asrge [[HI_TMP]], r1, #31
|
||||
; CHECK: asrge r0, r1, [[EXTRA_SHIFT]]
|
||||
; CHECK: mov r1, [[HI_TMP]]
|
||||
|
||||
; EXPAND: push {[[REG:r[0-9]+]], lr}
|
||||
; EXPAND-NEXT: bl __aeabi_lasr
|
||||
; EXPAND-NEXT: pop {[[REG]], pc}
|
||||
; EXPAND: @ %bb.0:
|
||||
; EXPAND-NEXT: .save {r7, lr}
|
||||
; EXPAND-NEXT: push {r7, lr}
|
||||
; EXPAND-NEXT: bl __aeabi_lasr
|
||||
; EXPAND-NEXT: pop {r7, pc}
|
||||
%res = ashr i64 %val, %amt
|
||||
ret i64 %res
|
||||
}
|
||||
|
@ -524,3 +524,83 @@ define void @test_vsel64uno_nnan(float %lhs32, float %rhs32, double %a, double %
|
||||
; CHECK: vselvs.f64 d16, d1, d2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_ltzero(i32 %lhs32, float %a, float %b) {
|
||||
; CHECK-LABEL: test_vsel_ltzero
|
||||
%tst1 = icmp slt i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, float %a, float %b
|
||||
store float %val1, float* @varfloat
|
||||
; CHECK: cmp r0, #0
|
||||
; CHECK: vselge.f32 s0, s1, s0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_lezero(i32 %lhs32, float %a, float %b) {
|
||||
; CHECK-LABEL: test_vsel_lezero
|
||||
%tst1 = icmp sle i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, float %a, float %b
|
||||
store float %val1, float* @varfloat
|
||||
; CHECK: cmp r0, #1
|
||||
; CHECK: vselge.f32 s0, s1, s0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_gtzero(i32 %lhs32, float %a, float %b) {
|
||||
; CHECK-LABEL: test_vsel_gtzero
|
||||
%tst1 = icmp sgt i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, float %a, float %b
|
||||
store float %val1, float* @varfloat
|
||||
; CHECK: cmp r0, #0
|
||||
; CHECK: vselgt.f32 s0, s0, s1
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_gezero(i32 %lhs32, float %a, float %b) {
|
||||
; CHECK-LABEL: test_vsel_gezero
|
||||
%tst1 = icmp sge i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, float %a, float %b
|
||||
store float %val1, float* @varfloat
|
||||
; CHECK: cmn r0, #1
|
||||
; CHECK: vselgt.f32 s0, s0, s1
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_ltzero64(i32 %lhs32, double %a, double %b) {
|
||||
; CHECK-LABEL: test_vsel_ltzero
|
||||
%tst1 = icmp slt i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, double %a, double %b
|
||||
store double %val1, double* @vardouble
|
||||
; CHECK: cmp r0, #0
|
||||
; CHECK: vselge.f64 d16, d1, d0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_lezero64(i32 %lhs32, double %a, double %b) {
|
||||
; CHECK-LABEL: test_vsel_lezero
|
||||
%tst1 = icmp sle i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, double %a, double %b
|
||||
store double %val1, double* @vardouble
|
||||
; CHECK: cmp r0, #1
|
||||
; CHECK: vselge.f64 d16, d1, d0
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_gtzero64(i32 %lhs32, double %a, double %b) {
|
||||
; CHECK-LABEL: test_vsel_gtzero
|
||||
%tst1 = icmp sgt i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, double %a, double %b
|
||||
store double %val1, double* @vardouble
|
||||
; CHECK: cmp r0, #0
|
||||
; CHECK: vselgt.f64 d16, d0, d1
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_vsel_gezero64(i32 %lhs32, double %a, double %b) {
|
||||
; CHECK-LABEL: test_vsel_gezero
|
||||
%tst1 = icmp sge i32 %lhs32, 0
|
||||
%val1 = select i1 %tst1, double %a, double %b
|
||||
store double %val1, double* @vardouble
|
||||
; CHECK: cmn r0, #1
|
||||
; CHECK: vselgt.f64 d16, d0, d1
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user