Index: llvm/lib/Target/ARM/ARMInstrMVE.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrMVE.td +++ llvm/lib/Target/ARM/ARMInstrMVE.td @@ -1952,6 +1952,46 @@ def MVE_VQNEGs16 : MVE_VQABSNEG<"vqneg", "s16", 0b01, 0b1>; def MVE_VQNEGs32 : MVE_VQABSNEG<"vqneg", "s32", 0b10, 0b1>; +let Predicates = [HasMVEInt] in { + def : Pat<(v16i8 (vselect + (v16i1 (ARMvcmpz (v16i8 MQPR:$reg), (i32 12))), + (v16i8 MQPR:$reg), + (v16i8 (vselect + (v16i1 (ARMvcmp (v16i8 MQPR:$reg), + (v16i8 (ARMvmovImm (i32 3712))), + (i32 0))), + (v16i8 (ARMvmovImm (i32 3711))), + (sub + (v16i8 (bitconvert (v4i32 (ARMvmovImm (i32 0))))), + (v16i8 MQPR:$reg)))))), + (v16i8(MVE_VQABSs8 (v16i8 MQPR:$reg)))>; + def : Pat<(v8i16 (vselect + (v8i1 (ARMvcmpz (v8i16 MQPR:$reg), (i32 12))), + (v8i16 MQPR:$reg), + (v8i16 (vselect + (v8i1 (ARMvcmp (v8i16 MQPR:$reg), + (v8i16 (ARMvmovImm (i32 2688))), + (i32 0))), + (v8i16 (ARMvmvnImm (i32 2688))), + (sub + (v8i16 (bitconvert (v4i32 (ARMvmovImm (i32 0))))), + (v8i16 MQPR:$reg)))))), + (v8i16(MVE_VQABSs16 (v8i16 MQPR:$reg)))>; + def : Pat<(v4i32 (vselect + (v4i1 (ARMvcmpz (v4i32 MQPR:$reg), (i32 12))), + (v4i32 MQPR:$reg), + (v4i32 (vselect + (v4i1 (ARMvcmp + (v4i32 MQPR:$reg), + (v4i32 (ARMvmovImm (i32 1664))), + (i32 0))), + (v4i32 (ARMvmvnImm (i32 1664))), + (sub + (v4i32 (ARMvmovImm (i32 0))), + (v4i32 MQPR:$reg)))))), + (v4i32(MVE_VQABSs32 (v4i32 MQPR:$reg)))>; +} + class MVE_mod_imm cmode, bit op, dag iops, list pattern=[]> : MVE_p<(outs MQPR:$Qd), iops, NoItinerary, iname, suffix, "$Qd, $imm", Index: llvm/test/CodeGen/Thumb2/vqabs.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/Thumb2/vqabs.ll @@ -0,0 +1,50 @@ +; RUN: llc -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+mve.fp %s -o - | FileCheck %s + +define arm_aapcs_vfpcc <16 x i8> @vqabs_test16(<16 x i8> %A) nounwind { +; CHECK-LABEL: vqabs_test16: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vqabs.s8 q0, q0 +; CHECK-NEXT: bx lr +entry: + + %0 = icmp sgt <16 x i8> %A, zeroinitializer + %1 = icmp eq <16 x i8> %A, + %2 = sub nsw <16 x i8> zeroinitializer, %A + %3 = select <16 x i1> %1, <16 x i8> , <16 x i8> %2 + %4 = select <16 x i1> %0, <16 x i8> %A, <16 x i8> %3 + + ret <16 x i8> %4 +} + +define arm_aapcs_vfpcc <8 x i16> @vqabs_test8(<8 x i16> %A) nounwind { +; CHECK-LABEL: vqabs_test8: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vqabs.s16 q0, q0 +; CHECK-NEXT: bx lr +entry: + + %0 = icmp sgt <8 x i16> %A, zeroinitializer + %1 = icmp eq <8 x i16> %A, + %2 = sub nsw <8 x i16> zeroinitializer, %A + %3 = select <8 x i1> %1, <8 x i16> , <8 x i16> %2 + %4 = select <8 x i1> %0, <8 x i16> %A, <8 x i16> %3 + + ret <8 x i16> %4 +} + +define arm_aapcs_vfpcc <4 x i32> @vqabs_test4(<4 x i32> %A) nounwind { +; CHECK-LABEL: vqabs_test4: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: vqabs.s32 q0, q0 +; CHECK-NEXT: bx lr +entry: + + %0 = icmp sgt <4 x i32> %A, zeroinitializer + %1 = icmp eq <4 x i32> %A, + %2 = sub nsw <4 x i32> zeroinitializer, %A + %3 = select <4 x i1> %1, <4 x i32> , <4 x i32> %2 + %4 = select <4 x i1> %0, <4 x i32> %A, <4 x i32> %3 + + ret <4 x i32> %4 +} +