From 358d8cce26375911867d07a5e06ef13e6ad50a1b Mon Sep 17 00:00:00 2001 From: Renato Golin Date: Tue, 2 Aug 2016 10:26:08 +0000 Subject: [PATCH] Merging r276701 and r277439 The saturation instructions appeared in v6T2 / 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 v6T2 / DSP-enable only cores. Fixes PR28607. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@277440 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelLowering.cpp | 3 +- lib/Target/ARM/ARMInstrInfo.td | 12 +++++--- lib/Target/ARM/ARMInstrThumb2.td | 10 ++++--- test/CodeGen/ARM/ssat-v4t.ll | 9 ++++++ test/CodeGen/ARM/ssat.ll | 30 ++++++++++++------- test/CodeGen/ARM/usat-v4t.ll | 9 ++++++ .../ARM/unpredictable-SSAT-arm.txt | 2 +- 7 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 test/CodeGen/ARM/ssat-v4t.ll create mode 100644 test/CodeGen/ARM/usat-v4t.ll diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index d6e7caf98a8..3cfcb1e09f0 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -3857,7 +3857,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->isThumb() && Subtarget->hasV6Ops()) || Subtarget->isThumb2()) && + isSaturatingConditional(Op, SatValue, SatConstant)) return DAG.getNode(ARMISD::SSAT, dl, VT, SatValue, DAG.getConstant(countTrailingOnes(SatConstant), dl, VT)); diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 060376b0a27..c9735f3ec27 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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<[IsARM,HasV6]>{ bits<4> Rd; bits<5> sat_imm; bits<4> Rn; @@ -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<[IsARM,HasV6]>{ bits<4> Rd; bits<4> sat_imm; bits<4> Rn; @@ -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<[IsARM,HasV6]> { bits<4> Rd; bits<5> sat_imm; bits<4> Rn; @@ -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<[IsARM,HasV6]>{ bits<4> Rd; bits<4> sat_imm; bits<4> Rn; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 55e5308be40..fe699b28488 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -2240,7 +2240,8 @@ class T2SatI { + NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []>, + Requires<[IsThumb2]> { let Inst{31-27} = 0b11110; let Inst{25-22} = 0b1100; let Inst{20} = 0; @@ -2251,7 +2252,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; @@ -2265,7 +2266,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]> { let Inst{31-27} = 0b11110; let Inst{25-22} = 0b1110; let Inst{20} = 0; @@ -2275,7 +2277,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; diff --git a/test/CodeGen/ARM/ssat-v4t.ll b/test/CodeGen/ARM/ssat-v4t.ll new file mode 100644 index 00000000000..3d74c88da82 --- /dev/null +++ b/test/CodeGen/ARM/ssat-v4t.ll @@ -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 diff --git a/test/CodeGen/ARM/ssat.ll b/test/CodeGen/ARM/ssat.ll index 2b75bc410aa..f1e11dd33d1 100644 --- a/test/CodeGen/ARM/ssat.ll +++ b/test/CodeGen/ARM/ssat.ll @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/test/CodeGen/ARM/usat-v4t.ll b/test/CodeGen/ARM/usat-v4t.ll new file mode 100644 index 00000000000..572c760e3ae --- /dev/null +++ b/test/CodeGen/ARM/usat-v4t.ll @@ -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 diff --git a/test/MC/Disassembler/ARM/unpredictable-SSAT-arm.txt b/test/MC/Disassembler/ARM/unpredictable-SSAT-arm.txt index 832aa3ffa30..6ff5f54b82b 100644 --- a/test/MC/Disassembler/ARM/unpredictable-SSAT-arm.txt +++ b/test/MC/Disassembler/ARM/unpredictable-SSAT-arm.txt @@ -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 -- 2.40.0