[AArch64] Mark [usp]mull, [us]addl, [us]abdl as commutative (#152158)

Fixes #61461.
This commit is contained in:
Cullen Rhodes 2025-08-08 09:35:28 +01:00 committed by GitHub
parent 6ebb8901cc
commit e9d71efb83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 46 additions and 63 deletions

View File

@ -296,22 +296,22 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
def int_aarch64_neon_sqrdmlah : AdvSIMD_3IntArg_Intrinsic;
def int_aarch64_neon_sqrdmlsh : AdvSIMD_3IntArg_Intrinsic;
// Vector Polynominal Multiply
def int_aarch64_neon_pmul : AdvSIMD_2VectorArg_Intrinsic;
let IntrProperties = [IntrNoMem, Commutative] in {
// Vector Polynominal Multiply
def int_aarch64_neon_pmul : AdvSIMD_2VectorArg_Intrinsic;
// Vector Long Multiply
def int_aarch64_neon_smull : AdvSIMD_2VectorArg_Long_Intrinsic;
def int_aarch64_neon_umull : AdvSIMD_2VectorArg_Long_Intrinsic;
def int_aarch64_neon_pmull : AdvSIMD_2VectorArg_Long_Intrinsic;
// Vector Long Multiply
def int_aarch64_neon_smull : AdvSIMD_2VectorArg_Long_Intrinsic;
def int_aarch64_neon_umull : AdvSIMD_2VectorArg_Long_Intrinsic;
def int_aarch64_neon_pmull : AdvSIMD_2VectorArg_Long_Intrinsic;
// 64-bit polynomial multiply really returns an i128, which is not legal. Fake
// it with a v16i8.
def int_aarch64_neon_pmull64 :
DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
// 64-bit polynomial multiply really returns an i128, which is not legal.
// Fake it with a v16i8.
def int_aarch64_neon_pmull64
: DefaultAttrsIntrinsic<[llvm_v16i8_ty], [llvm_i64_ty, llvm_i64_ty]>;
// Vector Extending Multiply
def int_aarch64_neon_fmulx : AdvSIMD_2FloatArg_Intrinsic {
let IntrProperties = [IntrNoMem, Commutative];
// Vector Extending Multiply
def int_aarch64_neon_fmulx : AdvSIMD_2FloatArg_Intrinsic;
}
// Vector Saturating Doubling Long Multiply

View File

@ -7362,7 +7362,9 @@ multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
[(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
V128, V128, V128,
asm#"2", ".8h", ".16b", ".16b", []>;
asm#"2", ".8h", ".16b", ".16b",
[(set (v8i16 V128:$Rd), (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))),
(v8i8 (extract_high_v16i8 (v16i8 V128:$Rm)))))]>;
let Predicates = [HasAES] in {
def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
V128, V64, V64,
@ -7374,10 +7376,6 @@ multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
[(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)),
(extract_high_v2i64 (v2i64 V128:$Rm))))]>;
}
def : Pat<(v8i16 (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))),
(v8i8 (extract_high_v16i8 (v16i8 V128:$Rm))))),
(!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
}
multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
@ -7402,6 +7400,7 @@ multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
(extract_high_v4i32 (v4i32 V128:$Rm))))]>;
}
let isCommutable = 1 in
multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
SDPatternOperator OpNode = null_frag> {
def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
@ -7483,6 +7482,7 @@ multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
(extract_high_v4i32 (v4i32 V128:$Rm)))))))]>;
}
let isCommutable = 1 in
multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
SDPatternOperator OpNode = null_frag> {
def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,

View File

@ -6055,6 +6055,7 @@ defm MLA : SIMDThreeSameVectorBHSTied<0, 0b10010, "mla", null_frag>;
defm MLS : SIMDThreeSameVectorBHSTied<1, 0b10010, "mls", null_frag>;
defm MUL : SIMDThreeSameVectorBHS<0, 0b10011, "mul", mul>;
let isCommutable = 1 in
defm PMUL : SIMDThreeSameVectorB<1, 0b10011, "pmul", int_aarch64_neon_pmul>;
defm SABA : SIMDThreeSameVectorBHSTied<0, 0b01111, "saba",
TriOpFrag<(add node:$LHS, (abds node:$MHS, node:$RHS))> >;
@ -6806,6 +6807,7 @@ defm ADDHN : SIMDNarrowThreeVectorBHS<0,0b0100,"addhn", int_aarch64_neon_addhn>
defm SUBHN : SIMDNarrowThreeVectorBHS<0,0b0110,"subhn", int_aarch64_neon_subhn>;
defm RADDHN : SIMDNarrowThreeVectorBHS<1,0b0100,"raddhn",int_aarch64_neon_raddhn>;
defm RSUBHN : SIMDNarrowThreeVectorBHS<1,0b0110,"rsubhn",int_aarch64_neon_rsubhn>;
let isCommutable = 1 in
defm PMULL : SIMDDifferentThreeVectorBD<0,0b1110,"pmull", AArch64pmull>;
defm SABAL : SIMDLongThreeVectorTiedBHSabal<0,0b0101,"sabal", abds>;
defm SABDL : SIMDLongThreeVectorBHSabdl<0, 0b0111, "sabdl", abds>;
@ -6822,6 +6824,7 @@ defm SQDMLAL : SIMDLongThreeVectorSQDMLXTiedHS<0, 0b1001, "sqdmlal", saddsat>;
defm SQDMLSL : SIMDLongThreeVectorSQDMLXTiedHS<0, 0b1011, "sqdmlsl", ssubsat>;
defm SQDMULL : SIMDLongThreeVectorHS<0, 0b1101, "sqdmull",
int_aarch64_neon_sqdmull>;
let isCommutable = 0 in
defm SSUBL : SIMDLongThreeVectorBHS<0, 0b0010, "ssubl",
BinOpFrag<(sub (sext node:$LHS), (sext node:$RHS))>>;
defm SSUBW : SIMDWideThreeVectorBHS<0, 0b0011, "ssubw",
@ -6836,6 +6839,7 @@ defm UMLAL : SIMDLongThreeVectorTiedBHS<1, 0b1000, "umlal",
defm UMLSL : SIMDLongThreeVectorTiedBHS<1, 0b1010, "umlsl",
TriOpFrag<(sub node:$LHS, (AArch64umull node:$MHS, node:$RHS))>>;
defm UMULL : SIMDLongThreeVectorBHS<1, 0b1100, "umull", AArch64umull>;
let isCommutable = 0 in
defm USUBL : SIMDLongThreeVectorBHS<1, 0b0010, "usubl",
BinOpFrag<(sub (zanyext node:$LHS), (zanyext node:$RHS))>>;
defm USUBW : SIMDWideThreeVectorBHS< 1, 0b0011, "usubw",

View File

@ -71,18 +71,11 @@ entry:
}
define void @test_commutable_vaddl_s8(<8 x i8> %a, <8 x i8> %b, ptr %c) {
; CHECK-SD-LABEL: test_commutable_vaddl_s8:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: saddl v0.8h, v0.8b, v1.8b
; CHECK-SD-NEXT: stp q0, q0, [x0]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_commutable_vaddl_s8:
; CHECK-GI: // %bb.0: // %entry
; CHECK-GI-NEXT: saddl v2.8h, v0.8b, v1.8b
; CHECK-GI-NEXT: saddl v0.8h, v1.8b, v0.8b
; CHECK-GI-NEXT: stp q2, q0, [x0]
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_commutable_vaddl_s8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: saddl v0.8h, v0.8b, v1.8b
; CHECK-NEXT: stp q0, q0, [x0]
; CHECK-NEXT: ret
entry:
%vmovl.i.i = sext <8 x i8> %a to <8 x i16>
%vmovl.i2.i = sext <8 x i8> %b to <8 x i16>
@ -131,18 +124,11 @@ entry:
}
define void @test_commutable_vaddl_u8(<8 x i8> %a, <8 x i8> %b, ptr %c) {
; CHECK-SD-LABEL: test_commutable_vaddl_u8:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: uaddl v0.8h, v0.8b, v1.8b
; CHECK-SD-NEXT: stp q0, q0, [x0]
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_commutable_vaddl_u8:
; CHECK-GI: // %bb.0: // %entry
; CHECK-GI-NEXT: uaddl v2.8h, v0.8b, v1.8b
; CHECK-GI-NEXT: uaddl v0.8h, v1.8b, v0.8b
; CHECK-GI-NEXT: stp q2, q0, [x0]
; CHECK-GI-NEXT: ret
; CHECK-LABEL: test_commutable_vaddl_u8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: uaddl v0.8h, v0.8b, v1.8b
; CHECK-NEXT: stp q0, q0, [x0]
; CHECK-NEXT: ret
entry:
%vmovl.i.i = zext <8 x i8> %a to <8 x i16>
%vmovl.i2.i = zext <8 x i8> %b to <8 x i16>

View File

@ -1611,9 +1611,8 @@ define <16 x i8> @poly_mulv16i8(<16 x i8> %lhs, <16 x i8> %rhs) {
define <16 x i8> @commutable_poly_mul(<16 x i8> %lhs, <16 x i8> %rhs) {
; CHECK-LABEL: commutable_poly_mul:
; CHECK: // %bb.0:
; CHECK-NEXT: pmul v2.16b, v0.16b, v1.16b
; CHECK-NEXT: pmul v0.16b, v1.16b, v0.16b
; CHECK-NEXT: add v0.16b, v2.16b, v0.16b
; CHECK-NEXT: pmul v0.16b, v0.16b, v1.16b
; CHECK-NEXT: add v0.16b, v0.16b, v0.16b
; CHECK-NEXT: ret
%1 = call <16 x i8> @llvm.aarch64.neon.pmul.v16i8(<16 x i8> %lhs, <16 x i8> %rhs)
%2 = call <16 x i8> @llvm.aarch64.neon.pmul.v16i8(<16 x i8> %rhs, <16 x i8> %lhs)

View File

@ -57,9 +57,8 @@ define void @commutable_sabdl(ptr %A, ptr %B, ptr %C) nounwind {
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr d0, [x0]
; CHECK-GI-NEXT: ldr d1, [x1]
; CHECK-GI-NEXT: sabdl.8h v2, v0, v1
; CHECK-GI-NEXT: sabdl.8h v0, v1, v0
; CHECK-GI-NEXT: str q2, [x2]
; CHECK-GI-NEXT: sabdl.8h v0, v0, v1
; CHECK-GI-NEXT: str q0, [x2]
; CHECK-GI-NEXT: str q0, [x2]
; CHECK-GI-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A
@ -198,9 +197,8 @@ define void @commutable_uabdl(ptr %A, ptr %B, ptr %C) nounwind {
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr d0, [x0]
; CHECK-GI-NEXT: ldr d1, [x1]
; CHECK-GI-NEXT: uabdl.8h v2, v0, v1
; CHECK-GI-NEXT: uabdl.8h v0, v1, v0
; CHECK-GI-NEXT: str q2, [x2]
; CHECK-GI-NEXT: uabdl.8h v0, v0, v1
; CHECK-GI-NEXT: str q0, [x2]
; CHECK-GI-NEXT: str q0, [x2]
; CHECK-GI-NEXT: ret
%tmp1 = load <8 x i8>, ptr %A

View File

@ -82,9 +82,8 @@ define <2 x i64> @smull2d(ptr %A, ptr %B) nounwind {
define void @commutable_smull(<2 x i32> %A, <2 x i32> %B, ptr %C) {
; CHECK-LABEL: commutable_smull:
; CHECK: // %bb.0:
; CHECK-NEXT: smull v2.2d, v0.2s, v1.2s
; CHECK-NEXT: smull v0.2d, v1.2s, v0.2s
; CHECK-NEXT: stp q2, q0, [x0]
; CHECK-NEXT: smull v0.2d, v0.2s, v1.2s
; CHECK-NEXT: stp q0, q0, [x0]
; CHECK-NEXT: ret
%1 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %A, <2 x i32> %B)
%2 = call <2 x i64> @llvm.aarch64.neon.smull.v2i64(<2 x i32> %B, <2 x i32> %A)
@ -140,9 +139,8 @@ define <2 x i64> @umull2d(ptr %A, ptr %B) nounwind {
define void @commutable_umull(<2 x i32> %A, <2 x i32> %B, ptr %C) {
; CHECK-LABEL: commutable_umull:
; CHECK: // %bb.0:
; CHECK-NEXT: umull v2.2d, v0.2s, v1.2s
; CHECK-NEXT: umull v0.2d, v1.2s, v0.2s
; CHECK-NEXT: stp q2, q0, [x0]
; CHECK-NEXT: umull v0.2d, v0.2s, v1.2s
; CHECK-NEXT: stp q0, q0, [x0]
; CHECK-NEXT: ret
%1 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %A, <2 x i32> %B)
%2 = call <2 x i64> @llvm.aarch64.neon.umull.v2i64(<2 x i32> %B, <2 x i32> %A)
@ -246,9 +244,8 @@ define <8 x i16> @pmull8h(ptr %A, ptr %B) nounwind {
define void @commutable_pmull8h(<8 x i8> %A, <8 x i8> %B, ptr %C) {
; CHECK-LABEL: commutable_pmull8h:
; CHECK: // %bb.0:
; CHECK-NEXT: pmull v2.8h, v0.8b, v1.8b
; CHECK-NEXT: pmull v0.8h, v1.8b, v0.8b
; CHECK-NEXT: stp q2, q0, [x0]
; CHECK-NEXT: pmull v0.8h, v0.8b, v1.8b
; CHECK-NEXT: stp q0, q0, [x0]
; CHECK-NEXT: ret
%1 = call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> %A, <8 x i8> %B)
%2 = call <8 x i16> @llvm.aarch64.neon.pmull.v8i16(<8 x i8> %B, <8 x i8> %A)
@ -3273,9 +3270,8 @@ define <16 x i8> @test_commutable_pmull_64(i64 %l, i64 %r) nounwind {
; CHECK: // %bb.0:
; CHECK-NEXT: fmov d0, x1
; CHECK-NEXT: fmov d1, x0
; CHECK-NEXT: pmull v2.1q, v1.1d, v0.1d
; CHECK-NEXT: pmull v0.1q, v0.1d, v1.1d
; CHECK-NEXT: add v0.16b, v2.16b, v0.16b
; CHECK-NEXT: pmull v0.1q, v1.1d, v0.1d
; CHECK-NEXT: add v0.16b, v0.16b, v0.16b
; CHECK-NEXT: ret
%1 = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 %l, i64 %r)
%2 = call <16 x i8> @llvm.aarch64.neon.pmull64(i64 %r, i64 %l)