[ARM][MVE] Match canonical saturating negation patterns - #213085
Conversation
|
@llvm/pr-subscribers-backend-arm Author: Ties Stuij (stuij) ChangesInstCombine commit 2c35727 (no pull request) canonicalized the saturating negation idiom to an llvm.ssub.sat operation. For the ARM backend we only recognized the original select and subtract pattern, causing vector absolute values to expand to VQSUB plus a compare and select instead of VQABS. In this patch we teach the VQABS and VQNEG patterns to recognize the canonical ssub.sat form. Full diff: https://github.com/llvm/llvm-project/pull/213085.diff 3 Files Affected:
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td
index 38f36cb239535..6b4feb638c9e3 100644
--- a/llvm/lib/Target/ARM/ARMInstrMVE.td
+++ b/llvm/lib/Target/ARM/ARMInstrMVE.td
@@ -2568,6 +2568,14 @@ multiclass vqabsneg_pattern<MVEVectorVTInfo VTI, dag int_min, dag int_max,
int_max,
(sub (VTI.Vec zero_vec), (VTI.Vec MQPR:$reg)))))),
(VTI.Vec (vqabs_instruction (VTI.Vec MQPR:$reg)))>;
+ // InstCombine canonicalizes the saturating negate in the expression above
+ // to ssub.sat(0, r).
+ def : Pat<(VTI.Vec (vselect
+ (VTI.Pred (ARMvcmpz (VTI.Vec MQPR:$reg), ARMCCgt)),
+ (VTI.Vec MQPR:$reg),
+ (VTI.Vec (ssubsat (VTI.Vec zero_vec),
+ (VTI.Vec MQPR:$reg))))),
+ (VTI.Vec (vqabs_instruction (VTI.Vec MQPR:$reg)))>;
// Similarly, this tree represents vqneg, i.e. the following vectorized expression:
// r == INT_MIN ? INT_MAX : -r
def : Pat<(VTI.Vec (vselect
@@ -2575,6 +2583,9 @@ multiclass vqabsneg_pattern<MVEVectorVTInfo VTI, dag int_min, dag int_max,
int_max,
(sub (VTI.Vec zero_vec), (VTI.Vec MQPR:$reg)))),
(VTI.Vec (vqneg_instruction (VTI.Vec MQPR:$reg)))>;
+ def : Pat<(VTI.Vec (ssubsat (VTI.Vec zero_vec),
+ (VTI.Vec MQPR:$reg))),
+ (VTI.Vec (vqneg_instruction (VTI.Vec MQPR:$reg)))>;
}
}
diff --git a/llvm/test/CodeGen/Thumb2/vqabs.ll b/llvm/test/CodeGen/Thumb2/vqabs.ll
index f8f4b65a1f7dc..832d85b1095c4 100644
--- a/llvm/test/CodeGen/Thumb2/vqabs.ll
+++ b/llvm/test/CodeGen/Thumb2/vqabs.ll
@@ -52,10 +52,7 @@ entry:
define arm_aapcs_vfpcc <16 x i8> @vqabs_sat_test16(<16 x i8> %A) {
; CHECK-LABEL: vqabs_sat_test16:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: vmov.i32 q1, #0x0
-; CHECK-NEXT: vcmp.s8 gt, q0, zr
-; CHECK-NEXT: vqsub.s8 q1, q1, q0
-; CHECK-NEXT: vpsel q0, q0, q1
+; CHECK-NEXT: vqabs.s8 q0, q0
; CHECK-NEXT: bx lr
entry:
%0 = icmp sgt <16 x i8> %A, zeroinitializer
@@ -67,10 +64,7 @@ entry:
define arm_aapcs_vfpcc <8 x i16> @vqabs_sat_test8(<8 x i16> %A) {
; CHECK-LABEL: vqabs_sat_test8:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: vmov.i32 q1, #0x0
-; CHECK-NEXT: vcmp.s16 gt, q0, zr
-; CHECK-NEXT: vqsub.s16 q1, q1, q0
-; CHECK-NEXT: vpsel q0, q0, q1
+; CHECK-NEXT: vqabs.s16 q0, q0
; CHECK-NEXT: bx lr
entry:
%0 = icmp sgt <8 x i16> %A, zeroinitializer
@@ -82,10 +76,7 @@ entry:
define arm_aapcs_vfpcc <4 x i32> @vqabs_sat_test4(<4 x i32> %A) {
; CHECK-LABEL: vqabs_sat_test4:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: vmov.i32 q1, #0x0
-; CHECK-NEXT: vcmp.s32 gt, q0, zr
-; CHECK-NEXT: vqsub.s32 q1, q1, q0
-; CHECK-NEXT: vpsel q0, q0, q1
+; CHECK-NEXT: vqabs.s32 q0, q0
; CHECK-NEXT: bx lr
entry:
%0 = icmp sgt <4 x i32> %A, zeroinitializer
diff --git a/llvm/test/CodeGen/Thumb2/vqneg.ll b/llvm/test/CodeGen/Thumb2/vqneg.ll
index 4f357d81a5fc5..3a7c227bf4d22 100644
--- a/llvm/test/CodeGen/Thumb2/vqneg.ll
+++ b/llvm/test/CodeGen/Thumb2/vqneg.ll
@@ -46,8 +46,7 @@ entry:
define arm_aapcs_vfpcc <16 x i8> @vqneg_sat_test16(<16 x i8> %A) {
; CHECK-LABEL: vqneg_sat_test16:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: vmov.i32 q1, #0x0
-; CHECK-NEXT: vqsub.s8 q0, q1, q0
+; CHECK-NEXT: vqneg.s8 q0, q0
; CHECK-NEXT: bx lr
entry:
%0 = tail call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> zeroinitializer, <16 x i8> %A)
@@ -57,8 +56,7 @@ entry:
define arm_aapcs_vfpcc <8 x i16> @vqneg_sat_test8(<8 x i16> %A) {
; CHECK-LABEL: vqneg_sat_test8:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: vmov.i32 q1, #0x0
-; CHECK-NEXT: vqsub.s16 q0, q1, q0
+; CHECK-NEXT: vqneg.s16 q0, q0
; CHECK-NEXT: bx lr
entry:
%0 = tail call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> zeroinitializer, <8 x i16> %A)
@@ -68,8 +66,7 @@ entry:
define arm_aapcs_vfpcc <4 x i32> @vqneg_sat_test4(<4 x i32> %A) {
; CHECK-LABEL: vqneg_sat_test4:
; CHECK: @ %bb.0: @ %entry
-; CHECK-NEXT: vmov.i32 q1, #0x0
-; CHECK-NEXT: vqsub.s32 q0, q1, q0
+; CHECK-NEXT: vqneg.s32 q0, q0
; CHECK-NEXT: bx lr
entry:
%0 = tail call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> zeroinitializer, <4 x i32> %A)
|
e3293aa to
a041b1d
Compare
davemgreen
left a comment
There was a problem hiding this comment.
Oh I have a patch to do this somewhere locally (which is why the tests already exist). It was just waiting on the AArch64 side, which works a little differently. They look almost identical to this, almost down to the formatting.
Sorry it wasn't done earlier. LGTM
| (sub (VTI.Vec zero_vec), (VTI.Vec MQPR:$reg)))), | ||
| (VTI.Vec (vqneg_instruction (VTI.Vec MQPR:$reg)))>; | ||
| def : Pat<(VTI.Vec (ssubsat (VTI.Vec zero_vec), | ||
| (VTI.Vec MQPR:$reg))), |
There was a problem hiding this comment.
Done, and np, spoils go to the committer.
InstCombine pull request llvm#194519 canonicalized the saturating negation idiom to an llvm.ssub.sat operation. For the ARM backend we only recognized the original select and subtract pattern, causing vector absolute values to expand to VQSUB plus a compare and select instead of VQABS. In this patch we teach the VQABS and VQNEG patterns to recognize this ssub.sat form.
a041b1d to
a86f2fd
Compare
InstCombine pull request llvm#194519 canonicalized the saturating negation idiom to an llvm.ssub.sat operation. For the ARM backend we only recognized the original select and subtract pattern, causing vector absolute values to expand to VQSUB plus a compare and select instead of VQABS. In this patch we teach the VQABS and VQNEG patterns to recognize this ssub.sat form.
|
/cherry-pick c99e675 |
|
/pull-request #213699 |
InstCombine pull request llvm#194519 canonicalized the saturating negation idiom to an llvm.ssub.sat operation. For the ARM backend we only recognized the original select and subtract pattern, causing vector absolute values to expand to VQSUB plus a compare and select instead of VQABS. In this patch we teach the VQABS and VQNEG patterns to recognize this ssub.sat form.
InstCombine pull request llvm#194519 canonicalized the saturating negation idiom to an llvm.ssub.sat operation. For the ARM backend we only recognized the original select and subtract pattern, causing vector absolute values to expand to VQSUB plus a compare and select instead of VQABS. In this patch we teach the VQABS and VQNEG patterns to recognize this ssub.sat form. (cherry picked from commit c99e675)
InstCombine pull request llvm#194519 canonicalized the saturating negation idiom to an llvm.ssub.sat operation. For the ARM backend we only recognized the original select and subtract pattern, causing vector absolute values to expand to VQSUB plus a compare and select instead of VQABS. In this patch we teach the VQABS and VQNEG patterns to recognize this ssub.sat form.
InstCombine pull request #194519 canonicalized the saturating negation idiom to
an llvm.ssub.sat operation. For the ARM backend we only recognized the original
select and subtract pattern, causing vector absolute values to expand to VQSUB
plus a compare and select instead of VQABS.
In this patch we teach the VQABS and VQNEG patterns to recognize this ssub.sat
form.