[Hexagon] Add builtins and intrinsics for V6_v[add|sub]carryo
authorKrzysztof Parzyszek <kparzysz@quicinc.com>
Mon, 31 Oct 2022 19:28:25 +0000 (12:28 -0700)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Mon, 31 Oct 2022 20:41:31 +0000 (13:41 -0700)
clang/include/clang/Basic/BuiltinsHexagonDep.def
clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/builtins-hexagon-v66-128B.c
clang/test/CodeGen/builtins-hexagon-v66.c
llvm/include/llvm/IR/IntrinsicsHexagonDep.td
llvm/lib/Target/Hexagon/HexagonDepInstrIntrinsics.inc
llvm/lib/Target/Hexagon/HexagonDepMapAsm2Intrin.td

index 2eb4ca6..f08fa2f 100644 (file)
@@ -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.
 
index 389eadb..9390d54 100644 (file)
@@ -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)
index 0ca664b..8bb5626 100644 (file)
@@ -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:
index 5839d3a..62beeb5 100644 (file)
@@ -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);
+}
+
+
index a222228..75da03f 100644 (file)
@@ -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);
+}
+
+
index 1771146..06287fb 100644 (file)
@@ -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<IntrinsicProperty> 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<IntrinsicProperty> 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<string GCCIntSuffix,
       list<IntrinsicProperty> 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 :
index b556011..0944092 100644 (file)
 {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},
 {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},
index 64bc509..6be2f2f 100644 (file)
@@ -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.