https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/142222
This change upstream supports VectorType in the helper function and adds a test for the Vector type of FP binary operations Issue https://github.com/llvm/llvm-project/issues/136487 >From 706cc1150052e2faf8f057366e1caccafac4e736 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Fri, 30 May 2025 20:14:25 +0200 Subject: [PATCH] [CIR] Upstream VectorType support in helper function --- .../CIR/Dialect/IR/CIRTypeConstraints.td | 37 ++++++++++ clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 3 +- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 6 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 9 --- clang/test/CIR/CodeGen/vector-ext.cpp | 67 ++++++++++++++++++ clang/test/CIR/CodeGen/vector.cpp | 69 ++++++++++++++++++- 6 files changed, 176 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index ec461cab961c7..7b20ca4e2d1d4 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -31,6 +31,18 @@ class CIR_ConfinedType<Type type, list<Pred> preds, string summary = ""> : Type<And<[type.predicate, CIR_CastedSelfsToType<type.cppType, preds>]>, summary, type.cppType>; +// Generates a type summary. +// - For a single type: returns its summary. +// - For multiple types: returns `any of <comma-separated summaries>`. +class CIR_TypeSummaries<list<Type> types> { + assert !not(!empty(types)), "expects non-empty list of types"; + + list<string> summaries = !foreach(type, types, type.summary); + string joined = !interleave(summaries, ", "); + + string value = !if(!eq(!size(types), 1), joined, "any of " # joined); +} + //===----------------------------------------------------------------------===// // Bool Type predicates //===----------------------------------------------------------------------===// @@ -184,6 +196,8 @@ def CIR_PtrToVoidPtrType // Vector Type predicates //===----------------------------------------------------------------------===// +def CIR_AnyVectorType : CIR_TypeBase<"::cir::VectorType", "vector type">; + // Vector of integral type def IntegerVector : Type< And<[ @@ -211,4 +225,27 @@ def CIR_AnyScalarType : AnyTypeOf<CIR_ScalarTypes, "cir scalar type"> { let cppFunctionName = "isScalarType"; } +//===----------------------------------------------------------------------===// +// Element type constraint bases +//===----------------------------------------------------------------------===// + +class CIR_ElementTypePred<Pred pred> : SubstLeaves<"$_self", + "::mlir::cast<::cir::VectorType>($_self).getElementType()", pred>; + +class CIR_VectorTypeOf<list<Type> types, string summary = ""> + : CIR_ConfinedType<CIR_AnyVectorType, + [Or<!foreach(type, types, CIR_ElementTypePred<type.predicate>)>], + !if(!empty(summary), + "vector of " # CIR_TypeSummaries<types>.value, + summary)>; + +// Vector of type constraints +def CIR_VectorOfFloatType : CIR_VectorTypeOf<[CIR_AnyFloatType]>; + +def CIR_AnyFloatOrVecOfFloatType + : AnyTypeOf<[CIR_AnyFloatType, CIR_VectorOfFloatType], + "floating point or vector of floating point type"> { + let cppFunctionName = "isFPOrVectorOfFPType"; +} + #endif // CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 3845fd2a4b67d..51983b51d31d5 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -16,6 +16,7 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/Interfaces/CIRFPTypeInterface.h" namespace cir { @@ -26,8 +27,6 @@ struct RecordTypeStorage; bool isValidFundamentalIntWidth(unsigned width); -bool isFPOrFPVectorTy(mlir::Type); - } // namespace cir //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 8448c164a5e58..b33bb71c99c90 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1311,7 +1311,7 @@ mlir::Value ScalarExprEmitter::emitMul(const BinOpInfo &ops) { !canElideOverflowCheck(cgf.getContext(), ops)) cgf.cgm.errorNYI("unsigned int overflow sanitizer"); - if (cir::isFPOrFPVectorTy(ops.lhs.getType())) { + if (cir::isFPOrVectorOfFPType(ops.lhs.getType())) { assert(!cir::MissingFeatures::cgFPOptionsRAII()); return builder.createFMul(loc, ops.lhs, ops.rhs); } @@ -1370,7 +1370,7 @@ mlir::Value ScalarExprEmitter::emitAdd(const BinOpInfo &ops) { !canElideOverflowCheck(cgf.getContext(), ops)) cgf.cgm.errorNYI("unsigned int overflow sanitizer"); - if (cir::isFPOrFPVectorTy(ops.lhs.getType())) { + if (cir::isFPOrVectorOfFPType(ops.lhs.getType())) { assert(!cir::MissingFeatures::cgFPOptionsRAII()); return builder.createFAdd(loc, ops.lhs, ops.rhs); } @@ -1418,7 +1418,7 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) { !canElideOverflowCheck(cgf.getContext(), ops)) cgf.cgm.errorNYI("unsigned int overflow sanitizer"); - if (cir::isFPOrFPVectorTy(ops.lhs.getType())) { + if (cir::isFPOrVectorOfFPType(ops.lhs.getType())) { assert(!cir::MissingFeatures::cgFPOptionsRAII()); return builder.createFSub(loc, ops.lhs, ops.rhs); } diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index b402177a5ec18..21d957afefeb6 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -552,15 +552,6 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, .getABIAlignment(dataLayout, params); } -//===----------------------------------------------------------------------===// -// Floating-point and Float-point Vector type helpers -//===----------------------------------------------------------------------===// - -bool cir::isFPOrFPVectorTy(mlir::Type t) { - assert(!cir::MissingFeatures::vectorType()); - return isAnyFloatingPointType(t); -} - //===----------------------------------------------------------------------===// // FuncType Definitions //===----------------------------------------------------------------------===// diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index 8a0479fc1d088..d1acfeabd1161 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -1091,3 +1091,70 @@ void foo17() { // OGCG: %[[VEC_A:.*]] = alloca <2 x double>, align 16 // OGCG: %[[TMP:.*]] = load <2 x double>, ptr %[[VEC_A]], align 16 // OGCG: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16> + +void foo19() { + vf4 a; + vf4 b; + + vf4 c = a + b; + vf4 d = a - b; + vf4 e = a * b; + vf4 f = a / b; +} + +// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["a"] +// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["b"] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[ADD:.*]] = cir.binop(add, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[ADD]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[SUB:.*]] = cir.binop(sub, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[SUB]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[MUL:.*]] = cir.binop(mul, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[MUL]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[DIV:.*]] = cir.binop(div, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[DIV]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> + +// LLVM: %[[VEC_A:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[VEC_B:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[ADD:.*]] = fadd <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[ADD]], ptr {{.*}}, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[SUB:.*]] = fsub <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[SUB]], ptr {{.*}}, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[MUL:.*]] = fmul <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[MUL]], ptr {{.*}}, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[DIV:.*]] = fdiv <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[DIV]], ptr {{.*}}, align 16 + +// OGCG: %[[VEC_A:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[VEC_B:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[ADD:.*]] = fadd <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[ADD]], ptr {{.*}}, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[SUB:.*]] = fsub <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[SUB]], ptr {{.*}}, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[MUL:.*]] = fmul <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[MUL]], ptr {{.*}}, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[DIV:.*]] = fdiv <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[DIV]], ptr {{.*}}, align 16 diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp index 4c50f68a56162..7e43a9cbf12a5 100644 --- a/clang/test/CIR/CodeGen/vector.cpp +++ b/clang/test/CIR/CodeGen/vector.cpp @@ -1069,4 +1069,71 @@ void foo17() { // OGCG: %[[VEC_A:.*]] = alloca <2 x double>, align 16 // OGCG: %[[TMP:.*]] = load <2 x double>, ptr %[[VEC_A]], align 16 -// OGCG: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16> \ No newline at end of file +// OGCG: %[[RES:.*]]= fptoui <2 x double> %[[TMP]] to <2 x i16> + +void foo19() { + vf4 a; + vf4 b; + + vf4 c = a + b; + vf4 d = a - b; + vf4 e = a * b; + vf4 f = a / b; +} + +// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["a"] +// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["b"] +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[ADD:.*]] = cir.binop(add, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[ADD]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[SUB:.*]] = cir.binop(sub, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[SUB]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[MUL:.*]] = cir.binop(mul, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[MUL]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[DIV:.*]] = cir.binop(div, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !cir.float> +// CIR: cir.store{{.*}} %[[DIV]], {{.*}} : !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>> + +// LLVM: %[[VEC_A:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[VEC_B:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[ADD:.*]] = fadd <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[ADD]], ptr {{.*}}, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[SUB:.*]] = fsub <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[SUB]], ptr {{.*}}, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[MUL:.*]] = fmul <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[MUL]], ptr {{.*}}, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// LLVM: %[[DIV:.*]] = fdiv <4 x float> %[[TMP_A]], %[[TMP_B]] +// LLVM: store <4 x float> %[[DIV]], ptr {{.*}}, align 16 + +// OGCG: %[[VEC_A:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[VEC_B:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[ADD:.*]] = fadd <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[ADD]], ptr {{.*}}, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[SUB:.*]] = fsub <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[SUB]], ptr {{.*}}, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[MUL:.*]] = fmul <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[MUL]], ptr {{.*}}, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[VEC_A]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[VEC_B]], align 16 +// OGCG: %[[DIV:.*]] = fdiv <4 x float> %[[TMP_A]], %[[TMP_B]] +// OGCG: store <4 x float> %[[DIV]], ptr {{.*}}, align 16 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits