diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td index ca6e2128812f..6d53bf8b172d 100644 --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -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 diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index d068a12c7f7d..b033f889fbf6 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -7362,7 +7362,9 @@ multiclass SIMDDifferentThreeVectorBD opc, string asm, [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>; def v16i8 : BaseSIMDDifferentThreeVector; + 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 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(NAME#"v16i8") V128:$Rn, V128:$Rm)>; } multiclass SIMDLongThreeVectorHS opc, string asm, @@ -7402,6 +7400,7 @@ multiclass SIMDLongThreeVectorHS opc, string asm, (extract_high_v4i32 (v4i32 V128:$Rm))))]>; } +let isCommutable = 1 in multiclass SIMDLongThreeVectorBHSabdl opc, string asm, SDPatternOperator OpNode = null_frag> { def v8i8_v8i16 : BaseSIMDDifferentThreeVector opc, (extract_high_v4i32 (v4i32 V128:$Rm)))))))]>; } +let isCommutable = 1 in multiclass SIMDLongThreeVectorBHS opc, string asm, SDPatternOperator OpNode = null_frag> { def v8i8_v8i16 : BaseSIMDDifferentThreeVector; 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", diff --git a/llvm/test/CodeGen/AArch64/arm64-neon-3vdiff.ll b/llvm/test/CodeGen/AArch64/arm64-neon-3vdiff.ll index 557fcbbb4196..9a1b6a0661e6 100644 --- a/llvm/test/CodeGen/AArch64/arm64-neon-3vdiff.ll +++ b/llvm/test/CodeGen/AArch64/arm64-neon-3vdiff.ll @@ -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> diff --git a/llvm/test/CodeGen/AArch64/arm64-neon-mul-div.ll b/llvm/test/CodeGen/AArch64/arm64-neon-mul-div.ll index e3515124a6d3..0d427c05e3b7 100644 --- a/llvm/test/CodeGen/AArch64/arm64-neon-mul-div.ll +++ b/llvm/test/CodeGen/AArch64/arm64-neon-mul-div.ll @@ -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) diff --git a/llvm/test/CodeGen/AArch64/arm64-vabs.ll b/llvm/test/CodeGen/AArch64/arm64-vabs.ll index 8e3611d31261..ede5a7c2ae42 100644 --- a/llvm/test/CodeGen/AArch64/arm64-vabs.ll +++ b/llvm/test/CodeGen/AArch64/arm64-vabs.ll @@ -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 diff --git a/llvm/test/CodeGen/AArch64/arm64-vmul.ll b/llvm/test/CodeGen/AArch64/arm64-vmul.ll index cac980fd99b6..d12f7ce33e24 100644 --- a/llvm/test/CodeGen/AArch64/arm64-vmul.ll +++ b/llvm/test/CodeGen/AArch64/arm64-vmul.ll @@ -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)