+; 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-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
+; 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
- %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
}
-; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
}
; 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
+; 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
}
; 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
}
; 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
}
; 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
+}