From 13918432cf67c60d56b7a89bf9b1acf9c0d0866a Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Mon, 31 Oct 2022 12:28:25 -0700 Subject: [PATCH] [Hexagon] Add builtins and intrinsics for V6_v[add|sub]carryo --- clang/include/clang/Basic/BuiltinsHexagonDep.def | 4 +++ .../clang/Basic/BuiltinsHexagonMapCustomDep.def | 4 +++ clang/lib/CodeGen/CGBuiltin.cpp | 19 +++++++++++++ clang/test/CodeGen/builtins-hexagon-v66-128B.c | 32 ++++++++++++++++++++++ clang/test/CodeGen/builtins-hexagon-v66.c | 32 ++++++++++++++++++++++ llvm/include/llvm/IR/IntrinsicsHexagonDep.td | 26 ++++++++++++++++++ .../Target/Hexagon/HexagonDepInstrIntrinsics.inc | 2 ++ llvm/lib/Target/Hexagon/HexagonDepMapAsm2Intrin.td | 8 ++++++ 8 files changed, 127 insertions(+) diff --git a/clang/include/clang/Basic/BuiltinsHexagonDep.def b/clang/include/clang/Basic/BuiltinsHexagonDep.def index 2eb4ca6..f08fa2f 100644 --- a/clang/include/clang/Basic/BuiltinsHexagonDep.def +++ b/clang/include/clang/Basic/BuiltinsHexagonDep.def @@ -1720,6 +1720,8 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B, "vV128biiV32iV32i", "", HV // V66 HVX Instructions. +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo, "V16iV16iV16iv*", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo_128B, "V32iV32iV32iv*", "", HVXV66) TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat, "V16iV16iV16iV64b", "", HVXV66) TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B, "V32iV32iV32iV128b", "", HVXV66) TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into, "V32iV32iV16iV16i", "", HVXV66) @@ -1728,6 +1730,8 @@ TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr, "V16iV16iV16i", "", HVXV66) TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr_128B, "V32iV32iV32i", "", HVXV66) TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw, "V16iV16iV16i", "", HVXV66) TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B, "V32iV32iV32i", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo, "V16iV16iV16iv*", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo_128B, "V32iV32iV32iv*", "", HVXV66) // V68 HVX Instructions. diff --git a/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def b/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def index 389eadb..9390d54 100644 --- a/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def +++ b/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def @@ -12,3 +12,7 @@ CUSTOM_BUILTIN_MAPPING(V6_vaddcarry, 64) CUSTOM_BUILTIN_MAPPING(V6_vaddcarry_128B, 128) CUSTOM_BUILTIN_MAPPING(V6_vsubcarry, 64) CUSTOM_BUILTIN_MAPPING(V6_vsubcarry_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddcarryo, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddcarryo_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubcarryo, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubcarryo_128B, 128) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0ca664b..8bb56263 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19303,6 +19303,25 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, PredAddr.getAlignment()); return Builder.CreateExtractValue(Result, 0); } + // These are identical to the builtins above, except they don't consume + // input carry, only generate carry-out. Since they still produce two + // outputs, generate the store of the predicate, but no load. + case Hexagon::BI__builtin_HEXAGON_V6_vaddcarryo: + case Hexagon::BI__builtin_HEXAGON_V6_vaddcarryo_128B: + case Hexagon::BI__builtin_HEXAGON_V6_vsubcarryo: + case Hexagon::BI__builtin_HEXAGON_V6_vsubcarryo_128B: { + // Get the type from the 0-th argument. + llvm::Type *VecType = ConvertType(E->getArg(0)->getType()); + Address PredAddr = Builder.CreateElementBitCast( + EmitPointerWithAlignment(E->getArg(2)), VecType); + llvm::Value *Result = Builder.CreateCall(CGM.getIntrinsic(ID), + {EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1))}); + + llvm::Value *PredOut = Builder.CreateExtractValue(Result, 1); + Builder.CreateAlignedStore(Q2V(PredOut), PredAddr.getPointer(), + PredAddr.getAlignment()); + return Builder.CreateExtractValue(Result, 0); + } case Hexagon::BI__builtin_HEXAGON_V6_vmaskedstoreq: case Hexagon::BI__builtin_HEXAGON_V6_vmaskedstorenq: diff --git a/clang/test/CodeGen/builtins-hexagon-v66-128B.c b/clang/test/CodeGen/builtins-hexagon-v66-128B.c index 5839d3a..62beeb5 100644 --- a/clang/test/CodeGen/builtins-hexagon-v66-128B.c +++ b/clang/test/CodeGen/builtins-hexagon-v66-128B.c @@ -65,3 +65,35 @@ HEXAGON_Vect2048 test28(void *in1, void *in2, void *out) { return __builtin_HEXAGON_V6_vasr_into_128B(vr, v1, v2); } + +// CHECK-LABEL: @test29 +// CHECK: call { <32 x i32>, <128 x i1> } @llvm.hexagon.V6.vaddcarryo.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}}) +HEXAGON_Vect1024 test29(void *in, void *out) { + HEXAGON_Vect1024 v1, v2; + HEXAGON_Vect1024 *p; + HEXAGON_VecPred128 q1; + + p = (HEXAGON_Vect1024 *)in; + v1 = *p++; + v2 = *p++; + q1 = *p++; + + return __builtin_HEXAGON_V6_vaddcarryo_128B(v1, v2, &q1); +} + +// CHECK-LABEL: @test30 +// CHECK: call { <32 x i32>, <128 x i1> } @llvm.hexagon.V6.vsubcarryo.128B(<32 x i32> %{{[0-9]+}}, <32 x i32> %{{[0-9]+}}) +HEXAGON_Vect1024 test30(void *in, void *out) { + HEXAGON_Vect1024 v1, v2; + HEXAGON_Vect1024 *p; + HEXAGON_VecPred128 q1; + + p = (HEXAGON_Vect1024 *)in; + v1 = *p++; + v2 = *p++; + q1 = *p++; + + return __builtin_HEXAGON_V6_vsubcarryo_128B(v1, v2, &q1); +} + + diff --git a/clang/test/CodeGen/builtins-hexagon-v66.c b/clang/test/CodeGen/builtins-hexagon-v66.c index a222228..75da03f 100644 --- a/clang/test/CodeGen/builtins-hexagon-v66.c +++ b/clang/test/CodeGen/builtins-hexagon-v66.c @@ -89,3 +89,35 @@ HEXAGON_Vect1024 test8(void *in1, void *in2, void *out) { return __builtin_HEXAGON_V6_vasr_into(vr, v1, v2); } + +// CHECK-LABEL: @test9 +// CHECK: call { <16 x i32>, <64 x i1> } @llvm.hexagon.V6.vaddcarryo(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}}) +HEXAGON_Vect512 test9(void *in, void *out) { + HEXAGON_Vect512 v1, v2; + HEXAGON_Vect512 *p; + HEXAGON_VecPred64 q1; + + p = (HEXAGON_Vect512 *)in; + v1 = *p++; + v2 = *p++; + q1 = *p++; + + return __builtin_HEXAGON_V6_vaddcarryo(v1, v2, &q1); +} + +// CHECK-LABEL: @test10 +// CHECK: call { <16 x i32>, <64 x i1> } @llvm.hexagon.V6.vsubcarryo(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}}) +HEXAGON_Vect512 test10(void *in, void *out) { + HEXAGON_Vect512 v1, v2; + HEXAGON_Vect512 *p; + HEXAGON_VecPred64 q1; + + p = (HEXAGON_Vect512 *)in; + v1 = *p++; + v2 = *p++; + q1 = *p++; + + return __builtin_HEXAGON_V6_vsubcarryo(v1, v2, &q1); +} + + diff --git a/llvm/include/llvm/IR/IntrinsicsHexagonDep.td b/llvm/include/llvm/IR/IntrinsicsHexagonDep.td index 1771146..06287fb 100644 --- a/llvm/include/llvm/IR/IntrinsicsHexagonDep.td +++ b/llvm/include/llvm/IR/IntrinsicsHexagonDep.td @@ -491,6 +491,20 @@ class Hexagon_custom_v32i32v128i1_v32i32v32i32v128i1_Intrinsic_128B< [llvm_v32i32_ty,llvm_v128i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v128i1_ty], intr_properties>; +// tag : V6_vaddcarryo +class Hexagon_custom_v16i32v64i1_v16i32v16i32_Intrinsic< + list intr_properties = [IntrNoMem]> + : Hexagon_NonGCC_Intrinsic< + [llvm_v16i32_ty,llvm_v64i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty], + intr_properties>; + +// tag : V6_vaddcarryo +class Hexagon_custom_v32i32v128i1_v32i32v32i32_Intrinsic_128B< + list intr_properties = [IntrNoMem]> + : Hexagon_NonGCC_Intrinsic< + [llvm_v32i32_ty,llvm_v128i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty], + intr_properties>; + // tag : V6_vaddcarrysat class Hexagon_v16i32_v16i32v16i32v64i1_Intrinsic intr_properties = [IntrNoMem]> @@ -6103,6 +6117,12 @@ Hexagon__v128i1i32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vscattermwq_128B", [Intr // V66 HVX Instructions. +def int_hexagon_V6_vaddcarryo : +Hexagon_custom_v16i32v64i1_v16i32v16i32_Intrinsic; + +def int_hexagon_V6_vaddcarryo_128B : +Hexagon_custom_v32i32v128i1_v32i32v32i32_Intrinsic_128B; + def int_hexagon_V6_vaddcarrysat : Hexagon_v16i32_v16i32v16i32v64i1_Intrinsic<"HEXAGON_V6_vaddcarrysat">; @@ -6127,6 +6147,12 @@ Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatdw">; def int_hexagon_V6_vsatdw_128B : Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatdw_128B">; +def int_hexagon_V6_vsubcarryo : +Hexagon_custom_v16i32v64i1_v16i32v16i32_Intrinsic; + +def int_hexagon_V6_vsubcarryo_128B : +Hexagon_custom_v32i32v128i1_v32i32v32i32_Intrinsic_128B; + // V68 HVX Instructions. def int_hexagon_V6_v6mpyhubs10 : diff --git a/llvm/lib/Target/Hexagon/HexagonDepInstrIntrinsics.inc b/llvm/lib/Target/Hexagon/HexagonDepInstrIntrinsics.inc index b556011..0944092 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepInstrIntrinsics.inc +++ b/llvm/lib/Target/Hexagon/HexagonDepInstrIntrinsics.inc @@ -1024,6 +1024,7 @@ {Hexagon::V6_vaddbsat, Intrinsic::hexagon_V6_vaddbsat, Intrinsic::hexagon_V6_vaddbsat_128B}, {Hexagon::V6_vaddbsat_dv, Intrinsic::hexagon_V6_vaddbsat_dv, Intrinsic::hexagon_V6_vaddbsat_dv_128B}, {Hexagon::V6_vaddcarry, Intrinsic::hexagon_V6_vaddcarry, Intrinsic::hexagon_V6_vaddcarry_128B}, +{Hexagon::V6_vaddcarryo, Intrinsic::hexagon_V6_vaddcarryo, Intrinsic::hexagon_V6_vaddcarryo_128B}, {Hexagon::V6_vaddcarrysat, Intrinsic::hexagon_V6_vaddcarrysat, Intrinsic::hexagon_V6_vaddcarrysat_128B}, {Hexagon::V6_vaddclbh, Intrinsic::hexagon_V6_vaddclbh, Intrinsic::hexagon_V6_vaddclbh_128B}, {Hexagon::V6_vaddclbw, Intrinsic::hexagon_V6_vaddclbw, Intrinsic::hexagon_V6_vaddclbw_128B}, @@ -1407,6 +1408,7 @@ {Hexagon::V6_vsubbsat, Intrinsic::hexagon_V6_vsubbsat, Intrinsic::hexagon_V6_vsubbsat_128B}, {Hexagon::V6_vsubbsat_dv, Intrinsic::hexagon_V6_vsubbsat_dv, Intrinsic::hexagon_V6_vsubbsat_dv_128B}, {Hexagon::V6_vsubcarry, Intrinsic::hexagon_V6_vsubcarry, Intrinsic::hexagon_V6_vsubcarry_128B}, +{Hexagon::V6_vsubcarryo, Intrinsic::hexagon_V6_vsubcarryo, Intrinsic::hexagon_V6_vsubcarryo_128B}, {Hexagon::V6_vsubh, Intrinsic::hexagon_V6_vsubh, Intrinsic::hexagon_V6_vsubh_128B}, {Hexagon::V6_vsubh_dv, Intrinsic::hexagon_V6_vsubh_dv, Intrinsic::hexagon_V6_vsubh_dv_128B}, {Hexagon::V6_vsubhnq, Intrinsic::hexagon_V6_vsubhnq, Intrinsic::hexagon_V6_vsubhnq_128B}, diff --git a/llvm/lib/Target/Hexagon/HexagonDepMapAsm2Intrin.td b/llvm/lib/Target/Hexagon/HexagonDepMapAsm2Intrin.td index 64bc509..6be2f2f 100644 --- a/llvm/lib/Target/Hexagon/HexagonDepMapAsm2Intrin.td +++ b/llvm/lib/Target/Hexagon/HexagonDepMapAsm2Intrin.td @@ -3343,6 +3343,10 @@ def: Pat<(int_hexagon_V6_vscattermwq_128B HvxQR:$src1, IntRegs:$src2, ModRegs:$s // V66 HVX Instructions. +def: Pat<(int_hexagon_V6_vaddcarryo HvxVR:$src1, HvxVR:$src2), + (V6_vaddcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX64B]>; +def: Pat<(int_hexagon_V6_vaddcarryo_128B HvxVR:$src1, HvxVR:$src2), + (V6_vaddcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX128B]>; def: Pat<(int_hexagon_V6_vaddcarrysat HvxVR:$src1, HvxVR:$src2, HvxQR:$src3), (V6_vaddcarrysat HvxVR:$src1, HvxVR:$src2, HvxQR:$src3)>, Requires<[HasV66, UseHVX64B]>; def: Pat<(int_hexagon_V6_vaddcarrysat_128B HvxVR:$src1, HvxVR:$src2, HvxQR:$src3), @@ -3359,6 +3363,10 @@ def: Pat<(int_hexagon_V6_vsatdw HvxVR:$src1, HvxVR:$src2), (V6_vsatdw HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX64B]>; def: Pat<(int_hexagon_V6_vsatdw_128B HvxVR:$src1, HvxVR:$src2), (V6_vsatdw HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX128B]>; +def: Pat<(int_hexagon_V6_vsubcarryo HvxVR:$src1, HvxVR:$src2), + (V6_vsubcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX64B]>; +def: Pat<(int_hexagon_V6_vsubcarryo_128B HvxVR:$src1, HvxVR:$src2), + (V6_vsubcarryo HvxVR:$src1, HvxVR:$src2)>, Requires<[HasV66, UseHVX128B]>; // V68 HVX Instructions. -- 2.7.4