[clang] [CIR] Upstream VectorType support in helper function (PR #142222)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 30 15:21:55 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Amr Hesham (AmrDeveloper)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/142222.diff
6 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td (+37)
- (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.h (+1-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+3-3)
- (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (-9)
- (modified) clang/test/CIR/CodeGen/vector-ext.cpp (+67)
- (modified) clang/test/CIR/CodeGen/vector.cpp (+68-1)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/142222
More information about the cfe-commits
mailing list