Skip to content

Commit

Permalink
[ARM] Saturation instructions are DSP-only
Browse files Browse the repository at this point in the history
The saturation instructions appeared in v6T2, with DSP extensions, but they
were being accepted / generated on any, with the new introduction of the
saturation detection in the back-end. This commit restricts the usage to
DSP-enable only cores.

Fixes PR28607.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276701 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rengolin committed Jul 25, 2016
1 parent f6fdf20 commit c5c6574
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 20 deletions.
3 changes: 2 additions & 1 deletion lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3850,7 +3850,8 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
// Try to convert two saturating conditional selects into a single SSAT
SDValue SatValue;
uint64_t SatConstant;
if (isSaturatingConditional(Op, SatValue, SatConstant))
if (Subtarget->hasDSP() &&
isSaturatingConditional(Op, SatValue, SatConstant))
return DAG.getNode(ARMISD::SSAT, dl, VT, SatValue,
DAG.getConstant(countTrailingOnes(SatConstant), dl, VT));

Expand Down
12 changes: 8 additions & 4 deletions lib/Target/ARM/ARMInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -3650,7 +3650,8 @@ def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),

def SSAT : AI<(outs GPRnopc:$Rd),
(ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> {
SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []>,
Requires<[HasDSP]>{
bits<4> Rd;
bits<5> sat_imm;
bits<4> Rn;
Expand All @@ -3666,7 +3667,8 @@ def SSAT : AI<(outs GPRnopc:$Rd),

def SSAT16 : AI<(outs GPRnopc:$Rd),
(ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm,
NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> {
NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []>,
Requires<[HasDSP]>{
bits<4> Rd;
bits<4> sat_imm;
bits<4> Rn;
Expand All @@ -3679,7 +3681,8 @@ def SSAT16 : AI<(outs GPRnopc:$Rd),

def USAT : AI<(outs GPRnopc:$Rd),
(ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh),
SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> {
SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []>,
Requires<[HasDSP]>{
bits<4> Rd;
bits<5> sat_imm;
bits<4> Rn;
Expand All @@ -3695,7 +3698,8 @@ def USAT : AI<(outs GPRnopc:$Rd),

def USAT16 : AI<(outs GPRnopc:$Rd),
(ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm,
NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []> {
NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []>,
Requires<[HasDSP]>{
bits<4> Rd;
bits<4> sat_imm;
bits<4> Rn;
Expand Down
10 changes: 6 additions & 4 deletions lib/Target/ARM/ARMInstrThumb2.td
Original file line number Diff line number Diff line change
Expand Up @@ -2241,7 +2241,8 @@ class T2SatI<dag oops, dag iops, InstrItinClass itin,
def t2SSAT: T2SatI<
(outs rGPR:$Rd),
(ins imm1_32:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh),
NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> {
NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []>,
Requires<[IsThumb2, HasDSP]> {
let Inst{31-27} = 0b11110;
let Inst{25-22} = 0b1100;
let Inst{20} = 0;
Expand All @@ -2252,7 +2253,7 @@ def t2SSAT: T2SatI<
def t2SSAT16: T2SatI<
(outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary,
"ssat16", "\t$Rd, $sat_imm, $Rn", []>,
Requires<[IsThumb2, HasDSP]> {
Requires<[IsThumb2, HasDSP]> {
let Inst{31-27} = 0b11110;
let Inst{25-22} = 0b1100;
let Inst{20} = 0;
Expand All @@ -2266,7 +2267,8 @@ def t2SSAT16: T2SatI<
def t2USAT: T2SatI<
(outs rGPR:$Rd),
(ins imm0_31:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh),
NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> {
NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []>,
Requires<[IsThumb2, HasDSP]> {
let Inst{31-27} = 0b11110;
let Inst{25-22} = 0b1110;
let Inst{20} = 0;
Expand All @@ -2276,7 +2278,7 @@ def t2USAT: T2SatI<
def t2USAT16: T2SatI<(outs rGPR:$Rd), (ins imm0_15:$sat_imm, rGPR:$Rn),
NoItinerary,
"usat16", "\t$Rd, $sat_imm, $Rn", []>,
Requires<[IsThumb2, HasDSP]> {
Requires<[IsThumb2, HasDSP]> {
let Inst{31-22} = 0b1111001110;
let Inst{20} = 0;
let Inst{15} = 0;
Expand Down
9 changes: 9 additions & 0 deletions test/CodeGen/ARM/ssat-v4t.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; RUN: not llc -O1 -mtriple=armv4t-none-none-eabi %s -o - 2>&1 | FileCheck %s

; CHECK: Cannot select: intrinsic %llvm.arm.ssat
define i32 @ssat() nounwind {
%tmp = call i32 @llvm.arm.ssat(i32 128, i32 1)
ret i32 %tmp
}

declare i32 @llvm.arm.ssat(i32, i32) nounwind readnone
30 changes: 20 additions & 10 deletions test/CodeGen/ARM/ssat.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
; RUN: llc -mtriple=armv4t-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=V4T
; RUN: llc -mtriple=armv6t2-eabi %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=V6T2

; Check for several conditions that should result in SSAT.
; For example, the base test is equivalent to
Expand All @@ -16,7 +17,8 @@
; 32-bit base test
define i32 @sat_base_32bit(i32 %x) #0 {
; CHECK-LABEL: sat_base_32bit:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpLow = icmp slt i32 %x, -8388608
%cmpUp = icmp sgt i32 %x, 8388607
Expand All @@ -29,7 +31,8 @@ entry:
; 16-bit base test
define i16 @sat_base_16bit(i16 %x) #0 {
; CHECK-LABEL: sat_base_16bit:
; CHECK: ssat r0, #12, r0
; V6T2: ssat r0, #12, r0
; V4T-NOT: ssat
entry:
%cmpLow = icmp slt i16 %x, -2048
%cmpUp = icmp sgt i16 %x, 2047
Expand All @@ -42,7 +45,8 @@ entry:
; 8-bit base test
define i8 @sat_base_8bit(i8 %x) #0 {
; CHECK-LABEL: sat_base_8bit:
; CHECK: ssat r0, #6, r0
; V6T2: ssat r0, #6, r0
; V4T-NOT: ssat
entry:
%cmpLow = icmp slt i8 %x, -32
%cmpUp = icmp sgt i8 %x, 31
Expand All @@ -60,7 +64,8 @@ entry:
; x < -k ? -k : (x < k ? x : k)
define i32 @sat_lower_upper_1(i32 %x) #0 {
; CHECK-LABEL: sat_lower_upper_1:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpLow = icmp slt i32 %x, -8388608
%cmpUp = icmp slt i32 %x, 8388607
Expand All @@ -72,7 +77,8 @@ entry:
; x > -k ? (x > k ? k : x) : -k
define i32 @sat_lower_upper_2(i32 %x) #0 {
; CHECK-LABEL: sat_lower_upper_2:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpLow = icmp sgt i32 %x, -8388608
%cmpUp = icmp sgt i32 %x, 8388607
Expand All @@ -84,7 +90,8 @@ entry:
; x < k ? (x < -k ? -k : x) : k
define i32 @sat_upper_lower_1(i32 %x) #0 {
; CHECK-LABEL: sat_upper_lower_1:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpUp = icmp slt i32 %x, 8388607
%cmpLow = icmp slt i32 %x, -8388608
Expand All @@ -96,7 +103,8 @@ entry:
; x > k ? k : (x < -k ? -k : x)
define i32 @sat_upper_lower_2(i32 %x) #0 {
; CHECK-LABEL: sat_upper_lower_2:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpUp = icmp sgt i32 %x, 8388607
%cmpLow = icmp slt i32 %x, -8388608
Expand All @@ -108,7 +116,8 @@ entry:
; k < x ? k : (x > -k ? x : -k)
define i32 @sat_upper_lower_3(i32 %x) #0 {
; CHECK-LABEL: sat_upper_lower_3:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpUp = icmp slt i32 8388607, %x
%cmpLow = icmp sgt i32 %x, -8388608
Expand All @@ -125,7 +134,8 @@ entry:
; k <= x ? k : (x >= -k ? x : -k)
define i32 @sat_le_ge(i32 %x) #0 {
; CHECK-LABEL: sat_le_ge:
; CHECK: ssat r0, #24, r0
; V6T2: ssat r0, #24, r0
; V4T-NOT: ssat
entry:
%cmpUp = icmp sle i32 8388607, %x
%cmpLow = icmp sge i32 %x, -8388608
Expand Down
9 changes: 9 additions & 0 deletions test/CodeGen/ARM/usat-v4t.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; RUN: not llc -O1 -mtriple=armv4t-none-none-eabi %s -o - 2>&1 | FileCheck %s

; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.usat
define i32 @usat1() nounwind {
%tmp = call i32 @llvm.arm.usat(i32 128, i32 31)
ret i32 %tmp
}

declare i32 @llvm.arm.usat(i32, i32) nounwind readnone
2 changes: 1 addition & 1 deletion test/MC/Disassembler/ARM/unpredictable-SSAT-arm.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 2>&1 | FileCheck %s
# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 2>&1 | FileCheck %s

# Opcode=322 Name=SSAT Format=ARM_FORMAT_SATFRM(13)
# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Expand Down

0 comments on commit c5c6574

Please sign in to comment.