From ac406e3f234fef2c8d85f41021b95e4c0f132e7c Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 16 May 2025 14:37:23 +0200 Subject: [PATCH] [CIR] Refactor vector type constraints --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 52 +++++++++----- .../CIR/Dialect/IR/CIRTypeConstraints.td | 55 +++++++++++++++ clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 3 +- .../include/clang/CIR/Dialect/IR/CIRTypes.td | 70 ++++++------------- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 2 +- .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 6 +- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 6 +- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 38 +--------- .../Targets/LoweringPrepareX86CXXABI.cpp | 6 +- clang/test/CIR/IR/invalid-vector.cir | 2 +- clang/test/CIR/IR/invalid.cir | 4 +- 11 files changed, 128 insertions(+), 116 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 300b26de840c..ed66e83e0cd3 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1237,9 +1237,13 @@ def ShiftOp : CIR_Op<"shift", [Pure]> { ``` }]; - let results = (outs CIR_AnyIntOrVecOfInt:$result); - let arguments = (ins CIR_AnyIntOrVecOfInt:$value, CIR_AnyIntOrVecOfInt:$amount, - UnitAttr:$isShiftleft); + let arguments = (ins + CIR_AnyIntOrVecOfIntType:$value, + CIR_AnyIntOrVecOfIntType:$amount, + UnitAttr:$isShiftleft + ); + + let results = (outs CIR_AnyIntOrVecOfIntType:$result); let assemblyFormat = [{ `(` @@ -3125,7 +3129,7 @@ def VecInsertOp : CIR_Op<"vec.insert", [Pure, let arguments = (ins CIR_VectorType:$vec, - AnyType:$value, + CIR_VectorElementType:$value, CIR_AnyFundamentalIntType:$index ); @@ -3158,7 +3162,7 @@ def VecExtractOp : CIR_Op<"vec.extract", [Pure, CIR_AnyFundamentalIntType:$index ); - let results = (outs CIR_AnyType:$result); + let results = (outs CIR_VectorElementType:$result); let assemblyFormat = [{ $vec `[` $index `:` type($index) `]` attr-dict `:` qualified(type($vec)) @@ -3181,7 +3185,7 @@ def VecCreateOp : CIR_Op<"vec.create", [Pure]> { in the vector type. }]; - let arguments = (ins Variadic:$elements); + let arguments = (ins Variadic:$elements); let results = (outs CIR_VectorType:$result); let assemblyFormat = [{ @@ -3211,7 +3215,7 @@ def VecSplatOp : CIR_Op<"vec.splat", [Pure, All elements of the vector have the same value, that of the given scalar. }]; - let arguments = (ins CIR_AnyType:$value); + let arguments = (ins CIR_VectorElementType:$value); let results = (outs CIR_VectorType:$result); let assemblyFormat = [{ @@ -3264,8 +3268,13 @@ def VecTernaryOp : CIR_Op<"vec.ternary", The result is a vector of the same type as the second and third arguments. Each element of the result is `(bool)a[n] ? b[n] : c[n]`. }]; - let arguments = (ins IntegerVector:$cond, CIR_VectorType:$vec1, - CIR_VectorType:$vec2); + + let arguments = (ins + CIR_VectorOfIntType:$cond, + CIR_VectorType:$vec1, + CIR_VectorType:$vec2 + ); + let results = (outs CIR_VectorType:$result); let assemblyFormat = [{ `(` $cond `,` $vec1 `,` $vec2 `)` `:` qualified(type($cond)) `,` @@ -3328,7 +3337,7 @@ def VecShuffleDynamicOp : CIR_Op<"vec.shuffle.dynamic", result vector is constructed by taking the elements from the first input vector from the indices indicated by the elements of the second vector. }]; - let arguments = (ins CIR_VectorType:$vec, IntegerVector:$indices); + let arguments = (ins CIR_VectorType:$vec, CIR_VectorOfIntType:$indices); let results = (outs CIR_VectorType:$result); let assemblyFormat = [{ $vec `:` qualified(type($vec)) `,` $indices `:` qualified(type($indices)) @@ -4712,8 +4721,8 @@ def LLrintOp : UnaryFPToIntBuiltinOp<"llrint", "LlrintOp">; class UnaryFPToFPBuiltinOp : CIR_Op { - let arguments = (ins CIR_AnyFloatOrVecOfFloat:$src); - let results = (outs CIR_AnyFloatOrVecOfFloat:$result); + let arguments = (ins CIR_AnyFloatOrVecOfFloatType:$src); + let results = (outs CIR_AnyFloatOrVecOfFloatType:$result); let summary = "libc builtin equivalent ignoring " "floating point exceptions and errno"; let assemblyFormat = "$src `:` type($src) attr-dict"; @@ -4743,8 +4752,6 @@ def TanOp : UnaryFPToFPBuiltinOp<"tan", "TanOp">; def TruncOp : UnaryFPToFPBuiltinOp<"trunc", "FTruncOp">; def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> { - let arguments = (ins CIR_AnySignedIntOrVecOfSignedInt:$src, UnitAttr:$poison); - let results = (outs CIR_AnySignedIntOrVecOfSignedInt:$result); let summary = [{ libc builtin equivalent abs, labs, llabs @@ -4760,6 +4767,14 @@ def AbsOp : CIR_Op<"abs", [Pure, SameOperandsAndResultType]> { %2 = cir.abs %3 : !cir.vector ``` }]; + + let arguments = (ins + CIR_AnySIntOrVecOfSIntType:$src, + UnitAttr:$poison + ); + + let results = (outs CIR_AnySIntOrVecOfSIntType:$result); + let assemblyFormat = "$src ( `poison` $poison^ )? `:` type($src) attr-dict"; } @@ -4769,9 +4784,12 @@ class BinaryFPToFPBuiltinOp libc builtin equivalent ignoring floating-point exceptions and errno. }]; - let arguments = (ins CIR_AnyFloatOrVecOfFloat:$lhs, - CIR_AnyFloatOrVecOfFloat:$rhs); - let results = (outs CIR_AnyFloatOrVecOfFloat:$result); + let arguments = (ins + CIR_AnyFloatOrVecOfFloatType:$lhs, + CIR_AnyFloatOrVecOfFloatType:$rhs + ); + + let results = (outs CIR_AnyFloatOrVecOfFloatType:$result); let assemblyFormat = [{ $lhs `,` $rhs `:` qualified(type($lhs)) attr-dict diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td index 85113d73a6f0..19057ae80c9b 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -275,4 +275,59 @@ defvar CIR_ScalarTypes = [ def CIR_AnyScalarType : AnyTypeOf { let cppFunctionName = "isScalarType"; } + +//===----------------------------------------------------------------------===// +// Vector Type predicates +//===----------------------------------------------------------------------===// + +def CIR_AnyVectorType : CIR_TypeBase<"::cir::VectorType", "vector type">; + +def CIR_VectorElementType : AnyTypeOf<[CIR_AnyIntOrFloatType, CIR_AnyPtrType], + "any cir integer, floating point or pointer type" +> { + let cppFunctionName = "isValidVectorTypeElementType"; +} + +// Element type constraint bases +class CIR_ElementTypePred : SubstLeaves<"$_self", + "::mlir::cast<::cir::VectorType>($_self).getElementType()", pred>; + +class CIR_VectorTypeOf types, string summary = ""> + : CIR_ConfinedType)>], + !if(!empty(summary), + "vector of " # CIR_TypeSummaries.value, + summary)>; + +// Vector of type constraints +def CIR_VectorOfIntType : CIR_VectorTypeOf<[CIR_AnyIntType]>; +def CIR_VectorOfUIntType : CIR_VectorTypeOf<[CIR_AnyUIntType]>; +def CIR_VectorOfSIntType : CIR_VectorTypeOf<[CIR_AnySIntType]>; +def CIR_VectorOfFloatType : CIR_VectorTypeOf<[CIR_AnyFloatType]>; + +// Vector or Scalar type constraints +def CIR_AnyIntOrVecOfIntType + : AnyTypeOf<[CIR_AnyIntType, CIR_VectorOfIntType], + "integer or vector of integer type"> { + let cppFunctionName = "isIntOrVectorOfIntType"; +} + +def CIR_AnySIntOrVecOfSIntType + : AnyTypeOf<[CIR_AnySIntType, CIR_VectorOfSIntType], + "signed integer or vector of signed integer type"> { + let cppFunctionName = "isSIntOrVectorOfSIntType"; +} + +def CIR_AnyUIntOrVecOfUIntType + : AnyTypeOf<[CIR_AnyUIntType, CIR_VectorOfUIntType], + "unsigned integer or vector of unsigned integer type"> { + let cppFunctionName = "isUIntOrVectorOfUIntType"; +} + +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 230ca015756f..0cd207f38f82 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -26,8 +26,7 @@ struct RecordTypeStorage; } // namespace detail bool isValidFundamentalIntWidth(unsigned width); -bool isFPOrFPVectorTy(mlir::Type); -bool isIntOrIntVectorTy(mlir::Type); + } // namespace cir mlir::ParseResult parseAddrSpaceAttribute(mlir::AsmParser &p, diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 4aa48eb38730..a726fd9e2b34 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -345,11 +345,31 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", let summary = "CIR vector type"; let description = [{ - `cir.vector' represents fixed-size vector types. The parameters are the - element type and the number of elements. + The `!cir.vector` type represents a fixed-size, one-dimensional vector. + It takes two parameters: the element type and the number of elements. + + Syntax: + + ```mlir + vector-type ::= !cir.vector + element-type ::= float-type | integer-type | pointer-type + ``` + + The `element-type` must be a scalar CIR type. Zero-sized vectors are not + allowed. The `size` must be a positive integer. + + Examples: + + ```mlir + !cir.vector x 4> + !cir.vector + ``` }]; - let parameters = (ins "mlir::Type":$elementType, "uint64_t":$size); + let parameters = (ins + CIR_VectorElementType:$elementType, + "uint64_t":$size + ); let builders = [ TypeBuilderWithInferredContext<(ins @@ -503,50 +523,6 @@ def CIR_VoidType : CIR_Type<"Void", "void"> { }]; } -// Constraints - -// Vector of integral type -def IntegerVector : Type< - And<[ - CPred<"::mlir::isa<::cir::VectorType>($_self)">, - CPred<"::mlir::isa<::cir::IntType>(" - "::mlir::cast<::cir::VectorType>($_self).getElementType())">, - CPred<"::mlir::cast<::cir::IntType>(" - "::mlir::cast<::cir::VectorType>($_self).getElementType())" - ".isFundamental()"> - ]>, "!cir.vector of !cir.int"> { -} - -// Vector of signed integral type -def SignedIntegerVector : Type< - And<[ - CPred<"::mlir::isa<::cir::VectorType>($_self)">, - CPred<"::mlir::isa<::cir::IntType>(" - "::mlir::cast<::cir::VectorType>($_self).getElementType())">, - CPred<"::mlir::cast<::cir::IntType>(" - "::mlir::cast<::cir::VectorType>($_self).getElementType())" - ".isSignedFundamental()"> - ]>, "!cir.vector of !cir.int"> { -} - -// Vector of Float type -def FPVector : Type< - And<[ - CPred<"::mlir::isa<::cir::VectorType>($_self)">, - CPred<"::mlir::isa<::cir::SingleType, ::cir::DoubleType>(" - "::mlir::cast<::cir::VectorType>($_self).getElementType())">, - ]>, "!cir.vector of !cir.fp"> { -} - -// Constraints -def CIR_AnyIntOrVecOfInt: AnyTypeOf<[CIR_IntType, IntegerVector]>; - -def CIR_AnySignedIntOrVecOfSignedInt: AnyTypeOf<[ - CIR_AnyFundamentalSIntType, SignedIntegerVector -]>; - -def CIR_AnyFloatOrVecOfFloat: AnyTypeOf<[CIR_AnyFloatType, FPVector]>; - //===----------------------------------------------------------------------===// // RecordType // diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 2ef4193dff32..738351ac41ad 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1482,7 +1482,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_elementwise_abs: { mlir::Type cirTy = convertType(E->getArg(0)->getType()); - bool isIntTy = cir::isIntOrIntVectorTy(cirTy); + bool isIntTy = cir::isIntOrVectorOfIntType(cirTy); if (!isIntTy) { return emitUnaryFPBuiltin(*this, *E); } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index 4a63ccdf9aaa..5e807a091f7a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -4015,7 +4015,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, mlir::Location loc = getLoc(E->getExprLoc()); Ops[0] = builder.createBitcast(Ops[0], ty); Ops[1] = builder.createBitcast(Ops[1], ty); - if (cir::isFPOrFPVectorTy(ty)) { + if (cir::isFPOrVectorOfFPType(ty)) { return builder.create(loc, Ops[0], Ops[1]); } return builder.create(loc, cir::BinOpKind::Max, Ops[0], Ops[1]); @@ -4026,7 +4026,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, case NEON::BI__builtin_neon_vmin_v: case NEON::BI__builtin_neon_vminq_v: { llvm::StringRef name = usgn ? "aarch64.neon.umin" : "aarch64.neon.smin"; - if (cir::isFPOrFPVectorTy(ty)) + if (cir::isFPOrVectorOfFPType(ty)) name = "aarch64.neon.fmin"; return emitNeonCall(builder, {ty, ty}, Ops, name, ty, getLoc(E->getExprLoc())); @@ -4037,7 +4037,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E, case NEON::BI__builtin_neon_vabd_v: case NEON::BI__builtin_neon_vabdq_v: { llvm::StringRef name = usgn ? "aarch64.neon.uabd" : "aarch64.neon.sabd"; - if (cir::isFPOrFPVectorTy(ty)) + if (cir::isFPOrVectorOfFPType(ty)) name = "aarch64.neon.fabd"; return emitNeonCall(builder, {ty, ty}, Ops, name, ty, getLoc(E->getExprLoc())); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index a84f777d7153..8a81b60c1c2b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1361,7 +1361,7 @@ mlir::Value ScalarExprEmitter::emitMul(const BinOpInfo &Ops) { !CanElideOverflowCheck(CGF.getContext(), Ops)) llvm_unreachable("NYI"); - if (cir::isFPOrFPVectorTy(Ops.LHS.getType())) { + if (cir::isFPOrVectorOfFPType(Ops.LHS.getType())) { CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); return Builder.createFMul(Ops.LHS, Ops.RHS); } @@ -1414,7 +1414,7 @@ mlir::Value ScalarExprEmitter::emitAdd(const BinOpInfo &Ops) { !CanElideOverflowCheck(CGF.getContext(), Ops)) llvm_unreachable("NYI"); - if (cir::isFPOrFPVectorTy(Ops.LHS.getType())) { + if (cir::isFPOrVectorOfFPType(Ops.LHS.getType())) { CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); return Builder.createFAdd(Ops.LHS, Ops.RHS); } @@ -1457,7 +1457,7 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &Ops) { !CanElideOverflowCheck(CGF.getContext(), Ops)) llvm_unreachable("NYI"); - if (cir::isFPOrFPVectorTy(Ops.LHS.getType())) { + if (cir::isFPOrVectorOfFPType(Ops.LHS.getType())) { CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); return Builder.createFSub(Ops.LHS, Ops.RHS); } diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 26271503e48b..a6e7f49d2733 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -421,17 +421,7 @@ mlir::LogicalResult cir::VectorType::verify( mlir::Type elementType, uint64_t size) { if (size == 0) return emitError() << "the number of vector elements must be non-zero"; - - // Check if it a valid FixedVectorType - if (mlir::isa(elementType)) - return success(); - - // Check if it a valid VectorType - if (mlir::isa(elementType) || - isAnyFloatingPointType(elementType)) - return success(); - - return emitError() << "unsupported element type for CIR vector"; + return success(); } // TODO(cir): Implement a way to cache the datalayout info calculated below. @@ -758,32 +748,6 @@ LongDoubleType::getABIAlignment(const mlir::DataLayout &dataLayout, .getABIAlignment(dataLayout, params); } -//===----------------------------------------------------------------------===// -// Floating-point and Float-point Vector type helpers -//===----------------------------------------------------------------------===// - -bool cir::isFPOrFPVectorTy(mlir::Type t) { - - if (isa(t)) { - return isAnyFloatingPointType( - mlir::dyn_cast(t).getElementType()); - } - return isAnyFloatingPointType(t); -} - -//===----------------------------------------------------------------------===// -// CIR Integer and Integer Vector type helpers -//===----------------------------------------------------------------------===// - -bool cir::isIntOrIntVectorTy(mlir::Type t) { - - if (isa(t)) { - return isa( - mlir::dyn_cast(t).getElementType()); - } - return isa(t); -} - //===----------------------------------------------------------------------===// // ComplexType Definitions //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareX86CXXABI.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareX86CXXABI.cpp index 334034b682c1..d9cd288bd999 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareX86CXXABI.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/LoweringPrepareX86CXXABI.cpp @@ -201,12 +201,12 @@ mlir::Value LoweringPrepareX86CXXABI::lowerVAArgX86_64( "Unexpected ABI info for mixed regs"); mlir::Type tyLo = recordTy.getMembers()[0]; mlir::Type tyHi = recordTy.getMembers()[1]; - assert((isFPOrFPVectorTy(tyLo) ^ isFPOrFPVectorTy(tyHi)) && + assert((isFPOrVectorOfFPType(tyLo) ^ isFPOrVectorOfFPType(tyHi)) && "Unexpected ABI info for mixed regs"); mlir::Value gpAddr = builder.createPtrStride(loc, regSaveArea, gp_offset); mlir::Value fpAddr = builder.createPtrStride(loc, regSaveArea, fp_offset); - mlir::Value regLoAddr = isFPOrFPVectorTy(tyLo) ? fpAddr : gpAddr; - mlir::Value regHiAddr = isFPOrFPVectorTy(tyHi) ? gpAddr : fpAddr; + mlir::Value regLoAddr = isFPOrVectorOfFPType(tyLo) ? fpAddr : gpAddr; + mlir::Value regHiAddr = isFPOrVectorOfFPType(tyHi) ? gpAddr : fpAddr; // Copy the first element. // FIXME: Our choice of alignment here and below is probably pessimistic. diff --git a/clang/test/CIR/IR/invalid-vector.cir b/clang/test/CIR/IR/invalid-vector.cir index 2d26cade2348..43a1d1cb5dd8 100644 --- a/clang/test/CIR/IR/invalid-vector.cir +++ b/clang/test/CIR/IR/invalid-vector.cir @@ -4,7 +4,7 @@ module { -// expected-error @below {{unsupported element type for CIR vector}} +// expected-error @below {{failed to verify 'elementType'}} cir.global external @vec_b = #cir.zero : !cir.vector x 4> } diff --git a/clang/test/CIR/IR/invalid.cir b/clang/test/CIR/IR/invalid.cir index e2a4eb3bb1d2..9ac1fae82abc 100644 --- a/clang/test/CIR/IR/invalid.cir +++ b/clang/test/CIR/IR/invalid.cir @@ -477,7 +477,7 @@ cir.func @vec_insert_non_vector() { cir.func @vec_ternary_non_vector1() { %0 = cir.const #cir.int<0> : !s32i %1 = cir.vec.create(%0, %0 : !s32i, !s32i) : !cir.vector - %2 = cir.vec.ternary(%0, %1, %1) : !s32i, !cir.vector // expected-error {{'cir.vec.ternary' op operand #0 must be !cir.vector of !cir.int, but got '!cir.int'}} + %2 = cir.vec.ternary(%0, %1, %1) : !s32i, !cir.vector // expected-error {{'cir.vec.ternary' op operand #0 must be vector of integer type, but got '!cir.int'}} cir.return } @@ -506,7 +506,7 @@ cir.func @vec_ternary_different_size() { cir.func @vec_ternary_not_int(%p : !cir.float) { %0 = cir.vec.create(%p, %p : !cir.float, !cir.float) : !cir.vector - %1 = cir.vec.ternary(%0, %0, %0) : !cir.vector, !cir.vector // expected-error {{'cir.vec.ternary' op operand #0 must be !cir.vector of !cir.int, but got '!cir.vector'}} + %1 = cir.vec.ternary(%0, %0, %0) : !cir.vector, !cir.vector // expected-error {{'cir.vec.ternary' op operand #0 must be vector of integer type, but got '!cir.vector'}} cir.return }