-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[CIR][NFC] Upstream VectorType support in helper function #142222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR][NFC] Upstream VectorType support in helper function #142222
Conversation
@llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) ChangesThis change upstream supports VectorType in the helper function and adds a test for the Vector type of FP binary operations Issue #136487 Full diff: https://github.com/llvm/llvm-project/pull/142222.diff 6 Files Affected:
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
|
@llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesThis change upstream supports VectorType in the helper function and adds a test for the Vector type of FP binary operations Issue #136487 Full diff: https://github.com/llvm/llvm-project/pull/142222.diff 6 Files Affected:
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks mostly reasonable to me, but I'd like to have feedback from @xlauko.
It looks like it would be NFC though. Are the new tests verifying anything that didn't work before this change?
@@ -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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this including the current file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I was adding it to the other file, for the test, it was working before, and I was thinking of adding a test that covers Vec FP. I will remove it and convert this PR to NFC for now, and when we need more tests, we can add
706cc11
to
bc6569a
Compare
bc6569a
to
77d3586
Compare
This partially ports my changes from llvm/clangir#1626 I was originally waiting for other vector stuff to get merged so we don't conflict. Can you please mirror everything that is applicable from that PR? |
3efd6be
to
f0a401f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This change upstream supports VectorType in the helper function and adds a test for the Vector type of FP binary operations Issue llvm#136487
This change upstream supports VectorType in the helper function and adds a test for the Vector type of FP binary operations
Issue #136487