diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -544,10 +544,15 @@ setOperationAction(ISD::CTPOP, MVT::i32, Legal); setOperationAction(ISD::CTPOP, MVT::i64, Legal); setOperationAction(ISD::CTPOP, MVT::i128, Expand); + setOperationAction(ISD::PARITY, MVT::i128, Expand); + setOperationAction(ISD::CTTZ, MVT::i32, Legal); setOperationAction(ISD::CTTZ, MVT::i64, Legal); setOperationAction(ISD::CTTZ, MVT::i128, Expand); + + setOperationAction(ISD::ABS, MVT::i32, Legal); + setOperationAction(ISD::ABS, MVT::i64, Legal); } else { setOperationAction(ISD::CTPOP, MVT::i32, Custom); setOperationAction(ISD::CTPOP, MVT::i64, Custom); @@ -555,10 +560,10 @@ setOperationAction(ISD::PARITY, MVT::i64, Custom); setOperationAction(ISD::PARITY, MVT::i128, Custom); - } - setOperationAction(ISD::ABS, MVT::i32, Custom); - setOperationAction(ISD::ABS, MVT::i64, Custom); + setOperationAction(ISD::ABS, MVT::i32, Custom); + setOperationAction(ISD::ABS, MVT::i64, Custom); + } setOperationAction(ISD::SDIVREM, MVT::i32, Expand); setOperationAction(ISD::SDIVREM, MVT::i64, Expand); diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -7265,12 +7265,15 @@ } multiclass SIMDTwoScalarD opc, string asm, - SDPatternOperator OpNode = null_frag> { + SDPatternOperator OpNode = null_frag, + Predicate pred = IsTrue> { def v1i64 : BaseSIMDTwoScalar; + let Predicates = [pred] in { def : Pat<(i64 (OpNode (i64 FPR64:$Rn))), (!cast(NAME # "v1i64") FPR64:$Rn)>; + } } let mayRaiseFPException = 1, Uses = [FPCR] in diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -115,8 +115,9 @@ AssemblerPredicateWithAll<(all_of FeatureDotProd), "dotprod">; def HasCRC : Predicate<"Subtarget->hasCRC()">, AssemblerPredicateWithAll<(all_of FeatureCRC), "crc">; -def HasCSSC : Predicate<"Subtarget->hasCSSC()">, +def HasCSSC : Predicate<"Subtarget->hasCSSC()">, AssemblerPredicateWithAll<(all_of FeatureCSSC), "cssc">; +def HasNoCSSC : Predicate<"!Subtarget->hasCSSC()">; def HasLSE : Predicate<"Subtarget->hasLSE()">, AssemblerPredicateWithAll<(all_of FeatureLSE), "lse">; def HasNoLSE : Predicate<"!Subtarget->hasLSE()">; @@ -232,6 +233,7 @@ AssemblerPredicateWithAll<(all_of FeatureHBC), "hbc">; def HasMOPS : Predicate<"Subtarget->hasMOPS()">, AssemblerPredicateWithAll<(all_of FeatureMOPS), "mops">; +def IsTrue : Predicate<"true">; def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">; @@ -5035,7 +5037,7 @@ // Advanced SIMD two scalar instructions. //===----------------------------------------------------------------------===// -defm ABS : SIMDTwoScalarD< 0, 0b01011, "abs", abs>; +defm ABS : SIMDTwoScalarD< 0, 0b01011, "abs", abs, HasNoCSSC>; defm CMEQ : SIMDCmpTwoScalarD< 0, 0b01001, "cmeq", AArch64cmeqz>; defm CMGE : SIMDCmpTwoScalarD< 1, 0b01000, "cmge", AArch64cmgez>; defm CMGT : SIMDCmpTwoScalarD< 0, 0b01000, "cmgt", AArch64cmgtz>; @@ -8492,7 +8494,7 @@ //===----------------------------------------------------------------------===// // General Data-Processing Instructions (FEAT_V94_DP) //===----------------------------------------------------------------------===// -defm ABS : OneOperandData<0b001000, "abs">, Requires<[HasCSSC]>; +defm ABS : OneOperandData<0b001000, "abs", abs>, Requires<[HasCSSC]>; defm CNT : OneOperandData<0b000111, "cnt", ctpop>, Requires<[HasCSSC]>; defm CTZ : OneOperandData<0b000110, "ctz", cttz>, Requires<[HasCSSC]>; diff --git a/llvm/test/CodeGen/AArch64/iabs.ll b/llvm/test/CodeGen/AArch64/iabs.ll --- a/llvm/test/CodeGen/AArch64/iabs.ll +++ b/llvm/test/CodeGen/AArch64/iabs.ll @@ -1,12 +1,20 @@ -; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s +; RUN: llc < %s -mtriple=arm64-eabi -mattr=+cssc | FileCheck %s -check-prefix=CHECK-CSSC define i8 @test_i8(i8 %a) nounwind { ; CHECK-LABEL: test_i8: ; CHECK: // %bb.0: -; CHECK-NEXT: sxtb w8, w0 -; CHECK-NEXT: cmp w8, #0 -; CHECK-NEXT: cneg w0, w8, mi -; CHECK-NEXT: ret +; CHECK-NEXT: sxtb w8, w0 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: cneg w0, w8, mi +; CHECK-NEXT: ret +; +; CHECK-CSSC-LABEL: test_i8: +; CHECK-CSSC: // %bb.0: +; CHECK-CSSC-NEXT: sxtb w8, w0 +; CHECK-CSSC-NEXT: abs w0, w8 +; CHECK-CSSC-NEXT: ret %tmp1neg = sub i8 0, %a %b = icmp sgt i8 %a, -1 %abs = select i1 %b, i8 %a, i8 %tmp1neg @@ -16,10 +24,16 @@ define i16 @test_i16(i16 %a) nounwind { ; CHECK-LABEL: test_i16: ; CHECK: // %bb.0: -; CHECK-NEXT: sxth w8, w0 -; CHECK-NEXT: cmp w8, #0 -; CHECK-NEXT: cneg w0, w8, mi -; CHECK-NEXT: ret +; CHECK-NEXT: sxth w8, w0 +; CHECK-NEXT: cmp w8, #0 +; CHECK-NEXT: cneg w0, w8, mi +; CHECK-NEXT: ret +; +; CHECK-CSSC-LABEL: test_i16: +; CHECK-CSSC: // %bb.0: +; CHECK-CSSC-NEXT: sxth w8, w0 +; CHECK-CSSC-NEXT: abs w0, w8 +; CHECK-CSSC-NEXT: ret %tmp1neg = sub i16 0, %a %b = icmp sgt i16 %a, -1 %abs = select i1 %b, i16 %a, i16 %tmp1neg @@ -29,9 +43,14 @@ define i32 @test_i32(i32 %a) nounwind { ; CHECK-LABEL: test_i32: ; CHECK: // %bb.0: -; CHECK-NEXT: cmp w0, #0 -; CHECK-NEXT: cneg w0, w0, mi -; CHECK-NEXT: ret +; CHECK-NEXT: cmp w0, #0 +; CHECK-NEXT: cneg w0, w0, mi +; CHECK-NEXT: ret +; +; CHECK-CSSC-LABEL: test_i32: +; CHECK-CSSC: // %bb.0: +; CHECK-CSSC-NEXT: abs w0, w0 +; CHECK-CSSC-NEXT: ret %tmp1neg = sub i32 0, %a %b = icmp sgt i32 %a, -1 %abs = select i1 %b, i32 %a, i32 %tmp1neg @@ -41,12 +60,16 @@ define i64 @test_i64(i64 %a) nounwind { ; CHECK-LABEL: test_i64: ; CHECK: // %bb.0: -; CHECK-NEXT: cmp x0, #0 -; CHECK-NEXT: cneg x0, x0, mi -; CHECK-NEXT: ret +; CHECK-NEXT: cmp x0, #0 +; CHECK-NEXT: cneg x0, x0, mi +; CHECK-NEXT: ret +; +; CHECK-CSSC-LABEL: test_i64: +; CHECK-CSSC: // %bb.0: +; CHECK-CSSC-NEXT: abs x0, x0 +; CHECK-CSSC-NEXT: ret %tmp1neg = sub i64 0, %a %b = icmp sgt i64 %a, -1 %abs = select i1 %b, i64 %a, i64 %tmp1neg ret i64 %abs } -