[llvm] [AArch64] Add sqneg tablegen patterns (PR #196265)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 02:22:41 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: David Green (davemgreen)
<details>
<summary>Changes</summary>
This adds some tablegen patterns for sqneg instructions, largely copied from the equivalent MVE patterns. They perform a saturating negation, effectively just protecting against INT_MIN, which is equivalent to a `ssub_sat 0, R`.
---
Full diff: https://github.com/llvm/llvm-project/pull/196265.diff
3 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+18)
- (modified) llvm/test/CodeGen/AArch64/vqabs.ll (+8-16)
- (modified) llvm/test/CodeGen/AArch64/vqneg.ll (+8-16)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index fb54757ea775c..0e23b55821095 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -6676,6 +6676,24 @@ defm UQXTN : SIMDTwoScalarMixedBHS<1, 0b10100, "uqxtn", int_aarch64_neon_scalar
defm USQADD : SIMDTwoScalarBHSDTied< 1, 0b00011, "usqadd", AArch64usqadd,
int_aarch64_neon_usqadd>;
+// ssub_sat(0, R) -> sqneg(R)
+def : Pat<(v16i8 (ssubsat immAllZerosV, V128:$reg)),
+ (v16i8 (SQNEGv16i8 V128:$reg))>;
+def : Pat<(v8i16 (ssubsat immAllZerosV, V128:$reg)),
+ (v8i16 (SQNEGv8i16 V128:$reg))>;
+def : Pat<(v4i32 (ssubsat immAllZerosV, V128:$reg)),
+ (v4i32 (SQNEGv4i32 V128:$reg))>;
+def : Pat<(v2i64 (ssubsat immAllZerosV, V128:$reg)),
+ (v2i64 (SQNEGv2i64 V128:$reg))>;
+def : Pat<(v8i8 (ssubsat immAllZerosV, V64:$reg)),
+ (v8i8 (SQNEGv8i8 V64:$reg))>;
+def : Pat<(v4i16 (ssubsat immAllZerosV, V64:$reg)),
+ (v4i16 (SQNEGv4i16 V64:$reg))>;
+def : Pat<(v2i32 (ssubsat immAllZerosV, V64:$reg)),
+ (v2i32 (SQNEGv2i32 V64:$reg))>;
+def : Pat<(v1i64 (ssubsat immAllZerosV, V64:$reg)),
+ (v1i64 (SQNEGv1i64 V64:$reg))>;
+
// Floating-point conversion patterns.
multiclass IntegerToFPSIMDScalarPatterns<SDPatternOperator OpN, string INST> {
let Predicates = [HasFPRCVT] in {
diff --git a/llvm/test/CodeGen/AArch64/vqabs.ll b/llvm/test/CodeGen/AArch64/vqabs.ll
index a05bed23b14e2..7faba50d51e86 100644
--- a/llvm/test/CodeGen/AArch64/vqabs.ll
+++ b/llvm/test/CodeGen/AArch64/vqabs.ll
@@ -89,9 +89,8 @@ entry:
define <16 x i8> @vqabs_sat_v16i8(<16 x i8> %A) {
; CHECK-LABEL: vqabs_sat_v16i8:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.16b, v0.16b
; CHECK-NEXT: cmgt v2.16b, v0.16b, #0
-; CHECK-NEXT: sqsub v1.16b, v1.16b, v0.16b
; CHECK-NEXT: bif v0.16b, v1.16b, v2.16b
; CHECK-NEXT: ret
entry:
@@ -104,9 +103,8 @@ entry:
define <8 x i16> @vqabs_sat_v8i16(<8 x i16> %A) {
; CHECK-LABEL: vqabs_sat_v8i16:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.8h, v0.8h
; CHECK-NEXT: cmgt v2.8h, v0.8h, #0
-; CHECK-NEXT: sqsub v1.8h, v1.8h, v0.8h
; CHECK-NEXT: bif v0.16b, v1.16b, v2.16b
; CHECK-NEXT: ret
entry:
@@ -119,9 +117,8 @@ entry:
define <4 x i32> @vqabs_sat_v4i32(<4 x i32> %A) {
; CHECK-LABEL: vqabs_sat_v4i32:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.4s, v0.4s
; CHECK-NEXT: cmgt v2.4s, v0.4s, #0
-; CHECK-NEXT: sqsub v1.4s, v1.4s, v0.4s
; CHECK-NEXT: bif v0.16b, v1.16b, v2.16b
; CHECK-NEXT: ret
entry:
@@ -134,9 +131,8 @@ entry:
define <2 x i64> @vqabs_sat_v2i64(<2 x i64> %A) {
; CHECK-LABEL: vqabs_sat_v2i64:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.2d, v0.2d
; CHECK-NEXT: cmgt v2.2d, v0.2d, #0
-; CHECK-NEXT: sqsub v1.2d, v1.2d, v0.2d
; CHECK-NEXT: bif v0.16b, v1.16b, v2.16b
; CHECK-NEXT: ret
entry:
@@ -149,9 +145,8 @@ entry:
define <8 x i8> @vqabs_sat_v8i8(<8 x i8> %A) {
; CHECK-LABEL: vqabs_sat_v8i8:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.8b, v0.8b
; CHECK-NEXT: cmgt v2.8b, v0.8b, #0
-; CHECK-NEXT: sqsub v1.8b, v1.8b, v0.8b
; CHECK-NEXT: bif v0.8b, v1.8b, v2.8b
; CHECK-NEXT: ret
entry:
@@ -164,9 +159,8 @@ entry:
define <4 x i16> @vqabs_sat_v4i16(<4 x i16> %A) {
; CHECK-LABEL: vqabs_sat_v4i16:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.4h, v0.4h
; CHECK-NEXT: cmgt v2.4h, v0.4h, #0
-; CHECK-NEXT: sqsub v1.4h, v1.4h, v0.4h
; CHECK-NEXT: bif v0.8b, v1.8b, v2.8b
; CHECK-NEXT: ret
entry:
@@ -179,9 +173,8 @@ entry:
define <2 x i32> @vqabs_sat_v2i32(<2 x i32> %A) {
; CHECK-LABEL: vqabs_sat_v2i32:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
+; CHECK-NEXT: sqneg v1.2s, v0.2s
; CHECK-NEXT: cmgt v2.2s, v0.2s, #0
-; CHECK-NEXT: sqsub v1.2s, v1.2s, v0.2s
; CHECK-NEXT: bif v0.8b, v1.8b, v2.8b
; CHECK-NEXT: ret
entry:
@@ -194,9 +187,8 @@ entry:
define <1 x i64> @vqabs_sat_v1i64(<1 x i64> %A) {
; CHECK-SD-LABEL: vqabs_sat_v1i64:
; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: movi v1.2d, #0000000000000000
+; CHECK-SD-NEXT: sqneg d1, d0
; CHECK-SD-NEXT: cmgt d2, d0, #0
-; CHECK-SD-NEXT: sqsub d1, d1, d0
; CHECK-SD-NEXT: bif v0.8b, v1.8b, v2.8b
; CHECK-SD-NEXT: ret
;
diff --git a/llvm/test/CodeGen/AArch64/vqneg.ll b/llvm/test/CodeGen/AArch64/vqneg.ll
index 7e91ea5a48289..351c8f4bb0db3 100644
--- a/llvm/test/CodeGen/AArch64/vqneg.ll
+++ b/llvm/test/CodeGen/AArch64/vqneg.ll
@@ -73,8 +73,7 @@ entry:
define <16 x i8> @vqneg_sat_v16i8(<16 x i8> %A) {
; CHECK-LABEL: vqneg_sat_v16i8:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.16b, v1.16b, v0.16b
+; CHECK-NEXT: sqneg v0.16b, v0.16b
; CHECK-NEXT: ret
entry:
%0 = tail call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> zeroinitializer, <16 x i8> %A)
@@ -84,8 +83,7 @@ entry:
define <8 x i16> @vqneg_sat_v8i16(<8 x i16> %A) {
; CHECK-LABEL: vqneg_sat_v8i16:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.8h, v1.8h, v0.8h
+; CHECK-NEXT: sqneg v0.8h, v0.8h
; CHECK-NEXT: ret
entry:
%0 = tail call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> zeroinitializer, <8 x i16> %A)
@@ -95,8 +93,7 @@ entry:
define <4 x i32> @vqneg_sat_v4i32(<4 x i32> %A) {
; CHECK-LABEL: vqneg_sat_v4i32:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.4s, v1.4s, v0.4s
+; CHECK-NEXT: sqneg v0.4s, v0.4s
; CHECK-NEXT: ret
entry:
%0 = tail call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> zeroinitializer, <4 x i32> %A)
@@ -106,8 +103,7 @@ entry:
define <2 x i64> @vqneg_sat_v2i64(<2 x i64> %A) {
; CHECK-LABEL: vqneg_sat_v2i64:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.2d, v1.2d, v0.2d
+; CHECK-NEXT: sqneg v0.2d, v0.2d
; CHECK-NEXT: ret
entry:
%0 = tail call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> zeroinitializer, <2 x i64> %A)
@@ -117,8 +113,7 @@ entry:
define <8 x i8> @vqneg_sat_v8i8(<8 x i8> %A) {
; CHECK-LABEL: vqneg_sat_v8i8:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.8b, v1.8b, v0.8b
+; CHECK-NEXT: sqneg v0.8b, v0.8b
; CHECK-NEXT: ret
entry:
%0 = tail call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> zeroinitializer, <8 x i8> %A)
@@ -128,8 +123,7 @@ entry:
define <4 x i16> @vqneg_sat_v4i16(<4 x i16> %A) {
; CHECK-LABEL: vqneg_sat_v4i16:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.4h, v1.4h, v0.4h
+; CHECK-NEXT: sqneg v0.4h, v0.4h
; CHECK-NEXT: ret
entry:
%0 = tail call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> zeroinitializer, <4 x i16> %A)
@@ -139,8 +133,7 @@ entry:
define <2 x i32> @vqneg_sat_v2i32(<2 x i32> %A) {
; CHECK-LABEL: vqneg_sat_v2i32:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: movi v1.2d, #0000000000000000
-; CHECK-NEXT: sqsub v0.2s, v1.2s, v0.2s
+; CHECK-NEXT: sqneg v0.2s, v0.2s
; CHECK-NEXT: ret
entry:
%0 = tail call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> zeroinitializer, <2 x i32> %A)
@@ -150,8 +143,7 @@ entry:
define <1 x i64> @vqneg_sat_v1i64(<1 x i64> %A) {
; CHECK-SD-LABEL: vqneg_sat_v1i64:
; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: movi v1.2d, #0000000000000000
-; CHECK-SD-NEXT: sqsub d0, d1, d0
+; CHECK-SD-NEXT: sqneg d0, d0
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: vqneg_sat_v1i64:
``````````
</details>
https://github.com/llvm/llvm-project/pull/196265
More information about the llvm-commits
mailing list