[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:
David Green 2019-07-04 08:49:32 +00:00
parent 0e835405fd
commit 5349edee0f
4 changed files with 437 additions and 156 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}